How to verify with Hardhat or Truffle a smart contract using OpenZeppelin Contracts

For a complete list of resources regarding verification visit How to verify a contract on Etherscan/BscScan/PolygonScan.

The recommended way to verify a smart contract inheriting from OpenZeppelin Contracts is as a "multi-file" contract (corresponding to the Standard-Json-Input compiler type on Etherscan). It is easier to read, imports are maintained, licenses are maintained.

Verified using Hardhat

Verified using Truffle

Hardhat

Hardhat has an Etherscan plugin: Hardhat Etherscan plugin

Note: Hardhat was previously Buidler.

You can also use Hardhat to verify on BSCscan, see: https://docs.binance.org/smart-chain/developer/deploy/hardhat-verify.html

  1. Install the plugin
npm install --save-dev @nomiclabs/hardhat-etherscan
  1. Configure the plugin in hardhat.config.js
    Add require("@nomiclabs/hardhat-etherscan");
    Add Etherscan API key (:warning: keep secret and don't commit to version control)
    Set compiler version to match what was deployed
// hardhat.config.js
const { infuraProjectId, mnemonic, etherscanApiKey } = require('./secrets.json');

require('@nomiclabs/hardhat-ethers');
require("@nomiclabs/hardhat-etherscan");
/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {

  networks: {
    rinkeby: {
      url: `https://rinkeby.infura.io/v3/${infuraProjectId}`,
      accounts: {mnemonic: mnemonic}
    },
    ropsten: {
      url: `https://ropsten.infura.io/v3/${infuraProjectId}`,
      accounts: {mnemonic: mnemonic}
    },
    kovan: {
      url: `https://kovan.infura.io/v3/${infuraProjectId}`,
      accounts: {mnemonic: mnemonic}
    },
    goerli: {
      url: `https://goerli.infura.io/v3/${infuraProjectId}`,
      accounts: {mnemonic: mnemonic}
    },
    mainnet: {
      url: `https://mainnet.infura.io/v3/${infuraProjectId}`,
      accounts: {mnemonic: mnemonic}
    }
  },

  etherscan: {
    // Your API key for Etherscan
    // Obtain one at https://etherscan.io/
    apiKey: etherscanApiKey
  },
  solidity: "0.6.12"
};
  1. Verify
    :warning: Remove any unnecessary contracts and clear the artifacts otherwise these will also be part of the verified contract.
npx hardhat verify --network mainnet DEPLOYED_CONTRACT_ADDRESS "Constructor argument 1"

To verify SimpleToken (below) deployed on Rinkeby (https://rinkeby.etherscan.io/address/0x0bB0e851Da4f0149C7c3f77ac3492C824F1f4dD0#code) I ran the following:

$ npx hardhat verify --network rinkeby 0x0bB0e851Da4f0149C7c3f77ac3492C824F1f4dD0
Nothing to compile
Successfully submitted source code for contract
contracts/SimpleToken.sol:SimpleToken at 0x0bB0e851Da4f0149C7c3f77ac3492C824F1f4dD0
for verification on etherscan. Waiting for verification result...
Successfully verified contract on etherscan

Truffle

Truffle has an Etherscan plugin: truffle-plugin-verify

You can also use Truffle to verify on BSCscan, see: * https://docs.binance.org/smart-chain/developer/deploy/truffle-verify.html

:warning: You need to deploy with Truffle to verify with the Truffle verify plugin.

  1. Install the plugin
npm install -D truffle-plugin-verify
  1. Configure the plugin in truffle-config.js
// truffle-config.js
...
const { infuraProjectId, mnemonic, etherscanApiKey } = require('./secrets.json');
const HDWalletProvider = require('@truffle/hdwallet-provider');

module.exports = {
  ...

  networks: {
    ...
    rinkeby: {
      provider: () => new HDWalletProvider(
        mnemonic, `https://rinkeby.infura.io/v3/${infuraProjectId}`
      ),
      network_id: 4,
      gasPrice: 10e9,
      skipDryRun: true
    },
    ropsten: {
      provider: () => new HDWalletProvider(
        mnemonic, `https://ropsten.infura.io/v3/${infuraProjectId}`
      ),
      network_id: 3,
      gasPrice: 10e9,
      skipDryRun: true
    },
    kovan: {
      provider: () => new HDWalletProvider(
        mnemonic, `https://kovan.infura.io/v3/${infuraProjectId}`
      ),
      network_id: 42,
      gasPrice: 10e9,
      skipDryRun: true
    },
    goerli: {
      provider: () => new HDWalletProvider(
        mnemonic, `https://goerli.infura.io/v3/${infuraProjectId}`
      ),
      network_id: 5,
      gasPrice: 10e9,
      skipDryRun: true
    }
  },

  // Set default mocha options here, use special reporters etc.
  mocha: {
    // timeout: 100000
  },

  // Configure your compilers
  compilers: {
    solc: {
      version: "0.6.12",    // Fetch exact version from solc-bin (default: truffle's version)
      // docker: true,        // Use "0.5.1" you've installed locally with docker (default: false)
      // settings: {          // See the solidity docs for advice about optimization and evmVersion
      //  optimizer: {
      //    enabled: false,
      //    runs: 200
      //  },
      //  evmVersion: "byzantium"
      // }
    }
  },
  plugins: [
    'truffle-plugin-verify'
  ],
  api_keys: {
    etherscan: etherscanApiKey
  }
};
  1. Verify
npx truffle run verify SomeContractName AnotherContractName --network networkName

To verify SimpleToken (below) deployed on Goerli (https://goerli.etherscan.io/address/0x27Bb3535432DE5351f7f892aDF99085f9cfCbfcb#code) I ran the following (from the project I used to deploy SimpleToken):

$ npx truffle run verify SimpleToken --network goerli
Verifying SimpleToken
Pass - Verified: https://goerli.etherscan.io/address/0x27Bb3535432DE5351f7f892aDF99085f9cfCbfcb#contracts
Successfully verified 1 contract(s).

SimpleToken.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

/**
 * @title SimpleToken
 * @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
 * Note they can later distribute these tokens as they wish using `transfer` and other
 * `ERC20` functions.
 */
contract SimpleToken is ERC20 {

    /**
     * @dev Constructor that gives msg.sender all of existing tokens.
     */
    constructor() public ERC20("SimpleToken", "SIM") {
        _mint(msg.sender, 10000000 * (10 ** uint256(decimals())));
    }
}
9 Likes

A post was split to a new topic: Verify ERC20PresetMinterPauser

3 posts were split to a new topic: Verify contract deployed with Remix

2 posts were split to a new topic: Verify smart contract inheriting from OpenZeppelin Contracts on xDAI

4 posts were split to a new topic: How to verify upgradeable contract?

@abcoathup I followed the steps for HardHat, did the npm installs but I keep getting a Error: Cannot find module './secrets.json'

Did secrets.json get moved else where?

thoughts?

No, you should create such file by yourself, and set your own config, do not show these sensitive config to others.

@Skyge So in essence this is saying for me to create a secret.json file as:

{ "mnemonic": "my metamask seed phrase" } (?)

This seems like a very high security flaw… How do I avoid that file from being caught in the wild and cause me harm?

Yes.

You can add this file in your .gitignore to ignore this file, so then this file will not be uploaded to the github.

1 Like

Encountering errors while trying to verify with etherscan plugin for hardhat.

Contract:

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract KwnToken is ERC20 {
  constructor(uint totalSupply) ERC20('KWN', 'KwnToken') {
    uint amount = totalSupply * 10 ** decimals();
    _mint(_msgSender(), amount);
  }

}

Running verify:

npx hardhat verify --network goerli 0x1be5ccde92e839c1cdbefd02045830855257a152 10
Nothing to compile
Error in plugin @nomiclabs/hardhat-etherscan: More than one contract was found to match the deployed bytecode.
Please use the contract parameter with one of the following contracts:
  * @openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20
  * contracts/KwnToken.sol:KwnToken

For example:

  hardhat verify --contract contracts/Example.sol:ExampleContract <other args>

If you are running the verify subtask from within Hardhat instead:

  await run("verify:verify", {
    <other args>,
    contract: "contracts/Example.sol:ExampleContract"
  };

Trying another way:

npx hardhat verify --network goerli --contract contracts/KwnToken.sol:KwnToken 0x1be5ccde92e839c1cdbefd02045830855257a152 10
Nothing to compile
Compiling 1 file with 0.8.0
Successfully submitted source code for contract
contracts/KwnToken.sol:KwnToken at 0x1be5ccde92e839c1cdbefd02045830855257a152
for verification on Etherscan. Waiting for verification result...

We tried verifying your contract KwnToken without including any unrelated one, but it failed.
Trying again with the full solc input used to compile and deploy it.
This means that unrelated contracts may be displayed on Etherscan...

Successfully submitted source code for contract
contracts/KwnToken.sol:KwnToken at 0x1be5ccde92e839c1cdbefd02045830855257a152
for verification on Etherscan. Waiting for verification result...

Error in plugin @nomiclabs/hardhat-etherscan: The contract verification failed.
Reason: Fail - Unable to verify

For more info run Hardhat with --show-stack-traces

Did you insert your Etherscan API key in your network config (hardhat.config.js)?

Hi, i got the same problem here my contract is kinda like the SimpleToken which is the solidity is different version from the contract in BSC and multiple files. But i coulnd’t get my ABI-encoded format and bytecode…may i know how to solve this ? Thank you

While verifying m getting this error

Please help

1 Like

I was successul, all good.

Hi, welcome! :wave:

Have you installed all package?

I’m also getting the same error.

yes I have just deployed the contract and then m verifying it, you can see in the screenshot packages are there in the nodemodules

Maybe there is something wrong with your path, I am not sure, I do not use windows system, you can have a try:

@openzeppelin\contracts\introspection\ERC165.sol

That is \, not /.

I will give a try. but if there is any issue in the import and all then why it dont occur during compile and deployment. why it only occur during verify.

Maybe what I said is not right, and you can remove the package and reinstall to have a try.