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?

3 Answers 3

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
  })
}
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;
    }
}
2
  • 1
    Thank you for your answer. I've found a helper function from Ethers which finds the future address idiomatically. Commented May 11, 2021 at 17:19
  • @secretshardul what was the helper function?
    – Kwame
    Commented Jun 2, 2022 at 12:11
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.