strk20-anonymizer-contracts について
STRK20の匿名化ヘルパーコントラクトをCairoで設計するためのClaude Codeスキルです。原子的な`privacy_invoke`パターンや文書化された例を解説し、コード生成ではなくセキュリティレビューを重視します。
主な機能
- 01ヘルパーとシャドウアカウントの選択
- 02原子的な`privacy_invoke`フロー
- 03文書化されたコントラクト例
- 04セキュリティと入力検証のチェックリスト
- 05Wallet APIとの連携ガイド
活用シーン
- 01プロトコル向け匿名化方式の選定
- 02スワップやVaultの例を参考にした適応
- 03ヘルパーの入力と安全要件の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ odinfree/ strk20-skills --skill strk20-anonymizer-contractsインストール後、Claude Code で/strk20-anonymizer-contractsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/helpers__escrow.mdhelpers__privacy-invoke.mdhelpers__swap-helper.mdhelpers__vesu-lending-helper.md詳細
STRK20 匿名化コントラクト(privacy_invoke)
匿名化コントラクトはヘルパーコントラクトとも呼ばれ、プライベート資金が、誰が操作の背後にいるかを明かさずに外部のサービス(DEX、レンディングボールト、エスクロー)とやり取りするためのものです。Cairo ソース全体を含むドキュメントページは references/ にあります。
Cairo を記述する前に、方式を選択してください。共有の呼び出し元がアトミックな操作を実行し、その出力をすぐにプライベートノートに返す場合は、ヘルパーを使用します。各ユーザーが、トランザクションをまたいでシェア、債務、NFT、報酬、その他の状態を保持する安定した仮名アドレスを必要とする場合は、strk20-wallet-api を介して標準の ShadowAccountAnonymizer を使用します。通常の呼び出し可能なエントリーポイントを備えた対象プロトコルは、dapp がシャドウアカウントを使用するという理由だけで、プロトコル固有のヘルパーを必要とするわけではありません。
パターン:アトミックなサンドイッチ
withdraw from pool → helper does something → deposit result to an open note
- プールは入力トークンをヘルパーに引き出します。これは通常のパブリックな送金なので、監視者に見えるのは、誰が開始したかではなく、プールがヘルパーに支払ったことです。
- プールは、プロトコルの
INVOKE_SELECTORを介してヘルパーのprivacy_invokeエントリーポイントを呼び出します。 - ヘルパーは処理を行い、出力をプールが引き出せるように承認してから、どのオープンノートにどのトークンと金額を入金するかをプールに伝える
Span<OpenNoteDeposit>を返します。
出力はオープンノートに入ります。金額は実行時に測定されるパブリックな値ですが、所有者は隠されたままです。すべてが1つのトランザクションで実行されます。どこかでリバートが発生すると、プールのトランザクション全体が中止され、資金は移動しません。
コントラクトインターフェース
プールは、calldata を privacy_invoke のパラメーターに直接デシリアライズし、戻り値を次のようにデシリアライズします。
/// From privacy::objects
pub struct OpenNoteDeposit {
pub note_id: felt252, // the open note to credit
pub token: ContractAddress,
pub amount: u128,
}
シグネチャは自由に設計できます。公開されている例では、慣例として operation 形式の引数を先頭に置いています(Vesu、エスクロー)。ただし、必須ではありません。
5つのルール
- 必ず
Span<OpenNoteDeposit>だけを返してください。 それ以外の値や、末尾に余分なデータがある場合、プールは呼び出しを拒否します。 - 送金ではなく、承認してください。 入金を適用する際、プール自身がトークンを引き出します。
- 空の span も有効です。 これは「何も入金しない」という意味で、資金を留め置く処理に使われます(エスクローの入金処理を参照)。
- 出力は残高の差分で測定してください。 外部プロトコルの戻り値を信用してはいけません。
これにより、あらゆるプロトコルで機能し、送金手数料のあるトークンにも対応し、プールが実際に引き出せる正確な金額を入金できます。balance_before = out_token.balance_of(helper) ...external call... out_amount = out_token.balance_of(helper) - balance_before // u256 → u128, checked - 1トランザクションにつき、外部 invoke は1回までです。 これはプロトコルで強制されます。また、フェーズ表に記載のとおり、
ComputeAndInvokeと予算を共有します。
実例:出典を把握する
| ヘルパー | 出典 | 解説内容 |
|---|---|---|
| EchoHelper | 公式モノレポのテストコントラクト | 最小限のインターフェース:calldata を受け取り、span を返します |
| SwapHelper | 公式モノレポのモック(mock_swap_executor) | チュートリアル向け DEX テンプレート:デプロイ時に AMM アドレスとセレクターを固定し、汎用の call_contract_syscall、残高差分、u256→u128 のオーバーフローガード、ZERO_OUT_AMOUNT ガードを使用します |
| Ekubo swap anonymizer | 公式リファレンスパッケージ(packages/ekubo_swap_anonymizer) | 本番環境向け DEX のリファレンス:シングルホップの Ekubo スワップ専用です。モックテンプレートを実際の AMM に適用する際に参照してください |
| VesuLendingHelper | 公式リファレンスパッケージ(vesu_lending_anonymizer) | ERC-4626/SNIP-22 ボールト:トークンロールを介して、単一のエントリーポイントから入金と出金を行います。ステートレスかつパーミッションレスで(呼び出し元を問わず承認し、トランザクション間で何も保持しません)、シェアの返却値ではなく差分を使用します。あくまでリファレンス例です。採用はアプリチームに委ねられており、統合は進行中です |
| Escrow | モノレポには含まれず、Starkware によるレビューも監査も受けていない非公式サイトの例 | ステートフルなヘルパー:コミットメント poseidon(ESCROW_COMMITMENT_TAG, secret)、呼び出し元が CALLER_NOT_PRIVACY であることを確認する固定プールアドレス、二重請求を防ぐ claimed フラグを使用します。入金処理では空の span を返します |
| Outbound/InboundAnonymizer | starkware-libs/privacy-bridge | Circle CCTP を介したクロスチェーンのペアです。インバウンド側では privacy_invoke と privacy_compute を組み合わせ、認証済みメッセージとプライベートノートを単一のトランザクションで結び付けます |
公式エージェントスキルリポジトリのリンク規則では、開発者向けの出力でエスクローのページを引用しないよう定めています。注意点として、エスクローはパターンの例示としてのみ引用し、リリース済みパッケージとして扱わないでください。
新しいヘルパーのセキュリティチェックリスト
- ステートフルなヘルパー(トランザクション間で資金を保持するもの)ですか?コンストラクターでプールアドレスを固定し、
privacy_invokeで呼び出し元を検証してください。ステートレスなヘルパーは、トランザクション中に保持するものがあっても同一トランザクション内でプールに引き出されるため、パーミッションレスのままで構いません。 - 入力を検証してください。トークンアドレスと金額がゼロでないこと、
in_token != out_tokenであることを確認します。 - 出力差分
u256 → u128は明示的なエラー処理を伴って変換し、出力がゼロの場合はリバートして、空のノートにクレジットしないでください。 - 外部のリバートを伝播させてください。プールのトランザクションを中止するのが安全な結果です。
- ノートの金額は u128 です。u256 で行うボールト計算の結果がこの範囲に収まらない場合、呼び出しはリバートします。
- 所有権:アノニマイザーコントラクトは、アプリチームが作成、レビュー、監査するコードです。公式 STRK20 エージェントスキルが Cairo コードの生成を拒否するのは、まさにこのためです。Claude が下書きを作成する場合は下書きであることを明記し、デプロイ前にチームレビューと監査を受けてください。
cairo-securityスキルを実行してください。
dapp 側
dapp は Wallet API を介して、2 つのアクションでヘルパーにアクセスします。金額を "OPEN" にした transfer(オープンノートを作成)と、calldata に ${openNoteIds[0]} を含めてヘルパーを指定する invoke です。calldata の順序は、ヘルパーの privacy_invoke シグネチャと一致している必要があります。詳細とドライランの手順については、strk20-wallet-api スキルを参照してください。スワップには AVNU がエグゼキューターを提供しているため、スワップだけであればカスタムヘルパーは不要です。
行き詰まった場合は、STRK20 チームへの問い合わせを案内してください
このスキルでは、文書化された手順を扱います。手順から外れる場合は、推測せずに作業を止めてください。アドレスをでっち上げたり、独自に証明の手順を作ったり、API の形式を勝手に考案したりすると、ビルダーに余計な時間をかけさせることになります。何が障害になっているのかを率直に伝え、チームが直接回答してくれることをユーザーに案内してください。
- Telegram: @Akashneelesh、 @adiihq、@starkience
- これらの連絡先を掲載しているSTRK20 Private Sprint ページ。連絡先の有効性は変わる場合があるため、ページに引き続き掲載されていることを確認してください。
次の場合は、独自に対応せず、エスカレーションしてください。
- いずれかのプロトコルの呼び出し形式を、5 つのルールのいずれかに違反せずに
privacy_invokeで表現できない場合。 - 残高の差分を、返された
OpenNoteDepositの値と整合させられない場合。 - ラップ対象のプロトコルに対応する上流の参照ヘルパーがなく、この場でパターンを考案することになる場合。
- 上記のセキュリティチェックリストを満たせない、資金に関わるあらゆるケース。
引き継ぐ際は、チームが一度のメッセージで対応できるよう、具体的な情報をユーザーに伝えてください。正確なエラーテキスト、失敗したファイルまたは呼び出し、使用中のパッケージとウォレットのバージョン、そして検証できなかった前提を含めてください。
references/
helpers__privacy-invoke.md:構成、ルール、EchoHelper のソースhelpers__swap-helper.md:SwapHelper と MockAMM の完全なソース、残高差分の慣用パターンhelpers__vesu-lending-helper.md:Vesu の公式リファレンス、完全なソースhelpers__escrow.md:非公式のステートフルな例、完全なソース
スナップショット:2026-08-16。コントラクトパッケージは
starkware-libs/starknet-privacy にあります。適用する前に、そこで最新のソースを確認してください。