在0.4.26版本的solidity中,delegatecall的返回值只有1个,表示delegatecall是否调用成功的布尔变量。 在0.6.8版本的solidity中,delegatecall的返回值有2个,一个是表示delegatecall是否调用成功的布尔变量,另一个则是被调用函数的返回值。 通过delegatecall调用逻辑合约来修改数据合约中的状态变量,从而实现数据和逻辑分离。后面可以通过升级逻辑合约来改变业务逻辑,但数据合约不能升级。 下面通过例子来说明在0.6.8版本的solidity中如何使用delegatecall进行合约升级。 合约代码: pragma solidity ^0.6.8;// 数据合约 contract DataContract { uint256 public num1; uint256 public num2; uint256 public num3; address public issuer; event Log(string str, bool result); event Log2(string str, uint256 result); constructor() public { issuer = msg.sender; num1 = 1; num2 = 2; num3 = 3; } function callLogicContract(address logicContractAddr) public { bool r; bytes memory s; // 通过delegatecall调用逻辑合约来修改数据合约中的状态变量,从而实现数据和逻辑分离。后面可以通过升级逻辑合约来改变业务逻辑,但数据合约不能升级 (r, s) = logicContractAddr.delegatecall(abi.encodeWithSignature("test(address)", this)); emit Log("delegatecall return ", r); // r为true或false uint256 result = bytesToUint(s); emit Log2("test() return ", result); } function bytesToUint(bytes memory b) public pure returns (uint256){ uint256 number; for(uint i= 0; i<b.length; i++){ number = number + uint8(b[i])*(2**(8*(b.length-(i+1)))); } return number; } function setNum1(uint256 s) public { num1 = s; } function setNum2(uint256 s) public { num2 = s; } function setNum3(uint256 s) public { num3 = s; } function getNum1() public view returns(uint256){ return num1; } function getNum2() public view returns(uint256){ return num2; } function getNum3() public view returns(uint256){ return num3; } } // 升级前的逻辑合约 contract LogicContract { uint256 public num1; uint256 public num2; uint256 public num3; //num1, num2, num3声明的顺序和位置必须和DataContract中的一样,否则无法修改DataContract中的num3 address public caller; address public dataContract; event Log(string str, uint256 num); event Log2(string str, address addr); function test(address addr) public returns(uint256) { dataContract = addr; // 数据合约DataContract地址 caller = msg.sender; // 运行数据合约DataContract的以太坊账号 num3 = num3*10; // DataContract通过delegatecall调用LogicContract的test函数,test函数里修改的是DataContract中的num3而不是LogicContract中的num3 emit Log("after upgrading contract, num3=", num3); emit Log2("dataContract=", dataContract); emit Log2("caller=", caller); return num3; } } // 升级后的逻辑合约 contract LogicContract2 { uint256 public num1; uint256 public num2; uint256 public num3; //num1, num2, num3声明的顺序和位置必须和DataContract中的一样,否则无法修改DataContract中的num3 address public caller; address public dataContract; event Log(string str, uint256 num); event Log2(string str, address addr); function test(address addr) public returns(uint256) { dataContract = addr; // 数据合约DataContract地址 caller = msg.sender; // 运行数据合约DataContract的以太坊账号 num3 = num3*300; // DataContract通过delegatecall调用LogicContract的test函数,test函数里修改的是DataContract中的num3而不是LogicContract2中的num3 emit Log("after upgrading contract, num3=", num3); emit Log2("dataContract=", dataContract); emit Log2("caller=", caller); return num3; } } 地址列表: 运行数据合约DataContract的以太坊账号:0xC264358Ef94b48B62e7F94ce10795255f8b9EED7数据合约DataContract地址: 0x4ABFb9D52f63834b2A30B42202Be4F43C8CC8b48 逻辑合约LogicContract地址: 0x565d6eE58b7D0d4BbdA5e2E337eaada2D634B40D 逻辑合约LogicContract2地址: 0x9c9f6158adC9B7E9FE5fF99cEE27eECE6433edCb 运行结果的输出日志: 升级合约前,调用合约LogicContract的test函数的日志输出logs [ { "from": "0x4abfb9d52f63834b2a30b42202be4f43c8cc8b48", "topic": "0xdd970dd9b5bfe707922155b058a407655cb18288b807e2216442bca8ad83d6b5", "event": "Log", "args": { "0": "after upgrading contract, num3=", "1": "30", "str": "after upgrading contract, num3=", "num": "30", "length": 2 } }, { "from": "0x4abfb9d52f63834b2a30b42202be4f43c8cc8b48", "topic": "0x953bb7c6c7f939308a523ff2ce38248d9a26e7e8212c5f982fd8dffaca3fc523", "event": "Log2", "args": { "0": "dataContract=", "1": "0x4ABFb9D52f63834b2A30B42202Be4F43C8CC8b48", "str": "dataContract=", "addr": "0x4ABFb9D52f63834b2A30B42202Be4F43C8CC8b48", "length": 2 } }, { "from": "0x4abfb9d52f63834b2a30b42202be4f43c8cc8b48", "topic": "0x953bb7c6c7f939308a523ff2ce38248d9a26e7e8212c5f982fd8dffaca3fc523", "event": "Log2", "args": { "0": "caller=", "1": "0xC264358Ef94b48B62e7F94ce10795255f8b9EED7", "str": "caller=", "addr": "0xC264358Ef94b48B62e7F94ce10795255f8b9EED7", "length": 2 } }, { "from": "0x4abfb9d52f63834b2a30b42202be4f43c8cc8b48", "topic": "0x52dd9d08c343f72c69027ade2a075f6242dba2eeca3a3c61bfd8d00d32f6bd20", "event": "Log", "args": { "0": "delegatecall return ", "1": true, "str": "delegatecall return ", "result": true, "length": 2 } }, { "from": "0x4abfb9d52f63834b2a30b42202be4f43c8cc8b48", "topic": "0x0c231cace93330e81aabd308eaecd9a98302e543efad0c88d0b99732e7c2ef5f", "event": "Log2", "args": { "0": "test() return ", "1": "30", "str": "test() return ", "result": "30", "length": 2 } } ] 升级合约后,调用合约LogicContract2的test函数的日志输出 logs [ { "from": "0x4abfb9d52f63834b2a30b42202be4f43c8cc8b48", "topic": "0xdd970dd9b5bfe707922155b058a407655cb18288b807e2216442bca8ad83d6b5", "event": "Log", "args": { "0": "after upgrading contract, num3=", "1": "9000", "str": "after upgrading contract, num3=", "num": "9000", "length": 2 } }, { "from": "0x4abfb9d52f63834b2a30b42202be4f43c8cc8b48", "topic": "0x953bb7c6c7f939308a523ff2ce38248d9a26e7e8212c5f982fd8dffaca3fc523", "event": "Log2", "args": { "0": "dataContract=", "1": "0x4ABFb9D52f63834b2A30B42202Be4F43C8CC8b48", "str": "dataContract=", "addr": "0x4ABFb9D52f63834b2A30B42202Be4F43C8CC8b48", "length": 2 } }, { "from": "0x4abfb9d52f63834b2a30b42202be4f43c8cc8b48", "topic": "0x953bb7c6c7f939308a523ff2ce38248d9a26e7e8212c5f982fd8dffaca3fc523", "event": "Log2", "args": { "0": "caller=", "1": "0xC264358Ef94b48B62e7F94ce10795255f8b9EED7", "str": "caller=", "addr": "0xC264358Ef94b48B62e7F94ce10795255f8b9EED7", "length": 2 } }, { "from": "0x4abfb9d52f63834b2a30b42202be4f43c8cc8b48", "topic": "0x52dd9d08c343f72c69027ade2a075f6242dba2eeca3a3c61bfd8d00d32f6bd20", "event": "Log", "args": { "0": "delegatecall return ", "1": true, "str": "delegatecall return ", "result": true, "length": 2 } }, { "from": "0x4abfb9d52f63834b2a30b42202be4f43c8cc8b48", "topic": "0x0c231cace93330e81aabd308eaecd9a98302e543efad0c88d0b99732e7c2ef5f", "event": "Log2", "args": { "0": "test() return ", "1": "9000", "str": "test() return ", "result": "9000", "length": 2 } } ] 我的csdn:https://blog.csdn.net/powervip 我的腾讯微云网盘:https://share.weiyun.com/5qT0TvG 我的github: https://github.com/powervip 如果你觉得这篇文章写得还可以,请帮忙点个赞,谢谢! 你的鼓励,我的动力! 本文来源:powervip —- 编译者/作者:powervip 玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。 |
在0.6.8版本的solidity中,使用delegatecall进行合约升级
2020-06-24 powervip 来源:火星财经
LOADING...
相关阅读:
- 以太坊在反弹洗牌市场中成为领导者2020-08-06
- Ethereum.org通过新内容和总督插图进行了重新设计2020-08-06
- 8.6以太坊凌晨分析及操作:的以太坊势如破竹的跌破下方、上方多头无2020-08-06
- 30天内达到70%-以太坊的增长速度快于Eth2测试网2020-08-06
- 交易者利用Opyn ETH认沽期权,以37万美元的抵押品流失; 团队追回超过2020-08-06