How to pass storageSlots to make default values instead of undefined

Here is storage of my Market contract that has following data.

How to pass storageSlots them so it would work, because I tried to do ::default() but value is still undefined , so I have to use try_read().unwrap_or(0) in every line where I want to read value.

1 Like

Me and @sway tried to understand how to do that using the doc, and on the Deploying a contract binary page we have next example:

But we can’t understand, in this example author uses key and value as Bytes32.
For example, we have that type of storage

storage {
    collateral_configurations: StorageMap<AssetId, CollateralConfiguration> = StorageMap {}, 
    collateral_configurations_keys: StorageVec<AssetId> = StorageVec {},
    pause_config: PauseConfiguration = PauseConfiguration::default(),
    totals_collateral: StorageMap<AssetId, u64> = StorageMap {},
    user_collateral: StorageMap<(Address, AssetId), u64> = StorageMap {},
    user_basic: StorageMap<Address, UserBasic> = StorageMap {},
    market_basic: MarketBasics = MarketBasics::default(),
    
    debug_timestamp: u64 = 0,
}

Can you explain please how to define all of the storage here?

I expected something like this as an answer:

let rng = &mut StdRng::seed_from_u64(2322u64);
let salt: [u8; 32] = rng.gen();

// Optional: Configure storage
let mut storage_configuration = StorageConfiguration::default();

storage_configuration.add("collateral_configurations", vec![]);
storage_configuration.add("collateral_configurations_keys", vec![]);
storage_configuration.add("pause_config", PauseConfiguration::default());
storage_configuration.add("totals_collateral", HashMap::new());
storage_configuration.add("user_collateral", HashMap::new());
storage_configuration.add("user_basic", HashMap::new());
storage_configuration.add("market_basic", MarketBasics::default());
debug_timestamp.add("market_basic", 0);

let configuration = LoadConfiguration::default()
    .with_storage_configuration(storage_configuration)
    .with_salt(salt);

// Optional: Configure deployment parameters
let tx_parameters = TxParameters::default()
    .with_gas_price(0)
    .with_gas_limit(1_000_000)
    .with_maturity(0);

let contract_id_2 = Contract::load_from(
    "../../packages/fuels/tests/contracts/contract_test/out/debug/contract_test.bin",
    configuration,
)?
.deploy(&wallet, tx_parameters)
.await?;

println!("Contract deployed @ {contract_id_2}");

Toolchain

Default host: aarch64-apple-darwin
fuelup home: /Users/alexey/.fuelup

installed toolchains
--------------------
beta-3-aarch64-apple-darwin
beta-4-rc.2-aarch64-apple-darwin
latest-aarch64-apple-darwin (default)
hotfix
my-custom-toolchain

active toolchain
-----------------
latest-aarch64-apple-darwin (default)
  forc : 0.44.1
    - forc-client
      - forc-deploy : 0.44.1
      - forc-run : 0.44.1
    - forc-doc : 0.44.1
    - forc-explore : 0.28.1
    - forc-fmt : 0.44.1
    - forc-index : 0.20.7
    - forc-lsp : 0.44.1
    - forc-tx : 0.44.1
    - forc-wallet : 0.3.0
  fuel-core : 0.20.4
  fuel-core-keygen : Error getting version string
  fuel-indexer : 0.20.7

fuels versions
---------------
forc : 0.45
forc-wallet : 0.45

P.S.
I found how to load default storage slots, but still don’t know how to edit it

    let mut rng = rand::thread_rng();
    let salt = rng.gen::<[u8; 32]>();
    let configurables = MarketContractConfigurables::default()
        .with_MARKET_CONFIGURATION(Option::Some(market_configuration))
        .with_DEBUG_STEP(debug_step);
    let storage = StorageConfiguration::load_from("./out/debug/market-storage_slots.json").unwrap();
    let config = LoadConfiguration::default()
        .with_configurables(configurables)
        .with_storage_configuration(storage);

    let id = Contract::load_from("./out/debug/market.bin", config)
        .unwrap()
        .with_salt(salt)
        .deploy(wallet, TxParameters::default().with_gas_price(1))
        .await
        .unwrap();

    MarketContract::new(id, wallet.clone())

Hi there!

Definitively try_read().unwrap_or(0) is not funny at all + requires too much typing :sob:
Such an awful experience makes me feel that something’s off and this is the case.

Basically the issue is that “the language isn’t the software that does the initialization” so the client must enforce that default values initialization. This was a bug, solved for fuels-ts and fuels-rs. It will be available from 0.48.

I strongly recommend you to update your sdk versions since they now automatically enforce default values initialization. Otherwise, check this fix.

The main difference between this fix and the one you found is that the default storage values are output into a different json file from the abi. This mean you’ll have to load that file (rather than setting a default value for each storage property).

ie

// fuels-rs
 let storage_config =
        StorageConfiguration::load_from("out/debug/counter-contract-storage_slots.json").unwrap();
    let load_config = LoadConfiguration::default().set_storage_configuration(storage_config);

    let id = Contract::load_from("./out/debug/counter-contract.bin", load_config)
        .unwrap()
        .deploy(&wallet, TxParameters::default())
        .await
        .unwrap();

Anyways , this is just explanatory code just to answer to your specific question since the fix for storage initialization is already merged and it’s done automatically in the latest versions of fuels-ts and fuels-rs. (0.48 and beyond for fuels-rs)

I’m using the latest version of Rust SDK 0.47

  • We need to deploy/load contracts like here to avoid try_read().unwrap_or(.., is it correct?
  • How to change storage slots during deployment I still don’t understand, can you explain it, please?
  • What was fixed on fuels-ts and fuels-rs ? Like storage slots stand up automatically? I don’t quite get it.
  1. yes, this workaround enforces the default storage initialization
  2. It seems to me that overwriting the props of storage_configuration is the best choice if you want to modify the default storage during deployment, but why would you like to do that?
  3. yes, the automatic storage initialization was merged but not released yet. It will be available since fuels-rs 0.48

1 and 3 ok
2:
In swaylend, we need to put collateral configurations into contract storage rn we are calling fn add_asset_collateral 6 times after deployment

But I want to set this data into storage during deployment

1 Like

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.