Foundry使ったスマートコントラクト開発の所感
はじめに
Foundryの概要と簡単な使用感をhardhatとの比較を交えて書いていきます。
現状、solidity開発のどういうケースだと使えそうか?に対する答えを出そうと思います。
Foundryとは
Crypto VCのParadigm が開発した、Rust製のsolidity開発ツールです。
※現状の主なsolidityスマートコントラクト開発ツール
-
テストが js or ts
- truffle
- hardhat
-
ブラウザで簡単
- remix
-
実装もテストもsolidity
- Foundry <-- NEW!!
特徴
速い
rust製ということもあり、コンパイル・テストがめちゃくちゃ速いです。具体的な数字は、hardhat との比較で後で記述します。
git submodules 依存関係の管理
hardhatやtruffleではnpmでパッケージの管理を行いますが、
foundry のcli, forgeでは git submodulesを使っています。
fuzzing test
fuzzing test がネイティブで実装されています。
trace
テスト実行時に、verbosityのレベルが五段階用意されています。
forge test -vv
forge test -vvv
forge test -vvvv
forge test -vvvvv
使用するCLI一覧
-
Forge
- package インストール
- テスト実行
- コントラクトdeploy・verify
-
Anvil
- ローカルノード立ち上げ
-
Cast
- スマートコントラクトのcall
- read transaction
hardhatと比べて
良い
githubに,スピードテストの結果がdapptoolsと比較されています。
また、uniswap-v3coreのコンパイル結果もhardhatと比較されてグラフになっています。
hardhatでは、コントラクト実装はsolidity, テストの際はjsもしくはts と、別の言語へのスイッチングコストがありますが、foundryはコントラクトもテストもsolidityです。
先ほどの特徴でも説明しましたが、ネイティブで実装されています。
// fuzzing testしたい値を関数に引数として追加する
function testMint(uint256 amount) public {
vm.prank(creator);
reconeToken.mint(user, amount);
assertEq(reconeToken.balanceOf(user), amount);
}
消費するgas量が相対的にわかる
[<Gas Usage>] <Contract>::<Function>(<Parameters>)
├─ [<Gas Usage>] <Contract>::<Function>(<Parameters>)
│ └─ ← <Return Value>
└─ ← <Return Value>
$ forge test -vvvvv
Traces:
[72583] EmitContractTest::testExpectEmit()
├─ [33287] → new ExpectEmit@"0xce71…c246"
│ └─ ← 166 bytes of code
├─ [0] VM::expectEmit(true, true, false, true)
│ └─ ← ()
├─ emit Transfer(from: EmitContractTest: [0xb4c79dab8f259c7aee6e5b2aa729821864227e84], to: 0x0000000000000000000000000000000000000539, amount: 1337)
├─ [1940] ExpectEmit::t()
│ ├─ emit Transfer(from: EmitContractTest: [0xb4c79dab8f259c7aee6e5b2aa729821864227e84], to: 0x0000000000000000000000000000000000000539, amount: 1337)
│ └─ ← ()
悪い
jsやtsに比べて、dapps開発以外で、solidity使ってテストを書くことがないことと、foundryにネイティブで存在するライブラリの使い方を覚える必要があるため、テスト書くときに多少のコストがかかります。
foundryのdapptoolsに影響を受けて開発されたので、似たようなメソッドがあるので、もし以前に使ったことあれば書きやすいかもです。
やはりすでにさまざまなプロトコルで採用されている hardhat よりも、プラグインの数がかなり少ないです。
単純に使ってる人がまだ少ないのでいろんなケースで使用された記事や、日本語の記事も少ないです。
使用感
- コンパイルやテストがサクサク終わるので気持ち良い
- テスト書くとき、「フロント、ノードからコントラクト操作」というよりも「VM直接いじっている」感覚がある
- testファイルは'.t.sol', test関数名は'test....', script実行ファイルは'.s.sol'にする必要がある等、ファイル名や関数名に対しての一貫したルールがあって個人的には好き
その他 foundry でできること
- upgradeable contractの実装
- 実際のチェーンをローカルノードにフォークしてテスト
- differential testing
最後に
使えそうか?どういうユースケースで?
基本的には、まだhardhatでの開発で良いのではないかといった感じです。
- 実際のコントラクト実装には、hardhatほどのプラグインの豊富さと使用者の少なさ、ネット上の記事の少なさ的にはまだ採用するには早い
- 既存のhardhat開発を置き換えるのは難しい。使うとしても、新規で開発する
- 構造がシンプルなコントラクトを作成する際に使用できそう
参考資料
Discussion