概述

随着区块链的发展,智能合约的开发逐渐成为一片新的蓝海。与智能合约发展一同进步的其实还有一系列的智能合约开发工具和安全审计工具,但由于此方面很少有人介绍,导致大量新型工具并不为人所熟知。本文主要介绍智能合约开发和安全审计工具,以智能合约开发和测试为主线,依次介绍涉及以下方面的工具:

  1. 编辑器配置
  2. 代码编写、测试与部署
  3. 合约安全测试
  4. 链上合约调用分析
  5. 区块数据获取

本文章主要面向使用solidity语言进行太坊或以太坊兼容链智能合约开发的程序员。

编辑器配置

作为智能合约开发者,拥有一个配置良好的编辑器可以大幅度提高合约开发效率。由于目前智能合约开发刚刚起步,并没有使用专业的IDE,但通用编辑器VSCode配合各种插件可以拥有非常好的开发体验。在此处,我建议按照以下插件:

  1. solidity
  2. Solidity Visual Developer

前者可以提供一些基础的语言特性高亮和自动补齐功能,而后者专门为智能合约审计人员设计,提供了大量的附加功能,方便开发者理解合约。对于一般开发者而言,基础插件的功能较好理解,此处我们着重介绍Solidity Visual Developer,该插件提供了大量的合约可视化能力,如下图所示:

Solidity Graph

除此之外,此插件还提供了以下功能:

一是更加多样化的颜色绚烂、参数显示和函数信息显示,如下图所示:

highlighting

二是引入了更加丰富的关键词信息和安全建议展示,如下图: code augmentation

三是增加了显示所有函数选择器的展示,如下图: Function Signature Hashes

四是增加了合约概览展示,如下图: Outline View

总而言之,Solidity Visual Developer提供了大量对于智能合约开发者实用的功能,无论开发者从事合约开发抑或是合约审计,此插件都可以大幅度增加开发体验。

代码编写、测试与部署

在代码编写、测试与部署环节,我个人推荐使用foundry框架,此框架具有以下特点:

  1. 易于安装(仅针对Linux和MacOS系统)
  2. 可以快速编译智能合约
  3. 使用 solidity 作为测试框架语言,而不需要使用 javascript或 typescript 作为测试辅助语言
  4. 提供了本地测试网络anvil和以太坊交互工具cast

对于代码编写和单元测试方面是较为复杂的,由于本文主要推荐开发工具而不是针对代码编写和测试,我们在此处不进行完整介绍。

如果读者对于此方面想更加深入的了解,可以选择阅读我之前写的Foundry教程:编写测试部署ERC-20代币智能合约

除了阅读我个人编写的文章,一个更好的途径是阅读官方文档

就目前的合约测试而言,一个基本的共识是使用foundry作为框架进行单元测试,而后使用hardhat进行集成测试,读者可根据自己开发的实际情况选择。

链上合约阅读

对于很多合约开发者而言,阅读并理解其他人已部署的链上合约是一个非常重要的学习途径,正常的阅读链上合约的方法是首先查询合约部署方是否已经把合约开源在了github上,对于大部分合约而言,我们都可以非常简单的找到其开源在gtihub上的版本。

对于部分合约而言,其可能已经经过了etherscanContract Source Code Verified但没有github的开源版本,对于这些合约,我们可以简单地使用cast工具获得其合约代码,命令如下:

cast etherscan-source -d weth 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --ether
scan-api-key $etherscan

其中$etherscan需要为读者自行设置的etherscan的API密钥。

上述命令中的0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2WETH的合约地址

另一种更加简单的方法是使用etherscan.deth.net提供的服务,我们仍以获取WETH的合约代码为例,当我们已知其合约地址为0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2的情况下,我们可以访问https://etherscan.deth.net/address/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2,读者可以看到如下页面:

Deth

这样就可以在在线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.outputvscode内打开此文件,最终输出如下:

EthDis Output

读者可以通过分析合约最开始的跳转表配合cast 4byte命令获得合约包含的函数,比如使用cast 4byte 0x18160DDD可以分析获得此合约包含totalSupply()函数。

