見出し画像

zkEVM|zk-Rollupで一般的なDAppを構築する方法や設計上の課題


この記事は、EVM互換のzk-Rollupの構築を目指しているScroll Techが著した「zkEVM(https://hackmd.io/@yezhang/S1_KMMbGt)」の日本語訳です。


Scroll Techについて


Scroll Techは、強力な実証ネットワークを備えたEVM互換のzk-Rollupを構築することを目指しています。数ヶ月の調査の後、私たちは大きな技術的進歩を遂げました。この投稿では、進捗状況と更新情報を共有したいと思います。また、乗船しているすべての人を支援するために、問題の概要を示します。


Scroll Techの目標


以下の目標を設定します。


Scrollは、完全にEVM互換のzk-Rollupを構築します。

1つの簡潔な証明を通じてイーサリアムブロックの直接検証をサポートします。基本的な考え方は、EVM実行トレース内の各オペコードの整合性と整合性を検証することです。このようにして、L1スマートコントラクトをScrollにシームレスに移行できます。新しいzk対応のプリミティブを使用する代わりに、逆にビルドします—カスタマイズされた最適化を使用してネイティブEVMをサポートします。これにより、変更を加えることなく、既存のすべてのイーサリアムインフラストラクチャと互換性があるという大きな利点がもたらされます。


Scrollは、レイヤー2プルーフアウトソーシングを有効にして標準化します。



ローラーにゼロ知識証明を生成するようにインセンティブを与えることができる堅牢なアウトソーシングメカニズムを設計しました。このようなスキームを標準化して、より広範な一般的なオフチェーン計算に適合させます。これにより、新しいプルーフマーケットが開かれます。開発者にとってのもう1つの直接的な影響は、ガス制限を考慮せずにScrollで複雑なコントラクトを展開できることです。多くの新しいアプリケーションは、オンチェーンでコミットされた証明を使用してオフチェーンで有効にすることができます。私たちのチームはまた、これをサポートするために世界最速のGPUおよびASIC証明者を構築しました。長期的には、完全な分散化を実現し、MEVの影響を軽減する予定です。


Scrollは新しいプルーフシステムにアップグレードします。


5か月前に提案されたように、Scrollは新しい階層型ゼロ知識証明システムを採用します。最初のレイヤーは証明者効率が高くなります(カスタマイズされた回路最適化とハードウェア効率の証明アルゴリズム)。2番目のレイヤーは検証者の効率が高くなります(簡潔な証明とEVMに適した検証アルゴリズム)。既存のすべてのソリューションと比較して、EVMよりもさらに大きなプログラムやプライバシーなどのより多くの機能をサポートする可能性があります。


zkEVMについて


Vitalik Buterin、Barry Whitehat、Chih-Cheng Liang、Kobi Gurkan、GeorgiosKonstantopoulosのレビューと洞察に満ちたコメントに感謝します。



zk-Rollupは、非常に安価で安全なクラス最高のレイヤー2スケーリングソリューションである聖杯であると信じています。ただし、既存のzk-Rollupはアプリケーション固有であるため、zk-Rollup内で一般的な構成可能なDAppを構築し、既存のアプリケーションを移行することは困難です。一般的なEVM検証用のzk証明を生成できるzkEVMを紹介します。これにより、完全にEVM互換のzk-Rollupを構築できます。これは、既存のイーサリアムアプリケーションから簡単に移行できます。

この記事では、zkEVMの設計上の課題と、それが現在可能である理由を特定します。また、より具体的な直感を示し、ゼロから構築する方法の高レベルのアイデアについて説明します。


バックグラウンド



zk-Rollupは、イーサリアムに最適なスケーリングソリューションとして認識されています。イーサリアムレイヤー1と同じくらい安全で、他のすべてのレイヤー2ソリューションと比較してファイナライズ時間が最短です(詳細な比較はこちら)。


中長期的には、ZK-SNARKテクノロジーが向上するにつれて、すべてのユースケースでZKロールアップが優先されます。—ヴィタリック・ブテリン


zk-Rollupの基本的な考え方は、膨大な数のトランザクションを1つのRollupブロックに集約し、ブロックのオフチェーンの簡潔な証明を生成することです。次に、レイヤー1のスマートコントラクトは、証明を検証し、それらのトランザクションを再実行せずに、更新された状態を直接適用するだけで済みます。これにより、証明の検証は計算を再実行するよりもはるかに安価であるため、ガス料金を1桁節約できます。もう1つの節約は、データ圧縮によるものです(つまり、検証のために最小限のオンチェーンデータのみを保持します)


zk-Rollupは安全で効率的ですが、そのアプリケーションは依然として支払いとスワップに限定されています。次の2つの理由により、汎用DAppを構築するのは困難です。


まず、zk-RollupでDAppを開発する場合は、特別な言語(R1CSなど)を使用してすべてのスマートコントラクトロジックを作成する必要があります。必要な言語の構文が複雑であるだけでなく、そのためにはゼロ知識証明に関する非常に強力な専門知識が必要です。



第二に、現在のzk-Rollupは構成可能性をサポートしていません[1]。これは、異なるzk-Rollupアプリケーションがレイヤー2内で相互作用できないことを意味します。このような品質は、DeFiアプリケーションの構成可能性を著しく損ないます。



一言で言えば、zk-Rollupは開発者にとって使い勝手が悪く、今のところ機能が制限されています。



それが私たちが取り組みたい最大の問題です。ネイティブEVM検証を直接サポートすることで、最高の開発者エクスペリエンスを提供し、レイヤー2内の構成可能性をサポートして、既存のイーサリアムアプリケーションをそのままzk-Rollupに移行できるようにしたいと考えています。


zk-Rollupで一般的なDAppを構築する



zk-Rollupで一般的なDAppを構築する方法は2つあります。


1つは、さまざまなDApp用の特定用途向け回路(「ASIC」)を構築することです。



もう1つは、スマートコントラクトを実行するためのユニバーサルな「EVM」回路を構築することです。



「回路」とは、ゼロ知識証明で使用されるプログラム表現を指します。たとえば、hash(x)= yであることを証明したい場合は、回路形式を使用してハッシュ関数を書き直す必要があります。回路形式は非常に限定された式のみをサポートします(つまり、R1CSは加算と乗算のみをサポートします)。したがって、回路言語を使用してプログラムを作成することは非常に困難です。addとmulを使用して、すべてのプログラムロジック(if else、ループなどを含む)を構築する必要があります。


最初のアプローチでは、開発者はさまざまなDApp用に特化した「ASIC」回路を設計する必要があります。これは、ゼロ知識証明を使用する最も伝統的な方法です。各DAppは、カスタマイズされた回路設計により、オーバーヘッドが小さくなります。ただし、回路は「静的」であり、回路設計の強力な専門知識が必要なため、開発者の経験がひどいため、構成可能性の問題が発生します[2]。


2番目のアプローチでは、開発者に特別な設計や専門知識は必要ありません。このようなマシンベースの証明の高レベルの考え方は、すべてのプログラムが最終的にCPUで実行されるため、低レベルのCPUステップを検証するためにユニバーサルCPU回路を構築するだけで済みます。次に、このCPU回路を使用して、プログラムの実行を確認できます。このシナリオでは、プログラムはスマートコントラクトであり、CPUはEVMです。ただし、このアプローチは、オーバーヘッドが大きいため、過去数年間は一般的に採用されていません。たとえば、結果がadd1つのステップで正しいことを証明したいだけの場合でも、EVM回路全体のオーバーヘッドを許容する必要があります。実行トレースに数千のステップがある場合、証明者側では1000倍のEVM回路オーバーヘッドになります。[3]


最近、これら2つのアプローチに従ってzk証明を最適化するために多くの研究が行われています。たとえば、(i)新しいzkに適したプリミティブを提案します。つまり、Poseidonハッシュは回路でSHA256の100倍の効率を達成できます。(ii)効率を改善するための継続的な作業TinyRAMのような汎用の検証可能なVMの数、および(iii)Plookupのような汎用の最適化トリックの数の増加、さらに一般的にはより高速な暗号化ライブラリ。


当社では、以前の記事で、私たちは各DAPPのための「ASIC」回路を設計し、それらを暗号化の約束を介して通信できるように提案しています。ただし、コミュニティからのフィードバックに基づいて、優先順位を変更し、2番目のアプローチに続いて最初に一般的なEVM回路(いわゆる「zkEVM」)の構築に焦点を合わせます。zkEVMは、レイヤー1での開発とまったく同じ開発者エクスペリエンスを可能にします。設計の複雑さを開発者に任せる代わりに、それを引き継ぎ、カスタマイズされたEVM回路設計を通じて効率の問題を解決します。


zkEVMの設計上の課題



zkEVMを構築するのは難しいです。直感は何年もの間明らかですが、ネイティブEVM回路を正常に構築した人は誰もいません。TinyRAMとは異なり、次の理由により、zkEVMの設計と実装はさらに困難です。


まず、EVMでは楕円曲線のサポートが制限されています。現在のところ、EVMはBN254ペアリングのみをサポートしています。循環楕円曲線は直接サポートされていないため、証明再帰を実行するのは困難です。この設定では、他の特殊なプロトコルを使用することも困難です。検証アルゴリズムはEVMに対応している必要があります。



次に、EVMのワードサイズは256ビットです。 EVMは256ビット整数で動作しますが(ほとんどの通常のVMは32〜64ビット整数で動作します)、zk証明は素数フィールドで最も「自然に」機能します。回路内で「不整合フィールド演算」を実行するには、範囲証明が必要です。これにより、EVMステップごとに最大100の制約が追加されます。これにより、EVM回路のサイズが2桁大きくなります。



第3に、EVMには多くの特別なオペコードがあります。EVMは従来のVMとは異なり、のような多くの特別なオペコードがCALLあり、実行コンテキストとガスに関連するエラータイプもあります。これは、回路設計に新たな課題をもたらします。



第4に、EVMはスタックベースの仮想マシンです。SyncVM(zksync)とCario(starkware)アーキテクチャは、レジスタベースモデルに独自のIR / AIRを定義します。彼らは、スマートコントラクトコードを新しいzk対応のIRにコンパイルするための専用コンパイラを構築しました。彼らのアプローチは、ネイティブのEVM互換ではなく、言語互換です。スタックベースのモデルを証明し、ネイティブツールチェーンを直接サポートすることは困難です。



第5に、イーサリアムのストレージレイアウトは大きなオーバーヘッドを伴います。イーサリアムのストレージレイアウトは、Keccakと巨大なMPT [4 ]に大きく依存しています。どちらも、zkに対応しておらず、大きな証明オーバーヘッドがあります。たとえば、Keccakハッシュは回路内のPoseidonハッシュよりも1000倍大きくなります。ただし、Keccakを別のハッシュに置き換えると、既存のイーサリアムインフラストラクチャの互換性の問題が発生します。



第6に、マシンベースの証明には巨大なオーバーヘッドがあります。前述のすべての問題を適切に処理できる場合でも、完全なEVM回路を取得するには、それらを一緒に構成する効率的な方法を見つける必要があります。前のセクションで述べたように、のような単純なオペコードでさえadd、EVM回路全体のオーバーヘッドをもたらす可能性があります。



なぜ今可能ですか?



この分野の研究者による大きな進歩のおかげで、過去2年間でますます多くの効率の問題が解決され、zkEVMの証明コストは最終的に実現可能になりました!最大の技術改善は、次の側面からもたらされます。


多項式コミットメントの使用。過去数年間、ほとんどの簡潔なゼロ知識証明プロトコルは、アプリケーション固有の信頼できるセットアップでエンコードされたPCPクエリを使用してR1CSに固執しています。通常、回路サイズは大きくなり、各制約の次数は2である必要があるため、多くのカスタマイズされた最適化を行うことはできません(双線形ペアリングでは、指数で1回の乗算しかできません)。多項式ビットコミットメント、あなたはユニバーサル設定、あるいは透明セットアップをどの程度にあなたの制約を持ち上げることができます。これにより、バックエンドの選択に大きな柔軟性がもたらされます。



ルックアップテーブルの引数とカスタマイズされたガジェットの外観。もう1つの強力な最適化は、ルックアップテーブルの使用によるものです。最適化は最初にAryaで提案され、次にPlookupで最適化されます。これにより、zkに適さないプリミティブ(つまり、AND、XORなどのビット演算)の多くを節約できます。カスタマイズされたガジェットを使用すると、高度な制約を効率的に実行できます。TurboPlonkとUltraPlonkは、ルックアップテーブルの使用とカスタマイズされたガジェットの定義を容易にするために、エレガントなプログラム構文を定義しています。これは、EVM回路のオーバーヘッドを削減するのに非常に役立ちます。



再帰的な証明はますます実行可能です。再帰的証明は、特別なペアリングに適した周期的楕円曲線(つまり、MNT曲線ベースの構築)に依存しているため、過去には大きなオーバーヘッドがありました。これにより、大きな計算オーバーヘッドが発生します。しかし、より多くの技術が効率を犠牲にすることなくこれを可能にしています。たとえば、Haloはペアリングに適した曲線の必要性を回避し、特別な内積引数を使用して再帰のコストを償却できます。Aztecは、既存のプロトコルのプルーフアグリゲーションを直接実行できることを示しています(ルックアップテーブルを使用すると、非ネイティブフィールド操作のオーバーヘッドを削減できるため、検証回路を小さくできます)。サポートされている回路サイズのスケーラビリティを大幅に向上させることができます。



ハードウェアアクセラレーションにより、証明がより効率的になります。私たちの知る限りでは、証明者向けに最速のGPUおよびASIC / FPGAアクセラレータを作成しました。ASIC証明者について説明した私たちの論文は、今年最大のコンピューター会議(ISCA)ですでに受け入れられています。GPU証明者は、ファイルコインの実装よりも約5倍から10倍高速です。これにより、証明者の計算効率を大幅に向上させることができます。



では、どのように機能し、どのように構築するのでしょうか。



強力な直感とテクノロジーの向上に加えて、より具体的なアーキテクチャを証明して理解するために何が必要かについて、より明確なアイデアを得る必要があります。フォローアップ記事で、より技術的な詳細と比較を紹介します。ここでは、全体的なワークフローといくつかの重要なアイデアについて説明します。


開発者とユーザーのためのワークフロー



開発者は、EVM互換の言語を使用してスマートコントラクトを実装し、コンパイルされたバイトコードをScrollにデプロイできます。次に、ユーザーはトランザクションを送信して、デプロイされたスマートコントラクトと対話できます。ユーザーと開発者の両方のエクスペリエンスはレイヤー1とまったく同じになります。ただし、ガス料金は大幅に削減され、トランザクションはScrollで即座に事前確認されます(撤回は完了するのに数分しかかかりません)。


zkEVMのワークフロー



外部のワークフローが同じままであっても、レイヤー1とレイヤー2の基本的な処理手順は完全に異なります。


レイヤー1は、スマートコントラクトの再実行に依存しています。
レイヤ2は、zkEVM回路の有効性の証明に依存しています。
レイヤー1とレイヤー2のトランザクションで状況がどのように異なるかについて、より詳細に説明しましょう。


レイヤー1では、デプロイされたスマートコントラクトのバイトコードがイーサリアムストレージに保存されます。トランザクションはP2Pネットワークでブロードキャストされます。トランザクションごとに、各フルノードは対応するバイトコードをロードしてEVMで実行し、同じ状態に到達する必要があります(トランザクションは入力データとして使用されます)。


レイヤー2では、バイトコードもストレージに格納され、ユーザーは同じように動作します。トランザクションは、オフチェーンで一元化されたzkEVMノードに送信されます。次に、バイトコードを実行するだけでなく、zkEVMは簡潔な証明を生成して、トランザクションの適用後に状態が正しく更新されたことを証明します。最後に、レイヤー1コントラクトは、トランザクションを再実行せずに、証明を検証し、状態を更新します。


実行プロセスを詳しく見て、1日の終わりにzkEVMが何を証明する必要があるかを見てみましょう。ネイティブ実行では、EVMはバイトコードをロードし、バイトコード内のオペコードを最初から1つずつ実行します。各オペコードは、次の3つのサブステップを実行すると考えることができます。(i)スタック、メモリ、またはストレージから要素を読み取る(ii)それらの要素に対して何らかの計算を実行する(iii)結果をスタック、メモリ、またはストレージに書き戻す。[5]たとえば、addオペコードはスタックから2つの要素を読み取り、それらを合計して、結果をスタックに書き戻す必要があります。


したがって、zkEVMの証明には、実行プロセスに対応する次の側面が含まれている必要があることは明らかです。


バイトコードは永続ストレージから正しくロードされます(指定されたアドレスからロードされた正しいオペコードを実行しています)


バイトコード内のオペコードは一貫して1つずつ実行されます


(バイトコードは、オペコードを見逃したりスキップしたりすることなく、順番に実行されます)


各オペコードは正しく実行されます(各オペコードの3つのサブステップが正しく実行されます、R / W +計算)


zkEVMデザインのハイライト


zkEVMのアーキテクチャを設計するときは、前述の3つの側面を1つずつ処理/対処する必要があります。


暗号化アキュムレータの回路を設計する必要があります。


この部分は「検証可能なストレージ」のように機能します。正しく読んでいることを証明するためのテクニックが必要です。これを効率的に実現するには、暗号化アキュムレータを使用できます。[6]



例としてマークルツリーを取り上げましょう。デプロイされたバイトコードは、リーフとしてマークルツリーに保存されます。次に、ベリファイアは、簡潔な証明を使用して、指定されたアドレスからバイトコードが正しくロードされていることを確認できます(つまり、回路内のマークルパスを確認します)。FまたはEthereumストレージの場合、回路はMerkle PatriciaTrieおよびKeccakハッシュ関数と互換性がある必要があります。


バイトコードを実際の実行トレースにリンクする回路を設計する必要があります。


バイトコードを静的回路に移動する際の問題の1つは、(スマートコントラクトのelseステートメントの場合はループに対応する)のような条件付きオペコードjumpです。どこにでもジャンプできます。特定の入力でバイトコードを実行する前に、宛先は決定されません。これが、実際の実行トレースを検証する必要がある理由です。実行トレースは「展開されたバイトコード」と考えることができ、実際の実行順序でオペコードのシーケンスが含まれます(つまり、別の位置にジャンプすると、トレースには宛先のオペコードと位置が含まれます)。


証明者は、回路の証人として実行トレースを直接提供します。提供された実行トレースが、特定の入力を使用してバイトコードから「展開」されたものであることを証明する必要があります。アイデアは、プログラムカウンターの値を一貫させることです。未定の目的地に対処するために、アイデアは証明者にすべてを提供させることです。次に、ルックアップ引数を使用して一貫性を効率的にチェックできます(つまり、適切なグローバルカウンターを持つオペコードが「バス」に含まれていることを証明します)。


各オペコードの回路を設計する必要があります(各オペコードの読み取り、書き込み、および計算が正しいことを証明してください)。


これは最も重要な部分です—実行トレースの各オペコードが正しく一貫していることを証明します。すべてのものを直接まとめると、大きなオーバーヘッドが発生します。ここでの重要な最適化のアイデアは、


・R / Wと計算を2つの証明に分けることができます。すべてのオペコードに必要な要素を「バス」にフェッチします。もう1つは、「バス」からの要素に対して実行された計算が正しく実行されていることを証明します。これにより、各部分のオーバーヘッドを大幅に削減できます(つまり、計算証明でEVMストレージ全体を考慮する必要はありません)。詳細な仕様、最初のものは、「状態の証明」と呼ばれ、2つ目は、「EVM証明」と呼ばれます。もう1つの観察結果は、「バスマッピング」はルックアップ引数によって効率的に処理できることです。



・オペコードごとに高度にカスタマイズされた制約を設計できます(つまり、EVMワードは、いくつかのチャンクに切り刻むことで効率的に解決できます)。必要に応じて、セレクター多項式を使用して制約を「開く」かどうかを選択できます。これにより、各ステップでEVM回路全体のオーバーヘッドを回避できます。



このアーキテクチャは、最初にイーサリアム財団によって指定されています。それはまだ初期段階であり、活発な開発が行われています。私たちはこれについて彼らと緊密に協力して、EVM回路を実装するための最良の方法を見つけています。これまでのところ、最も重要な特性が定義されており、いくつかのオペコードがすでにここに実装されています(Halo2リポジトリのUltraPlonk構文を使用)。詳細については、フォローアップ記事で紹介します。興味のある読者には、このドキュメントを読んでもらいます。開発プロセスは透過的になります。これは、コミュニティの努力と完全にオープンソースの設計になります。より多くの人々がこれに参加し、貢献できることを願っています。


他に何をもたらすことができますか?


zkEVMは、単なるレイヤー2スケーリング以上のものです。これは、レイヤー1の有効性証明を介してイーサリアムレイヤー1をスケーリングする直接的な方法と考えることができます。つまり、特別なレイヤー2なしで既存のレイヤー1をスケーリングできます。


たとえば、zkEVMをフルノードとして使用できます。証明は、既存の状態間の遷移を直接証明するために使用できます—レイヤー2に何も移植する必要はなく、すべてのレイヤー1トランザクションを直接証明できます。より広義には、zkEVMを使用して、ミナのようなイーサリアム全体の簡潔な証明を生成できます。追加する必要があるのは、証明の再帰(つまり、ブロックの検証回路をzkEVMに埋め込む)だけです[7]。


結論


zkEVMは、開発者とユーザーに同じエクスペリエンスを提供できます。セキュリティを犠牲にすることなく、桁違いに安価です。モジュール方式で構築するためのアーキテクチャが提案されています。ゼロ知識証明の最近の進歩を活用して、オーバーヘッドを削減します(カスタマイズされた制約、ルックアップ引数、証明の再帰、ハードウェアアクセラレーションなど)。より多くの人々がzkEVMコミュニティの取り組みに参加し、ブレインストーミングを行うのを楽しみにしています。


:スクロール: 私たちについて少し



Scroll Techは、新しく設立されたテクノロジー主導の会社です。強力な実証ネットワークを備えたEVM互換のzk-Rollupの構築を目指しています(概要はこちらをご覧ください)。現在、チーム全体が開発に注力しています。私たちはより情熱的な開発者を積極的に採用しています。hr@ scroll.techまでご連絡ください。技術的な内容について質問がある場合は、yezhang @ scroll.techまでご連絡ください。DMもオープンしています。


脚注


[1]:Starkwareは、数日前に構成可能性を達成したと主張しています(ここを参照)

[2]:回路は固定されており、静的です。たとえば、プログラムを回路として実装する場合、可変上限ループを使用することはできません。上限は最大値に固定する必要があります。動的ロジックを処理することはできません。

[3]:より明確にするために、ここではEVM回路のコストについて詳しく説明します。前に説明したように、回路は固定されて静的です。したがって、EVM回路にはすべての可能なロジック(純粋なものより10000倍大きいadd)が含まれている必要があります。つまり、証明したいだけのadd場合でも、EVM回路で可能なすべてのロジックのオーバーヘッドを許容する必要があります。コストが10000倍になります。実行トレースには、証明する一連のオペコードがあり、各オペコードには非常に大きなオーバーヘッドがあります。

[4]:EVM自体はMerklePatriciaツリーに緊密にバインドされていません。MPTは、今のところイーサリアムの状態が保存される方法です。別のものを簡単に接続できます(つまり、MPTをVerkleツリーに置き換えるという現在の提案)。

[5]:これは非常に単純化された抽象化です。技術的には、「EVM状態」のリストは、PC、残りのガス、コールスタック(上記のすべてに加えて、スタック内のコールごとのアドレスと静的性)、ログのセット、およびトランザクションスコープの変数(ウォームストレージスロット、払い戻し、自己破壊)。構成可能性は、さまざまな呼び出しコンテキストの追加の識別子を使用して直接サポートできます。

[6]:ストレージが大きいため、ストレージにはアキュムレータを使用します。メモリとスタックには、編集可能なPlookupを使用できます(「RAM」はこの方法で効率的に実装できます)。

[7]:zkEVM回路に完全な再帰的証明を追加することは簡単ではありません。再帰を実行する最良の方法は、依然として周期的な楕円曲線(つまり、パスタ曲線)を使用することです。イーサリアムレイヤー1で検証できるようにするには、「ラッピング」プロセスが必要です。


この記事が気に入ったらサポートをしてみませんか?