Truffle 部署的合约无法通过 Etherscan 进行验证

Posted

技术标签:

【中文标题】Truffle 部署的合约无法通过 Etherscan 进行验证【英文标题】:Truffle deployed contracts can't be verified through Etherscan 【发布时间】:2017-11-26 00:42:30 【问题描述】:

我面临的问题是 truffle 生成的字节码与 solcjs(本地编译器)和 Remix(在线编译器)不同。因此我无法通过 Etherscan 验证我的合约(请参阅 https://etherscan.io/verifyContract)

我的环境:

OS: Ubuntu 15.10

$ uname -a
Linux sasha 4.2.0-42-generic #49-Ubuntu SMP Tue Jun 28 21:26:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

$ truffle version
Truffle v3.2.4

$ solcjs --version
0.4.11+commit.68ef5810.Emscripten.clang

我想做什么:

1) 我创建了一个简单的智能合约 Ownable:

pragma solidity ^0.4.11;

contract Ownable 
    address public owner;

    function Ownable() 
        owner = msg.sender;
    

    modifier onlyOwner 
        if (msg.sender != owner) throw;
        _;
    

    function transferOwnership(address newOwner) onlyOwner 
        if (newOwner != address(0)) 
            owner = newOwner;
        
    

2) 启动一个新的 truffle 项目并将 Ownable.sol 复制到“contract”文件夹中。

所以项目的结构必须如下:

test-comtract
-- contracts
   -- Ownable.sol
-- migrations
   -- 1_initial_migration.js
   -- 2_deploy_contracts.js
-- test
truffle.js

3) 编译松露项目:

$ cd test-comtract 
$ truffle compile

编译后会创建“build”文件夹。

4) 转到“build”文件夹并在那里搜索 Ownable.json 文件。在此文件中搜索“unlinked_binary”属性中生成的字节码。该值如下所示:

0x6060604052341561000c57fe5b5b60008054600160a060020a03191633600160a060020a03161790555b5b60f3806100386000396000f300606060405263ffffffff60e060020a6000350416638da5cb5b8114602a578063f2fde38b146053575bfe5b3415603157fe5b6037606e565b60408051600160a060020a039092168252519081900360200190f35b3415605a57fe5b606c600160a060020a0360043516607d565b005b600054600160a060020a031681565b60005433600160a060020a0390811691161460985760006000fd5b600160a060020a0381161560c25760008054600160a060020a031916600160a060020a0383161790555b5b5b505600a165627a7a72305820607fc60d96cffbd50e58fbc028c1e4b6f3dfdf356bd439390481a479ef8d25500029 P>

5) 尝试通过 Remix 在线编译器进行编译。 https//ethereum.github.io/browser-solidity/#version=soljson-v0.4.11+commit.68ef5810.js&optimize=true

编译结果如下图:

6060604052341561000c57fe5b5b60008054600160a060020a03191633600160a060020a03161790555b5b610119806100396000396000f300606060405263ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416638da5cb5b81146043578063f2fde38b14606c575bfe5b3415604a57fe5b60506087565b60408051600160a060020a039092168252519081900360200190f35b3415607357fe5b6085600160a060020a03600435166096565b005b600054600160a060020a031681565b60005433600160a060020a0390811691161460b15760006000fd5b600160a060020a0381161560e8576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b5b505600a165627a7a723058201eb1de901e30ec9818544272a4c70946cd9cb7cd848237ba3dca118e44d771a60029 P>

6) 尝试通过solcjs的帮助进行编译:

$ cd test-comtract/contracts 
$ solcjs --optimize --bin Ownable.sol

在“test-comtract/contracts”文件夹中将创建文件“Ownable.sol:Ownable.bin”

6060604052341561000c57fe5b5b60008054600160a060020a03191633600160a060020a03161790555b5b610119806100396000396000f300606060405263ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416638da5cb5b81146043578063f2fde38b14606c575bfe5b3415604a57fe5b60506087565b60408051600160a060020a039092168252519081900360200190f35b3415607357fe5b6085600160a060020a03600435166096565b005b600054600160a060020a031681565b60005433600160a060020a0390811691161460b15760006000fd5b600160a060020a0381161560e8576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b5b505600a165627a7a7230582083a10cb56ea55b0a181cbc132bdf1bd4e0e8a02d5664db73bbc62217f0b7b8d00029 P>

结果:SolJS 字节码与 Remix 字节码相同,但与 truffle 字节码不同。

7) 我还通过松露将 Ownable.sol 部署到了以太坊 (TEST_NET)。您可以通过以下网址看到它:

https://ropsten.etherscan.io/address/0x6c8e1b321ce94b12069222b543558d4159527ecd

也许有人面临这样的问题。我将非常感谢听到它发生的任何版本。也许这是 Truffle 框架的一个已知错误。在谷歌我发现一些更多的文章描述了类似的问题,但没有人提出解决方案。我非常需要帮助

提前致谢!

-- 亚历克斯

【问题讨论】:

【参考方案1】:

我创建了truffle-plugin-verify 来自动在 Etherscan 上验证 Truffle 合约。


    使用 npm 安装插件
npm install truffle-plugin-verify
    将插件添加到您的truffle.jstruffle-config.js 文件中
module.exports = 
  /* ... rest of truffle-config */

  plugins: [
    'truffle-plugin-verify'
  ]

    在您的 Etherscan 帐户上生成 API 密钥(请参阅 Etherscan website) 将您的 Etherscan API 密钥添加到您的 truffle 配置中
module.exports = 
  /* ... rest of truffle-config */

  api_keys: 
    etherscan: 'MY_API_KEY'
  


将合约迁移到公共网络后,您可以通过运行以下命令在 Etherscan 上对其进行验证:

truffle run verify ContractName [--network networkName]

更多信息可以在the repository或我的文章Automatically verify Truffle smart contracts on Etherscan中找到。

【讨论】:

【参考方案2】:

你可以像我一样开始猜测优化级别和编译器。尝试 100 次后,您可能会得到它。我做到了。从现在开始,我不会在 truffle 的主网上部署任何东西。它非常适合测试和开发,但它与 etherscan 不一致。为此,您需要连接所有内容并在将来使用 remix。

【讨论】:

【参考方案3】:

有一个verifier 2.0支持Truffle的编译。

https://etherscan.io/verifyContract2

【讨论】:

【参考方案4】:

solc/truffle-compile 中有一个编译器优化,目前 etherscan 在编译合约时不支持。

https://github.com/trufflesuite/truffle-compile/blob/331809c73389f27f9dda40229061bb75b18f27ca/index.js#L70

向 etherscan 发送评论!

【讨论】:

问题出在编译器优化上。随着“运行:200”一切正常。我会向 Etherscan 发送电子邮件。非常感谢!!! @Alex:也许是一个愚蠢的问题,但我仍然不清楚。给定您的示例,如果我查看 Remix 和 solc.js 输出,例如我有两条尾巴:“18e44d771a60029”与“17f0b7b8d00029”。为什么你认为两者相同? 在下面使用 truffle-plugin-verify 查看 Rosco 的解决方案 - 这对我有用

以上是关于Truffle 部署的合约无法通过 Etherscan 进行验证的主要内容,如果未能解决你的问题,请参考以下文章

验证使用 Truffle 部署的智能合约代码

Truffle 合约验证无法在 BSC 测试网上运行

Truffle Migrations(迁移)- 多个合约一起部署 如何链接库

Truffle项目搭建编译部署验证合约

ChainIDE 3. 使用truffle部署合约

truffle部署指定的合约到指定网络