Solidity 及EVM 开发工具介绍

NIC Lin热度: 13181

Foundry 除了测试之外的功能及VSCode 的Solidity Visual Developer 插件

原文作者:NIC Lin

原文来源:medium

Solidity 及EVM 开发工具介绍

这篇文章将介绍Ethereum 开发者的一些实用工具:Foundry 除了测试之外的功能及VSCode 的Solidity Visual Developer 插件

Photo by Dan Cristian Pădureț on UnsplashFoundry

Foundry 除了提供合约开发、测试和部署,其实还有许多其他实用的功能。

安装Foundry

如果是Linux 或macOS,先安装foundryup,接着直接用 foundryup 指令就可以安装。未来要升级foundry 也只需要执行 foundryup 就好,非常简单直觉。

// Install foundryup

curl -L https://foundry.paradigm.xyz | bash

// Install or update Foundry

foundryup

详细可以参考Foundry book 的Installation 页面

Auto Completion

Foundry 安装完后会有forge、cast及 anvil 三个指令,每个指令也都有许多option,这时有Auto Completion 会非常省事。例如产生bash 用的Auto Completion script:

分析

其他Shell script 的产生方式可以参考Foundry book 的Shell Autocompletion 页面

anvil

其实就和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

cast 是用来取链上资料非常好用的工具(也有送交易的工具但个人觉得不太实用)。因为有很多功能,这里我只会列出我常用及觉得实用的功能。

注:要读取链的状态记得要在foundry.toml 档里附上endpoint url(eth_rpc_url=$URL)或透过 --rpc-url $URL 的方式。

首先是抓取交易资讯:

  • cast tx/receipt:抓取交易receipt 资讯
  • cast run:印出一笔已被收入的交易的execution trace或进行live debug(加上--debugoption),为了得到准确的交易前状态,预设会模拟执行同一区块里在该笔交易前面所有的交易,但这可能很耗时,如果只想看交易执行过程且不需要最精准的执行结果的话,可以加上--quickoption,它会跳过前面交易的模拟,直接把该笔交易当作区块的第一笔交易来执行

注:cast run --debug的debug 介面可能没有那么好读,如果不需要看到执行过程中的memory/stack/storage 等细节时可以直接用ethtx.infoTenderly,好读很多。

分析

接着是从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

forge 的inspect 指令则是用来挖出一个合约更进阶的资讯。它不是去拉链上的资料,而是作用在本地端的档案(例如MyContract),所以如果你需要分析(链上的)其他合约,你需要先把它下载下来。

forge inspect MyContract ...

注:在分析前 forge 会先编译合约,会花一些时间。

首先是列出合约基本资料的功能:

  • forge inspect MyContract abi/bytecode/deployedBytecode:列出 MyContract的ABI/编译完的bytecode/实际部署到链上后的bytecode,方便export ABI 或是比对部署在链上的bytecode
  • forge inspect MyContract methods/gas:列出 MyContract的(public 的) function 列表(包含function signature 及selector)/ 每个function 的预估gas 消耗。用 cast 4b/4bd 其实就能反查特定function selector,这个功能比较像是能看到一个合约完整的function 资讯
  • forge inspect MyContract storage:列出 MyContract的storage,包含每个变数的storageslot和offset(如果有多个变数被pack 在一起的话,offset会是每个变数在该slot 的起始位置)。但呈现的资料比较丑一点,可以改用slither 来分析合约storage 或读取合约变数的值,它还可以拉链上的合约来分析,不需要先下载合约下来。

接下来是比较进阶的使用: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 页面

VSCode

最后是介绍一个在review 合约时很实用的VSCode 插件:Solidity Visual Developer

注:以下介绍会是个人使用心得,所以会有特色或功能是没有介绍到的。可以自己下载来试用看看,看能不能发现适合你的用途的功能。

Solidity Visual Developer - Visual Studio Marketplace🌐 📩 🔥 ] Advanced Solidity Language Support Code Augmentation Source Exploration Visual Security Linting An extension…marketplace.visualstudio.com

里面最常看到的就是它为你合约的变数套上框框并能连结到宣告变数的地方,以及函式的参数套上底色方便识别(虽然有时候颜色太多会看得有点眼花)。另外有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

声明:本文为入驻“MarsBit 专栏”作者作品,不代表MarsBit官方立场。
转载请联系网页底部:内容合作栏目,邮件进行授权。授权后转载时请注明出处、作者和本文链接。未经许可擅自转载本站文章,将追究相关法律责任,侵权必究。
提示:投资有风险,入市须谨慎,本资讯不作为投资理财建议。
免责声明:本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况,及遵守所在国家和地区的相关法律法规。