Foundry 除了测试之外的功能及VSCode 的Solidity Visual Developer 插件
原文作者:NIC Lin
原文来源:medium
这篇文章将介绍Ethereum 开发者的一些实用工具:Foundry 除了测试之外的功能及VSCode 的Solidity Visual Developer 插件
Foundry 除了提供合约开发、测试和部署,其实还有许多其他实用的功能。
如果是Linux 或macOS,先安装foundryup,接着直接用 foundryup 指令就可以安装。未来要升级foundry 也只需要执行 foundryup 就好,非常简单直觉。
// Install foundryup
curl -L https://foundry.paradigm.xyz | bash
// Install or update Foundry
foundryup
详细可以参考Foundry book 的Installation 页面。
Foundry 安装完后会有forge、cast及 anvil 三个指令,每个指令也都有许多option,这时有Auto Completion 会非常省事。例如产生bash 用的Auto Completion script:
其他Shell script 的产生方式可以参考Foundry book 的Shell Autocompletion 页面。
其实就和Ganache 及 hardhat node 一样:跑起一个节点。可以是全新的一个本地节点,也可以是背后连上Forked State(例如Forked Mainnet、Forked Goerli)的节点。如果你平常都是习惯用来跑一个短暂的全新测试节点就直接下 anvil 即可。
如果你会想在一个Forked State 内实验或测试的话,多加上 --fork-url 和 --fork-block-number 的option。另外可以留意 --compute-units-per-second 这个option,它会控制每秒请求的计算量,避免取Forked State 太频繁导致遇到像是Alchemy Rate Limit的问题。
更详细的节点设置可以参考Foundry book 的Anvil Reference 页面。
cast 是用来取链上资料非常好用的工具(也有送交易的工具但个人觉得不太实用)。因为有很多功能,这里我只会列出我常用及觉得实用的功能。
注:要读取链的状态记得要在foundry.toml 档里附上endpoint url(eth_rpc_url=$URL)或透过 --rpc-url $URL 的方式。
首先是抓取交易资讯:
注:cast run --debug的debug 介面可能没有那么好读,如果不需要看到执行过程中的memory/stack/storage 等细节时可以直接用ethtx.info或Tenderly,好读很多。
接着是从Etherscan 抓取合约资讯:
注:如果想直接在浏览器开启VSCode 环境来浏览、编辑合约的话,可以使用deth.net。还可以透过书签一键开启,非常方便,请参考这则twitter。
接着是encode/decode ABI 的功能:
注:因为function selector 只有4 bytes,如果多个function signature 都是同一个function selector 的话,则反查会回传所有可能function signature
最后是一些转换或计算的小工具:
更多cast 功能可以参考Foundry book 的cast Commands 页面。你可以从中按照你的需求找到对你有帮助的常用指令。
forge 的inspect 指令则是用来挖出一个合约更进阶的资讯。它不是去拉链上的资料,而是作用在本地端的档案(例如MyContract),所以如果你需要分析(链上的)其他合约,你需要先把它下载下来。
forge inspect MyContract ...
注:在分析前 forge 会先编译合约,会花一些时间。
首先是列出合约基本资料的功能:
接下来是比较进阶的使用:irOptimized(或iro),主要是你想再优化你合约的gas 消耗时可以采用的方式。
forge inspect MyContract irOptimized
它会呈现你的合约编译成(优化过的)Yul后的长相。Yul 就像assembly,它介于Solidity 和EVM opcode 之间,它可以让你看到你写的Solidity function 背后实际上还做了哪些事情,如此你就可以开始删去一些不需要的检查。
这个工具是从这两则twitter(link1 , link2)发现到的,这边直接引用里面的范例和图片来搭配说明。以一个简单的将 number 变数递增的 Counter 合约为例,里面有一个 setNumber 函式用来设置 number 的值及一个 increment 函式用来把 number 加1。右边则是执行 forge inspect Counter irOptimized 后所输出Yul 版本的 Counter 合约:
source: https://twitter.com/w1nt3r_eth/status/1579486967963693057
可以看到一个简单的Solidity 合约编译完后变得复杂许多。接下来以 increment 函式为例:
source: https://twitter.com/w1nt3r_eth/status/1579486967963693057
可以发现一个 number++ 里面其实包含了很多检查,例如not payable 和overflow。但其实我们知道它只会以一次加 1 的方式递增所以几乎不可能会overflow(加上unchecked),然后如果这个函式是可以接受ether 的话,那就可以再省掉not payable 的检查(加上payable):
source: https://twitter.com/w1nt3r_eth/status/1579486967963693057
可以发现省去了许多执行步骤。
比起原地把Solidity 程式码替换成assembly 程式码这种比较冒险的优化方式,这是一个新的管道让你能重新完整地检视你的合约,并且可以看出修改前后的对比。但要注意还是以安全为优先,不要为了省一点的gas 而拿掉你没有把握的程式码或检查。
其他forge inspect 功能可以参考Foundry book 的forge inspect 页面。
最后是介绍一个在review 合约时很实用的VSCode 插件:Solidity Visual Developer
注:以下介绍会是个人使用心得,所以会有特色或功能是没有介绍到的。可以自己下载来试用看看,看能不能发现适合你的用途的功能。
里面最常看到的就是它为你合约的变数套上框框并能连结到宣告变数的地方,以及函式的参数套上底色方便识别(虽然有时候颜色太多会看得有点眼花)。另外有variable shadowing 的警告提醒,例如你的合约继承了 Ownable 合约但某个函式宣告了一个 owner 参数,这时候这个 owner 参数就会被套上显眼的红色框框来提醒你:
owner变数被 owner 参数shadow 了
keywords 例如block.timestamp、tx.origin、msg.data或是 external 等等关键字都有提供hover 时显示安全提醒:
block.timestamp 的安全提醒
external 的安全提醒
如果你在review 合约需要做笔记时,可以利用 @audit 及 @audit-ok 这两个tag,它会出现像Bookmarks那样的图示方便你回到笔记过的程式码段落:
@audit 及@audit-ok 分别显示红色及绿色的书签图示
它还有提供一些分析整个合约的功能,让你能得到不同合约间的继承关系(inheritance)和函式之间的关系(graph),这边直接使用官方的图:
https://marketplace.visualstudio.com/items?itemName=tintinweb.solidity-visual-auditor
https://marketplace.visualstudio.com/items?itemName=tintinweb.solidity-visual-auditor
还有其他工具像是flatten:
Solidity Visual Developer 这个插件对review 或审计合约算是非常有帮助,但写合约时帮助比较少。虽然对一般人来说里面大部分的工具其实平常几乎都用不太到,不过至少知道有哪些工具可以使用之后,未来有天当你需要review 合约的时候它们就可以派上用场。
责任编辑:MK
责任编辑:MK