Skip to content

Latest commit

 

History

History
53 lines (47 loc) · 1.8 KB

File metadata and controls

53 lines (47 loc) · 1.8 KB

DelegateCall

DelegateCall和Call的区别

A合约委托调用B合约,执行的是B合约的函数,但是状态变量和上下文都是A的

什么情况下会用到DelegateCall

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

Create的用法很简单,就是new一个合约; x是合约对象(地址),如果构造函数是payable,可以在创建时转入_value数量的ETH; params是构造函数的参数

Contract x = new Contract{value:_value}(params);

create如何计算出地址

新地址 = hash(调用者地址,nonce);

对于用户来说,调用者地址是钱包地址,nonce是该钱包交易的次数; 对于合约来说,调用者地址是合约地址,nonce是该地址创建合约的次数;