スパースマークルツリー

ユーザーと開発者はSMTに直接アクセスしません。除外証明は operator-private-channel サービスによって自動的に計算・送信されます。このページはオペレーターおよびオペレーターツールを構築するすべての人向けのリファレンス資料です。

エスクロープログラムは、このスパースマークルツリー設計からオンチェーンのノンスビットマップ(上流で追跡中)へ移行中です。このページは現在のエスクロープログラムに基づいて正確な情報を提供しており、変更が反映された後に改訂される予定です。

目的

プライベートチャンネルは、スパースマークルツリー(SMT)を使用して、各出金ノンスが一度だけ決済されることを保証します。オペレーターが ReleaseFunds を呼び出す際、2つの証明を提供する必要があります。ノンスが現在のルートに対してまだ存在しないことを示す除外証明と、呼び出し元が提供した新しいルートにノンスが存在することを示す包含証明です。両方のチェックが通過した場合にのみ、プログラムは新しいルートを保存し、ノンスの再利用の試みを証明可能な無効とします。

ツリーパラメーター

  • ツリーの高さ: 16
  • 最大リーフ数: 65,536(2^16)
  • ハッシュ関数: SHA-256
  • 空のリーフ値: [0u8; 32](32ゼロバイト)
  • 非空のリーフ値: SHA256([1u8; 32])、定数 NON_EMPTY_LEAF_HASH として格納
Root Hash (32 bytes)
/ \
Hash(L, R) Hash(L, R)
/ \ / \
Hash(L, R) Hash(L, R) Hash(L, R) Hash(L, R)
/ \ / \ / \ / \
... ... ... ... ... ... ... ...
/ \ / \ / \ / \ / \ / \ / \ / \
Leaf0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
(nonces recorded as leaf positions using their value modulo 65536)

リーフ構造

各出金はちょうど1つのリーフを占有します。リーフの位置は以下によって決定されます:

leaf_position = transaction_nonce % 65536

リーフの値が NON_EMPTY_LEAF_HASH(すなわち SHA256([1u8; 32]))と等しい場合、そのリーフは非空とみなされます。空のリーフはすべてゼロです。

ノンスとリーフ位置

ReleaseFunds 内の transaction_nonce は u64 型です。ツリー内での位置は nonce % 65536 です。期待されるepochは nonce / 65536 です。オンチェーンプログラムは、この計算されたepochが Instance.current_tree_index と等しいことを検証します。不一致の場合は InvalidTransactionNonceForCurrentTreeIndex がスローされます。

ツリーローテーション

Tree Index 0 (nonces 0-65,535) Tree Index 1 (nonces 65,536-131,071)
┌────────────────────────────┐ ┌────────────────────────────┐
│ Root: 0x8fe6... │ │ Root: 0x8fe6... (reset) │
│ Nonces Used: 65,536/65,536 │ Rotate │ Nonces Used: 0/65,536 │
│ Status: FULL │ ──────> │ Status: ACTIVE │
└────────────────────────────┘ └────────────────────────────┘
(Tree exhausted) (Fresh tree)

SMTのリーフ容量は65,536個に固定されています。オペレーターサービスは、nonce > 0 の場合に nonce % 65536 == 0 かどうかを確認することでローテーションの必要性を検出します。この境界は新しいepochの開始を示します。その時点で、operator-private-channel は次の ReleaseFunds を送信する前に ResetSmtRoot を呼び出します:

  • Instance.current_tree_index がインクリメントされる
  • 出金ルートが空のツリーにリセットされる
  • 前のツリーepochのノンスが無効化される

オペレーターサービスはまた、各 ReleaseFunds 呼び出しの前に、ローカルのSMTルートがオンチェーンの Instance.withdrawal_transactions_root と一致することを確認します。不一致が検出された場合、無効な証明の送信を避けるために安全シャットダウンが実行されます。

ツリーローテーションは、オンチェーンに格納された Instance.current_tree_index: u64 によって追跡されます。

ReleaseFundsにおける検証

ReleaseFunds の sibling_proofs 引数はちょうど [u8; 512]:16個のシブリングハッシュ × 各32バイトで、ツリーの高さ16に対応しています。

オンチェーンの検証プロセスは、順番に2つの独立したチェックを実行します:

  1. verify_smt_exclusion_proof は、現在の Instance.withdrawal_transactions_root に対してノンスリーフが現在空であることを証明します
  2. verify_smt_inclusion_proof は、呼び出し元が提供した new_withdrawal_root 引数にノンスリーフが存在することを証明します
  3. 両方のチェックが通過した場合にのみ、プログラムは new_withdrawal_root を新しい Instance.withdrawal_transactions_root として保存し、トークンをリリースします

いずれかのチェックが失敗すると InvalidSmtProof がスローされます。ステップ3のルート更新は各 ReleaseFunds 呼び出しとアトミックです。

Is this page helpful?

目次

ページを編集
© 2026 Solana Foundation. 無断転載を禁じます。