Inter Contract Calls

Icon Link使用 SDK 进行合约间调用

本指南介绍如何使用 SDK 执行合约调用,其中一个合约与另一个合约进行交互。我们将使用一个简单的场景,涉及到一个 SimpleToken 合约和一个 TokenDepositor 合约。

Icon LinkSimpleTokenTokenDepositor 合约

在这个例子中,我们有一个 SimpleToken 合约,代表一个基本的代币合约,能够为不同地址保存余额。我们还有一个 TokenDepositor 合约,它将代币存入 SimpleToken 合约。

Icon Link合约: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
    }
}

Icon Link合约: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);
    }
}

Icon Link使用 SDK 进行合约间调用

一旦两个合约都部署了,我们就可以使用 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 方法。该方法接受一个已部署合约实例的数组。如果不调用此方法,合约间调用将不起作用。