How to flatten and verify a smart contract using OpenZeppelin Contracts

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

This guide uses flattening for verification, but we recommend doing multifile verification as it is easier to read, maintains licenses and imports. See guide at How to automatically verify smart contract using from OpenZeppelin Contracts with Hardhat or Truffle.

To verify a contract inheriting from OpenZeppelin Contracts you can create a single file (flat) contract using truffle-flattener and verify as a single file on Etherscan. e.g.

NOTE: This guide uses npx to run npm packages locally, though you could install packages globally and run.

Deploy contract

Example: SimpleToken.sol

SimpleToken based on: OpenZeppelin SimpleToken inherits ERC20 contracts from OpenZeppelin Contracts.

pragma solidity ^0.5.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Detailed.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, ERC20Detailed {

     * @dev Constructor that gives msg.sender all of existing tokens.
    constructor () public ERC20Detailed("SimpleToken", "SIM", 18) {
        _mint(msg.sender, 10000 * (10 ** uint256(decimals())));

Compile SimpleToken

Using truffle compile the contract e.g. npx truffle compile

$ npx truffle compile

Compiling your contracts...
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/SimpleToken.sol
> Compiling @openzeppelin/contracts/math/SafeMath.sol
> Compiling @openzeppelin/contracts/token/ERC20/ERC20.sol
> Compiling @openzeppelin/contracts/token/ERC20/ERC20Detailed.sol
> Compiling @openzeppelin/contracts/token/ERC20/IERC20.sol
> Artifacts written to /mnt/c/Users/andre/Documents/projects/forum/verify/build/contracts
> Compiled successfully using:
   - solc: 0.5.10+commit.5a6ea5b1.Emscripten.clang

Deploy SimpleToken

Deploy SimpleToken to a public testnet, e.g. Ropsten using npx truffle migrate --network ropsten. You will need to have configured truffle to deploy to a public testnet.

$ npx truffle migrate --network ropsten

Compiling your contracts...
> Everything is up to date, there is nothing to compile.

Starting migrations...
> Network name:    'ropsten'
> Network id:      3
> Block gas limit: 0x7a121d


   Deploying 'Migrations'
   > transaction hash:    0xbdadedf8f9a74e584f9065991034864f1456b51f13812e6091281b7e27a8d8b9
   > Blocks: 2            Seconds: 73
   > contract address:    0xc6C209A3bA3319D823A6bFa6a0dB3AE2B0711D27
   > block number:        6089972
   > block timestamp:     1564466794
   > account:             0x77737a65C296012C67F8c7f656d1Df81827c9541
   > balance:             1.55775068
   > gas used:            263741
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.00527482 ETH

   Pausing for 2 confirmations...
   > confirmation number: 1 (block: 6089973)
   > confirmation number: 2 (block: 6089974)

   > Saving migration to chain.
   > Saving artifacts
   > Total cost:          0.00527482 ETH


   Deploying 'SimpleToken'
   > transaction hash:    0x19e48a15bfdfebb4231d9acb54b7409052d5f7aec31c4fd20a464635af6a3062
   > Blocks: 1            Seconds: 9
   > contract address:    0x8256e4Ac3F229966facC7164dA69A22ce2ca0a0f
   > block number:        6089979
   > block timestamp:     1564466944
   > account:             0x77737a65C296012C67F8c7f656d1Df81827c9541
   > balance:             1.53135022
   > gas used:            1278000
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.02556 ETH

   Pausing for 2 confirmations...
   > confirmation number: 1 (block: 6089980)
   > confirmation number: 2 (block: 6089981)

   > Saving migration to chain.
   > Saving artifacts
   > Total cost:             0.02556 ETH

> Total deployments:   2
> Final cost:          0.03083482 ETH

Verify contract

Flatten the contract

Flatten the contract using truffle-flattener and write to file e.g. FlatSimpleToken.sol in the contracts folder.

$ npx truffle-flattener ./contracts/SimpleToken.sol > ./contracts/FlatSimpleToken.sol
npx: installed 319 in 26.405s

Verify on Etherscan

Search for the contract on Etherscan using the contract address shown when you deployed and press Verify and Publish

Alternatively open the verifyContract page on Etherscan for the testnet that you are using e.g.

Enter the contract address, set the Compiler Type to Solidity (Single file), and set the Compiler Version shown when you compiled and select a Licence for the contract (e.g. OpenZeppelin Contracts use MIT licence). Etherscan has a summary of the different licence options.

Check agree to the terms if you do agree, (otherwise stop the verification) and press Continue.

Set the optimisation, truffle configuration doesn't have the optimizer enabled by default. Paste in the single flat contract

Set the constructor arguments, in this example we didn't have any constructor parameters.

Check I'm not a robot and complete the CAPTCHA and press the Verify and Publish button and wait.

The contract source code should verify. You can view the verified contract by selecting the contract address.

The contract now shows the source code as verified, and you can interact with the contract (read and write). e.g.

If you have any questions about verifying, please create a new topic in #support


When verifying a contract using OpenZeppelin Contracts - SafeMath there is no need to specify SafeMath as an external library.

SafeMath functions are all internal. There is no external library to link to.
... code of internal library functions and all functions called from therein will at compile time be pulled into the calling contract, and a regular JUMP call will be used instead of a DELEGATECALL.

1 Like

Hi @abcoathup !

If I have two contracts,
1st is for my Token and 2nd is for my Token Crowd Sale.
(From OZ example, the Token and the Crowdsale contract are also separated I guess)

Then do I have to verify both of the contracts ?
If so, does the compiler type should be changed to Solidity (Multiple File) ?


Hi @Charles808

You need to verify the Token and the Crowdsale separately as each is a separate contract.

Once you have deployed the two contracts, flatten each contract and then verify each using the above process as single files.

The Solidity (Multiple File) option is for when a single contract has multiple files, e.g. the smart contract is in one file, and each import is in a separate file.

I have found it easier to verify as a single file, which is why I flatten first.


A post was split to a new topic: Verify smart contract inheriting from OpenZeppelin?

A post was split to a new topic: File import callback not supported import “…/…/GSN/Context.sol”

5 posts were split to a new topic: Verify contract deployed using Remix inheriting from OpenZeppelin

A post was split to a new topic: Truffle Flattener: ParserError: missing ‘;’ at ‘{’

Hi abcoathup, i have a question, Can I add a crowdsale to my ERC20 token after I have developed it?

Generally, a contract that has been deployed can’t be modified. But for next time, you can do it by proxy, for more details, you can have a look at this documentation

I ran into some errors using truffle-flattener.
This “flatten-sol” CLI should work

1 Like

Use Remix, then install flattener plugin on the remix website