なぜ「小表モード」zkEVMがより効率的だと言われるのか?
著者:Fox Tech CEO 康水跃、Fox Tech CTO 林彦熹
前言:イーサリアム仮想マシンは、イーサリアムブロックチェーン上に構築されたコード実行環境であり、契約コードは外部から完全に隔離され、EVM内部で実行されます。その主な役割は、イーサリアムシステム内のスマートコントラクトを処理することです。イーサリアムがチューリング完全であると言われる理由は、開発者がSolidity言語を使用してEVM上で動作するアプリケーションを作成できるためであり、すべての計算可能な問題を計算できるからです。しかし、チューリング完全であるだけでは不十分で、人々はEVMをZK証明システムに封装しようとしていますが、問題は封装時に大量の冗長性が生じることです。Foxが発明した「小表モード」zkEVMは、ネイティブのSolidityイーサリアム開発者がzkEVMにシームレスに移行できることを保証しつつ、EVMをZK証明システムに封装する際に生じる冗長コストを大幅に削減します。
EVMは2015年の登場以来、史上最大のZK改造を経験しています。この大改造には主に2つの方向性があります。
1つ目の方向は、いわゆるzkVMトラックであり、このトラックプロジェクトはアプリケーションの性能を最適化することに専念しており、イーサリアム仮想マシンとの互換性は最優先事項ではありません。ここには2つのサブ方向があります。一つは独自のDSL(ドメイン特化言語)を作成することで、例えばStarkWareはCairo言語の普及に取り組んでおり、その難易度は高いです。もう一つは、既存の比較的成熟した言語との互換性を目指すことで、例えばRISC ZeroはzkVMをC++/Rustと互換性を持たせることに取り組んでいます。このトラックの難しさは、命令セットISAを導入することによって、最終的な出力の制約がより複雑になることです。
2つ目の方向は、いわゆるzkEVMトラックであり、このトラックプロジェクトはEVMバイトコードの互換性に専念しており、バイトコードレベルおよびそれ以上のEVMコードがZkEVMによって対応するゼロ知識証明を生成します。これにより、ネイティブのSolidityイーサリアム開発者は無コストでzkEVMに移行できるようになります。このトラックの選手には、Polygon zkEVM、Scroll、Taiko、Foxがあります。このトラックの難しさは、EVMのようなZK証明システムに封装するのに適さない冗長コストとの互換性です。Foxは長時間の思考と検証を経て、第一世代zkEVMの巨大な冗長性を根本的に削減する鍵を見つけました:「小表モード」zkEVM。
データと証明回路は、zkEVMが証明を生成するための2つの核心要素です。一方で、zkEVMでは、証明者はすべての取引に関与するデータを必要とし、取引による状態遷移が正しいことを証明する必要がありますが、EVM内のデータ量は多く、構造も複雑です。したがって、証明に必要なデータを整理し、組織する方法は、高効率のzkEVMを構築するために慎重に考慮すべき問題です。もう一方で、一連の回路制約を通じて計算実行の有効性と正確性を効率的に証明(または検証)する方法は、zkEVMの安全性を保証する基盤です。
まず、2つ目の問題について話しましょう。これはzkEVMを設計するすべてのチームが考慮すべき問題であり、この問題の本質は「私たちは一体何を証明する必要があるのか?」です。現在、皆がこの問題に対する考え方は似ています。取引(またはその関与するop-code)が多様であるため、各ステップの操作による状態変化が正しいことを順番に証明するのは現実的ではないため、分類して証明する必要があります。
図1: 大表、小表の2世代zkEVM解決策
例えば、スタック内の要素の変化を一つのブロックにまとめ、スタック回路を証明するために特別に作成し、単純な算術操作のために専用の算術回路を作成するなどです。こうすることで、各回路が考慮すべき状況は相対的に単純になります。これらの異なる機能の回路は、異なるzkEVMで異なる名前が付けられています。ある人はそれを回路と呼び、別の人は(サブ)状態機械と呼びますが、この考え方の本質は同じです。
このようにする意義をより明確に説明するために、例を挙げます。加算操作(スタックの上の2つの要素を取り出し、その和をスタックの頂点に戻す)を証明する必要があると仮定します:
元のスタックが[1,3,5,4,2]であるとします。
分類せずに分解しない場合、上記の操作を行った後、スタックが[1,3,5,6]に変わることを証明する必要があります。
しかし、分類して分解した場合、以下のことをそれぞれ証明するだけで済みます:
- スタック回路:
- C1:[1,3,5,4,2]から2と4をポップした後、[1,3,5]に変わることを証明
- C2:[1,3,5]にpush(6)した後、[1,3,5,6]に変わることを証明
- 算術回路:
- C3:a=2,b=4,c=6、a+b=cを証明
証明の複雑さは、回路が考慮すべきさまざまな状況の数に関連しています。分類せずに分解しない場合、回路がカバーする可能性は非常に巨大になります。
図2: 第一世代zkEVMが採用した大表モード
一旦分類して分解すれば、各部分の状況は相対的に単純になり、証明の難易度も大幅に減少します。
しかし、分類して分解することは他の問題も引き起こします。それは異なるカテゴリの回路間のデータの一貫性の問題です。例えば、上記の例では、実際には以下の2つのことを証明する必要があります:
- C4:「C1でポップされた数」 = 「C3のaとb」
- C5:「C2でプッシュされた数」 = 「C3のc」
この問題を解決するために、私たちは最初の問題に戻ります。つまり、取引に関与するデータをどのように整理するかです。以下でこのテーマを探求します:
直感的な方法は次のようになります:トレースを通じて、すべての取引に関与する各ステップを分解し、その関与するデータを把握し、ノードにリクエストを送信してトレースに含まれていないデータを取得します。その後、次のように大きな表Tに並べます:
「第一ステップ操作」 「第一ステップ操作に関与するデータ」
「第二ステップ操作」 「第二ステップ操作に関与するデータ」
…
「第nステップ操作」 「第nステップ操作に関与するデータ」
こうすることで、上記の例では、次のような行が記録されます:
「第kステップ:加算」 「a=2, b=4, c=6」
上記のC4は次のように証明できます:
- C4(a):C1でポップされた数と大表Tの第kステップが一致
- C4(a):C3のaとbと大表Tの第kステップが一致
C5も同様です。この操作(特定の要素が表に存在することを証明すること)はlookupと呼ばれます。lookupの具体的なアルゴリズムについては本稿では詳しく説明しませんが、lookup操作の複雑さは大表Tのサイズに密接に関連しています。したがって、再び最初の問題に戻ります:証明に使用するデータをどのように整理するか?
図3: Foxが発明した「小表モード」zkEVM
次のような一連の表を構築することを考えます:
表Ta:
「タイプaの最初の操作」 「タイプaの最初の操作に関与するデータ」
「タイプaの2番目の操作」 「タイプaの2番目の操作に関与するデータ」
…
「タイプaの第mの操作」 「タイプaの第mの操作に関与するデータ」
表Tb:
「タイプbの最初の操作」 「タイプbの最初の操作に関与するデータ」
「タイプbの2番目の操作」 「タイプbの2番目の操作に関与するデータ」
…
「タイプbの第mの操作」 「タイプbの第nの操作に関与するデータ」
…
このように複数の小表を構築することの利点は、必要なデータに関与する操作のタイプに基づいて、対応する小表で直接lookupを行うことができるため、効率を大幅に向上させることができる点です。
簡単な例(仮に毎回1つの要素しかlookupできないとします)は、a~hの8つの文字が[a,b,c,d,e,f,g,h]に存在することを証明する必要がある場合、サイズ8の表に対して8回のlookupを行う必要があります。しかし、表を[a,b,c,d]と[e,f,g,h]に分けると、サイズ4の2つの表に対してそれぞれ4回のlookupを行うだけで済みます!
FOXというレイヤー2のzkEVMでは、このような小表の設計を使用して効率を向上させています。さまざまな状況で完全な証明を保証するために、具体的な小表の分割方法は慎重に設計する必要があり、効率を向上させる鍵は表の内容の分類とそのサイズのバランスにあります。完全なzkEVMをこのフレームワーク内で実現するには膨大な作業量が必要ですが、私たちはこのようなzkEVMが性能面で画期的な進歩を遂げると期待しています。
結論:Foxが発明した「小表モード」zkEVMは、ネイティブのSolidityイーサリアム開発者が無コストでzkEVMに移行できることを保証しつつ、EVMをZK証明システムに封装する際に生じる冗長コストを大幅に削減します。これはzkEVM構造の重大な変革であり、イーサリアムのスケーリングソリューションに深遠な影響を与えるでしょう。