How to verify a contract on Etherscan/BscScan/PolygonScan

This guide is a work in progress. If your issue is not addressed here, or you want to suggest a recommendation, leave a comment below.

If you want to pay someone to do the verification for you, create a post in #smart-contracts:developer-wanted.

Make sure to read this post before asking a question about verification.

Resources

Tutorials

Documentation

Tools

General Recommendations

Practice in testnet

Before you deploy to production and risk losing hundreds of dollars to a deployment that you are not able to verify, deploy to a testnet and make sure you can verify the contract there.

Prefer Hardhat to deploy

In our experience, using Hardhat with the hardhat-etherscan plugin is the easiest way to guarantee smooth verification. Deploying with Remix will make things harder.

Use Remix plugins to help

Remix has plugins that you can activate by going to the plugin manager. There are two plugins that can help you verify: Etherscan and Flattener.

The Etherscan plugin requires that you configure an Etherscan API key, because it will try to verify using the Etherscan API. You can encode the constructor parameters using ABI Encoder Online.

The Flattener plugin can give you a flattened file that you can then use in Etherscan as Single file input.

Use versioned imports in Remix

If you use OpenZeppelin Contracts, your imports should include the version you want to import, for example 4.3.0. So it should look like either of these options:

import "@openzeppelin/contracts@4.3.0/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.3.0/contracts/token/ERC20/ERC20.sol;

While any of the following, using the master branch or a non-versioned import, are discouraged, and may result in non-reproducible deployments that can be extremely hard to verify.

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol;

Upgradeable Contracts and Proxies

When verifying an upgradeable deployment, there are two contracts involved: 1) the proxy, and 2) the implementation contract. The proxy should be automatically verified if you deployed the proxy using OpenZeppelin Upgrades Plugins. The implementation contract you need to verify using any of the methods mentioned in this article. In order to get the address of the implementation contract you can use the erc1967 module included in the plugins. This is the address that you need to verify against your contract code. Keep in mind that constructor arguments will be empty for verification, even if you have an initializer function with arguments.

Common Errors

Unable to generate Contract ByteCode and ABI

This is a generic error that doesn't offer any indication of the cause.

When you meet this error, please check the following one by one, making sure that it matches what you used to deploy exactly: contract source code, compiler version, compiler optimizations and runs number, constructor parameters, address of libraries.

Multiple SPDX license identifiers found in source file

This can happen when verifying a flattened contract. You need to remove the duplicate SPDX license comments manually, and only keep one valid SPDX license.If there are multiple different licenses in the file you can combine them into a single comment using the AND operator. There may be legal restrictions when combining different licenses.

You can find some discussion about the technical details and implications in https://github.com/nomiclabs/truffle-flattener/issues/55.

Definition of base has to precede definition of derived contract

This can happen when verifying a flattened contract. You should adjust the order of the contracts, putting the parent contracts first, and the child contract after them.

For example, the following is wrong:

contract Ownable is Context {}
contract Context {}

The right order should be:

contract Context {}
contract Ownable is Context {}

Expected library(ies) but one or more was not provided

This happens when your contract uses one or more public or external functions from a Solidity library. In this situation, the library has to be deployed on its own, and the resulting address is embedded in the final contract bytecode.

It only happens when you use Single or Multi-part files verification, because the library source code is available but not the address where the library is deployed is not known.

Etherscan requires that you specify the names and addresses of libraries in the section called "Contract Library Address".

If you deployed the contract with Remix, the library was deployed automatically without your intervention. In the console, you should find an entry that says creation of library <library> pending..., followed by the transaction that deploys the library, where you will find its address. If you can't find this entry in the console, it will be very difficult to retrieve the library address.

If you deployed the contract with Truffle migrations, this information is found in the corresponding build/contracts/<ContractName>.json file. In this file, there is a networks field that contains an entry for each network that you've ran your migrations on, indexed by network id. In the entry corresponding to the network you want to verify, you will find a field called links that contains name and address of each library that was used, and that you should input into Etherscan.

4 Likes