フィードバックとレビューをしてくれた Yoav Weiss、Dan Finlay、Martin Koppelmann、Arbitrum、Optimism、Polygon、Scroll、SoulWallet チームに感謝します。
3つの移行に関するこの投稿では、L1 + Cross-L2のサポート、ウォレットのセキュリティ、プライバシーを、個々のウォレットで個別に設計できるアドオンとして構築するのではなく、エコシステムスタックに必要な基本機能として明示的に考え始めることが価値がある主な理由をいくつか概説しました。
この投稿では、L2 から L1 を、L1 から L2 を読みやすくする方法、または別の L2 から L2 を読みやすくする方法という、特定のサブ問題の技術的な側面にもっと直接的に焦点を当てます。 この問題を解決することは、アセットとキーストアの分離アーキテクチャを実装するために重要ですが、L1 と L2 の間でのアセットの移動などのユースケースなど、信頼性の高い L2 間呼び出しの最適化など、他の領域でも貴重なユースケースがあります。
L2 が主流になれば、ユーザーは複数の L2 にまたがり、場合によっては L1 にも資産を持つようになります。 スマートコントラクトウォレット(マルチシグ、ソーシャルリカバリーなど)が主流になると、アカウントにアクセスするために必要なキーは時間の経過とともに変化し、古いキーは無効になる必要があります。 この 2 つが実現すると、ユーザーは、非常に多くのトランザクションを行うことなく、さまざまな場所に存在する多くのアカウントにアクセスする権限を持つキーを変更する方法が必要になります。
特に、反事実的なアドレス、つまり、まだオンチェーンで「登録」されていないが、資金を受け取り、安全に保持する必要があるアドレスを処理する方法が必要です。 イーサリアムを初めて使用するとき、オンチェーンでアドレスを「登録」することなく、誰かが支払いに使用できるETHアドレスを生成することができます(これにはtxfeeを支払う必要があり、したがってすでにETHを保有しています)。
EOAでは、すべてのアドレスは反事実アドレスとして始まります。スマートコントラクトウォレットでは、主に CREATE2のおかげで、特定のハッシュに一致するコードを持つスマートコントラクトによってのみ埋めることができるETHアドレスを持つことができます。
EIP-1014 (CREATE2) アドレス計算アルゴリズム。
しかし、スマートコントラクトウォレットは、アクセスキーが変わる可能性という新たな課題をもたらします。 initcodeのハッシュであるアドレスには、ウォレットの初期検証キーのみを含めることができます。 現在の検証キーはウォレットのストレージに保存されますが、そのストレージレコードは魔法のように他のL2に伝播されません。
ユーザーが多くの L2 に多数のアドレスを持っていて、その中には (反事実であるため) 自分が属している L2 が認識していないアドレスも含まれている場合、ユーザーがキーを変更できるようにする方法は 1 つしかないように思われます。 各ユーザーは、(i) すべてのウォレットの検証キーとキー変更のルールを保存する「キーストアコントラクト」(L1 または特定の L2) と、(ii) L1 と多くの L2 の「ウォレットコントラクト」を持ち、クロスチェーンを読み取って検証キーを取得します。
これを実装するには、次の 2 つの方法があります。
その複雑さを余すところなく示すために、キーストアが1つのL2にあり、ウォレットが別のL2にあるという、最も難しいケースを探ります。 キーストアまたはウォレットのいずれかがL1にある場合、この設計の半分のみが必要です。
キーストアが Lineaにあり、ウォレットが Kakarotにあると仮定しましょう。 ウォレットの鍵の完全な証明は、次のもので構成されます。
ここには、実装に関する 2 つの主要なトリッキーな質問があります。
次の 5 つの主要なオプションがあります。
必要なインフラ工事とユーザーにとってのコストについて、私は大まかに次のようにランク付けしています。
「アグリゲーション」とは、各ブロック内のユーザーから提供されたすべてのプルーフを、それらすべてを組み合わせた大きなメタプルーフに集約するという考え方を指します。 これはSNARKとKZGでは可能ですが、Merkleブランチでは不可能です( Merkleブランチを少し組み合わせることができますが、実際にはlog(txs/block)/log(keystoreの総数)しか節約できないので、おそらくコストに見合う価値はありません)。
アグリゲーションは、スキームにかなりの数のユーザーがいて初めて価値を発揮するため、現実的には、バージョン1の実装でアグリゲーションを除外し、バージョン2で実装しても問題ありません。
これは単純で、 前のセクションの図 に直接従うだけです。 より正確には、各「証明」(あるL2を別のL2に証明する最大難易度の場合を想定)には、次のものが含まれます。
残念ながら、イーサリアムの状態証明は複雑ですが、 それらを検証するためのライブラリは存在し、これらのライブラリを使用すれば、このメカニズムを実装するのはそれほど複雑ではありません。
より大きな問題はコストです。 マークルプルーフは長く、残念ながらパトリシアツリーは必要以上に~3.9倍長くなっています(正確には、N個のオブジェクトを保持するツリーへの理想的なマークルプルーフの長さは32 log2(N)バイトであり、イーサリアムのパトリシアツリーは子1人あたり16枚の葉を持っているため、これらのツリーのプルーフは32 15 log16(N) ~= 125 log2(N)バイトの長さです)。 約 2 億 5,000 万 (~2²⁸) のアカウントを持つ州では、各証明は 125 * 28 = 3500 バイト、つまり約 56,000 ガスになり、さらにハッシュのデコードと検証のための追加コストがかかります。
2つのプルーフを合わせると、約100,000〜150,000ガス(トランザクションごとに使用される場合の署名検証は含まない)のコストがかかり、トランザクションあたりの現在の基本21,000ガスを大幅に上回ります。 しかし、証明がL2で検証されている場合、格差はさらに悪化します。 L2内の計算は、オフチェーンで、L1よりもはるかに少ないノードを持つエコシステムで行われるため、安価です。 一方、データは L1 に転記する必要があります。 したがって、比較は21000ガスと150,000ガスではありません。21,000 L2ガスと100,000 L1ガスです。
これが何を意味するかは、L1ガスコストとL2ガスコストの比較を見ることで計算できます。
現在、L1は単純な送信ではL2よりも約15〜25倍高く、トークンスワップでは20〜50倍高価です。 単純な送信は比較的データ量が多いですが、スワップは計算量がはるかに多いです。 したがって、スワップは、L1計算とL2計算のコストを概算するためのより良いベンチマークです。 これらすべてを考慮すると、L1計算コストとL2計算コストのコスト比を30倍と仮定すると、L2にマークルプルーフを付けると、おそらく50回の通常のトランザクションに相当するコストがかかることを意味します。
もちろん、バイナリマークルツリーを使用すると、コストを~4倍削減できますが、それでも、ほとんどの場合、コストは高すぎます - そして、イーサリアムの現在のヘクサリーステートツリーと互換性がなくなるという犠牲を払うことをいとわないのであれば、さらに良いオプションを探すのもいいかもしれません。
概念的には、ZK-SNARKの使用も理解しやすいです: 上の図 のマークル証明を、それらのマークル証明が存在することを証明するZK-SNARKに置き換えるだけです。 ZK-SNARKは、~400,000ガスの計算コストと約400バイトのコストがかかります(比較:基本的なトランザクションでは21,000ガスと100バイトですが、将来的には 圧縮で~25バイトに削減できます)。 したがって、計算の観点から見ると、ZK-SNARKのコストは現在の基本的なトランザクションの19倍であり、データの観点からは、ZK-SNARKのコストは現在の基本的なトランザクションの4倍、基本的なトランザクションの将来のコストの16倍です。
これらの数値はマークル証明よりも大幅に改善されていますが、それでもかなり高価です。 これを改善するには、(i)特殊目的のKZG証明、または(ii) ERC-4337アグリゲーション に似ていますが、より高度な数学を使用するアグリゲーションの2つの方法があります。 両方を調べることができます。
警告、このセクションは他のセクションよりもはるかに数学的です。 これは、汎用ツールを超えて、より安価になるために特別な目的のものを構築しているため、より多くの「内部」に進む必要があるためです。 深い数学が気に入らない場合は、 次のセクションに直接スキップしてください。
まず、KZGのコミットメントがどのように機能するかを要約します。
理解しておくことが重要な主なプロパティには、次のようなものがあります。
したがって、一定のサイズ制限はあるものの、増え続けるリストの最後に値を追加し続けることができる構造になっています(現実的には、数億が実行可能になる可能性があります)。 次に、それをデータ構造として使用して、(i) 各 L2 に保存され、L1 にミラーリングされる各 L2 のキー リストへのコミットメント、および (ii) イーサリアム L1 に格納され、各 L2 にミラーリングされる L2 キー コミットメントのリストへのコミットメントを管理します。
コミットメントを最新の状態に保つことは、コアL2ロジックの一部になるか、デポジットブリッジと引き出しブリッジを通じてL2コアプロトコルの変更なしで実装することができます。
したがって、完全な証明には次のものが必要です。
実際には、2つのKZGプルーフを1つにマージすることが可能なので、合計サイズはわずか100バイトになります。
1つの微妙な点に注意してください:キーリストはリストであり、状態のようなキー/値マップではないため、キーリストは位置を順番に割り当てる必要があります。 キーコミットメントコントラクトには、各キーストアをIDにマッピングする独自の内部レジストリが含まれており、各キーに対して、キーだけでなくハッシュ(キー、キーストアのアドレス)を格納して、特定のエントリがどのキーストアを参照しているかを他のL2と明確に通信します。
この手法の利点は、L2で非常に優れたパフォーマンスを発揮することです。 データは 100 バイトで、ZK-SNARK より ~4 倍短く、Merkle 証明よりも短いです。 計算コストは、主にサイズ2のペアリングチェック1個分、 つまり約119,000ガスです。 L1では、データは計算よりも重要ではないため、残念ながらKZGはマークル証明よりもやや高価です。
Verkle ツリーは基本的に、KZG コミットメント (または、より効率的でより単純な暗号化を使用できる IPA コミットメント) を互いに積み重ねることを含みます: 2⁴⁸ 値を格納するために、2²⁴ 値のリストに対して KZG コミットメントを行うことができ、それぞれが 2²⁴ 値に対する KZG コミットメントです。 Verkle ツリーは <a href="https://notes.ethereum.org/@vbuterin/verkle_tree_eip">強くなっています Verkleツリーはリストだけでなく、キーと値のマップを保持するためにも使用できるため、イーサリアムのステートツリーで考慮されます(基本的に、サイズ2²⁵⁶のツリーを作成しても、それを空にして、実際に埋める必要があるときにツリーの特定の部分だけを埋めることができます)。
Verkleの木がどのように見えるか。 実際には、IPA ベースのツリーの場合は各ノードの幅を 256 == 2⁸ に、KZG ベースのツリーの場合は 2²⁴ にすることができます。
Verkleの木の証明はKZGより幾分長い;長さは数百バイトになる場合があります。 また、特に多くの証明を1つにまとめようとすると、検証が難しくなります。
現実的には、Verkle 木はマークル木のようなものであると考えるべきですが、SNARKing を使用しない場合 (データ コストが低いため)、SNARKing を使用すると安価 (プルーバー コストが低いため) になります。
Verkle ツリーの最大の利点は、データ構造を調和させることができることです: Verkle 証明は、オーバーレイ構造なしで、L1 と L2 にまったく同じメカニズムを使用して、L1 または L2 の状態上で直接使用できます。 量子コンピューターが問題になるか、マークル分岐の証明が十分に効率的になったら、Verkleツリーを適切なSNARKフレンドリーなハッシュ関数を持つバイナリハッシュツリーにインプレースで置き換えることができます。
N人のユーザーがN個のトランザクション(より現実的には、N 個のERC-4337 UserOperations)を行い、N個のクロスチェーンクレームを証明する必要がある場合、それらのプルーフを集約することで、多くのガスを節約することができます:これらのトランザクションをブロックまたはブロックに入るバンドルに結合するビルダーは、それらのクレームのすべてを同時に証明する単一のプルーフを作成することができます。
これは、次のことを意味します。
3つのケースすべてで、証明にはそれぞれ数十万のガスしかかかりません。 ビルダーは、その L2 のユーザーのために、各 L2 でこれらのうちの 1 つを作成する必要があります。したがって、これを構築に役立てるには、スキーム全体が十分な使用率を持ち、複数の主要なL2の同じブロック内に少なくともいくつかのトランザクションが存在することが非常に多い必要があります。
ZK-SNARKを使用する場合、主な限界費用は、契約間で数字を渡すという単なる「ビジネスロジック」であるため、ユーザーあたり数千のL2ガスが必要になる可能性があります。 KZGマルチプルーフを使用する場合、証明者は、そのブロック内で使用されるキーストア保持L2ごとに48ガスを追加する必要があるため、ユーザーあたりのスキームの限界費用は、L2あたり(ユーザーごとではなく)さらに~800のL1ガスを追加します。 しかし、これらのコストは、必然的にユーザーあたり10,000個以上のL1ガスと数十万個のL2ガスを必要とする、集約しない場合のコストよりもはるかに低くなります。 Verkle ツリーの場合、ユーザーごとに約 100 から 200 バイトを追加して Verkle マルチプルーフを直接使用するか、Merkle ブランチの ZK-SNARK と同様のコストを持つが、証明がかなり安価である Verkle マルチプルーフの ZK-SNARK を作成できます。
実装の観点からは、バンドラーに ERC-4337 アカウント抽象化標準を使用してクロスチェーンプルーフを集約させるのがおそらく最善です。 ERC-4337には、ビルダーがUserOperationsの一部をカスタムの方法で集約するためのメカニズムがすでにあります。 BLSシグネチャアグリゲーションには<a href="https://hackmd.io/ @voltrevo /BJ0QBy3zi">実装されており、 他の圧縮形式 にもよりますが、L2のガスコストを1.5倍から3倍に削減できます。
以前のバージョンのERC-4337内のBLSアグリゲート署名のワークフローを示す<a href=" https://hackmd.io/@voltrevo /BJ0QBy3zi">BLSウォレット実装の投稿からの図。クロスチェーンプルーフを集約するワークフローは、おそらく非常によく似ています。
最後の可能性は、L2 が L1 を読み取る (L1 が L2 を読み取るのではなく) 場合にのみ使用できることですが、L2 を変更して、L1 のコントラクトを直接静的に呼び出せるようにすることです。
これは、オペコードまたはプリコンパイルを使用して行うことができ、宛先アドレス、ガス、およびコールデータを提供するL1への呼び出しを許可し、出力を返しますが、これらの呼び出しは静的呼び出しであるため、実際にはL1の状態を変更することはできません。 L2は、預金を処理するためにすでにL1を認識している必要があるため、そのようなことが実行されるのを根本的に止めるものは何もありません。これは主に技術的な実装上の課題です( L1への静的コールをサポートするためのOptimismのこのRFPを参照)。
キーストアが L1 にあり、L2 が L1 静的コール機能を統合している場合、証明はまったく必要ありません。 ただし、L2 が L1 静的コールを統合していない場合、またはキーストアが L2 上にある場合 (L1 が少しでも高価になりすぎてユーザーが使用できなくなると、最終的には L2 にならざるを得なくなる可能性があります)、証明が必要になります。
上記のすべてのスキームでは、L2 が最近の L1 状態ルートまたは最近の L1 状態全体にアクセスする必要があります。 幸いなことに、すべての L2 には、最近の L1 状態にアクセスするための機能がすでに備わっています。 これは、L1 から L2 に着信するメッセージ、特にデポジットを処理するために、このような機能が必要であるためです。
実際、L2 にデポジット機能がある場合は、その L2 をそのまま使用して、L1 のコントラクトを L2 のコントラクトに移動させることができます: L1 のコントラクトに BLOCKHASH オペコードを呼び出してもらい、それをデポジット メッセージとして L2 に渡すだけです。 完全なブロック ヘッダーを受信し、その状態ルートを L2 側で抽出できます。 ただし、すべての L2 が、最近の L1 状態全体または最近の L1 状態ルートに直接アクセスする明示的な方法を持つ方がはるかに優れています。
L2 が最新の L1 状態ルートを受信する方法を最適化する際の主な課題は、安全性と低レイテンシーを同時に実現することです。
さらに、反対方向(L1sがL2を読み取る)では、次のようになります。
トラストレスなクロスチェーン操作のためのこれらの速度の一部は、多くのDeFiユースケースでは許容できないほど遅いです。そのような場合は、より不完全なセキュリティモデルを持つより高速なブリッジが必要です。 ただし、ウォレットキーの更新のユースケースでは、トランザクションを時間単位で遅延させるのではなく、キーの変更を遅らせるため、より長い遅延が許容されます。 古いキーを長く保持する必要があります。 鍵が盗まれたために鍵を変更する場合は、かなりの期間の脆弱性がありますが、これは軽減できます。フリーズ機能を持つウォレットによって。
結局のところ、レイテンシーを最小化する最善の解決策は、L2 が最適な方法で L1 状態ルートの直接読み取りを実装し、各 L2 ブロック (または状態ルート計算ログ) に最新の L1 ブロックへのポインターが含まれているため、L1 が復帰した場合、L2 も復帰できることです。 キーストアコントラクトは、メインネット、またはZKロールアップであり、L1に迅速にコミットできるL2のいずれかに配置する必要があります。
L2 チェーンのブロックは、以前の L2 ブロックだけでなく、L1 ブロックにも依存できます。 L1 がこのようなリンクを通過すると、L2 も元に戻ります。 これは、シャーディングの初期の(じめじめした)バージョンが想定されていた方法でもあることは注目に値します。コードについては 、こちら を参照してください。
意外なことに、それほど多くはありません。 L3やバリディウムであれば、L1またはZKロールアップでキーストアを保有している限り、そこにウォレットを保有しても問題ありません。 必要なのは、チェーンがイーサリアムの状態のルーツに直接アクセスし、イーサリアムが再編成された場合は再編成し、イーサリアムがハードフォークされた場合はハードフォークを進んで行うという技術的および社会的コミットメントです。
興味深い研究課題の1つは、ある鎖が他の複数の鎖(例えば、鎖)に対してこの形式の接続を持つことがどの程度可能であるかを特定することです。 イーサリアムとZcash)。 イーサリアムやZcashが再編成された場合(イーサリアムやZcashがハードフォークされた場合はハードフォーク)、チェーンが再編成することに合意しても、ノードオペレーターとコミュニティは技術的・政治的依存関係が2倍になるのが一般的です。 したがって、このような手法を使用して他のいくつかのチェーンに接続することができますが、コストが増加します。 ZKブリッジに基づくスキームは、魅力的な技術的特性を持っていますが、51%攻撃やハードフォークに対して堅牢ではないという重要な弱点があります。もっと賢い解決策があるかもしれません。
理想的には、プライバシーも保護する必要があります。 同じキーストアによって管理されているウォレットが多数ある場合は、次の点を確認する必要があります。
これにより、いくつかの問題が発生します。
SNARKsでは、解決策は概念的に簡単です:証明はデフォルトで情報を隠蔽し、アグリゲーターはSNARKを証明するために再帰的なSNARKを生成する必要があります。
現在のこのアプローチの主な課題は、アグリゲーターが再帰的な SNARK を作成する必要があることですが、これは現在非常に遅いです。
KZGでは、<a href="https://notes.ethereum.org/@vbuterin/non_index_revealing_proof">this 出発点として、非インデックスを明らかにするKZG証明(コー キング論文 のその研究のより形式化されたバージョンも参照)に取り組みます。しかし、盲検証明の集約は未解決の問題であり、より注意が必要です。
残念ながら、L2 内から L1 を直接読み取るとプライバシーは保護されませんが、直接読み取り機能を実装することは、レイテンシーを最小限に抑えるため、また他のアプリケーションでの有用性のために非常に便利です。
フィードバックとレビューをしてくれた Yoav Weiss、Dan Finlay、Martin Koppelmann、Arbitrum、Optimism、Polygon、Scroll、SoulWallet チームに感謝します。
3つの移行に関するこの投稿では、L1 + Cross-L2のサポート、ウォレットのセキュリティ、プライバシーを、個々のウォレットで個別に設計できるアドオンとして構築するのではなく、エコシステムスタックに必要な基本機能として明示的に考え始めることが価値がある主な理由をいくつか概説しました。
この投稿では、L2 から L1 を、L1 から L2 を読みやすくする方法、または別の L2 から L2 を読みやすくする方法という、特定のサブ問題の技術的な側面にもっと直接的に焦点を当てます。 この問題を解決することは、アセットとキーストアの分離アーキテクチャを実装するために重要ですが、L1 と L2 の間でのアセットの移動などのユースケースなど、信頼性の高い L2 間呼び出しの最適化など、他の領域でも貴重なユースケースがあります。
L2 が主流になれば、ユーザーは複数の L2 にまたがり、場合によっては L1 にも資産を持つようになります。 スマートコントラクトウォレット(マルチシグ、ソーシャルリカバリーなど)が主流になると、アカウントにアクセスするために必要なキーは時間の経過とともに変化し、古いキーは無効になる必要があります。 この 2 つが実現すると、ユーザーは、非常に多くのトランザクションを行うことなく、さまざまな場所に存在する多くのアカウントにアクセスする権限を持つキーを変更する方法が必要になります。
特に、反事実的なアドレス、つまり、まだオンチェーンで「登録」されていないが、資金を受け取り、安全に保持する必要があるアドレスを処理する方法が必要です。 イーサリアムを初めて使用するとき、オンチェーンでアドレスを「登録」することなく、誰かが支払いに使用できるETHアドレスを生成することができます(これにはtxfeeを支払う必要があり、したがってすでにETHを保有しています)。
EOAでは、すべてのアドレスは反事実アドレスとして始まります。スマートコントラクトウォレットでは、主に CREATE2のおかげで、特定のハッシュに一致するコードを持つスマートコントラクトによってのみ埋めることができるETHアドレスを持つことができます。
EIP-1014 (CREATE2) アドレス計算アルゴリズム。
しかし、スマートコントラクトウォレットは、アクセスキーが変わる可能性という新たな課題をもたらします。 initcodeのハッシュであるアドレスには、ウォレットの初期検証キーのみを含めることができます。 現在の検証キーはウォレットのストレージに保存されますが、そのストレージレコードは魔法のように他のL2に伝播されません。
ユーザーが多くの L2 に多数のアドレスを持っていて、その中には (反事実であるため) 自分が属している L2 が認識していないアドレスも含まれている場合、ユーザーがキーを変更できるようにする方法は 1 つしかないように思われます。 各ユーザーは、(i) すべてのウォレットの検証キーとキー変更のルールを保存する「キーストアコントラクト」(L1 または特定の L2) と、(ii) L1 と多くの L2 の「ウォレットコントラクト」を持ち、クロスチェーンを読み取って検証キーを取得します。
これを実装するには、次の 2 つの方法があります。
その複雑さを余すところなく示すために、キーストアが1つのL2にあり、ウォレットが別のL2にあるという、最も難しいケースを探ります。 キーストアまたはウォレットのいずれかがL1にある場合、この設計の半分のみが必要です。
キーストアが Lineaにあり、ウォレットが Kakarotにあると仮定しましょう。 ウォレットの鍵の完全な証明は、次のもので構成されます。
ここには、実装に関する 2 つの主要なトリッキーな質問があります。
次の 5 つの主要なオプションがあります。
必要なインフラ工事とユーザーにとってのコストについて、私は大まかに次のようにランク付けしています。
「アグリゲーション」とは、各ブロック内のユーザーから提供されたすべてのプルーフを、それらすべてを組み合わせた大きなメタプルーフに集約するという考え方を指します。 これはSNARKとKZGでは可能ですが、Merkleブランチでは不可能です( Merkleブランチを少し組み合わせることができますが、実際にはlog(txs/block)/log(keystoreの総数)しか節約できないので、おそらくコストに見合う価値はありません)。
アグリゲーションは、スキームにかなりの数のユーザーがいて初めて価値を発揮するため、現実的には、バージョン1の実装でアグリゲーションを除外し、バージョン2で実装しても問題ありません。
これは単純で、 前のセクションの図 に直接従うだけです。 より正確には、各「証明」(あるL2を別のL2に証明する最大難易度の場合を想定)には、次のものが含まれます。
残念ながら、イーサリアムの状態証明は複雑ですが、 それらを検証するためのライブラリは存在し、これらのライブラリを使用すれば、このメカニズムを実装するのはそれほど複雑ではありません。
より大きな問題はコストです。 マークルプルーフは長く、残念ながらパトリシアツリーは必要以上に~3.9倍長くなっています(正確には、N個のオブジェクトを保持するツリーへの理想的なマークルプルーフの長さは32 log2(N)バイトであり、イーサリアムのパトリシアツリーは子1人あたり16枚の葉を持っているため、これらのツリーのプルーフは32 15 log16(N) ~= 125 log2(N)バイトの長さです)。 約 2 億 5,000 万 (~2²⁸) のアカウントを持つ州では、各証明は 125 * 28 = 3500 バイト、つまり約 56,000 ガスになり、さらにハッシュのデコードと検証のための追加コストがかかります。
2つのプルーフを合わせると、約100,000〜150,000ガス(トランザクションごとに使用される場合の署名検証は含まない)のコストがかかり、トランザクションあたりの現在の基本21,000ガスを大幅に上回ります。 しかし、証明がL2で検証されている場合、格差はさらに悪化します。 L2内の計算は、オフチェーンで、L1よりもはるかに少ないノードを持つエコシステムで行われるため、安価です。 一方、データは L1 に転記する必要があります。 したがって、比較は21000ガスと150,000ガスではありません。21,000 L2ガスと100,000 L1ガスです。
これが何を意味するかは、L1ガスコストとL2ガスコストの比較を見ることで計算できます。
現在、L1は単純な送信ではL2よりも約15〜25倍高く、トークンスワップでは20〜50倍高価です。 単純な送信は比較的データ量が多いですが、スワップは計算量がはるかに多いです。 したがって、スワップは、L1計算とL2計算のコストを概算するためのより良いベンチマークです。 これらすべてを考慮すると、L1計算コストとL2計算コストのコスト比を30倍と仮定すると、L2にマークルプルーフを付けると、おそらく50回の通常のトランザクションに相当するコストがかかることを意味します。
もちろん、バイナリマークルツリーを使用すると、コストを~4倍削減できますが、それでも、ほとんどの場合、コストは高すぎます - そして、イーサリアムの現在のヘクサリーステートツリーと互換性がなくなるという犠牲を払うことをいとわないのであれば、さらに良いオプションを探すのもいいかもしれません。
概念的には、ZK-SNARKの使用も理解しやすいです: 上の図 のマークル証明を、それらのマークル証明が存在することを証明するZK-SNARKに置き換えるだけです。 ZK-SNARKは、~400,000ガスの計算コストと約400バイトのコストがかかります(比較:基本的なトランザクションでは21,000ガスと100バイトですが、将来的には 圧縮で~25バイトに削減できます)。 したがって、計算の観点から見ると、ZK-SNARKのコストは現在の基本的なトランザクションの19倍であり、データの観点からは、ZK-SNARKのコストは現在の基本的なトランザクションの4倍、基本的なトランザクションの将来のコストの16倍です。
これらの数値はマークル証明よりも大幅に改善されていますが、それでもかなり高価です。 これを改善するには、(i)特殊目的のKZG証明、または(ii) ERC-4337アグリゲーション に似ていますが、より高度な数学を使用するアグリゲーションの2つの方法があります。 両方を調べることができます。
警告、このセクションは他のセクションよりもはるかに数学的です。 これは、汎用ツールを超えて、より安価になるために特別な目的のものを構築しているため、より多くの「内部」に進む必要があるためです。 深い数学が気に入らない場合は、 次のセクションに直接スキップしてください。
まず、KZGのコミットメントがどのように機能するかを要約します。
理解しておくことが重要な主なプロパティには、次のようなものがあります。
したがって、一定のサイズ制限はあるものの、増え続けるリストの最後に値を追加し続けることができる構造になっています(現実的には、数億が実行可能になる可能性があります)。 次に、それをデータ構造として使用して、(i) 各 L2 に保存され、L1 にミラーリングされる各 L2 のキー リストへのコミットメント、および (ii) イーサリアム L1 に格納され、各 L2 にミラーリングされる L2 キー コミットメントのリストへのコミットメントを管理します。
コミットメントを最新の状態に保つことは、コアL2ロジックの一部になるか、デポジットブリッジと引き出しブリッジを通じてL2コアプロトコルの変更なしで実装することができます。
したがって、完全な証明には次のものが必要です。
実際には、2つのKZGプルーフを1つにマージすることが可能なので、合計サイズはわずか100バイトになります。
1つの微妙な点に注意してください:キーリストはリストであり、状態のようなキー/値マップではないため、キーリストは位置を順番に割り当てる必要があります。 キーコミットメントコントラクトには、各キーストアをIDにマッピングする独自の内部レジストリが含まれており、各キーに対して、キーだけでなくハッシュ(キー、キーストアのアドレス)を格納して、特定のエントリがどのキーストアを参照しているかを他のL2と明確に通信します。
この手法の利点は、L2で非常に優れたパフォーマンスを発揮することです。 データは 100 バイトで、ZK-SNARK より ~4 倍短く、Merkle 証明よりも短いです。 計算コストは、主にサイズ2のペアリングチェック1個分、 つまり約119,000ガスです。 L1では、データは計算よりも重要ではないため、残念ながらKZGはマークル証明よりもやや高価です。
Verkle ツリーは基本的に、KZG コミットメント (または、より効率的でより単純な暗号化を使用できる IPA コミットメント) を互いに積み重ねることを含みます: 2⁴⁸ 値を格納するために、2²⁴ 値のリストに対して KZG コミットメントを行うことができ、それぞれが 2²⁴ 値に対する KZG コミットメントです。 Verkle ツリーは <a href="https://notes.ethereum.org/@vbuterin/verkle_tree_eip">強くなっています Verkleツリーはリストだけでなく、キーと値のマップを保持するためにも使用できるため、イーサリアムのステートツリーで考慮されます(基本的に、サイズ2²⁵⁶のツリーを作成しても、それを空にして、実際に埋める必要があるときにツリーの特定の部分だけを埋めることができます)。
Verkleの木がどのように見えるか。 実際には、IPA ベースのツリーの場合は各ノードの幅を 256 == 2⁸ に、KZG ベースのツリーの場合は 2²⁴ にすることができます。
Verkleの木の証明はKZGより幾分長い;長さは数百バイトになる場合があります。 また、特に多くの証明を1つにまとめようとすると、検証が難しくなります。
現実的には、Verkle 木はマークル木のようなものであると考えるべきですが、SNARKing を使用しない場合 (データ コストが低いため)、SNARKing を使用すると安価 (プルーバー コストが低いため) になります。
Verkle ツリーの最大の利点は、データ構造を調和させることができることです: Verkle 証明は、オーバーレイ構造なしで、L1 と L2 にまったく同じメカニズムを使用して、L1 または L2 の状態上で直接使用できます。 量子コンピューターが問題になるか、マークル分岐の証明が十分に効率的になったら、Verkleツリーを適切なSNARKフレンドリーなハッシュ関数を持つバイナリハッシュツリーにインプレースで置き換えることができます。
N人のユーザーがN個のトランザクション(より現実的には、N 個のERC-4337 UserOperations)を行い、N個のクロスチェーンクレームを証明する必要がある場合、それらのプルーフを集約することで、多くのガスを節約することができます:これらのトランザクションをブロックまたはブロックに入るバンドルに結合するビルダーは、それらのクレームのすべてを同時に証明する単一のプルーフを作成することができます。
これは、次のことを意味します。
3つのケースすべてで、証明にはそれぞれ数十万のガスしかかかりません。 ビルダーは、その L2 のユーザーのために、各 L2 でこれらのうちの 1 つを作成する必要があります。したがって、これを構築に役立てるには、スキーム全体が十分な使用率を持ち、複数の主要なL2の同じブロック内に少なくともいくつかのトランザクションが存在することが非常に多い必要があります。
ZK-SNARKを使用する場合、主な限界費用は、契約間で数字を渡すという単なる「ビジネスロジック」であるため、ユーザーあたり数千のL2ガスが必要になる可能性があります。 KZGマルチプルーフを使用する場合、証明者は、そのブロック内で使用されるキーストア保持L2ごとに48ガスを追加する必要があるため、ユーザーあたりのスキームの限界費用は、L2あたり(ユーザーごとではなく)さらに~800のL1ガスを追加します。 しかし、これらのコストは、必然的にユーザーあたり10,000個以上のL1ガスと数十万個のL2ガスを必要とする、集約しない場合のコストよりもはるかに低くなります。 Verkle ツリーの場合、ユーザーごとに約 100 から 200 バイトを追加して Verkle マルチプルーフを直接使用するか、Merkle ブランチの ZK-SNARK と同様のコストを持つが、証明がかなり安価である Verkle マルチプルーフの ZK-SNARK を作成できます。
実装の観点からは、バンドラーに ERC-4337 アカウント抽象化標準を使用してクロスチェーンプルーフを集約させるのがおそらく最善です。 ERC-4337には、ビルダーがUserOperationsの一部をカスタムの方法で集約するためのメカニズムがすでにあります。 BLSシグネチャアグリゲーションには<a href="https://hackmd.io/ @voltrevo /BJ0QBy3zi">実装されており、 他の圧縮形式 にもよりますが、L2のガスコストを1.5倍から3倍に削減できます。
以前のバージョンのERC-4337内のBLSアグリゲート署名のワークフローを示す<a href=" https://hackmd.io/@voltrevo /BJ0QBy3zi">BLSウォレット実装の投稿からの図。クロスチェーンプルーフを集約するワークフローは、おそらく非常によく似ています。
最後の可能性は、L2 が L1 を読み取る (L1 が L2 を読み取るのではなく) 場合にのみ使用できることですが、L2 を変更して、L1 のコントラクトを直接静的に呼び出せるようにすることです。
これは、オペコードまたはプリコンパイルを使用して行うことができ、宛先アドレス、ガス、およびコールデータを提供するL1への呼び出しを許可し、出力を返しますが、これらの呼び出しは静的呼び出しであるため、実際にはL1の状態を変更することはできません。 L2は、預金を処理するためにすでにL1を認識している必要があるため、そのようなことが実行されるのを根本的に止めるものは何もありません。これは主に技術的な実装上の課題です( L1への静的コールをサポートするためのOptimismのこのRFPを参照)。
キーストアが L1 にあり、L2 が L1 静的コール機能を統合している場合、証明はまったく必要ありません。 ただし、L2 が L1 静的コールを統合していない場合、またはキーストアが L2 上にある場合 (L1 が少しでも高価になりすぎてユーザーが使用できなくなると、最終的には L2 にならざるを得なくなる可能性があります)、証明が必要になります。
上記のすべてのスキームでは、L2 が最近の L1 状態ルートまたは最近の L1 状態全体にアクセスする必要があります。 幸いなことに、すべての L2 には、最近の L1 状態にアクセスするための機能がすでに備わっています。 これは、L1 から L2 に着信するメッセージ、特にデポジットを処理するために、このような機能が必要であるためです。
実際、L2 にデポジット機能がある場合は、その L2 をそのまま使用して、L1 のコントラクトを L2 のコントラクトに移動させることができます: L1 のコントラクトに BLOCKHASH オペコードを呼び出してもらい、それをデポジット メッセージとして L2 に渡すだけです。 完全なブロック ヘッダーを受信し、その状態ルートを L2 側で抽出できます。 ただし、すべての L2 が、最近の L1 状態全体または最近の L1 状態ルートに直接アクセスする明示的な方法を持つ方がはるかに優れています。
L2 が最新の L1 状態ルートを受信する方法を最適化する際の主な課題は、安全性と低レイテンシーを同時に実現することです。
さらに、反対方向(L1sがL2を読み取る)では、次のようになります。
トラストレスなクロスチェーン操作のためのこれらの速度の一部は、多くのDeFiユースケースでは許容できないほど遅いです。そのような場合は、より不完全なセキュリティモデルを持つより高速なブリッジが必要です。 ただし、ウォレットキーの更新のユースケースでは、トランザクションを時間単位で遅延させるのではなく、キーの変更を遅らせるため、より長い遅延が許容されます。 古いキーを長く保持する必要があります。 鍵が盗まれたために鍵を変更する場合は、かなりの期間の脆弱性がありますが、これは軽減できます。フリーズ機能を持つウォレットによって。
結局のところ、レイテンシーを最小化する最善の解決策は、L2 が最適な方法で L1 状態ルートの直接読み取りを実装し、各 L2 ブロック (または状態ルート計算ログ) に最新の L1 ブロックへのポインターが含まれているため、L1 が復帰した場合、L2 も復帰できることです。 キーストアコントラクトは、メインネット、またはZKロールアップであり、L1に迅速にコミットできるL2のいずれかに配置する必要があります。
L2 チェーンのブロックは、以前の L2 ブロックだけでなく、L1 ブロックにも依存できます。 L1 がこのようなリンクを通過すると、L2 も元に戻ります。 これは、シャーディングの初期の(じめじめした)バージョンが想定されていた方法でもあることは注目に値します。コードについては 、こちら を参照してください。
意外なことに、それほど多くはありません。 L3やバリディウムであれば、L1またはZKロールアップでキーストアを保有している限り、そこにウォレットを保有しても問題ありません。 必要なのは、チェーンがイーサリアムの状態のルーツに直接アクセスし、イーサリアムが再編成された場合は再編成し、イーサリアムがハードフォークされた場合はハードフォークを進んで行うという技術的および社会的コミットメントです。
興味深い研究課題の1つは、ある鎖が他の複数の鎖(例えば、鎖)に対してこの形式の接続を持つことがどの程度可能であるかを特定することです。 イーサリアムとZcash)。 イーサリアムやZcashが再編成された場合(イーサリアムやZcashがハードフォークされた場合はハードフォーク)、チェーンが再編成することに合意しても、ノードオペレーターとコミュニティは技術的・政治的依存関係が2倍になるのが一般的です。 したがって、このような手法を使用して他のいくつかのチェーンに接続することができますが、コストが増加します。 ZKブリッジに基づくスキームは、魅力的な技術的特性を持っていますが、51%攻撃やハードフォークに対して堅牢ではないという重要な弱点があります。もっと賢い解決策があるかもしれません。
理想的には、プライバシーも保護する必要があります。 同じキーストアによって管理されているウォレットが多数ある場合は、次の点を確認する必要があります。
これにより、いくつかの問題が発生します。
SNARKsでは、解決策は概念的に簡単です:証明はデフォルトで情報を隠蔽し、アグリゲーターはSNARKを証明するために再帰的なSNARKを生成する必要があります。
現在のこのアプローチの主な課題は、アグリゲーターが再帰的な SNARK を作成する必要があることですが、これは現在非常に遅いです。
KZGでは、<a href="https://notes.ethereum.org/@vbuterin/non_index_revealing_proof">this 出発点として、非インデックスを明らかにするKZG証明(コー キング論文 のその研究のより形式化されたバージョンも参照)に取り組みます。しかし、盲検証明の集約は未解決の問題であり、より注意が必要です。
残念ながら、L2 内から L1 を直接読み取るとプライバシーは保護されませんが、直接読み取り機能を実装することは、レイテンシーを最小限に抑えるため、また他のアプリケーションでの有用性のために非常に便利です。