FuelLabs / sway-standards

SRC Standards set for the Sway language
Apache License 2.0
161 stars 50 forks source link

SRC20: A method to retrieve assets #143

Open andy-thomason opened 2 months ago

andy-thomason commented 2 months ago

Motivation

SRC20 has a total_assets() method to get the number of assets present and we have new log types to retrieve these data through log scraping.

However it is still impossible retrieve contract metadata entirely from state as we cannot make any assumptions about the AssetId or sub_id.

Might it not be a good idea to add a method:

    /// Returns the Asset ID at a certain index.
    ///
    /// # Returns
    ///
    /// * [Option<AssetId>] - The Asset ID at a certain index or None if out of bounds.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    ///
    /// fn foo(contract: ContractId) {
    ///     let contract_abi = abi(SRC20, contract);
    ///     let asset = contract_abi.asset(0);
    ///     assert(asset.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn asset(index: u64) -> Option<AssetId>;

With this we can enumerate contained assets.

andy-thomason commented 2 months ago

Note that if sub_id < total_assets then this is unnecessary.

dmihal commented 2 months ago

I'm not sure this is the right approach, as this requires significant ($O(n)$) state to store all these assets. It also requires contracts to "order" their assets, which they may not want to.

andy-thomason commented 2 months ago

If you could suggest another way to enumerate assets or sub_ids, this would be useful.

A simpler approach would be to simply require sequential sub_ids.

andy-thomason commented 2 months ago

A contract could choose to return sequential sub_ids or use a mapping from asset index to asset.

The former requires zero storage and the latter only one storage slot per asset.

Note that the majority of the current SRC20 implementations use sub_id = 0 and have only one asset requiring no extra storage to implement this.

andy-thomason commented 2 months ago

I currently have to do symbolic execution of the contracts to impute the assets. Not an option for the causal user.