solidity-core
solidity-core: Solidity 開発基盤スキル
Solidity スマートコントラクト開発における言語ベストプラクティス、セキュリティ、ガス最適化、Foundry テスト戦略を提供する基盤スキル。
対象
- Solidity 0.8.x 以降のスマートコントラクト開発全般
- Foundry(forge / cast / anvil / chisel)を使った開発フロー
- コントラクトのセキュリティレビュー・最適化
ワークフロー
Step 1: プロジェクト構造の確認
- プロジェクトルートで Foundry プロジェクトか確認する:
foundry.tomlの存在をチェックhardhat.config.*が存在する場合は Hardhat プロジェクトとして扱う- いずれも存在しない場合は AskUserQuestion で開発環境を確認する
- Solidity バージョンを確認する:
foundry.tomlのsolc_versionを読み取る- または
pragma solidity宣言を Grep で検出する - バージョンが 0.8.0 未満の場合はアップグレードを推奨する
- 依存関係を確認する:
lib/ディレクトリ(Foundry)またはnode_modules/(Hardhat)をスキャン- OpenZeppelin、Solmate、Solady 等のライブラリ使用状況を把握する
- 既存のコントラクト構造を Glob でスキャンする:
src/**/*.solまたはcontracts/**/*.sol- テストファイル:
test/**/*.sol - スクリプト:
script/**/*.sol
検証ゲート: foundry.toml または hardhat.config.* が存在し、Solidity バージョンが 0.8.0 以上であること。
Step 2: リファレンス読み込み
タスクに応じて以下のリファレンスを読み込み、該当セクションを選択する:
| ファイル | 用途 | 読み込む条件 |
|---|---|---|
references/language-patterns.md |
言語機能・コーディング規約 | 新規コントラクト作成、コードレビュー時。NatSpec 記法、命名規則、error / event 定義パターンを確認する |
references/security-checklist.md |
脆弱性パターン・防御策 | セキュリティレビュー時、外部呼び出しを含むコード作成時。該当する脆弱性カテゴリを選択する |
references/gas-optimization.md |
ガス最適化テクニック | ガスコスト改善要求時、ループ・ストレージ操作を含むコード作成時。適用可能なテクニックを選択する |
references/foundry-workflow.md |
Foundry 開発フロー・テスト戦略 | テスト作成、デプロイスクリプト作成、Fuzz/Invariant テスト設計時 |
判断が不明な場合: 複数のリファレンスが関連する場合は全て読み込む。特にセキュリティは常に確認する。
検証ゲート: 少なくとも 1 つのリファレンスファイルが正常に読み込めること。
Step 3: コード生成・レビュー
- 新規コントラクト作成時:
language-patterns.mdに従い、NatSpec・コーディング規約を適用するsecurity-checklist.mdの該当パターンを確認し、防御コードを組み込むgas-optimization.mdの最適化ポイントを考慮する- OpenZeppelin コントラクトの継承で実装可能な機能は独自実装を避ける
- 既存コード修正時:
- 変更箇所に関連するセキュリティパターンを
security-checklist.mdで確認する - ガスコストへの影響を
gas-optimization.mdで評価する - 変更がインターフェースに影響する場合は NatSpec も更新する
- 変更箇所に関連するセキュリティパターンを
- テスト作成時:
foundry-workflow.mdに従い、forge test の構成を決定する- 正常系・異常系・境界値のテストケースを網羅する
- Fuzz テストの適用可否を判断する(数値入力がある関数は原則 Fuzz テスト)
- Invariant テストの適用可否を判断する(状態を持つコントラクトは推奨)
検証ゲート: forge build がエラーなく完了すること。forge test で全テストがパスすること。
Step 4: セキュリティ最終チェック
コード生成・修正後、security-checklist.md の該当項目で最終確認を行う:
- Reentrancy: Checks-Effects-Interactions パターンの遵守。外部呼び出しの前に状態を更新しているか。
- Access Control: 適切な修飾子(
onlyOwner,onlyRole)の使用。OpenZeppelin のOwnable/AccessControlを推奨。 - Integer:
uncheckedブロックの安全性。明確にオーバーフローが発生しない場合にのみ使用しているか。 - External Call: 外部呼び出しの戻り値チェック。
callの返り値を確認しているか。 - Input Validation:
require/ カスタムエラーで入力値を検証しているか。
検証ゲート: セキュリティチェックリストの CRITICAL 項目に該当する問題が 0 件であること。
使用例
例 1: ERC20 トークンの作成
ユーザー入力: 「Foundry で ERC20 トークンを作りたい」
アクション:
- Step 1:
foundry.toml確認 → Foundry プロジェクト。lib/openzeppelin-contractsの存在を確認 - Step 2:
language-patterns.md(NatSpec 規約)+foundry-workflow.md(テスト構成)を読み込み - Step 3: 以下を生成:
src/MyToken.sol— OpenZeppelinERC20を継承、NatSpec 付き、ミント関数にonlyOwnertest/MyToken.t.sol— デプロイ、transfer、mint 権限、ゼロアドレスチェックのテストscript/DeployMyToken.s.sol— デプロイスクリプト
- Step 4: セキュリティチェック → アクセス制御確認、ミント上限の有無を確認
結果: OpenZeppelin ベースの型安全な ERC20 トークンがテスト付きで生成される。
例 2: 既存コントラクトのセキュリティレビュー
ユーザー入力: 「このコントラクトのセキュリティをチェックして」
アクション:
- Step 1: 対象コントラクトを読み込み、言語バージョン・外部依存を把握
- Step 2:
security-checklist.mdを読み込み、全カテゴリのチェック項目を確認 - Step 3: コントラクトの各関数を検査:
- external / public 関数のアクセス制御を確認
- 外部呼び出しの有無と CEI パターンの遵守を確認
- ストレージ操作の安全性を確認
delegatecall/selfdestructの使用有無を確認
- Step 4: 発見した問題を重要度別(CRITICAL / WARNING / INFO)に分類して報告
結果: 脆弱性の一覧と修正推奨事項が重要度順に出力される。
例 3: ガス最適化
ユーザー入力: 「このコントラクトのガスを最適化して」
アクション:
- Step 1: 対象コントラクトを読み込み、
forge test --gas-reportでベースラインを計測 - Step 2:
gas-optimization.mdを読み込み、適用可能なテクニックを選択 - Step 3: 以下の最適化を検討・適用:
- storage → memory の読み込み回数削減
immutable/constantの適用uncheckedの安全な適用(ループカウンタ等)- カスタムエラーへの置き換え(
require(cond, "msg")→if (!cond) revert CustomError()) - ストレージパッキングの最適化
- Step 4: 最適化後に
forge test --gas-reportで改善量を確認。テストが全件パスすることを確認
結果: ガスコストの改善量がベースラインとの比較で表示される。
トラブルシューティング
1. Foundry が検出されない
症状: forge コマンドが見つからない
原因と対策:
- Foundry 未インストール:
curl -L https://foundry.paradigm.xyz | bash && foundryupでインストールを案内する。 - PATH 未設定:
~/.foundry/binが PATH に含まれているか確認する。 - Hardhat プロジェクト:
hardhat.config.*が存在する場合は Hardhat ワークフローに切り替える。npx hardhat compile/npx hardhat testを使用。
2. Solidity バージョン不一致
症状: forge build でコンパイルエラー(Source file requires different compiler version)
原因と対策:
- pragma と foundry.toml の不一致:
foundry.tomlのsolc_versionをpragma solidityのバージョン範囲に合わせる。 - 依存ライブラリのバージョン制約: OpenZeppelin の最新版は
^0.8.20を要求することがある。forge install openzeppelin/openzeppelin-contracts@v4.xで旧バージョンを指定するか、プロジェクトの Solidity バージョンを上げる。 - remappings の不備:
remappings.txtに正しいマッピングが設定されているか確認する。forge remappings > remappings.txtで再生成可能。
3. コンパイルエラー(Stack too deep)
症状: CompilerError: Stack too deep
原因と対策:
- ローカル変数が多すぎる: 関数内のローカル変数を struct にまとめる。
- 関数の引数/戻り値が多い: struct を引数/戻り値に使用する。
- via-ir の有効化:
foundry.tomlにvia_ir = trueを追加する。コンパイル時間が長くなるが、stack depth の制限が緩和される。
4. テストの forge test が失敗する
症状: テストが setUp で失敗、または予期しない revert
原因と対策:
- fork テストの RPC 問題:
--fork-urlの RPC エンドポイントがレート制限に引っかかっている。環境変数で有料 RPC を設定する。 - ブロックタイムスタンプ:
vm.warpでタイムスタンプを設定していない。時間依存のロジックがある場合は明示的に設定する。 - msg.sender の不一致:
vm.prank/vm.startPrankでテスト用のアドレスを設定しているか確認する。
5. 依存関係のインストール失敗
症状: forge install がエラー、またはインポートが解決できない
原因と対策:
- git submodule の問題:
git submodule update --init --recursiveで再初期化する。 - remappings の未設定:
forge remappings > remappings.txtで remappings を生成する。VS Code の Solidity 拡張もこのファイルを参照する。 - バージョン指定:
forge install openzeppelin/openzeppelin-contracts@v5.0.0のようにタグを指定する。
注意事項
- Solidity 0.8.0 以降は算術オーバーフロー/アンダーフローが組み込みでチェックされるため、SafeMath は不要。
uncheckedブロックは明確にオーバーフローが発生しない場合にのみ使用する。- DeFi、NFT、ガバナンス等のドメイン固有パターンは、対応する専門スキル(
solidity-defi、solidity-nft、solidity-governance)を参照する。 - クロスチェーンパターンは
solidity-crosschainを参照する。 - フロントエンド統合は
web3-frontendを参照する。 - アカウント抽象化は
web3-account-abstractionを参照する。 - OpenZeppelin コントラクトの利用を推奨し、独自実装は避ける。