合约之间的函数调用
- EOA,external owned account,外部账号,例如metamask
- 调用最终总是由EOA发起的
- 合约之间的调用使得一次完整的调用成为一个调用链条
合约间调用过程
- 调用者须持有被调用合约的地址
- 得到被调用合约的信息
- 将地址重载为被调用合约,调用它的函数
最直接的调用方式(源文件内部)
- 调用者直接将被调用合约的地址重载为合约的实例
- 用合约实例调用合约函数
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
contract Callee {
uint public x;
function setX(uint _x)public{
x = _x;
}
}
contract Caller{
address calleeAddress;
constructor(address _calleeAddress){
calleeAddress = _calleeAddress;
}
function setCalleeX(uint _x)public{
Callee callee = Callee(calleeAddress);
callee.setX(_x);
}
}
//0xd9145CCE52D386f254917e481eB44e9943F39138 // Callee合约实例的地址 先部署Callee合约获取地址作为Caller的构造参数
通过import调用合约函数(源文件之间)
- import被调用合约的源文件
- 调用者将被调用合约的地址重载为合约实例
- 用合约实例调用合约函数
Callee.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
contract Callee {
uint public x;
function setX(uint _x)public{
x = _x;
}
}
Caller.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
import "./Callee.sol";
contract Caller{
address calleeAddress;
constructor(address _calleeAddress){
calleeAddress = _calleeAddress;
}
function setCalleeX(uint _x)public{
Callee callee = Callee(calleeAddress);
callee.setX(_x);
}
}
// 0xd9145CCE52D386f254917e481eB44e9943F39138
通过接口的调用
- 合约的接口等价于其ABI
- 接的定义方法
- 接口的使用方法
ICallee.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
interface ICallee {
function setX(uint _x) external;
}
Callee.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
// import "./ICallee.sol"; // 柔性,不强制一定要is Icallee 只要实现是一致就行
// contract Callee is Icallee {
contract Callee {
uint public x;
uint public y;
function setX(uint _x)public{
x = _x;
}
function setY(uint _y)public {
y=_y;
}
//.....
}
Caller.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
interface ICallee {
function setX(uint _x) external;
function setY(uint _x) external;
}
contract Caller{
address calleeAddress;
constructor(address _calleeAddress){
calleeAddress = _calleeAddress;
}
function setCalleeX(uint _x)public{
ICallee callee = ICallee(calleeAddress);
callee.setY(_x);
}
}
// 0xd9145CCE52D386f254917e481eB44e9943F39138
面向接口
- 与一般开发语言一样,面向接口而不是实现
- 不要求被调用者语法上实现一个接口
- 接口最小化(有必要的才放入接口)