随着区块链的发展,智能合约的开发逐渐成为一片新的蓝海。与智能合约发展一同进步的其实还有一系列的智能合约开发工具和安全审计工具,但由于此方面很少有人介绍,导致大量新型工具并不为人所熟知。本文主要介绍智能合约开发和安全审计工具,以智能合约开发和测试为主线,依次介绍涉及以下方面的工具:
本文章主要面向使用solidity
语言进行太坊或以太坊兼容链智能合约开发的程序员。
作为智能合约开发者,拥有一个配置良好的编辑器可以大幅度提高合约开发效率。由于目前智能合约开发刚刚起步,并没有使用专业的IDE,但通用编辑器VSCode
配合各种插件可以拥有非常好的开发体验。在此处,我建议按照以下插件:
前者可以提供一些基础的语言特性高亮和自动补齐功能,而后者专门为智能合约审计人员设计,提供了大量的附加功能,方便开发者理解合约。对于一般开发者而言,基础插件的功能较好理解,此处我们着重介绍Solidity Visual Developer
,该插件提供了大量的合约可视化能力,如下图所示:
除此之外,此插件还提供了以下功能:
一是更加多样化的颜色绚烂、参数显示和函数信息显示,如下图所示:
总而言之,Solidity Visual Developer
提供了大量对于智能合约开发者实用的功能,无论开发者从事合约开发抑或是合约审计,此插件都可以大幅度增加开发体验。
在代码编写、测试与部署环节,我个人推荐使用foundry
框架,此框架具有以下特点:
anvil
和以太坊交互工具cast
对于代码编写和单元测试方面是较为复杂的,由于本文主要推荐开发工具而不是针对代码编写和测试,我们在此处不进行完整介绍。
如果读者对于此方面想更加深入的了解,可以选择阅读我之前写的Foundry教程:编写测试部署ERC-20代币智能合约。
除了阅读我个人编写的文章,一个更好的途径是阅读官方文档
就目前的合约测试而言,一个基本的共识是使用foundry
作为框架进行单元测试,而后使用hardhat
进行集成测试,读者可根据自己开发的实际情况选择。
对于很多合约开发者而言,阅读并理解其他人已部署的链上合约是一个非常重要的学习途径,正常的阅读链上合约的方法是首先查询合约部署方是否已经把合约开源在了github
上,对于大部分合约而言,我们都可以非常简单的找到其开源在gtihub
上的版本。
对于部分合约而言,其可能已经经过了etherscan
的Contract Source Code Verified
但没有github
的开源版本,对于这些合约,我们可以简单地使用cast
工具获得其合约代码,命令如下:
cast etherscan-source -d weth 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --ether
scan-api-key $etherscan
其中$etherscan
需要为读者自行设置的etherscan
的API密钥。
上述命令中的
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
是WETH
的合约地址
另一种更加简单的方法是使用etherscan.deth.net
提供的服务,我们仍以获取WETH
的合约代码为例,当我们已知其合约地址为0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
的情况下,我们可以访问https://etherscan.deth.net/address/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
,读者可以看到如下页面:
这样就可以在在线VSCode
内浏览代码,但不能进行修改等操作。
对于部分没有经过验证的智能合约,我本人不太建议分析此类合约,但如果读者有特殊需求可以通过使用emvdis进行反汇编,在此处我们给出一个示例,假如上文使用的WETH
合约未经过验证,我们首先通过以下命令获得合约字节码:
cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url https://rpc.ankr.com/eth > test.evm
此命令会下载0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
地址内的字节码并将其存储在test.evm
中,使用任一编辑工具删除test.evm
中最开始的0x
标识并保存。然后调用此命令:
cat test.evm | evmdis > test.output
此命令会将反汇编结果输送到test.output
中,如果您的系统内安装了VSCode
可以使用code test.output
在vscode
内打开此文件,最终输出如下:
读者可以通过分析合约最开始的跳转表配合cast 4byte
命令获得合约包含的函数,比如使用cast 4byte 0x18160DDD
可以分析获得此合约包含totalSupply()
函数。
链上交易的分析是了解合约结构的一个重要方法,此处我们介绍以下三种可用于链上交易分析的网站:
我们可以通过下述表格体现网站的不同:
网站名称 | 加载速度 | 包含功能 | 支持链 |
---|---|---|---|
Samczsun Tx | 快 | 交易基本信息、各参与方价值变化、交易行为、调用过程 | 以太坊及其主流L2、BSC |
Ethtx Info | 快 | 交易释放事件、各参与方价值变化、代币转账、调用流程 | 以太坊及Goerli测试网 |
tenderly | 慢 | 交易基本信息、代币转账、调用流程 | 包含几乎所有EVM兼容链 |
Blocksec Phalcon | 中 | 交易基本信息、代币转账、调用流程、 交易模拟 | 以太坊、BSC、Ploygon |
其中,Samczsun Tx
和Ethtx Info
均采用了较为简单的界面设计,提供的功能基本一致,而tenderly
采用了较为复杂的UI设计,且提供了调用debug功能,值得注意的是此功能需要注册账户才可以使用。
在此处,我们给出一笔位于以太坊主网上的复杂清算交易,其哈希为0x11d0050b5040438b8f95b4a6d07b31656242f30405e5e931d75b2cca19dfc94e
,读者可以在不同网站内查询此交易以进一步判断哪个网站更适合自己。当然,读者也可以直接使用下述链接直接跳转:
总结来说,如果读者查询的是一笔比较简单的交易且不希望通过合约代码深入理解具体调用流程,使用Samczsun Tx
和Ethtx Info
是一个不错的选择。如果读者希望获得更加详细的包含合约代码的深度分析,使用tenderly
是必要的,如下图:
如果读者希望模拟一笔交易在任意区块任意位置的运行,请选择Blocksec Phalcon
,其提供了一个较为好用的交易模拟系统,如下图:
如果读者更倾向于使用终端继续相关测试,那么cast run
命令可以满足大部分读者的需求,在此处给出一个简单示例,在终端内输入以下命令:
cast run \
0xd15e0237413d7b824b784e1bbc3926e52f4726e5e5af30418803b8b327b4f8ca \
--rpc-url https://rpc.ankr.com/eth --quick
此处的
quick
标识此交易直接被默认为块内的第一个交易执行,如果不增加此参数,则会将与此交易位于同一区块内此交易之前的所有交易重放执行一遍,较为耗时。
即会在本地测试环境内重放交易0xd15e0237413d7b824b784e1bbc3926e52f4726e5e5af30418803b8b327b4f8ca
并输出对应的堆栈,如下:
Traces:
[29962] 0xc02a…6cc2::transfer(0x40950267d12e979ad42974be5ac9a7e452f9505e, 105667789681831058)
├─ emit Transfer(param0: 0xc564ee9f21ed8a2d8e7e76c085740d5e4c5fafbe, param1: 0x40950267d12e979ad42974be5ac9a7e452f9505e, param2: 105667789681831058)
└─ ← 0x0000000000000000000000000000000000000000000000000000000000000001
Transaction successfully executed.
Gas used: 51618
如果读者想深入研究交易流程内发生详细流程,可增加--debug
开启debug
模式,使用后会展示如下TUI界面:
但阅读此界面需要读者拥有相当高的合约编程经验和对EVM的底层了解,在此处我们不再详细介绍。
对于部分开发者而言,可能具有获取大量区块数据的需求,使用目前已有的以太坊RPC URL可以获得,在此处我们给出通过RPC
获取区块数据的方法,命令如下:
cast block latest --rpc-url https://rpc.ankr.com/eth
在此处,我们省略输出。此命令事实上使用了eth_getBlockByNumber
接口,具体定义读者可自行参考文档。
上述方式的致命确定在于由于RPC服务商的速率限制,我们无法大批量请求获得相关数据,简单测试,我们可以得到以下性能对比表:
服务商 | 每秒可获得的区块数 |
---|---|
Alchemy | 0.17 |
Cloudflare | 1 |
Infura | 4.75 |
Quicknode | 0.78 |
上表数据来源Launching 0xFast Stream
如果读者希望使用此方法获得完整的以太坊区块数据需要大量时间,在此处,我们可以使用0xFast Stream
提供的极速区块数据下载服务,此服务可以每秒下载 220 个区块,使用方法也非常简单,读者可自行点击以下链接:
上文链接中的10进制字符均可替换为16进制数,如 https://stream.0xfast.com/beta/eth-mainnet/0x1
此服务返回JSON
编码的区块数据,更多内容可参考Launching 0xFast Stream文章。
本文介绍了大量有助于智能合约开发者的相关工具,由于本文仅作为工具推荐文章,所有没有深度探讨其在智能合约开发复杂场景中的使用,我会在未来介绍智能合约开发的相关文章内穿插使用这些工具,以进一步增加其实用性。