发布于 2022-08-22 15:20:52
让我看看我是否理解你的需要..。
那么,您想知道在另一个EVM兼容的链中部署一个与另一个链中现有的合同地址相同的合同会有多难呢?
它平均需要2**256尝试为EVM创建一个具有所需地址的salt,因为create2使用创建者契约的地址与creationCode和salt混合来生成新的契约地址。这意味着,在另一个链中,用户需要有一个私钥,该私钥生成一个与原始链中的地址/帐户完全相同的公钥,该公钥进行事务处理,直到它将当前设置为原始用户在创建智能契约时所拥有的当前值为止,并且该智能契约本身确保具有正确的nonce,就像原始用户创建智能契约时一样,或者如果它使用create2,然后使用相同的设置并对原始合同使用盐。所以,实际上,应该是同一个人,因为我们都知道猜测私钥是不可行的。
create2操作码不接受任意地址作为输入,即使在像new TestDeployContract{salt: hash}()一样创建它时也不接受。它使用创建契约的地址,我们没有办法强迫它接受我们想要的任意地址。
因此,我们对create2操作码的唯一控制是契约的bytecode和salt,在您的例子中,我们希望部署与原始链中完全相同的字节码,因此更改它不是一种选择。
我们知道keccak256哈希从给定的数据中产生一个256位的数字.EVM create2使用keccak256将其与契约字节码、创建者契约地址和salt混合使用来派生新的契约地址。如果我们可以以某种方式传递一个salt,一个随机数,这会使create2的keccak256哈希产生与原始链中产生的哈希相同的哈希。
我们都知道这是野蛮的力量。尝试让keccak256在不同的输入下创建相同的输出是不可行的。因此,平均而言,它需要2**256尝试,生成一个随机盐,并尝试手动计算地址,看看它是否与我们想要的地址相同。
所以,回答你的问题,是的,很难,真的很难,2**256硬,或者至少是2**160,因为算法复制了keccak256的最后20个字节作为地址。因此,理论上,我们需要尝试,蛮力,直到最后20个字节的哈希是我们所期望的。
一些带有一些示例和注释的代码:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
contract TestDeployContract {
uint256 public id = 50;
}
contract Contract {
// Using keccak256 hash of the contract name to use it as the salt
bytes32 hash = keccak256("TestDeployContract");
uint256 hashValue = uint(keccak256("TestDeployContract"));
address public testDeployContractAddress;
// Function to derive the address of a smart contract.
function getAddress() public view returns (address) {
// Passing address(this) manually here. But we have no option to provide any address we want when actually deploying the contract with create2
bytes32 hash32 = keccak256(
abi.encodePacked(bytes1(0xff), address(this), hashValue, keccak256(type(TestDeployContract).creationCode))
);
return address(uint160(uint(hash32)));
}
function createContract() public {
// No option provide any creator address we want when actually deploying the contract
// So it uses the address of the contract that is executing this code,
// mix it with the bytecode of the TestDeployContract and the salt to produce a
// keccak256 hash and derive the new contract address from it
TestDeployContract testDeployContract = new TestDeployContract{salt: hash}();
testDeployContractAddress = address(testDeployContract);
}
}https://ethereum.stackexchange.com/questions/134137
复制相似问题