CALL|CALLCODE|DELEGATECALL|STATICCALL
四种调用的区别
CALL 调用的上下文环境是被调用合约的环境,修改的是被调用合约的 state,调用者函数不能为 view。

STATICCALL 只能调用不修改 state 的函数(pure view 修饰的函数),调用者函数可以为 view。

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
// 调用者
contract ContractA {
uint256 x;
function add(uint256 _num) public {
x = x + _num;
}
function getX() external view returns(uint256) {
return x;
}
}
// 被调用者
contract ContractB {
function call(address _addr, uint256 _num) external {
bytes memory data = abi.encodeWithSignature("add(uint256)", _num);
(bool result, ) = _addr.call(data);
require(result, "transaction failed");
}
function staticcall(address _addr) external view returns(uint256) {
bytes memory data = abi.encodeWithSignature("getX()");
(bool result, bytes memory returnNum) = _addr.staticcall(data);
require(result, "transaction failed");
return abi.decode(returnNum, (uint256));
}
}
CALLCODE已被DELEGATECALL取代,区别就是 msg.sender不同。DELEGATECALL会一直使用原始调用者的地址,而CALLCODE不会。

委托调用的上下文环境是调用者合约的环境,也就是说msg.sender是用户。通常用在可升级的代理合约中。
