Ethereum中涉及各种类型的方法调用。一个编程中常用的call概念,可能为Ethereum Vitrual Machine(EVM)内的call,又可能为EVM外的call,又涉及诸如Message/Transaction等基本概念;同时还包括call/delegatecall/callcode/send/transfer/sendTransaction等等方法。
对这些调用机制及基本概念的说明散落在 solidity文档 、黄皮书、白皮书 中,初学者容易搞晕。这里对这些基本概念、调用机制及用法做一下整体梳理。
PDF版本下载:Ethereum调用机制总结pdf版本
PNG版本下载:Ethereum调用机制总结png版本
示例代码下载:测试代码
pragma solidity ^ 0.4.18;
contract A {
uint public var2;
uint public var1;
B b1;
address addrB;
function A() public {
b1 = new B();
addrB=address(b1);
}
function callSet(address addr, uint param) public returns(uint) {
//addr.call(bytes4(keccak256("set(uint)")), param); //使用了uint,调用不生效。应当使用uint256; uint是uint256的昵称,但在ABI调用时候,只能使用长类型。
//使用address.call
addr.call(bytes4(keccak256("set(uint256)")), param); //call 使用的是被调用者的存储,因此改变的是B.var1值
//使用实例方式,可以直接采用callee.method形式调用,从而直接获取函数返回值
/*
B b2 = B(addr);
uint result = b2.set(param);
return result;
*/
//使用 new B()方式方式调用
// uint b1=b1.set(param);
// addrB.call(bytes4(keccak256("set(uint256)")), param);
return 1;
}
function delegatecallSet(address addr, uint param) {
//addr.delegatecall(bytes4(keccak256("set(uint)")), param); //使用了uint,调用不生效。应当使用uint256; uint是uint256的昵称,但在ABI调用时候,只能使用长类型。
addr.delegatecall(bytes4(keccak256("set(uint256)")), param); //delegatecall和callcode都是使用调用者的存储,特别要注意调用者和被调用者合约变量定义顺序,目前改变的是A.var2的值。
B b2 = B(addr); //使用实例方式,可以直接采用callee.method形式调用,从而直接获取函数返回值
uint result = b2.set(param);
// uint b1=b1.set(param);
// addrB.call(bytes4(keccak256("set(uint256)")), param);
}
function callcodeSet(address addr, uint param) {
addr.callcode(bytes4(keccak256("set(uint256)")), param);
}
function getVar1() public view returns(uint) {
return var1;
}
function getVar2() public view returns(uint) {
return var2;
}
function getAddr() public view returns(address) {
return addrB;
}
}
contract B {
uint public var1;
event MyEvent(uint param, uint result);
function set(uint param) public returns(uint) {
var1 = param;
MyEvent(param, 1);
return param;
}
}
Congratulations @chuanliang! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Vote for @Steemitboard as a witness to get one more award and increased upvotes!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit