# Confusion about Assets on Sway

**URL:** <https://forum.fuel.network/t/confusion-about-assets-on-sway/4210>\
**Category:** Sway\
**Tags:** testnet\
**Created:** [February 9, 2024, 4:10am UTC](https://forum.fuel.network/t/confusion-about-assets-on-sway/4210 "2024-02-09T04:10:02Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![theAusicist](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/theausicist/32/1987_2.png) [@theAusicist](https://forum.fuel.network/u/theAusicist)\
**Post date:** [February 9, 2024, 4:10am UTC](https://forum.fuel.network/t/confusion-about-assets-on-sway/4210/1 "2024-02-09T04:10:02Z")

</div>

I’ve been trying to wrap my head around assets on Sway, and I’m confused to say the least. It’s quite different from how an ERC-20 token on the EVM is constructed. I’m using the [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets/) part of the docs, and this has confused me even further. I’ll try and elucidate my thinking process, and I’d love if someone could help clear this.

Essentially, the `BASE_SUB_ID`/`BASE_ASSET_ID` (which is an alias for `ZERO_B256`/`0x0000000000000000000000000000000000000000000000000000000000000000`) represents the native asset on the Fuel network (_i.e_ Ether), so if I was writing a method that would accept only Ether, I’d construct it as follows:

```rust
fn deposit(amount: u64) {
    require(msg_asset_id() == BASE_SUB_ID, "Only Ether accepted");
    ...
}

```

# Minting/Burning

The above makes empirical sense, but the confusion starts when attempting to `mint` and `transfer` your own assets. Following the [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets/) section of the docs, we see the following methods

```rust
/// Mint an amount of this contracts native asset to the contracts balance.
fn mint_coins(mint_amount: u64) {
	mint(ZERO_B256, mint_amount);
}
 
/// Burn an amount of this contracts native asset.
fn burn_coins(burn_amount: u64) {
	burn(ZERO_B256, burn_amount);
}

```

Based on [this post](https://forum.fuel.network/t/ownership-of-native-assets/3106/5), the `ZERO_B256` is the sub id of the asset (the final asset id of which is a hash of the current `contract_id()` and this `sub_id`). So, this allows for multiple native tokens under the same contract (which is neat!).

# Getting Balance

But because of this abstraction (the final asset id of which is a hash of the current `contract_id()` and the `sub_id`), querying the balance of a contract is a little confusing with `balance_of`.

From [here](https://github.com/FuelLabs/sway/blob/046d292615c60934c691a181874b87fac0d35a27/sway-lib-std/src/context.sw#L54), the implementation of `balance_of` is:

````rust
/// # Examples
///
/// ```sway
/// use std::{context::balance_of, constants::ZERO_B256, hash::sha256, asset::mint, call_frames::contract_id};
///
/// fn foo() {
/// mint(ZERO_B256, 50);
/// assert(balance_of(contract_id(), sha256((ZERO_B256, contract_id()))) == 50);
/// }
/// ```
pub fn balance_of(target: ContractId, asset_id: AssetId) -> u64 {
    asm(balance, asset: asset_id.value, id: target.value) {
        bal balance asset id;
        balance: u64
    }
}

````

Based on this design, there’s a slight nuance involved: there’s no obvious way of querying a contract’s balance for a particular `sub_id` _outright_. According to the docs, the right way of calling the `balance_of` method is: `balance_of(contract_id(), sha256((ZERO_B256, contract_id())` where `ZERO_B256` again is for the `sub_id` of the asset. But _is this correct?_

I wrote a helper method below to query the contract’s internal balance as below, according to the method docs, but **this is incorrect**

```rust
fn this_balance() -> u64 {
    balance_of(
        /* target: current contract */
        contract_id(), 
        /* asset_id: hash of sub_id and contract_id */
        AssetId::from(sha256((ZERO_B256, contract_id()))) 
    )
}

```

the **correct** way is by swapping the values of `sub_id` and `contract_id()` within the hash function like so:

```rust
fn this_balance() -> u64 {
    balance_of(
        /* target: current contract */
        contract_id(), 
        /* asset_id: hash of sub_id and contract_id */
        AssetId::from(sha256((contract_id(), ZERO_B256)))
    )
}

```

imo, there needs to be better documentation highlighting this, something like the following:

```rust
fn get_balance(
    target: ContractId, 
    native_asset_contr: ContractId, 
    sub_id: b256
) -> u64 {
    let asset_id = AssetId::from(sha256((native_asset_contr, sub_id)));
    balance_of(contract_id(), asset_id)
}

```

and something similar for the `transfer` method as well.

**Question:** is there no way to query the balance of a regular EOA on-chain like one can do with contracts? I am aware of the UTXO model for EOAs which doesn’t exist for contracts, but still curious if something like this is possible to achieve?

**Question** : since there exists a scope for many different types of `sub_id`s for a particular contract leading to many different native assets for said contract, how would their `asset_id`s be viewable in the explorer?

Edit: some resources that can help:

- [https://github.com/FuelLabs/sway-applications/blob/master/native-assets/native-asset/project/contracts/native-asset-contract/](https://github.com/FuelLabs/sway-applications/blob/master/native-assets/native-asset/project/contracts/native-asset-contract/)
- [https://github.com/FuelLabs/sway-libs/blob/master/libs/native\_asset](https://github.com/FuelLabs/sway-libs/blob/master/libs/native_asset)

---

<div class="post-metadata">

**Author:** ![bitzoic](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/bitzoic/32/2077_2.png) [@bitzoic](https://forum.fuel.network/u/bitzoic)\
**Post date:** [February 9, 2024, 4:42am UTC](https://forum.fuel.network/t/confusion-about-assets-on-sway/4210/2 "2024-02-09T04:42:24Z")

</div>

> **this is incorrect**
> 
> ```auto
> fn this_balance() -> u64 {
> balance_of(
> /* target: current contract */
> contract_id(), 
> /* asset_id: hash of sub_id and contract_id */
> AssetId::from(sha256((ZERO_B256, contract_id()))) 
> )
> }
> 
> ```

Here you are hashing first the `SubId` and then the `ContractId` i.e. `(SubId, ContractId)`. As the input/bytes for the hash are different from `(ContractId, SubId)` the resulting hash is different. Ordering here matters. For example, the hash digest of `(0u8, 1u8)` is different from `(1u8, 0u8)`.

> is there no way to query the balance of a regular EOA on-chain like one can do with contracts? I am aware of the UTXO model for EOAs which doesn’t exist for contracts, but still curious if something like this is possible to achieve?

This is not possible to do in the Sway language but can be done with the Rust or typescript SDK. One can however view the inputs and outputs of a transaction and thus see the balance with `msg_amount()`.

> since there exists a scope for many different types of `sub_id` s for a particular contract leading to many different native assets for said contract, how would their `asset_id` s be viewable in the explorer?

The `AssetId` of all assets minted by a contract are distinguishable from one another. They will each have a unique `AssetId` and would be viewed in the explorer as separate assets.

Anytime a new asset is minted, there is a [receipt](https://github.com/FuelLabs/fuel-specs/blob/master/src/abi/receipts.md#mint-receipt) logged containing the `ContractId` and `SubId`. The `SubId` of an asset should only be relevant when minting and burning, as all transfer and mangement functions use the `AssetId`.

To create a new `AssetId` from a `ContractId` and `SubId`, you can use the `AssetId::new()` function found [here](https://github.com/FuelLabs/sway/blob/80be6085171cd5cb05a655e42f45331379e546c0/sway-lib-std/src/asset_id.sw#L107).

In your example, you can query the balance like so:

```sway
// For any SubId within the current contract
let asset_id = AssetId::new(contract_id(), my_sub_id);
let balance = this_balance(asset_id);

// For DEFAULT_SUB_ID or the ZERO_B256 within the current contract
let asset_id = AssetId::default();
let balance = this_balance(asset_id);

// For the BASE_ASSET_ID within the current contract
let balance = this_balance(BASE_ASSET_ID);

// For any external contract and SubId
let asset_id = AssetId::new(my_contract, my_sub_id);
let balance = balance_of(my_contract, asset_id);

```

---

<div class="post-metadata">

**Author:** ![theAusicist](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/theausicist/32/1987_2.png) [@theAusicist](https://forum.fuel.network/u/theAusicist)\
**Post date:** [February 9, 2024, 4:54am UTC](https://forum.fuel.network/t/confusion-about-assets-on-sway/4210/3 "2024-02-09T04:54:11Z")

</div>

> [@bitzoic](#):
>
> Here you are hashing first the `SubId` and then the `ContractId` i.e. `(SubId, ContractId)`. As the input/bytes for the hash are different from `(ContractId, SubId)` the resulting hash is different. Ordering here matters. For example, the hash digest of `(0u8, 1u8)` is different from `(1u8, 0u8)`.

yup, the comment over the [`balance_of` implementation](https://github.com/FuelLabs/sway/blob/046d292615c60934c691a181874b87fac0d35a27/sway-lib-std/src/context.sw#L54) is incorrect (points to the incorrect ordering (`sha256((ZERO_B256, contract_id()))` as opposed to `sha256((contract_id(), ZERO_B256))`), so that added to the confusion.

Thanks a ton!

---

<div class="post-metadata">

**Author:** ![bitzoic](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/bitzoic/32/2077_2.png) [@bitzoic](https://forum.fuel.network/u/bitzoic)\
**Post date:** [February 9, 2024, 5:04am UTC](https://forum.fuel.network/t/confusion-about-assets-on-sway/4210/4 "2024-02-09T05:04:02Z")

</div>

> yup, the comment over the [`balance_of` implementation](https://github.com/FuelLabs/sway/blob/046d292615c60934c691a181874b87fac0d35a27/sway-lib-std/src/context.sw#L54) is incorrect

Thank you for bringing this up. This is resolved in [this](https://github.com/FuelLabs/sway/pull/5586) PR.

---

<div class="post-metadata">

**Author:** ![david](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/david/32/32_2.png) [@david](https://forum.fuel.network/u/david)\
**Post date:** [February 9, 2024, 5:39am UTC](https://forum.fuel.network/t/confusion-about-assets-on-sway/4210/5 "2024-02-09T05:39:05Z")

</div>

Whoops, @bitzoic beat me to responding, but here’s my original response just for reference 🙂

* * *

Hey @theAusicist, Fuel’s native assets are definitely one of our more unique features. This unlocks some really interesting stuff, but can also be a bit of a transition compared to ERC20-style architectures.

I saw that you’re using the `sha256` directly a few places, which certainly _should_ work, however the suggested way to generate an AssetId is using the `new` function:

```rust
let assetId = AssetId::new(contract_id(), sub_id);

```

> imo, there needs to be better documentation highlighting this, something like the

100%, this is great feedback, I’m sharing this internally to make sure we can make this clearer in the docs.

> **Question:** is there no way to query the balance of a regular EOA on-chain like one can do with contracts?

Correct, the UTXO model of Fuel means that you can’t definitively check the balance of an address on-chain, because some UTXOs might not be included in a given transaction.

> **Question** : since there exists a scope for many different types of `sub_id`s for a particular contract leading to many different native assets for said contract, how would their `asset_id`s be viewable in the explorer?

Great question, I’d have to defer to the team building our block explorer, but I believe the explorer will show a list of all assets minted by a given smart contract.

---

<div class="post-metadata">

**Author:** ![theAusicist](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/theausicist/32/1987_2.png) [@theAusicist](https://forum.fuel.network/u/theAusicist)\
**Post date:** [February 9, 2024, 6:01am UTC](https://forum.fuel.network/t/confusion-about-assets-on-sway/4210/6 "2024-02-09T06:01:21Z")

</div>

neat. thanks @david and @bitzoic.

---

<div class="post-metadata">

**Author:** ![theAusicist](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/theausicist/32/1987_2.png) [@theAusicist](https://forum.fuel.network/u/theAusicist)\
**Post date:** [February 12, 2024, 4:45am UTC](https://forum.fuel.network/t/confusion-about-assets-on-sway/4210/8 "2024-02-12T04:45:00Z")

</div>

Wrote an implementation of the Fuel Native Asset standard incorporating the SRC20 and SRC3 (mint/burn capabilities): [GitHub - burralabs/fuel-asset-standard: An unofficial implementation of the Fuel Native Asset Standard](https://github.com/burralabs/fuel-asset-standard)
