调用其他合约
在Cairo,有两种不同的方式可以调用其他合约。
调用其他合约的最简单方法是使用要调用的合约的调度程序。 您可以在 Cairo Book 中阅读有关 Dispatchers 的更多信息
另一种方法是自己使用starknet::call_contract_syscall
系统调用。但是,不建议使用此方法。
为了使用调度程序调用其他合约,您需要将被调用合约的接口定义为使用 #[starknet::interface]
属性注释的trait,然后将 IContractDispatcher
和 IContractDispatcherTrait
项导入到合约中。
#[starknet::interface]
trait ICallee<TContractState> {
fn set_value(ref self: TContractState, value: u128) -> u128;
}
#[starknet::contract]
mod Callee {
#[storage]
struct Storage {
value: u128,
}
#[abi(embed_v0)]
impl ICalleeImpl of super::ICallee<ContractState> {
fn set_value(ref self: ContractState, value: u128) -> u128 {
self.value.write(value);
value
}
}
}
在 Voyager 上访问 合约 或在 Remix中尝试它。
use starknet::ContractAddress;
// We need to have the interface of the callee contract defined
// so that we can import the Dispatcher.
#[starknet::interface]
trait ICallee<TContractState> {
fn set_value(ref self: TContractState, value: u128) -> u128;
}
#[starknet::interface]
trait ICaller<TContractState> {
fn set_value_from_address(ref self: TContractState, addr: ContractAddress, value: u128);
}
#[starknet::contract]
mod Caller {
// We import the Dispatcher of the called contract
use super::{ICalleeDispatcher, ICalleeDispatcherTrait};
use starknet::ContractAddress;
#[storage]
struct Storage {}
#[abi(embed_v0)]
impl ICallerImpl of super::ICaller<ContractState> {
fn set_value_from_address(ref self: ContractState, addr: ContractAddress, value: u128) {
ICalleeDispatcher { contract_address: addr }.set_value(value);
}
}
}