在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;