How to get Hardhat deployProxy gas used

Using this code for contract deployment and getting certain informations after deployment

  const contract = (await upgrades.deployProxy(contractFactory, [], {
    kind: 'uups',
  })) as ContractType;
  await contract.deployed();

console.log(`contract address: ${contract.address}`);
console.log(`deployer address: ${contract.deployTransaction.from}`);
console.log(`gas price: ${contract.deployTransaction.gasPrice}`);
console.log(`gas used: ${contract.deployTransaction.gasLimit}`);

But, i figured there's a difference, big difference in "gas used" reported above vs "gas used" reported by hardhat-gas-reporter

How can i get the total gas used in deploying or upgrading a contract with its proxy?

I can't think of a simple way to get the gas used as part of a deployment script.

If it's acceptable to inspect this manually:

  • If you're working on a local environment you can run a node (hardhat node) and manually inspect the output you get after running your deployment script against this node (hardhat run --network localhost scripts/deploy.js).
  • If you're working on a network that has an Etherscan explorer, you can go on the explorer to see all the transactions that were sent and how much gas they consumed.

If you need to do it in a script, what you could do is get the current block number before you deploy anything, then after your deployment get the new current block number. Then list all of the transactions that happened between those two blocks, filter it to those that were sent from your deployer account, and then sum the total gas. This is the only way I can think of for doing it programmatically.

Sorry there is no easier way!

I did it like this in hardhat local node, getting the list of gasUsed in all preceding blocks until now after any deployment

    console.log(`${contractId} deployed to: ${contractInstance.address}`);
    console.log(
      `Block number: ${contractInstance.deployTransaction.blockNumber}`
    );
    for (
      let index = contractInstance.deployTransaction.blockNumber || 1;
      index > 0;
      index--
    ) {
      console.log(
        (
          await ethers.provider.send('eth_getBlockByNumber', [
            ethers.utils.hexValue(index),
            true,
          ])
        ).gasUsed.toNumber
      );
    }

With the comments, i was able to check the contract deployed, their address, name and gas used

2 Likes

Looks good except keep in mind it will count all transactions that have happened on the node since it started. If you want to measure the deployment only you could ask for current block number before deployment and only check from that block onward.

Yea, that was used in a hardhat test where the node get kicked up just for the test, i need to know the gasUsed of all deployment happening in that test...

I'm sure there would be 100s of better implementations than this workaround i posted above...