调用其他合约

在Cairo,有两种不同的方式可以调用其他合约。

调用其他合约的最简单方法是使用要调用的合约的调度程序。 您可以在 Cairo Book 中阅读有关 Dispatchers 的更多信息

另一种方法是自己使用starknet::call_contract_syscall系统调用。但是,不建议使用此方法。

为了使用调度程序调用其他合约,您需要将被调用合约的接口定义为使用 #[starknet::interface] 属性注释的trait,然后将 IContractDispatcherIContractDispatcherTrait 项导入到合约中。

#[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);
        }
    }
}

Voyager 上访问合约或在 Remix 中尝试它。

Last change: 2023-11-30, commit: fec6527