*译文出自:登链翻译计划 [1]

*译 者:Tiny 熊 [2]

*校 对 : 无

*原文地址:Automatically verify Truffle smart contracts on Etherscan[3]

*作 者:Rosco Kalis[4]

Etherscan 是以太坊上最受欢迎的浏览器。它的一大功能是验证智能合约的源代码 [5]。使用户可以在使用合约之前通过源码了解合约的功能。从而增加用户对合约的信任,也因此使开发者受益。

通过 Etherscan 网站表单提交代码是验证代码的主要方法,但是这需要很多手动工作。需要输入诸如编译器版本和构造函数参数之类的内容,并且需要提交展开后的合约源代码(译者注:这里是指当合约引用了其他的文件时,需要把引用展开),该合约源代码需要与部署的代码完全匹配。

有些人使用命令行工具来展开 Truffle 合约,并使用基于浏览器的 Remix IDE 来部署展开后的源代码。然后,把相同的展开后的源代码复制到 Etherscan 验证表单提交。这是一个非常繁琐的过程,应该自动化。

这是为什么我创建了 truffle-plugin-verify[6] 插件,它通过 Etherscan API 来自动验证 Truffle 合约。此插件是一个开源项目,有许多不同的参与者,包括 Ren[7] 的一些开发人员。使用这个插件只需一个简单的命令即可验证合约:

*

    truffle run verify ContractName

依赖条件

本文中,我们假设您已经有一个可部署的 Truffle 项目。如果没有,可以参考此 Truffle 教程 [8],该教程也说明了如何使用 Infura 设置 Truffle 项目的部署。

你也可以查看本文在 GitHub 上的源代码 [9]。

合约

我们以 Casino 合约为例。在合约中,玩家可以下注 1-10 个 ETH。为确保合约不会亏空,玩家只能押注合约总金额的一小部分。

中奖号码是对当前区块号进行模运算的结果。这个运算在测试中可以的,但是要注意,在正式生产中可能会被滥用。

在本文中,我们将专门对合约进行进一步拆分,以使合约分散到多个文件中。便于展示插件的全部功能。

contracts/Killable.sol

    pragma solidity ^0.5.8;  
    contract Killable {    address payable public owner;  
        constructor() public {        owner = msg.sender;    }  
        function kill() external {        require(msg.sender == owner, "Only the owner can kill this contract");        selfdestruct(owner);    }}

