Verifying a contract inheriting from OpenZeppelin Contracts

Verifying

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. https://ropsten.etherscan.io/verifyContract

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


1_initial_migration.js
======================

   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


2_deploy.js
===========

   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


Summary
=======
> 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. https://ropsten.etherscan.io/verifyContract

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. https://ropsten.etherscan.io/address/0x8256e4Ac3F229966facC7164dA69A22ce2ca0a0f#code


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

2 Likes

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.

https://solidity.readthedocs.io/en/latest/contracts.html#libraries
… 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.

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) ?

1 Like

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.

1 Like