There’s a discrepancy in the values returned by getBalance
in the TS SDK, and balance_of
fn in Sway.
To reproduce:
use std::{context::*, asset::*, call_frames::contract_id};
abi Fungible {
fn get_asset_id() -> AssetId;
fn mint(recipient: Identity, amount: u64) ;
#[payable]
fn transfer(to: Identity, amount: u64);
}
impl Fungible for Contract {
fn get_asset_id() -> AssetId {
AssetId::new(contract_id(), ZERO_B256)
}
#[storage(read, write)]
fn mint(recipient: Identity, amount: u64) {
let asset_id = AssetId::new(contract_id(), ZERO_B256);
let supply = storage.total_supply.get(asset_id);
storage
.total_supply
.insert(asset_id, supply.try_read().unwrap_or(0) + amount);
mint_to(recipient, ZERO_B256, amount);
}
#[payable]
fn transfer(to: Identity, amount: u64) {
let asset_id = AssetId::new(contract_id(), ZERO_B256);
transfer(to, asset_id, amount);
}
}
use std::{context::*, asset::*, call_frames::contract_id};
abi BalanceChecker {
fn get_balance_for(asset_id: AssetId) -> u64;
}
impl BalanceChecker for Contract {
/// Get the internal balance of a specific coin at a specific contract.
fn get_balance_for(asset_id: AssetId) -> u64 {
balance_of(contract_id(), asset_id)
}
}
deploy both contracts via local node
// BTC = Fungible
// BALANCE_CHECKER = BalanceChecker
// Balance before: { contr: '0', balan: '0' }
console.log("Balance before:", {
contr: (await BALANCE_CHECKER.functions.get_balance_for(toAsset(BTC)).call()).value.toString(),
balan: (await BALANCE_CHECKER.getBalance(getAssetId(BTC))).toString()
})
await BTC.functions.mint(addrToIdentity(deployer), "2_000_000_000").call()
await BTC.functions
.transfer(contrToIdentity(BALANCE_CHECKER), "1_000_000_000")
.callParams({ forward: ["1_000_000_000", getAssetId(BTC)] })
// Balance after: { contr: '0', balan: '1000000000' }
console.log("Balance after:", {
contr: (await BALANCE_CHECKER.functions.get_balance_for(toAsset(BTC)).call()).value.toString(),
balan: (await BALANCE_CHECKER.getBalance(getAssetId(BTC))).toString()
})
import { getAssetId as getAssetIdFuels, } from "fuels"
// getAssetId:
export function getAssetId(
fungibleContract: any,
sub_id: string = "0x0000000000000000000000000000000000000000000000000000000000000000",
): string {
return getAssetIdFuels(fungibleContract.id.toHexString(), sub_id)
}
// Verify assetids
const asset_id_from_contract = (await BTC.functions.get_asset_id().call()).value.value
const asset_id_from_fuels = getAssetId(BTC)
assert asset_id_from_contract == asset_id_from_fuels // this doesn't throw
according to the above, the native asset “BTC” is transferred successfully to the contract BALANCE_CHECKER, and can be verified with the getBalance
function in the TS SDK. However, from the contract’s perspective, there was no native asset forwarded to it. Am I doing something wrong here?
I’ve also verified that the asset id’s match (see the assert statement above).