12

I have 2 contracts which take each other's addresses as constructor arguments. Here's the pseudocode,

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

I am deploying contracts using

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

How to find the contract address before deployment?

secretshardul
  • 465
  • 4
  • 15

3 Answers3

12

@ethersproject/address provides a getContractAddress() function to find future deployment address.

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 }) }

secretshardul
  • 465
  • 4
  • 15
4

Contract addresses are deterministic and need the deployer address and nonce to pre-compute it.

You can use the following code to determine the contract address before deployment.

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}

But I will recommend adding a method in the second contract and update the contract address later. Make sure that the function is callable only once, this will be a more reliable approach.

Sample code:

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;
}

}

Prashant Prabhakar Singh
  • 8,026
  • 5
  • 40
  • 79
1

Based on Prashant's answer, I created Soladd -- a web tool for finding smart contract address before deployment, just based on wallet address -- where nonce is fetched from chain but can also be set manually, if required.

enter image description here

yupuday
  • 11
  • 1