通過new創(chuàng)建合約

2022-05-12 17:02 更新

一個合約可以使用new關(guān)鍵字創(chuàng)建其他合約。在編譯創(chuàng)建合約時,必須知道正在創(chuàng)建的合約的完整代碼,因此遞歸創(chuàng)建依賴項是不可能的。

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract D {
    uint public x;
    constructor(uint a) payable {
        x = a;
    }
}

contract C {
    D d = new D(4); // will be executed as part of C's constructor

    function createD(uint arg) public {
        D newD = new D(arg);
        newD.x();
    }

    function createAndEndowD(uint arg, uint amount) public payable {
        // Send ether along with the creation
        D newD = new D{value: amount}(arg);
        newD.x();
    }
}

D如示例所示,可以在創(chuàng)建使用該選項的實例時發(fā)送 Ether value,但無法限制 gas 量。如果創(chuàng)建失?。ㄓ捎诔鰲!⒂囝~不足或其他問題),則拋出異常。

加鹽合約創(chuàng)建 / create2

創(chuàng)建合約時,合約的地址是根據(jù)創(chuàng)建合約的地址和隨著每次合約創(chuàng)建而增加的計數(shù)器計算出來的。

如果您指定選項salt(bytes32 值),則合約創(chuàng)建將使用不同的機制來提供新合約的地址:

它將根據(jù)創(chuàng)建合約的地址、給定的鹽值、創(chuàng)建合約的(創(chuàng)建)字節(jié)碼和構(gòu)造函數(shù)參數(shù)來計算地址。

特別是,不使用計數(shù)器(“nonce”)。這為創(chuàng)建合約提供了更大的靈活性:您可以在創(chuàng)建新合約之前獲取它的地址。此外,您也可以依賴此地址,以防創(chuàng)建合約同時創(chuàng)建其他合約。

這里的主要用例是充當(dāng)鏈下交互法官的合約,只有在有爭議時才需要創(chuàng)建。

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract D {
    uint public x;
    constructor(uint a) {
        x = a;
    }
}

contract C {
    function createDSalted(bytes32 salt, uint arg) public {
        // This complicated expression just tells you how the address
        // can be pre-computed. It is just there for illustration.
        // You actually only need ``new D{salt: salt}(arg)``.
        address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
            bytes1(0xff),
            address(this),
            salt,
            keccak256(abi.encodePacked(
                type(D).creationCode,
                abi.encode(arg)
            ))
        )))));

        D d = new D{salt: salt}(arg);
        require(address(d) == predictedAddress);
    }
}

警告

鹽漬創(chuàng)作有一些特殊性。合約被銷毀后,可以在同一地址重新創(chuàng)建。然而,即使創(chuàng)建的字節(jié)碼是相同的,新創(chuàng)建的合約也有可能擁有不同的部署字節(jié)碼(這是一個要求,否則地址會改變)。這是因為構(gòu)造函數(shù)可以查詢可能在兩次創(chuàng)建之間發(fā)生變化的外部狀態(tài),并在存儲之前將其合并到部署的字節(jié)碼中。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號