VERIFY CONTRACTS USING HARDHAT

INSTALLATION

1. Install Hardhat

If you are starting from scratch, create an npm project by going to an empty folder, running npm init, and following the instructions. Recommend npm 7 or higher.

Once your project is ready:

npm instructions

npm install --save-dev hardhat

yarn instructions

yarn add --dev hardhat

2. Create a project

Run npx hardhat in your project folder and follow the instructions to create (more info here).

3. Install plugin

Install the hardhat-etherscan plugin (requires v3.0.0+).

npm

npm install --save-dev @nomiclabs/hardhat-etherscan

yarn

yarn add --dev @nomiclabs/hardhat-etherscan

4. Add plugin reference to config file

Add the following statement to your hardhat.config.js.

require("@nomiclabs/hardhat-etherscan");

If using TypeScript, add this to your hardhat.config.ts. More info on using typescript with hardhat available here.

import "@nomiclabs/hardhat-etherscan";

CONFIG FILE

Your basic Hardhat config file (hardhat.config.js or hardhat.config.ts) will be setup to support the network you are working on. In this example we use the Gather test network and a .js file.

Here we add an RPC url without an API key, however some value is still required. You can use any arbitrary string. More info.

If you prefer, you can migrate to hardhat-toolbox to use a plugin bundle.

require("@nomiclabs/hardhat-waffle");
require("@nomiclabs/hardhat-etherscan");
require('hardhat-deploy');

let secret = require("./secret");

module.exports = {
  solidity: "0.8.9",
  networks: {
      gatherTestnet: {
      url: "https://testnet.gather.network",
      accounts: [secret.key]
    },
      gatherMainnet: {
      url: "https://mainnet.gather.network",
      accounts: [secret.key]
    }
  },
  etherscan: {
    apiKey: "abc"
  }
};

Add Gather Network as custom chain

Now add gather mainnet and testnet as custom chain in the etherscan.

You can add a customChains object to the config file. It includes:

  • chainID - Network chain ID

    • Gather Mainnet: 192837465

    • Gather Testnet: 356256156

  • apiURL - Block explorer API URL

    • Gather Mainnet: https://explorer.gather.network/api

    • Gather Testnet: https://testnet-explorer.gather.network/api

  • browserURL - Block explorer URL

    • Gather Mainnet: https://explorer.gather.network

    • Gather Testnet: https://testnet-explorer.gather.network

This is how it would be added to the config file. The network name in customChains must match the network name in the apiKey object.

Note: The apiKey can contain any random string as api key verification is not required for Gather, but it cannot be empty.

etherscan: {
    apiKey: {
      gatherMainnet: "abc",
      gatherTestnet: "abc"
    },
    customChains: [
      {
        network: "gatherMainnet",
        chainId: 192837465,
        urls: {
          apiURL: "https://explorer.gather.network/api",
          browserURL: "https://explorer.gather.network"
        }
      },
      {
        network: "gatherTestnet",
        chainId: 356256156,
        urls: {
          apiURL: "https://testnet-explorer.gather.network/api",
          browserURL: "https://testnet-explorer.gather.network"
        }
      }
    ]
  }

Your final hardhat config file (hardhat.config.js or hardhat.config.ts) should be like this:

require("@nomiclabs/hardhat-waffle");
require("@nomiclabs/hardhat-etherscan");
require('hardhat-deploy');

let secret = require("./secret");

module.exports = {
  solidity: "0.8.9",
  networks: {
      gatherTestnet: {
      url: "https://testnet.gather.network",
      accounts: [secret.key]
    },
      gatherMainnet: {
      url: "https://mainnet.gather.network",
      accounts: [secret.key]
    }
  },
  etherscan: {
    apiKey: {
      gatherMainnet: "abc",
      gatherTestnet: "abc"
    },
    customChains: [
      {
        network: "gatherMainnet",
        chainId: 192837465,
        urls: {
          apiURL: "https://explorer.gather.network/api",
          browserURL: "https://explorer.gather.network"
        }
      },
      {
        network: "gatherTestnet",
        chainId: 356256156,
        urls: {
          apiURL: "https://testnet-explorer.gather.network/api",
          browserURL: "https://testnet-explorer.gather.network"
        }
      }
    ]
  }
};

DEPLOY AND VERIFY

Deploy

npx hardhat run scripts\deploy.js --network <network>

Verify

You can include constructor arguments with the verify task

npx hardhat verify --network <network> DEPLOYED_CONTRACT_ADDRESS "Constructor argument 1"

Without constructor arguments

npx hardhat verify --network <network> DEPLOYED_CONTRACT_ADDRESS

Complex constructor arguments

When the constructor has a complex argument list, you'll need to write a javascript module that exports the argument list. The expected format is the same as a constructor list for an ethers contract. For example, if you have a contract like this:

struct Point {
  uint x;
  uint y;
}

contract Foo {
  constructor (uint x, string s, Point memory point, bytes b) { ... }
}

then you can use an arguments.js file like this:

module.exports = [
  50,
  "a string argument",
  {
    x: 10,
    y: 5,
  },
  // bytes have to be 0x-prefixed
  "0xabcdef",
];

The module can then be loaded by the verify task when invoked like this:

npx hardhat verify --constructor-args arguments.js DEPLOYED_CONTRACT_ADDRESS

Gather testnet example (complex constructor arguments):

$ npx hardhat verify --network gathertestnet --constructor-args arguments.js 0x2e58ccAD9A7fF467Dc04C41389F18b92E7269319
Nothing to compile
Compiling 1 file with 0.8.17
Successfully submitted source code for contract
contracts/BatchTransferRewardDistributor.sol:BatchTransferRewardDistributor at 0x2e58ccAD9A7fF467Dc04C41389F18b92E7269319
for verification on the block explorer. Waiting for verification result...

Successfully verified contract BatchTransferRewardDistributor on Etherscan.
https://testnet-explorer.gather.network/api/address/0x2e58ccAD9A7fF467Dc04C41389F18b92E7269319#code

CONFIRM VERIFICATION ON GATHER EXPLORER

Go to Gather explorer and paste the contract address into the search bar. If verified, the code tab will display a green checkmark.

Last updated