Rust製のEthereumアプリケーション開発ツールFoundry
2021年の12月にGeorgios Konstantopoulos氏がRust製のEthereumアプリケーション開発ツール「Foundry」をParadigmのブログにてアナウンスした。
Foundryの概要
Foundryは主な特徴として次のことが可能である。
- Rustで構築されていることによる高速なテスト
- Fuzzingを用いたテスト
- VMのステートを上書きしたテスト
- 稼働しているネットワークに対するテスト
また、設計思想としてテストに使用できる言語をSolidityに限定して、JavaScriptによるテストを排している。
FoundryはForgeとCastの2つのツールから成り立っている。ForgeはTruffleやHardhatのようなテストフレームワークであり、Castはチェーンと通信するためのツールで、EVMコントラクトの対話やトランザクションの送信、チェーンデータを取得できる。
Rustで構築されていることによる高速なテスト
FoundryはDappHubチームのテストフレームワークDapptoolsをRustで実装し直したものをベースに作られている。アナウンスではDapptoolsと比較して3~7倍ほど高速化されていることが示されており、また、OpenZeppelin/openzeppelin-contractsをコンパイルしたところHardhatは15.244秒だったのに対しFoundryのForgeは9.449秒と約40%の時間が削減されたと報告している。
Fuzzingを用いたテスト
Fuzzingとは無効なデータや予期しないデータを自動生成してプログラムに入力し潜在的なバグを見つけるテスト手法である。ここ数年で脆弱性診断に使われることが一般的になってきた手法であり、ブロックチェーンのアプリケーション開発においても有効である。FoundryではFuzzingをサポートし、例えば次のようなテストコードを書くことで自動的にFuzzingを実行できる。
function testDoubleWithFuzzing(uint256 x) public {
foo.set(x);
require(foo.x() == x);
foo.double();
require(foo.x() == 2 * x);
}
VMのステートを上書きしたテスト
FoundryではVMのステートを柔軟に上書きした上でテストの実行が可能である。この機能は例えば「自分のアドレスの特定トークンの残高を改変したい」「ガバナンスのテストで数万ブロック進めたい」のようなケースで有効である。 実際に上書きするコードとしてブロックのタイムスタンプを変更するものは次のようになる。
interface Vm {
function warp(uint256 x) external;
function expectRevert(bytes calldata) external;
}
contract MyTest {
Vm vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
function testWarp() public {
vm.warp(100);
require(block.timestamp == 100);
}
}
上書きするためのチートコードの詳細はここに記載されている。
稼働しているネットワークに対するテスト
他のテストフレームワークと同様に、実際に稼働しているネットワークをフォークしてそのネットワークに対してテストを実行できる。実行コマンドはforge test --fork-url <your node url> [--fork-block-number <the block number you want>]のようにする。
テストの言語をSolidityに限定にした設計思想
FoundryはコントラクトのテストをJavaScript(やTypeScript)で行うことを批判しており、Solidityによるテストのみをサポートしている。理由として、JavaScriptによるテストは多くの設定ファイルや依存関係(モジュール)が必要であったり、多倍長整数のライブラリを必要としたりと、互換性の問題による生産性の低下を引き起こしていることを挙げている。JavaScriptによるテストは実際にテストしたいSolidityのプログラムから1段階抽象化されたものであり、JavaScriptでSolidityを扱うために諸々の手続きが必要である。この抽象化によってMochaやEthers.js、Web3.jsなど様々なフレームワークを学習する必要があり、Ethereumアプリケーション開発者の障壁になっている。Foundryはこの問題を解決すべくテストをSolidityに限定している。
Foundryとその周辺の開発支援ツールの今後
Paradigmは2020年の夏ごろからMiner Extractable Value (MEV)トレーダーのボット作成を支援するためにethers.jsのRust版であるethers-rsを開発してきた。それに続いて、MEV Inspect、Ethers Fireblocks、Ethers Flashbots、Ark Circom、Opticsなど、そういったEthereumアプリケーションの開発を支援するツールを構築してきた。Foundryもその一環であり、Paradigmは引き続きより洗練された新しい開発支援ツールを作成していくと述べている。