Token-2022 トランスファーフック スキャフォールド
トランスファーフックは、Token-2022拡張機能の中で最も正しく実装するのが難しい機能です。プログラムは、Anchorが生成しないインターフェース判別子を公開し、バイト単位で正確な順序で
ExtraAccountMetaListをレイアウトし、アウトオブバンド呼び出しに耐性を持つ必要があります。小さなミスは不透明なランタイムエラーとして表面化します。このスキルは、デフォルトでセキュアなパスであり、コンパイル可能なプログラムとLiteSVM攻撃テストによってバックアップされています。トークン拡張スキルとの比較:
solana-token-extensions/token-2022-extensionsは、フックを1つの機能として扱います(単一の静的サンプルと、ある場合はチェックリスト監査)。これは専用のフックツールであり、オンデマンドで新しいセキュアなフックを生成し(scaffold.sh)、その監査をパスする攻撃テストでバックアップする唯一のものです。補完的です。実際にフックを構築または強化する際に、それらと一緒にインストールしてください。
このスキルを使用するタイミング
- トランスファーフックの構築: ホワイトリスト/KYCゲーティング、ロイヤルティ強制、手数料ルーティング、転送ごとのアカウンティング/制限、ソウルバウンド的なルール。
- フックのデバッグ:
AccountNotFound、NotEnoughAccountKeys、IncorrectAccountAddress、または「フックなしでは転送が機能するが、フックありでは失敗する」。 - 既存のフックプログラムのレビュー/監査: 標準的な落とし穴の確認。
- フックを指すToken-2022ミントの作成、およびクライアント転送の配線。
インテグレーター注記: あなたが消費側(フックを持つサードパーティのミントを受け入れる)である場合、それは別の問題です。ほとんどのインテグレーターは未知のフックミントを拒否すべきです。関連スキル token2022-integration-guard を参照してください。
メンタルモデル(最初に読んでください)
- フックプログラムは
Execute(SPLトランスファーフックインターフェース)を実装します。これは、すべての転送時にToken-2022がCPIします。Anchorはsha256("global:<ix>")でディスパッチしますが、これはインターフェース判別子と一致しません。したがって、インターフェース命令をデコードし、インプロセスでディスパッチする**fallback**を追加します(自己CPIは避ける)。→ program.md - フックは追加のアカウントを要求できます。これらを一度**
ExtraAccountMetaList** PDA(["extra-account-metas", mint])で宣言します。Token-2022はそれを読み取り、それらのアカウントをExecuteに渡し、転送時にシードベースのPDAを解決します。順序が重要です。→ extra-account-metas.md - クライアントは
createTransferCheckedWithTransferHookInstructionを使用して転送を構築する必要があります(通常のtransferCheckedは追加アカウントを省略し、リバートします)。→ client-wiring.md - フックは攻撃者から到達可能です。保護してください。→ security.md
- フックを経由して転送するテストでそれを証明します。→ testing.md
ルーティングテーブル
| ユーザーが… | 読むもの |
|---|---|
| フックプログラムの作成(Execute、fallback、メタリストの初期化) | program.md |
| ExtraAccountMetaList / 不透明なアカウントエラーとの戦い | extra-account-metas.md |
| ミント + クライアント転送の配線 | client-wiring.md |
| セキュリティのためのフックの強化/監査 | security.md |
| フックのテスト作成 | testing.md |
| 新しいフックワークスペースのスキャフォールディング | /transfer-hook:scaffold を実行 |
| 既存のフックプログラムの監査 | /transfer-hook:audit を実行 |
| ソース / 参考文献 | resources.md |
このスキルに含まれるもの
| 成果物 | パス | 説明 |
|---|---|---|
| リファレンスフックプログラム | examples/hook/ | コンパイル可能な Anchor 1.0 フック: ホワイトリストゲート + ミントごとのカウンター、フォールバックルーター、is_transferring ガード。 |
| 攻撃テスト | examples/hook/tests/ | LiteSVM テスト: フックを経由して転送: ホワイトリスト登録済みは成功(カウンター増加)、未登録は失敗、直接 Execute は拒否。 |
| スキャフォールドスクリプト | scripts/scaffold.sh | リファレンスから新しいフックワークスペースを生成します。 |
固定スタック(2026年)
Anchor 1.0、anchor-spl 1.0.2、spl-transfer-hook-interface =2.1.0、
spl-tlv-account-resolution 0.11、@solana/spl-token 0.4.14、litesvm 1.2(キットネイティブ、Token-2022プリロード)。リファレンスプログラムはこのスタックでビルドされ、テストはパスします。
不可侵のルール
fallbackを追加し、TransferHookInstruction::Executeをデコードしてインプロセスでディスパッチします(__private::__global::transfer_hook)— 自身のプログラムをinvokeしないでください。- 最初の転送の前に
ExtraAccountMetaListを初期化し、Vec<ExtraAccountMeta>の順序をExecuteアカウント構造体と同一に保ちます。 Executeをis_transferringでガードします—実際の転送外での呼び出しを拒否します。- 注入されるすべてのアカウントをPDAシードにバインドします(
Account<T>+seeds)。裸のUncheckedAccountは使用しないでください。攻撃者がホワイトリストを偽装します。 - フックを最小限かつ全体的に保ちます—すべての転送で実行されます。パニックや重いCUはトークンを壊します。
- 転送パスをテストします。ユニットロジックだけではありません。コンパイルできるフックでも、解決時に失敗する可能性があります。