链上合约调用分析

链上交易的分析是了解合约结构的一个重要方法,此处我们介绍以下三种可用于链上交易分析的网站:

  1. Samczsun Tx
  2. Ethtx Info
  3. tenderly
  4. Blocksec Phalcon

我们可以通过下述表格体现网站的不同:

网站名称加载速度包含功能支持链
Samczsun Tx交易基本信息、各参与方价值变化、交易行为、调用过程以太坊及其主流L2、BSC
Ethtx Info交易释放事件、各参与方价值变化、代币转账、调用流程以太坊及Goerli测试网
tenderly交易基本信息、代币转账、调用流程包含几乎所有EVM兼容链
Blocksec Phalcon交易基本信息、代币转账、调用流程、 交易模拟以太坊、BSC、Ploygon

其中,Samczsun TxEthtx Info均采用了较为简单的界面设计,提供的功能基本一致,而tenderly采用了较为复杂的UI设计,且提供了调用debug功能,值得注意的是此功能需要注册账户才可以使用。

在此处,我们给出一笔位于以太坊主网上的复杂清算交易,其哈希为0x11d0050b5040438b8f95b4a6d07b31656242f30405e5e931d75b2cca19dfc94e,读者可以在不同网站内查询此交易以进一步判断哪个网站更适合自己。当然,读者也可以直接使用下述链接直接跳转:

  1. Samczsun Tx
  2. Ethtx Info
  3. tenderly
  4. Blocksec Phalcon

总结来说,如果读者查询的是一笔比较简单的交易且不希望通过合约代码深入理解具体调用流程,使用Samczsun TxEthtx Info是一个不错的选择。如果读者希望获得更加详细的包含合约代码的深度分析,使用tenderly是必要的,如下图:

Tenderly Debug

如果读者希望模拟一笔交易在任意区块任意位置的运行,请选择Blocksec Phalcon,其提供了一个较为好用的交易模拟系统,如下图:

Tx Simulator

如果读者更倾向于使用终端继续相关测试,那么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界面:

Debug TUI

但阅读此界面需要读者拥有相当高的合约编程经验和对EVM的底层了解,在此处我们不再详细介绍。

区块数据获取

对于部分开发者而言,可能具有获取大量区块数据的需求,使用目前已有的以太坊RPC URL可以获得,在此处我们给出通过RPC获取区块数据的方法,命令如下:

cast block latest --rpc-url https://rpc.ankr.com/eth

在此处,我们省略输出。此命令事实上使用了eth_getBlockByNumber接口,具体定义读者可自行参考文档

上述方式的致命确定在于由于RPC服务商的速率限制,我们无法大批量请求获得相关数据,简单测试,我们可以得到以下性能对比表:

服务商每秒可获得的区块数
Alchemy0.17
Cloudflare1
Infura4.75
Quicknode0.78

上表数据来源Launching 0xFast Stream

如果读者希望使用此方法获得完整的以太坊区块数据需要大量时间,在此处,我们可以使用0xFast Stream提供的极速区块数据下载服务,此服务可以每秒下载 220 个区块,使用方法也非常简单,读者可自行点击以下链接:

  1. https://stream.0xfast.com/beta/eth-mainnet/latest 获取最新区块数据
  2. https://stream.0xfast.com/beta/eth-mainnet/1 获取单一区块数据
  3. https://stream.0xfast.com/beta/eth-mainnet/1-10 获取系列区块数据

上文链接中的10进制字符均可替换为16进制数,如 https://stream.0xfast.com/beta/eth-mainnet/0x1

此服务返回JSON编码的区块数据,更多内容可参考Launching 0xFast Stream文章。

总结

本文介绍了大量有助于智能合约开发者的相关工具,由于本文仅作为工具推荐文章,所有没有深度探讨其在智能合约开发复杂场景中的使用,我会在未来介绍智能合约开发的相关文章内穿插使用这些工具,以进一步增加其实用性。