2

For some purpose. I use web3.js 0.20 to deploy contracts.(eg. press button to deploy contracts automatically, not through remix IDE). When I deploy contracts, etherscan need to verify solidity. Is there a method that verifies contracts automatically through Web3? Thanks a lot.

1

Nothing about Etherscan (a proprietary, third-party app) is built in to web3.js, but Etherscan does have an API for verifying contract source code: https://etherscan.io/apis#contracts.

0

There you go (relying on web3 v1.0.0-beta.34 and truffle-flattener v1.2.10)...

Create a file named verify.js with the contents below, and place it next to package.json:

const WORK_DIR = "./PROJ_DIR"; // your contracts folder should be under this path
const NODE_DIR = "../node_modules";
const INPUT_FILE = process.argv[2];

const fs        = require("fs");
const path      = require("path");
const request   = require("request");
const spawnSync = require("child_process").spawnSync;

const input = JSON.parse(fs.readFileSync(INPUT_FILE, {encoding: "utf8"}));
//  input example:
//  {
//      "network"        : "api", // use "api" for mainnet or "api-<testnet>" for testnet
//      "apiKey"         : "",    // generate this value at https://etherscan.io/myapikey
//      "compilerVersion": "v0.4.24+commit.e67f0147",
//      "optimization"   : {"used": 1, "runs": 6000},
//      "contracts"      : {
//          "Contract1": {"addr": "0x0000000000000000000000000000000000000001", "args": "<abi-encoded constructor arguments>"},
//          "Contract2": {"addr": "0x0000000000000000000000000000000000000002", "args": "<abi-encoded constructor arguments>"},
//          "Contract3": {"addr": "0x0000000000000000000000000000000000000003", "args": "<abi-encoded constructor arguments>"}
//      }
//  }

function run() {
    for (const pathName of getPathNames("contracts")) {
        const contractName = path.basename(pathName, ".sol");
        if (input.contracts.hasOwnProperty(contractName))
            post(contractName, getSourceCode(pathName));
    }
}

function getPathNames(dirName) {
    let pathNames = [];
    for (const fileName of fs.readdirSync(WORK_DIR + "/" + dirName)) {
        if (fs.statSync(WORK_DIR + "/" + dirName + "/" + fileName).isDirectory())
            pathNames = pathNames.concat(getPathNames(dirName + "/" + fileName));
        else if (fileName.endsWith(".sol"))
            pathNames.push(dirName + "/" + fileName);
    }
    return pathNames;
}

function getSourceCode(pathName) {
    const result = spawnSync("node", [NODE_DIR + "/truffle-flattener/index.js", pathName], {cwd: WORK_DIR});
    return result.output.toString().slice(1, -1);
}

function post(contractName, sourceCode) {
    console.log(contractName + ": sending verification request...");
    request.post({
            url: "https://" + input.network + ".etherscan.io/api",
            form: {
                module               : "contract",
                action               : "verifysourcecode",
                sourceCode           : sourceCode,
                contractname         : contractName,
                apikey               : input.apiKey,
                compilerversion      : input.compilerVersion,
                optimizationUsed     : input.optimization.used,
                runs                 : input.optimization.runs,
                contractaddress      : input.contracts[contractName].addr,
                constructorArguements: input.contracts[contractName].args,
            }
        },
        function(error, response, body) {
            if (error) {
                console.log(contractName + ": " + error);
            }
            else {
                body = JSON.parse(body);
                if (body.status == "1")
                    get(contractName, body.result);
                else
                    console.log(contractName + ": " + body.result);
            }
        }
    );
}

function get(contractName, guid) {
    console.log(contractName + ": checking verification status...");
    request.get(
        "https://" + input.network + ".etherscan.io/api?module=contract&action=checkverifystatus&guid=" + guid,
        function(error, response, body) {
            if (error) {
                console.log(contractName + ": " + error);
            }
            else {
                body = JSON.parse(body);
                if (body.result == "Pending in queue")
                    get(contractName, guid);
                else
                    console.log(contractName + ": " + body.result);
            }
        }
    );
}

run();

In package.json, add:

  "scripts": {
    "verify": "node verify.js"
  },
  "devDependencies": {
    "truffle-flattener": "1.2.10",
    "web3": "1.0.0-beta.34"
  }

After running npm install, you can verify your set of contracts by running npm verify input.txt from a command line. You'll need to create input.txt according to the input example at the top of verify.js.

0

I created truffle-plugin-verify to automate Truffle contract verification on Etherscan.


  1. Install the plugin with npm
npm install truffle-plugin-verify
  1. Add the plugin to your truffle.js or truffle-config.js file
module.exports = {
  /* ... rest of truffle-config */

  plugins: [
    'truffle-plugin-verify'
  ]
}
  1. Generate an API Key on your Etherscan account (see the Etherscan website)
  2. Add your Etherscan API key to your truffle config
module.exports = {
  /* ... rest of truffle-config */

  api_keys: {
    etherscan: 'MY_API_KEY'
  }
}

After migrating your contract to to a public network, you are able to verify it on Etherscan by running:

truffle run verify ContractName [--network networkName]

More information can be found on the repository or in my article Automatically verify Truffle smart contracts on Etherscan.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.