メインコンテンツまでスキップ

マークル証明

API が返すすべての解決結果には、マークル証明が添えられています。これにより、結果を送ってきたサーバーを 信頼する代わりに、答えを状態ルートと突き合わせて確認できます。

ツリー

PiNS はすべての名前を 128 ビットの鍵空間上のコンパクト疎マークルツリーに保持します。名前の鍵は SHA-256(domain_name) の先頭 16 バイトなので、名前は均等に分布し、自分の名前がどこに落ちるかを選べる人は いません。

「コンパクト」とは、葉が固定の深さ 128 ではなく、鍵の接頭辞が一意になる最も浅い深さに置かれるという意味 です。数千の名前を保持するツリーでは、ほとんどの証明はせいぜい十数個のハッシュにすぎません — スマート フォンでも、ブラウザ拡張でも、ウォレットの中でも検証できるほど小さいのです。

検証器を書く前に知っておくべき 2 つの帰結:

  • 証明の長さは可変です。 レスポンスから proof_depth を読んでください。固定サイズを決して前提に しないでください。
  • 空の部分木はどの高さでも 32 個のゼロバイトです。 そのため空のツリーのルートはすべてゼロです — 初期化直後のインデクサーが 0000…0000 を報告するのは正常であって、壊れているわけではありません。

証明に含まれるもの

フィールド意味
merkle_proof兄弟ハッシュ。[0] が最も深い(葉に最も近い)
proof_depth兄弟ノードの数 — merkle_proof.length と等しくなければならない
proof_terminal経路の末端にあるもの:OccupiedVacantBlocked のいずれか
smt_rootこれらの兄弟ノードが再構成するルート

存在と不在

証明が「この名前は登録されていない」を「されている」と同じくらい説得力をもって言えるのは、まさに ターミナルのおかげです:

  • Occupied — 経路の末端にその鍵自身の葉があります。名前は存在し、渡されたレコードはツリーの中に あるまさにそれです。
  • Vacant — そこには空の部分木があります。名前は登録されていません。
  • Blocked — その位置を別の名前の葉が占めています。名前は登録されておらず、レスポンスにはブロックして いるレコードが添えられているので、それがそこで見つかった葉にハッシュされること、そしてその鍵が実際に 同じ接頭辞を共有していることを検証できます。

Blocked がなければ、インデクサーは「その場所は空だ」と主張して登録を隠せてしまうでしょう。ブロックして いるレコードが丸ごと含まれているからこそ、その主張を受け入れる代わりに検証できるのです。

検証

レコードをハッシュして葉にし、各ステップで鍵のビットに従って左か右かを決めながら、兄弟ノードをルートへ 向けて畳み込みます。smt_root にたどり着けば、そのレコードはツリーがコミットしているものそのものです。

まだ 1 つ疑問が残ります。smt_root本物のルートでしょうか? BNB Smart Chain 上のアンカーコントラクトに 尋ねれば答えが出ます。Python、PHP、JavaScript のテスト済みコードとともに、両方の手順が 証明の検証にあります。