#dusk $DUSK @Dusk Duskのドキュメントを約40分間見つめながら、ずっと同じ問題を考えていました。MoonlightとPhoenix、この2つは結局どう収束するのだろうか。

Moonlightは公開アカウント方式のルートを取ります。残高、送金の送信者・受信者・金額までがチェーン上に書き込まれ、誰でも見られます。これは取引所への入金や、機関の照合など「透明性が必須」の場面に向いています。Phoenixはまったく別のロジックで、資産は暗号化されたnoteになり、Merkleツリーの中に隠されます。あなたが1回お金を使うとき、どのnoteを使ったのかは公開せず、nullifierとZKP証明を投げます。ネットワークはあなたが資金を持っていて二重使用していないことは検証できますが、金額や送信者は見えません。監査が必要なときは、viewing keyで選択的に開示できます。

月初にSEPA送金のメモを書いていたとき、似たような問題に触れました。2つの銀行システム間で照合すると、状態が一致しないだけでどれだけ厄介か。私はそのとき夜中の2時まで振り回されました。ブロックチェーンも2つの孤立した帳簿を別々に持つのなら、いっそ従来の金融のほうがまだマシです。

当時は少しイライラしていて、ドキュメントがこの点を十分に分かりやすく説明していないと感じました。Ruskモジュールのコントラクト設計の章をめくり、最初の2段落を読んでも、MoonlightとPhoenixそれぞれのデータ構造を説明しているだけで、特にピンときませんでした。ところが4段落目まで進んで、Transfer Contractのインターフェース定義に列挙型のpayloadが使われているのを見た瞬間、その設計意図がようやく腑に落ちました。

Transfer Contractは、調停(コーディネート)の入口です。さまざまな形式のpayloadを受け取ります。Moonlight形式もあり、Phoenix形式もあります。コントラクトは、あなたがどこから来たかは気にしません。payloadにどんなフィールドが入っているかだけを見て、対応する検証ロジックへ振り分けます。Moonlightの検証は公開アカウントの状態を直接読み、Phoenixの検証はZK proofを実行します。両方の検証が通ったら、結果を同じグローバル状態ツリーに書き込みます。私が長いこと考えてようやく分かった決定的なポイントは、2つの状態ツリーを1本に統合してしまえば、公開アカウントからプライバシーnoteへ1回送金するのは、本質的にはpayloadの変換にすぎない、ということです。ブリッジも不要で、複雑な同期プロトコルも不要。状態更新はアトミックで、全部成功するか、全部ロールバックされます。