contracts/Casino.sol

    pragma solidity ^0.5.8;  
    import "./Killable.sol"  
    contract Casino is Killable {    event Play(address payable indexed player, uint256 betSize, uint8 betNumber, uint8 winningNumber);    event Payout(address payable winner, uint256 payout);  
        function fund() external payable {}  
        function bet(uint8 number) external payable {        require(msg.value <= getMaxBet(), "Bet amount can not exceed max bet size");        require(msg.value >0, "A bet should be placed");  
            uint8 winningNumber = generateWinningNumber();        emit Play(msg.sender, msg.value, number, winningNumber);  
            if (number == winningNumber) {            payout(msg.sender, msg.value*10);        }    }  
        function getMaxBet() public view returns (uint256) {        return address(this).balance / 100;    }  
        function generateWinningNumber() internal view returns (uint8) {        return uint8(block.number % 10 + 1); // Don't do this in production    }  
        function payout(address payable winner, uint256 amount) internal {        assert(amount > 0);        assert(amount <= address(this).balance);  
            winner.transfer(amount);        emit Payout(winner, amount);    }}

验证合约

现在我们已经准备好合约,我们可以展示使用 truffle-plugin-verify 验证该合约有多么简单。

1. 安装 & 启用 truffle-plugin-verify

可以使用 npm 或 yarn 安装 Truffle 插件:

    npm install -D truffle-plugin-verifyyarn add -D truffle-plugin-verify

安装后,将以下内容添加到 truffle-config.jstruffle.js 文件中,以便 Truffle 启用该插件:

      *
    module.exports = {  /* ... rest of truffle-config */  
      plugins: [    'truffle-plugin-verify'  ]}

2. 创建一个 Etherscan API 密钥并将其添加到 Truffle

[译] 用 Truffle 插件自动在 Etherscan 上验证合约代码img

要创建 Etherscan API 密钥,首先需要在 Etherscan 网站 [10] 上创建一个帐户。创建帐户后,可以在个人资料页 [11] 上添加新的 API 密钥,如上图所示。创建新密钥后,将其添加到 truffle-config.jstruffle.js 文件的 api_keys 下的:

      *
    module.exports = {  /* ... rest of truffle-config */  
      api_keys: {    etherscan: 'MY_API_KEY'  }}

当前,你可以不提交 API key 到代码库中,建议使用 dotenv[12] 来保存 API key, 然后在 git 库中忽略 .env 文件,然后在 truffle-config.jstruffle.js 配置文件读取它,读取方式如下:

                        *
    var HDWalletProvider = require("truffle-hdwallet-provider");require('dotenv').config();  
    module.exports = {  networks: {    rinkeby: {      provider: function() {        return new HDWalletProvider(`${process.env.MNEMONIC}`, `https://rinkeby.infura.io/v3/${process.env.INFURA_ID}`)      },      network_id: 4    }  },  plugins: [   'truffle-plugin-verify'  ],  api_keys: {    etherscan: process.env.ETHERSCAN_API_KEY  }};

你的配置文件可能和上面有所不同,但是只要设置了公共网络部署,并且正确设置了 pluginsapi_keys 就可以。

3. 部署及验证合约

truffle-plugin-verify 的使用设置好了,接下来就是实际部署和验证智能合约。

部署:

*

    truffle migrate --network rinkeby

这将花费一些时间,部署完之后,将显示以下类似的内容:

    Summary=======> Total deployments:   2> Final cost:          0.0146786 ETH

部署合同后,我们就可以使用 truffle-plugin-verify 对我们的 Casino 合同进行 Etherscan 验证:

*

    truffle run verify Casino --network rinkeby

依旧需要花费一些时间,并最终返回:

*

    Pass - Verified: https://rinkeby.etherscan.io/address/0xAf6e21d371f1F3D2459D352242564451af9AA23F#contracts

结论

本文中,我们讨论了通过 Etherscan 在线表单进行验证代码的麻烦程度,因为每次部署合约时都需要执行几个手动步骤。在本文中,我们通过 truffle-plugin-verify 开发者只需一个简单的命令就可以验证任何智能合约,这为手动验证提供一种简单、自动的替代方法。

本翻译得到登链社区 [13] 及 CellNetwork[14] 支持。

参考资料

[1]

登链翻译计划 : https://github.com/lbc-team/Pioneer

[2]

Tiny 熊 : https://learnblockchain.cn/people/15

[3]

Automatically verify Truffle smart contracts on Etherscan: https://kalis.me/verify-truffle-smart-contracts-etherscan/

[4]

Rosco Kalis: https://kalis.me/

[5]

验证智能合约的源代码 : https://medium.com/etherscan-blog/verifying-contracts-on-etherscan-f995ab772327

[6]

truffle-plugin-verify: https://www.npmjs.com/package/truffle-plugin-verify

[7]

Ren: https://renproject.io/

[8]

此 Truffle 教程 : https://learnblockchain.cn/2019/03/30/dapp_noteOnChain

[9]

源代码 : https://github.com/rkalis/truffle-plugin-verify/tree/master/docs/kalis-me-tutorial-code

[10]

Etherscan 网站 : https://etherscan.io/

[11]

个人资料页 : https://etherscan.io/myapikey

[12]

dotenv: https://www.npmjs.com/package/dotenv

[13]

登链社区 : https://learnblockchain.cn/

[14]

CellNetwork: https://www.cellnetwork.io/?utm_souce=learnblockchain

[译] 用 Truffle 插件自动在 Etherscan 上验证合约代码

来源链接:mp.weixin.qq.com