为什么要验证合约?
源代码验证为与智能合约交互的用户提供了透明性。通过上传源代码,Etherscan将编译后的代码与区块链上的代码匹配。就像合同一样,“智能合约”应该为最终用户提供更多关于他们“数字签名”的信息,并让用户有机会审计代码,以独立地验证代码实际上做了应该做的事情。
ABI文件公开?目前我的Dapp做法需要将编译的合约 json 文件和WebApp放在一起,通过ajax读取 json 文件初始化合约。
如何验证?
具体就是将代码上传到etherscan.io,只需几步操作。
在 Etherscan 上打开你的合约地址: https://ropsten.etherscan.io/address/{合约地址}#contracts
但是,我每次面对的都是500错误,被搞的抓狂。
坑坑
- 网上很多文章说Etherscan 不支持import,那是因为老版本verifyContract2的原因,现在verifyContract是支持import的,选择多文件上传即可。
- 单文件HelloWorld合约提交也是500错误(这个最坑)
错误500的原因
合约提交500错误很烦,尝试了各种方法,网上说要用VPN,VPN也用上了,但是无奈当时是因为此VPN出了点状况,没能上Google。
** 这个500错误就是网络的问题,正确的判断是“提交的页面”有没有出现“人机身份验证”。**
查看了一下Chrome的网络,可以看到有一个js文件请求失败了,这就是Google的“人机身份验证”。(坑:加载失败了没提示错误???没通过“人机身份验证”提示报错???)
成功爬坑
- 首先要用VPN科学上网,确认能上Google
- 在提交代码页面确认出现了“人机身份验证”
- 正常提交就OK了。
下面是用HelloWorld合约测试的结果:
合并工具
如果依赖一些第三方库,而合约文件比较多,可以利用合并工具进行合并为单一文件。同时现在也是支持多文件和imports的。
1. SolidityFlattery
这是Golang写的工具,直接下载 github 中 flat
可执行文件,丢在 /usr/bin
目录就可以使用了
1 | $ flat -input MetaCoin.sol -output SourceCode |
2. solidity-flattener
这个是Python3写的工具,依赖Python。
1 | $ pip3 install solidity-flattener |
参考
以下是参考的资料和摘录
-
实现步骤
- 合并合约:将所有import导入的合约和库(library)都写到一个文件中
- 验证合约:进入verify contract页面,指定已部署合约地址和名称
- 编译合约:选择Compiler版本和优化方案
第一步比较繁琐,如果你使用了open-zeppelin之类的通用库,需要翻翻好多个目录才能把依赖的合约凑齐并放置在一个文件当中,而且特别要注意加上版本宏定义pragma solidity ^0.5.0;。
-
在填写表单时有以下注意事项:
- Compiler 选择最新版本
- Optimization 选择 No
虽然 solidity 支持 import 语法,但 Etherscan 对使用 import 进行开发的合约支持很鸡肋,目前它要求你需要把库文件也当作合约发布至网络才能够在表单中填写进行验证。
当然我们也可以选择手动把 import 库文件的内容手动复制粘贴到代码框里,注意要保留全部内容,包括 pragma 声明一行。 -
利用 SolidityFlattery 工具来删除 import 和合并合约
-
验证需要科学上网,否则会因网络问题造成验证失败
-
- https://ropsten.etherscan.io/address/0xcd4d737151d14742d9c75e2b9ef838e3b69bd00c#code
- https://etherscan.io/address/0x38c6A68304cdEfb9BEc48BbFaABA5C5B47818bb2#contracts
- https://etherscan.io/address/0x7da82c7ab4771ff031b66538d2fb9b0b047f6cf9#code
- https://etherscan.io/address/0x85bc00724203d53536072b000c44a2cc16cd12c5#code
- https://etherscan.io/address/0x63091244180ae240c87d1f528f5f269134cb07b3#code
《Demo HTTP Post for using the Source Code Verfication Submission API》
Contracts that use “imports” will need to have the ode concatenated into one file as we do not support “imports” in separate files. You can try using the Blockcat solidity-flattener or SolidityFlattery
合约中使用了“imports”的,需要代码连接到一个文件中,因为我们不支持在单独的文件中使用“imports”。你可以尝试使用Blockcat solidity-flattener
或SolidityFlattery
-
这个作者的情况和我遇到的很相似。