Nodejs

在 Hardhat 和 Ethers.js 中部署之前找到合約的地址

  • May 11, 2021

我有 2 個合約,它們將彼此的地址作為建構子參數。這是虛擬碼,

constructor A(address B)
constructor B(address A)

我正在使用部署契約

const Contract = await ethers.getContractFactory(contractName)
const contract = await Contract.deploy(...args)
await contract.deployed()

console.log(contract.address) // I want to find address before, not after deployment

部署前如何找到合約地址?

@ethersproject/address提供getContractAddress()查找未來部署地址的功能。

const { ethers } = require('hardhat')
const { getContractAddress } = require('@ethersproject/address')

async function main() {
 const [owner] = await ethers.getSigners()

 const transactionCount = await owner.getTransactionCount()

 const futureAddress = getContractAddress({
   from: owner.address,
   nonce: transactionCount
 })
}

合約地址是確定性的,需要部署者地址和隨機數來預先計算它。

您可以使用以下程式碼在部署前確定合約地址。

const rlp = require('rlp');
const keccak = require('keccak');
const web3 = require('web3')

const encodedData = rlp.encode([
 '0x6c4465dc4dc3466c5736142ce8e12917a1e22c4', // address from which contract is to be deployed
 web3.utils.toHex(4) // hex encoded nonce of address that will be used for contract deployment
]);

const contractAddress = `0x${keccak('keccak256').update(encodedData).digest('hex').substring(24)}`
console.log({contractAddress}

我會建議在第二個合約中添加一個方法,稍後更新合約地址。確保該函式只能呼叫一次,這將是一種更可靠的方法。

範常式式碼:

pragma solidity 0.6.8;

contract A {
   
   address b;
   
   function addSecondaryContract(address _b) public /* onlyOwner */ {
       require(b != address(0), "contract already added");
       b = _b;
   }
   
}

contract B {
   address a;
   
   constructor(address _a) public{
       a = _a;
   }
}

引用自:https://ethereum.stackexchange.com/questions/98700