本指南介绍如何使用 SDK 执行合约调用,其中一个合约与另一个合约进行交互。我们将使用一个简单的场景,涉及到一个 SimpleToken
合约和一个 TokenDepositor
合约。
SimpleToken
和 TokenDepositor
合约 在这个例子中,我们有一个 SimpleToken
合约,代表一个基本的代币合约,能够为不同地址保存余额。我们还有一个 TokenDepositor
合约,它将代币存入 SimpleToken
合约。
SimpleToken
这是一个简单的代币合约,允许保存余额:
contract;
use ::simple_token_abi::SimpleToken;
use std::hash::*;
storage {
balances: StorageMap<b256, u64> = StorageMap {},
}
impl SimpleToken for Contract {
#[storage(read, write)]
fn deposit(address: b256, amount: u64) {
let current_balance = storage.balances.get(address).try_read().unwrap_or(0);
storage.balances.insert(address, current_balance + amount);
}
#[storage(read)]
fn get_balance(address: b256) -> u64 {
let balance = storage.balances.get(address).try_read().unwrap_or(0);
balance
}
}
TokenDepositor
TokenDepositor
合约导入 SimpleToken
合约并调用其 deposit
函数存入代币:
contract;
use std::auth::msg_sender;
use ::simple_token_abi::SimpleToken;
abi TokenDepositor {
fn deposit_to_simple_token(contract_id: b256, amount: u64);
}
impl TokenDepositor for Contract {
fn deposit_to_simple_token(contract_id: b256, amount: u64) {
let simple_token_contract = abi(SimpleToken, contract_id);
let sender = msg_sender().unwrap();
let address: b256 = match sender {
Identity::Address(sender_param) => sender_param.bits(),
_ => revert(0),
};
simple_token_contract.deposit(address, amount);
}
}
一旦两个合约都部署了,我们就可以使用 SDK 使 TokenDepositor
合约调用 SimpleToken
合约。
const amountToDeposit = 70;
const { value: initialBalance } = await simpleToken.functions
.get_balance(wallet.address.toB256())
.call();
expect(new BN(initialBalance).toNumber()).toBe(0);
await tokenDepositor.functions
.deposit_to_simple_token(simpleToken.id.toB256(), amountToDeposit)
.addContracts([simpleToken])
.call();
const { value: finalBalance } = await simpleToken.functions
.get_balance(wallet.address.toB256())
.call();
expect(new BN(finalBalance).toNumber()).toBe(amountToDeposit);
请注意 TokenDepositor
合约调用的 addContracts
方法。该方法接受一个已部署合约实例的数组。如果不调用此方法,合约间调用将不起作用。