由于某种原因,当创建的契约接受address的构造函数参数时,预测/预计算地址并不等于实际地址,但是当构造函数参数是uint时,就可以了。我在下面的脚本中演示了这两个示例。
// 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;
}
}发布于 2022-08-10 16:12:33
只是为了完整
使用当前的solidity编译器,可以在不使用程序集的情况下使用以下代码调用CREATE2
带构造函数参数
bytes32 salt = keccak256(abi.encodePacked(parameter0, parameter1));
ImportedContract token = new ImportedContract{salt: salt}(parameter0, parameter1); // Use create2无构造函数参数
bytes32 salt = keccak256(abi.encodePacked(parameter0, parameter1));
ImportedContract token = new ImportedContract{salt: salt}(); // Use create2不需要复杂的程序集代码。
发布于 2022-03-16 13:29:19
使用create2方法而不是new关键字。
试试这个:
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
}
}发布于 2022-03-16 15:50:21
我设法使它正常工作,我所要做的就是将address转换为uint,如下所示:
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
} https://ethereum.stackexchange.com/questions/123967
复制相似问题