Solidity极简入门#21. 调用其他合约
  6WDFuiiGwNIX 2023年11月02日 36 0

调用已部署合约

开发者写智能合约来调用其他合约,这让Ethereum网络上的程序可以复用,从而建立繁荣的生态。很多web3项目依赖于调用其他合约,比如收益农场(yield farming)。这一讲,我们介绍如何在已知合约代码(或接口)和地址情况下调用目标合约的函数。

目标合约

我们先写一个简单的合约OtherContract来调用。

contract OtherContract {
uint256 private _x = 0; // 状态变量_x
// 收到eth的事件,记录amount和gas
event Log(uint amount, uint gas);

// 返回合约ETH余额
function getBalance() view public returns(uint) {
return address(this).balance;
}

// 可以调整状态变量_x的函数,并且可以往合约转ETH (payable)
function setX(uint256 x) external payable{
_x = x;
// 如果转入ETH,则释放Log事件
if(msg.value > 0){
emit Log(msg.value, gasleft());
}
}

// 读取_x
function getX() external view returns(uint x){
x = _x;
}
}


这个合约包含一个状态变量_x,一个事件Log在收到ETH时触发,三个函数:

  • getBalance(): 返回合约ETH余额。
  • setX(): external payable函数,可以设置_x的值,并向合约发送ETH。
  • getX(): 读取_x的值。

调用OtherContract合约

我们可以利用合约的地址和合约代码(或接口)来创建合约的引用:_Name(_Address),其中_Name是合约名,_Address是合约地址。然后用合约的引用来调用它的函数:_Name(_Address).f(),其中f()是要调用的函数。

下面我们介绍4个调用合约的例子,在remix中编译合约后,分别部署OtherContract和CallContract:

Solidity极简入门#21. 调用其他合约_Ethereum

Solidity极简入门#21. 调用其他合约_web3_02

Solidity极简入门#21. 调用其他合约_Ethereum_03

1. 传入合约地址

我们可以在函数里传入目标合约地址,生成目标合约的引用,然后调用目标函数。以调用OtherContract合约的setX函数为例,我们在新合约中写一个callSetX函数,传入已部署好的OtherContract合约地址_Address和setX的参数x:

function callSetX(address _Address, uint256 x) external{
OtherContract(_Address).setX(x);
}

复制OtherContract合约的地址,填入callSetX函数的参数中,成功调用后,调用OtherContract合约中的getX验证x变为123

Solidity极简入门#21. 调用其他合约_区块链_04

Solidity极简入门#21. 调用其他合约_Ethereum_05

2. 传入合约变量

我们可以直接在函数里传入合约的引用,只需要把上面参数的address类型改为目标合约名,比如OtherContract。下面例子实现了调用目标合约的getX()函数。

注意该函数参数OtherContract _Address底层类型仍然是address,生成的ABI中、调用callGetX时传入的参数都是address类型

function callGetX(OtherContract _Address) external view returns(uint x){
x = _Address.getX();
}

复制OtherContract合约的地址,填入callGetX函数的参数中,调用后成功获取x的值

Solidity极简入门#21. 调用其他合约_区块链_06

3. 创建合约变量

我们可以创建合约变量,然后通过它来调用目标函数。下面例子,我们给变量oc存储了OtherContract合约的引用:

function callGetX2(address _Address) external view returns(uint x){
OtherContract oc = OtherContract(_Address);
x = oc.getX();
}

复制OtherContract合约的地址,填入callGetX2函数的参数中,调用后成功获取x的值

Solidity极简入门#21. 调用其他合约_区块链_07

4. 调用合约并发送ETH

如果目标合约的函数是payable的,那么我们可以通过调用它来给合约转账:_Name(_Address).f{value: _Value}(),其中_Name是合约名,_Address是合约地址,f是目标函数名,_Value是要转的ETH数额(以wei为单位)。

OtherContract合约的setX函数是payable的,在下面这个例子中我们通过调用setX来往目标合约转账。

function setXTransferETH(address otherContract, uint256 x) payable external{
OtherContract(otherContract).setX{value: msg.value}(x);
}

复制OtherContract合约的地址,填入setXTransferETH函数的参数中,并转入10ETH

Solidity极简入门#21. 调用其他合约_web3_08

转账后,我们可以通过Log事件和getBalance()函数观察目标合约ETH余额的变化。

Solidity极简入门#21. 调用其他合约_web3_09

总结

这一讲,我们介绍了如何通过目标合约代码(或接口)和地址来创建合约的引用,从而调用目标合约的函数。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
6WDFuiiGwNIX