How to verify a contract on Etherscan/BscScan/PolygonScan

Make sure to read this post before asking a question about verification. If your issue is not addressed here, just leave a comment below.

If you want to pay someone to do the verification for you, create a post in Developer Wanted.

This guide applies to all Etherscan instances, including all of the following as well as their testnet explorers:

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.

Make sure to read the documentation for hardhat-etherscan, particularly the part about complex arguments if you're having trouble specifying arguments in the console.

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

Automated verification with Hardhat and OpenZeppelin Upgrades

Proxies that were deployed by the OpenZeppelin Upgrades Plugins can be fully verified using the Hardhat upgrades plugin's verify task.

Manual verification

When verifying an upgradeable deployment, there are at least two contracts involved: 1) the proxy, and 2) the implementation contract. If using a beacon proxy, a third contract (the beacon) is also involved. The proxy and beacon, if applicable, should be already verified if you deployed them using OpenZeppelin Upgrades Plugins (if not, see below). For full verification, however, you will need to verify the implementation contract, using any of the methods mentioned in this article.

In order to get the address of the implementation contract from a proxy, you can use the erc1967 module included in the plugins:

console.log(await upgrades.erc1967.getImplementationAddress(proxyAddress));

For beacon proxies, first get the beacon address from the proxy, then get the implementation address from the beacon. For example:

console.log(await upgrades.beacon.getImplementationAddress(await upgrades.erc1967.getBeaconAddress(proxyAddress)));

Both of the above examples provide 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.

Etherscan may not automatically recognize your contract as a proxy. In this case it is necessary to go to submit the contract address through the Proxy Contract Verification Page. A link to this page can be found under "More Options" in the top right of the contract source code:

Implementation contract was not detected for the proxy

Some kinds of proxies may need at least one transaction before they can be verified as a proxy on Etherscan.

If proxy is not verified

Proxy contracts, beacons, and the ProxyAdmin should be verified automatically as "Similar Match", because we have verified other instances of the same code. On some networks, there may not be a verified instance and the contract you deploy may show up as unverified. In that case, you can verify this contract using the Solc JSON Input shared below, or feel free to contact us in Upgrades to assist.

The compiler version is 0.8.20 and license is MIT.

Promote to Exact Match

If you would like to promote the contract from Similar Match to Exact Match you will need to contact Etherscan as explained on their documentation and send the JSON file attached above.

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.

File import callback not supported

This happens when you try to verify a Solidity file that has imports (dependencies), and the imported files were not included in the code submitted for verification.

For example, if your file builds on OpenZeppelin Contracts ERC20, it will contain a statement like:

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

This imported file needs to be included in the verification request.

The fix depends on the tool you used to develop your contract.

  1. Remix: Verify manually by flattening the source code.
  2. Truffle: Use the verify plugin, or do it manually by flattening the source code.
  3. Hardhat: Use the Etherscan plugin.

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.

Resources

Tutorials

Documentation

Tools

Other

Alternative approaches that are not currently documented below but may be good to explore:

  • Sourcify, a decentralized alternative to Etherscan for source code verification. (Hardhat Tutorial, Truffle Tutorial)
  • hardhat-deploy, a Hardhat plugin for managing deployments with automatic verification to Etherscan and Sourcify.
  • Multisol, a CLI application that extracts Solidity files with their dependencies for Multi-Part files verification on Etherscan.
  • Brownie, a Python development environment that can automatically verify deployed contracts.
20 Likes

Do you have any resource on how to use hardhat-etherscan to verify contracts on Polygon?

4 Likes

Hi, welcome! :wave:

I think just like verify on the ethereum, just use an API-Key of Polygon scan.

3 Likes

8 posts were split to a new topic: Difficulty verifying with Hardhat on Windows PowerShell

Thanks, I managed to get it working :slight_smile:

2 Likes

npx hardhat verify --show-stack-traces --network rinkeby 0xDAdC5E4798f35ED142d55BF4B0eD511DcC1D3Bd8

Error in plugin @nomiclabs/hardhat-etherscan: The address provided as argument contains a contract, but its bytecode doesn't match any of your local contracts.

Before deploying I made sure to delete everything in my artifacts folder am I missing anything?
I was able to get this to work once before but now i'm getting this every time after a deploy and trying to verify.

1 Like

Make sure the address is that of the implementation contract as opposed to the proxy contract. This is explained in the post in the section about upgradeable contracts and proxies.

1 Like

Error! Unable to generate Contract ByteCode and ABI (General Exception, unable to get compiled [bytecode]) . this is the error i get . used same source code . same version , Optimization is not enabled ,run time 0, and abi encoded from abi.hashex.com . can you know the problem

Hello. I am stuck at the part that says "it can be very difficult to retrieve the library address." Any suggestions? Any help would be greatly appreciated. Thanks for your time.

1 Like

If you have a transaction where you interacted with your contract in a way that the library would've been invoked, you may be able to look at the transaction logs to see where the library is located.

oh, okay. thank you so much for your help. I really appreciate it.

dang. can't seem to track down a transaction that would've interacted with the contracts. Any other suggestions? This is my first erc-20 and I have clearly made a couple of mistakes already. I just want to get it right and have something on chain to be proud of.

Is the contract on mainnet? Can you trigger a transaction that would invoke the library?

yes, the contract is live on polygon. i've called a couple transactions and none of them invoked the library.

In that case, since Polygon fees are not very high, it may be simpler to discard the contract, try on testnet to make sure you can verify the contract, and then deploy again to mainnet.

that was my worry. I think my mistake was forgetting to flatten to contract before deploying. thanks for your time.

Hey, I would appreciate some feedback. I've followed the steps for verification but it seems I may have misse something. I have a flattened contract, when trying to verify the contract with copied code (using Remix) it returns an error.

The constructor arguments were autofilled when i selected to verify contract.
Since the contract relied on Openzeppelin libraries, i flattened the contract to try verification with a single file since I was also having some trouble with verification with multiple files...
I am not sure what is needed now for a successful verification.

Any advice would be great, i would love to learn how to do this correctly.

They may not have been autofilled correctly. My recommendation is to review that.

Hey Frangio, OZ Team

Getting a blank on the tutorial for the Flattener plugin. What might cause this?

Notes