如何提前找到我要部署的智能合约的地址?

Owa*_*ans 14 solidity rsk

我有一个 Solidity 智能合约ContractFactory,正在RSK上部署并在Hardhat中开发。ContractFactory具有deploy生成新Child智能合约的函数。\n\xe2\x80\x8b

\n
// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\xe2\x80\x8b\ncontract ContractFactory {\n    event ContractDeployed(address owner, address childContract);\n\xe2\x80\x8b\n    function deploy() public {\n        Child newContract = new Child(msg.sender);\n        emit ContractDeployed(msg.sender, address(newContract));\n    }\n}\n\xe2\x80\x8b\ncontract Child {\n    address owner;\n\xe2\x80\x8b\n    constructor(address _owner) {\n        owner = _owner;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在调用该函数之前,我能否知道 新的智能合约将收到RSKdeploy上的哪个地址?Child

\n

Ale*_*hin 15

您可以更进一步,利用利用CREATE2规范的确定性部署技术。这里未来智能合约的地址是keccak2564 个参数的哈希值:

\n
    \n
  1. 0xFF,一个防止与 CREATE 发生冲突的常量
  2. \n
  3. 发送者\xe2\x80\x99s自己的地址
  4. \n
  5. salt(发送者提供的任意 32 字节长值)
  6. \n
  7. keccak256待部署合约\xe2\x80\x99s字节码
  8. \n
\n

请注意,CREATE2您不仅可以预测部署的智能合约地址,而且实际上可以通过更改值来影响该地址的内容salt

\n

尝试将以下功能添加到您的ContractFactory

\n
function deployCreate2(bytes32 _salt) public {\n    Child newContract = new Child{salt: _salt}(msg.sender);\n    emit ContractDeployed(msg.sender, address(newContract));\n}\n
Run Code Online (Sandbox Code Playgroud)\n

通过此测试,您可以确定部署的智能合约地址。

\n
function deployCreate2(bytes32 _salt) public {\n    Child newContract = new Child{salt: _salt}(msg.sender);\n    emit ContractDeployed(msg.sender, address(newContract));\n}\n
Run Code Online (Sandbox Code Playgroud)\n


Ahs*_*san 13

是的你可以。部署的智能合约地址是一个包含keccak2562 个参数的函数(哈希):

  1. 部署者地址(EAO 或其他智能合约)
  2. nonce是部署者地址的交易计数。您可以使用 Ethers.jsgetTransactionCount函数查找随机数,并getContractAddress使用函数计算未来的智能合约地址。

使用此测试来预测Child地址:

it('Should predict Child address', async () => {
    const nonce = await ethers.provider.getTransactionCount(factory.address);
    const anticipatedAddress = ethers.utils.getContractAddress({
      from: factory.address,
      nonce,
    });
    const tx = await factory.deploy();
    await expect(tx)
      .to.emit(factory, 'ContractDeployed')
      .withArgs(deployer.address, anticipatedAddress);
});
Run Code Online (Sandbox Code Playgroud)