How to verify your deployment on Etherscan with Hardhat Ignition

Step by step tutorial on how to verify source code from your Hardhat Ignition deployment on Etherscan

How to verify your deployment on Etherscan with Hardhat Ignition

Now that Hardhat Ignition is celebrating both a feature set that is reaching maturity as well as its inclusion inside Hardhat Toolbox, we’ve added several powerful new features we’re excited to show off including native create2 support, resumable deployments, and full contract type inference with Viem. The one we’ll be taking a look at today is source verification of your Hardhat Ignition deployments.


In this guide you will deploy your Hardhat Ignition module to a live network and verify the source code of each of its contracts.

Verifying a contract means making its source code public, along with the compiler settings you used, which allows anyone to verify what the contract is doing, and even compile it and run it locally. Doing this is extremely important in an open platform like Ethereum.

In this guide we’ll explain how to do this with the Etherscan explorer.

Getting an API key from Etherscan

The first thing you need is an API key from Etherscan. To get one, go to their site, sign in (or create an account if you don’t have one) and open the “API Keys” tab. Then click the “Add” button and give a name to the API key you are creating (e.g. “Hardhat”). After that you’ll see the newly created key in the list.

Open your Hardhat config and add the API key you just created:

// hardhat.config.ts 
 
export default { 
  // …rest of the config… 
  etherscan: { 
    apiKey: "ABCDE12345ABCDE12345ABCDE123456789", 
  }, 
};

Deploying and verifying on the Sepolia testnet

We are going to use the Sepolia testnet to deploy and verify our Ignition module, so you need to add this network in your Hardhat config. Here we are using Alchemy to connect to the network.

This example uses a new Hardhat feature called configuration variables. Read more about `vars` and configuration variables on our announcement blog post.

// hardhat.config.ts 
 
// Go to https://alchemy.com, sign up, create a new App in 
// its dashboard, and set the Hardhat configuration variable 
// ALCHEMY_API_KEY to the key 
const ALCHEMY_API_KEY = vars.get("ALCHEMY_API_KEY"); 
 
// Replace this private key with your Sepolia test account private key 
// To export your private key from Coinbase Wallet, go to 
// Settings > Developer Settings > Show private key 
// To export your private key from Metamask, open Metamask and 
// go to Account Details > Export Private Key 
// Beware: NEVER send mainnet ETH into testing accounts 
const SEPOLIA_PRIVATE_KEY = vars.get("SEPOLIA_PRIVATE_KEY"); 
 
export default { 
  // ...rest of your config... 
  networks: { 
    sepolia: { 
      url: `https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, 
      accounts: [SEPOLIA_PRIVATE_KEY], 
    }, 
  }, 
};

To deploy on Sepolia you need to send some Sepolia ETH to the address that’s going to be making the deployment. You can get testnet ETH from a faucet, a service that distributes testing-ETH for free. Here is Alchemy’s Sepolia Faucet.

This guide assumes you are using the contracts and HardhatIgnition module from the quick start guide, but the steps are the same for any deployment.

Now you are ready to deploy your module to the testnet, but first we are going to make the source code of our contract unique. The reason we need to do this is that the sample code from the quick start guide is already verified in Sepolia, so if you try to verify it you’ll get a warning. If you are using your own contracts, you can likely skip this step.

Open your contract and add a comment with something unique, like your GitHub’s username. Keep in mind that whatever you include here will be, like the rest of the code, publicly available on Etherscan:

// Author: @janedoe 
contract Rocket {

You can now run the deployment using the newly added Sepolia network:

npx hardhat ignition deploy ignition/modules/Apollo.ts --network sepolia --verify

The ` — verify` flag is optional, but it tells Hardhat Ignition to verify the contracts after a successful deployment.

If you have an existing deployment and want to verify it, you can also run the `verify` task directly by passing the deployment ID:

npx hardhat ignition verify chain-11155111

If you get an error saying that the address does not have bytecode, it probably means that Etherscan has not indexed your contract yet. In that case, wait for a minute and then try again.

After the task has successfully executed, for each deployed contract you’ll see a link to its publicly verified code.

To learn more about verifying, read the hardhat-verify documentation.

Feedback welcome

We would love your feedback if you run into any issues or have any feature requests! Please open an issue on Github.