メインコンテンツへスキップ

ページの最終更新日: 2026年2月26日

バークルツリー

バークルツリーはデータ構造であり、「ベクトルコミットメント」と「マークルツリー」を組み合わせた造語です。イーサリアムノードでは、アップグレードにより導入される予定です。バークルツリーを採用することで、ブロックの検証機能はそのままに、大量の状態データを保存する必要がなくなります。

ステートレス

バークルツリーは、ステートレスなイーサリアムクライアントの実現に欠かせない重要なステップです。 ステートレスクライアントは、受信したブロックを検証するために、状態データベース全体を格納する必要がありません。 クライアントがローカルに保存しているイーサリアムの状態のコピーを使用してブロックを検証する代わりに、ブロックに含まれる状態データの「ウィットネス」を使用します。 この「ウィットネス」は、特定の一連のトランザクションを実行するために必要な状態データの個々の部分を集めたもので、データ全体の一部であることを示す暗号学的証明になります。 ウィットネスは、状態データベースの_代わり_に使用されます。 ネットワーク全体に安全にブロードキャストするには、バリデータが12秒のスロット内に処理できる必要があります。そのためには、ウィットネスが非常に小さくなければなりません。 しかし、現在の状態データの構造では、ウィットネスが大きすぎるため、適していません。 バークルツリーは、小さなウィットネスを可能にすることで、この問題を解決します。これにより、ステートレスクライアントを実現するための、1つの大きな障害を克服することができます。

イーサリアムクライアントは現在、状態データを保存するためにパトリシア・マークル・ツリーと呼ばれるデータ構造を使用しています。 個々のアカウントに関する情報はツリー上のリーフとして保存され、そのリーフのペアが1つのハッシュになるまで繰り返しハッシュ化されます。 この最後のハッシュは、「ルート」と呼ばれます。 イーサリアムクライアントは、ブロック内のすべてのトランザクションを実行し、ローカルにある状態ツリーを更新することで、ブロックを検証します。 ローカルにあるツリーのルートが、ブロック提案者によって提供されたルートと同じであれば、ブロックは有効であると判断されます。なぜなら、ブロック提案者と検証ノードが異なる計算を実行した場合、ルートハッシュが完全に違うものになるためです。 問題は、ブロックチェーンを検証するために、各クライアントがブロックの先頭までの状態ツリー全体と複数の履歴ブロックを保持する必要があることです(Gethのデフォルト設定では、ヘッドから遡って128ブロックの状態データを保持します)。 現在の状態では、クライアントは大容量のディスク領域が必要になり、安価で低電力のハードウェアでフルノードを実行する際の障壁となります。 これに対する解決策は、より効率的な構造(バークルツリー)を持った状態ツリーを更新することです。バークルツリーでは、完全な状態データの代わりに、共有可能なデータである小さな「ウィットネス」を使うことで集約することができます。 状態データをバークルツリーに再フォーマットすることは、ステートレスクライアントへ移行するための足掛かりとなります。

ウィットネスの説明とその必要性

ブロックの検証では、ブロックに含まれるトランザクションを再実行し、その変更をイーサリアムの状態ツリーに適用することで、新しいルートハッシュを計算します。 検証されたブロックでは、その計算された状態ルートのハッシュがブロックで提供されたものと一致します。つまり、ブロックの提案者が本当にルートハッシュの計算を行ったことが確認できます。 現状のイーサリアムクライアントで状態を更新するには、状態ツリー全体にアクセスする必要があり、この巨大なデータ構造がローカルに保存されていなければなりません。 ウィットネスは、ブロック内のトランザクションを実行するために必要な状態データのフラグメントのみを含みます。 バリデータは、このフラグメントを使用して、ブロック提案者がブロックトランザクションを正しく実行し、状態が正常に更新されたかどうかを検証できます。 ただし、ウィットネスが各ノードにおいて12秒間のスロット内で安全に受信、処理されるためには、イーサリアムネットワーク上のピア間で十分な速度で転送する必要があります。 ウィットネスが大きすぎると、一部のノードにおいて、それをダウンロードしてチェーンを最新の状態を維持するのに時間がかかりすぎる可能性があります。 これでは、高速インターネット接続を持つノードのみがブロックの検証に参加できることになり、中央集権的な影響力を高めてしまいます。 バークルツリーでは、状態をハードドライブに保存する必要はありません。ブロックの検証に必要な_すべて_がブロック自体に含まれています。 残念ながら、マークルツリーから生成されるウィットネスは大きすぎるため、ステートレスクライアントをサポートできません。

