A合约委托调用B合约,执行的是B合约的函数,但是状态变量和上下文都是A的
DelegateCall将代理合约和逻辑合约分开,状态变量和上下文都存储在代理合约中,逻辑合约只负责提供所有的函数, 这样当需要升级的时候,只需要将逻辑合约的地址替换掉就可以无缝升级了
// 被调用的合约C(逻辑合约)
contract C {
uint public num;
address public sender;
function setVars(uint _num) public payable {
num = _num;
sender = msg.sender;
}
}
// 代理合约
contract B {
uint public num;
address public sender;
// 通过call来调用C的setVars()函数,将改变合约C里的状态变量
function callSetVars(address _addr, uint _num) external payable{
// call setVars()
(bool success, bytes memory data) = _addr.call(
abi.encodeWithSignature("setVars(uint256)", _num)
);
}
}
用户可以创建合约,合约同样也可以创建合约, 去中心化交易所uniswap就是通过工程合约(PairFactory)创建了无数个币对合约(Pair) 有两种方式可以创建合约,先讲Create
Create的用法很简单,就是new一个合约; x是合约对象(地址),如果构造函数是payable,可以在创建时转入_value数量的ETH; params是构造函数的参数
Contract x = new Contract{value:_value}(params);
新地址 = hash(调用者地址,nonce);
对于用户来说,调用者地址是钱包地址,nonce是该钱包交易的次数; 对于合约来说,调用者地址是合约地址,nonce是该地址创建合约的次数;