solidity实现合约的变更
1.Delegatecall 简介
1.1.什么是 delegatecall ?
delegatecall() 是 Solidity 中的一个方法,用于从一个原始合约中调用目标合约中的一个函数。然而,与其他方法不同的是,当使用.delegatecall()在目标合约中执行函数时,上下文从原始合约中传递,即代码在目标合约中执行,但变量在原始合约中被修改。
2.Delegatecall 实例
2.1.部署Calculator合约
pragma solidity ^0.8.4;
contract Calculator {
uint public result;
address public user;
function add(uint a, uint b) public returns (uint) {
result = a + b;
user = msg.sender;
return result;
}
}
部署合约:0x7764f7c51347723c70e0a11f5f58d7feaa19346a
2.2.部署Student合约
pragma solidity ^0.8.4;
contract Student {
uint public mySum;
address public studentAddress;
function addTwoNumbers(address calculator, uint a, uint b) public returns (uint) {
(bool success, bytes memory result) = calculator.delegatecall(abi.encodeWithSignature("add(uint256,uint256)", a, b));
require(success, "The call to calculator contract failed");
return abi.decode(result, (uint));
}
}
部署合约:0x731b202063e2b1b58834bbc36b9fd94bf83a5478
2.3.调用student合约:使用老Calculator合约
在student合约0x731b202063e2b1b58834bbc36b9fd94bf83a5478中调试:
填入Calculator:0x7764f7c51347723c70e0a11f5f58d7feaa19346a
可以看到老合约实现的是a+b=1+1=2
2.4.修改Calculator合约
// File: @openzeppelin/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.4;
contract Calculator {
uint public result;
address public user;
function add(uint a, uint b) public returns (uint) {
result = a + b + 2;
user = msg.sender;
return result;
}
}
把相加改成a+b+2
部署该合约:0xaf81d1a40a0d7be67287e0531efdccffb00ef56d
2.5.调用student的合约:使用新Calculator合约
在student合约0x731b202063e2b1b58834bbc36b9fd94bf83a5478中调试:
填入Calculator:0xaf81d1a40a0d7be67287e0531efdccffb00ef56d
调用完就变成4了
实现了合约的变更