バークルツリーが小さなウィットネスを可能にする仕組み

マークルツリーの構造では、ウィットネスのサイズが非常に大きくなるため、12秒間のスロット内では、ピア間で安全にブロードキャストすることができません。 これは、ウィットネスがリーフが持つデータからルートハッシュへ接続するパスであるためです。 データを確認するには、各リーフからルートに接続するための全ての中間ハッシュだけでなく、全ての「兄弟」ノードのハッシュを持っている必要があります。 証明内にある各ノードには、ツリーの一段階上へのハッシュを作成するためにハッシュされる兄弟ノードがあります。 これは非常に大きなデータになります。 バークルツリーは、ツリーのリーフとルートの距離を短縮し、ルートハッシュを検証するために兄弟ノードを提供する必要性をなくすことで、ウィットネスのサイズを削減します。 また、ハッシュ形式のベクトルコミットメントの代わりに強力な多項式コミットメント機構を利用することで、スペース効率がさらに向上します。 多項式コミットメントにより、ウィットネスが証明するリーフの数に関係なく、サイズを固定にすることができます。

多項式コミットメントスキームでは、ウィットネスが管理しやすいサイズになり、ピアツーピアネットワーク上で簡単に転送できます。 この仕組みにより、クライアントは、各ブロックの状態変化を最小限のデータで検証することができます。

ウィットネスのサイズは、含まれるリーフの数によって変わります。 例えば、1000枚のリーフを扱うウィットネスは、マークルツリーで約3.5MB(ツリーが7レベルと仮定しています)、 バークルツリーでは約150KB(ツリーが4レベルあると仮定します)となり、約23分の1に縮小できます。 このウィットネスのサイズ縮小により、ステートレスクライアントでも許容できる大きさになります。 多項式ウィットネスは、使用する具体的な多項式コミットメントに応じて、0.128kBから1kBの範囲です。

バークルツリーの構造

バークルツリーは(key,value)ペアであり、キーは31バイトの_ステム_と1バイトの_サフィックス_で構成される32バイトの要素です。 これらのキーは、_拡張_ノードと_内部_ノードに編成されます。 拡張ノードは、1つのステムを表すノードです。256個の子ノードがあり、それぞれ異なるサフィックスを持っています。 内部ノードも256個の子ノードを持っていますが、他の拡張ノードになることもあります。 バークルツリーとマークルツリー構造の主な違いは、バークルツリーの方がはるかにフラットなことです。 つまり、リーフとルートを結ぶ中間ノードが少ないため、証明を生成するために必要なデータが小さくなります。

バークルツリーの構造についての詳細 (opens in a new tab)

現在の進捗

バークルツリーのテストネットはすでに稼働していますが、バークルツリーをサポートするために必要なクライアントの更新はまだたくさん残っています。 コントラクトをテストネットにデプロイしたり、テストネットでクライアントを実行したりすることで、開発を進めるお手伝いができます。

Guillaume BalletによるCondrieuバークルテストネットの説明を見る (opens in a new tab)(Condrieuテストネットはプルーフ・オブ・ワークでしたが、現在はVerkle Gen Devnet 6テストネットに置き換えられていることに注意してください)。

参考リンク

ページの最終更新: 2026年2月26日

この記事は役に立ちましたか?