Verify on Etherscan
CLI utility / truffle plugin / Node.js library that automates verification on etherscan.io of contracts that were compiled and deployed with truffle.
The most common use case of verifying contracts after deployment should be covered by the following command even without installing the library:
API_KEY=<your_etherscan_api_key> npx verify-on-etherscan --network mainnet ./build/contracts/*
Etherscan supports mainnet, ropsten, rinkeby, kovan and goerli networks for verification and requires a valid Etherscan APIkey. You can see details here.
Installation
npm install --save-dev verify-on-etherscan
Usage
The library can be used as a cli utility -- the simplest way, as a truffle plugin -- to take advantage of truffle config or as a third-party library.
As a cli utility
Usage: API_KEY=<your_key> npx verify-on-etherscan [options] <artifact_paths ...> Positionals: artifacts a space separated list of paths to artifact json files or a glob pattern like ./build/contracts/*.json [string, string, string...] Options: --version, -v Show version number --network which network to verify contracts on [string] [required] [choices: "mainnet", "ropsten", "rinkeby", "kovan", "goerli"] --optimize, -o whether your contracts were optimized during compilation
By default the library will use Etherscan api to fetch transactions.
To use a web3
for that set --use-fetch=false
. That way an instance of web3
will be created for you and connected to https://<network>.infura.io
If no --optimizer
or --optimize-runs
flags are provided, the library will attempt to infer optimizer settings from ./truffle.js
or ./truffle-config.js
in the project directory. Failing that { enabled: false, runs: 200 }
will be used.
You can use voeth
as an alias for verify-on-etherscan
if you install it locally:
API_KEY=<your_etherscan_api_key> npx voeth --network rinkeby ./build/contracts/Contract1.json ./build/contracts/Contract2.json
As a truffle plugin
First add
plugins: "verify-on-etherscan"
to your config in truffle.js
or truffle-config.js
Usage: API_KEY=<your_key> npx truffle run verify [options] <artifact_paths ...> artifact_paths a space separated list of paths to artifact json files or a glob pattern like ./build/contracts/*.json API_KEY your key
By default a web3
instance will be created with a provider from the config returned from truffle.js
corresponding to the provided --network
. It will be used for requisting transaction data from the blockchain.
--use-fetch
allows to use Etherscan api to fetch transactions.
Optimizer settings are passed by truffle as part of the plugin config.
As a library
First import it in your project then call it with your options:
const verify = ; const result = await
verify(options)
returns a Promise that resolves to
// contracts that were already verified on Etherscan alreadyVerified: Array<absolute_artifact_paths> // contracts that were verified successfully successful: Array<absolute_artifact_paths> // contracts for which verification failed failed: Array<absolute_artifact_paths>
when the verification is finished, or rejects if any unhandled Errors are thrown inside.
Options:
cwd current working directory, relative to which artifacts will be looked up
If web3
is provided, it will be used to determine which network to verify contracts on (through web3.eth.net.getId()
matching).
if network
is provided and useFetch === false
, an instance of web3
will be created for you and connected to https://<network>.infura.io
. network
must be one of the networks which Etherscan supports for verification.
if network
is provided and useFetch === true
, no web3
instance will be created and the library will fetch transactions from Etherscan api.
Either web3
or network
must be provided.
Workflow
Step 0
In case of using the library as a cli utility or a truffle plugin some config parsing will first take place
Step 1
Depending on provided config an instance of web3
is created.
Step 2
JSON artifacts are read, parsed and necessary data is extracted.
Extracted: contractname, compilerversion, bytecode, contractaddress, txhash, sourcePath, library addresses (if any). contractaddress and txhash are dependent on the network set for verification.
It's also determined whether a contract has a non-emty constructor.
Step 3
For each contractaddress the libary fetches contract abi from Etherscan to filter out already verified contracts.
Keep in mind that recently verified contracts would still be reported as unverified by Etherscan for some time and won't be filtered out immediately.
Step 4
truffle-flattener processes sourcePath of each artifact and returns the flattened code.
Step 5 (optional)
If --output <directory>
was given, flattened contracts are written out there following <original_filename>.flat.sol
pattern.
Step 6
For contracts that have a non-emty constructor the library determines its encoded constructor arguments.
It gets the input data of the transaction corresponding to a contract's creation txhash. Then subtracts the artifact bytecode from it. The result is the encoded constructor arguments.
In case the bytecode and the transaction data don't match, provided source code and compiler are the same, the difference is usually in the metadata portion of the code.
A typical contract creation transaction data looks like this:
(solc v>=0.4.7 <0.4.22)0x6060604052[__contract_code__]a165627a7a72305820[__metadata__]0029[__constractor_arguments__] (solc v>=0.4.22)0x6080604052[__contract_code__]a165627a7a72305820[__metadata__]0029[__constractor_arguments__]
It is trivial to extract the constructor arguments from it.
Step 7
For each contract the library posts apiKey, optimizer settings, contractaddress, contractname, sourceCode, constructorArguments, library addresses and compileversion to Etherscan api getting GUIDs in return.
The library checks the GUIDs for status change until all contracts are either verified or fail verification. The interval between check is determined by the delay
option.
License
Licensed under the MIT license.