首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么create2预测的地址不等于实际地址?

为什么create2预测的地址不等于实际地址?
EN

Ethereum用户
提问于 2022-03-16 12:36:12
回答 3查看 478关注 0票数 0

由于某种原因,当创建的契约接受address的构造函数参数时,预测/预计算地址并不等于实际地址,但是当构造函数参数是uint时,就可以了。我在下面的脚本中演示了这两个示例。

代码语言:javascript
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Factory {

    // example 1:
    function createTest1(uint number1, uint number2) public {

        bytes32 salt = keccak256(abi.encodePacked(number1, number2));

        // source: https://docs.soliditylang.org/en/latest/control-structures.html#salted-contract-creations-create2
        address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
            bytes1(0xff),
            address(this),
            salt,
            keccak256(abi.encodePacked(
                type(Test1).creationCode,
                number1,
                number2
            ))
        )))));

        Test1 test1 = new Test1{salt: salt}(number1, number2);
        require(address(test1) == predictedAddress); // Does NOT revert
    }

    // example 2:
    function createTest2(address address1, address address2) public {

        bytes32 salt = keccak256(abi.encodePacked(address1, address2));

        address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
            bytes1(0xff),
            address(this),
            salt,
            keccak256(abi.encodePacked(
                type(Test2).creationCode,
                address1,
                address2
            ))
        )))));

        Test2 test2 = new Test2{salt: salt}(address1, address2);
        require(address(test2) == predictedAddress); // Does revert
    }    
}

contract Test1 {

    uint public number1;
    uint public number2;

    constructor(uint _number1, uint _number2) {
        number1 = _number1;
        number2 = _number2;
    }
}

contract Test2 {

    address public address1;
    address public address2;

    constructor(address _address1, address _address2) {
        address1 = _address1;
        address2 = _address2;
    }
}
EN

回答 3

Ethereum用户

发布于 2022-08-10 16:12:33

只是为了完整

使用当前的solidity编译器,可以在不使用程序集的情况下使用以下代码调用CREATE2

带构造函数参数

代码语言:javascript
复制
bytes32 salt = keccak256(abi.encodePacked(parameter0, parameter1));
ImportedContract token = new ImportedContract{salt: salt}(parameter0, parameter1); // Use create2

无构造函数参数

代码语言:javascript
复制
bytes32 salt = keccak256(abi.encodePacked(parameter0, parameter1));
ImportedContract token = new ImportedContract{salt: salt}(); // Use create2

不需要复杂的程序集代码。

票数 1
EN

Ethereum用户

发布于 2022-03-16 13:29:19

使用create2方法而不是new关键字。

试试这个:

代码语言:javascript
复制
 function createTest2(address address1, address address2) public {
        address addr;
        bytes32 _salt = keccak256(abi.encodePacked(address1, address1));
        bytes memory bytecode = abi.encodePacked(
                type(Test1).creationCode,
                abi.encode(address1,
                address2)
            );
        address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
            bytes1(0xff),
            address(this),
            _salt,
            keccak256(bytecode)
        )))));

       
        assembly {
            addr := create2(
                callvalue(), // wei sent with current call
                // Actual code starts after skipping the first 32 bytes
                add(bytecode, 0x20),
                mload(bytecode), // Load the size of code contained in the first 32 bytes
                _salt // Salt from function arguments
            )

            if iszero(extcodesize(addr)) {
                revert(0, 0)
            }
        }
        require(addr == predictedAddress); // Does revert
    }        
}
票数 0
EN

Ethereum用户

发布于 2022-03-16 15:50:21

我设法使它正常工作,我所要做的就是将address转换为uint,如下所示:

代码语言:javascript
复制
function createTest2(address address1, address address2) public {

    bytes32 salt = keccak256(abi.encodePacked(address1, address2));

    address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
        bytes1(0xff),
        address(this),
        salt,
        keccak256(abi.encodePacked(
            type(Test2).creationCode,
            uint(uint160(address1)),
            uint(uint160(address2))
        ))
    )))));

    Test2 test2 = new Test2{salt: salt}(address1, address2);
    require(address(test2) == predictedAddress); // No longer reverts
}  
票数 0
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/123967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档