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

ネットワークレイヤー

最終更新: 2026年3月2日

イーサリアムは、何千ものノードからなるピアツーピアネットワークですが、標準プロトコルを使用して、複数のノード間で直接的に相互に通信できる必要があります。 「ネットワークレイヤー」とは、これらのノードが互いを見つけて情報を交換可能とする為のプロトコルが集まったものです。 イーサリアムのネットワークレイヤーには、特定のノード間でのリクエストとレスポンスの交換(1対1の通信)だけでなく、ネットワーク上での情報の「ゴシップ」(1対多の通信)も含まれます。 各ノードは、正しい情報を送受信するために、特定のネットワークルールを遵守する必要があります。

クライアントソフトウェアには2つの部分(実行クライアントとコンセンサスクライアント)があり、それぞれ独自のネットワークスタックを備えています。 他のイーサリアムノードと通信するだけでなく、実行クライアントとコンセンサスクライアントは互いに通信する必要があります。 このページでは、初心者向けに、この通信を可能にするプロトコルを説明をします。

実行クライアントは、実行レイヤーのピアツーピアネットワーク上でトランザクションをゴシップします。 これには、認証されたピア同士の暗号化通信が必要です。 ブロックを提案するバリデータが選ばれると、そのノードのローカルトランザクションプールからトランザクションがローカルRPC接続を介してコンセンサスクライアントに渡され、ビーコンブロックにパッケージ化されます。 コンセンサスクライアントはその後、ピアツーピアネットワーク上でビーコンブロックをゴシップします。 これは2つの別々のピアツーピアネットワークを必要とします。1つはトランザクションゴシップのための実行クライアントを接続するもので、もう1つはブロックゴシップのためのコンセンサスクライアントを接続するものです。

前提条件

このページを理解するには、Ethereumのノードとクライアントに関する知識が役立ちます。

実行レイヤー

実行レイヤーのネットワークプロトコルは、2つのスタックに分割されています:

  • ディスカバリースタック: UDP上に構築され、新しいノードがピアに接続できるようにする

  • DevP2Pスタック:TCP上に構築され、ノードが情報交換できるようにする

両スタックは、並列的に動作します。 ディスカバリースタックは新しいネットワーク参加者をネットワークに送り込み、DevP2Pスタックによって相互通信が可能になります。

ディスカバリー

ディスカバリーとは、ネットワークの他のノードを見つけるプロセスです。 これは、少数のブートノード(アドレスがクライアントにハードコード (opens in a new tab)されているため、クライアントがすぐに見つけてピアに接続できるノード)のセットを使用してブートストラップされます。 これらのブートノードは、新しいノードをピアのセットに追加するためにのみ存在します。これが唯一の目的で、チェーンの同期などの通常のクライアントタスクには参加せず、クライアントが初回起動した時にのみ使用されます。

ノードとブートノード間のインタラクションに使用されるプロトコルは、Kademlia (opens in a new tab)の修正版であり、分散ハッシュテーブル (opens in a new tab)を使用してノードのリストを共有します。 各ノードには、最も近いピアに接続するために必要な情報を含む、分散ハッシュテーブルのバージョンがあります。 この「近さ」とは地理的なものではありません。ここでの距離はノードのIDの類似性によって定義されるものです。 各ノードのテーブルは、セキュリティ機能として定期的に更新されます。 例えば、Discv5 (opens in a new tab)では、ディスカバリープロトコルのノードは、クライアントがサポートするサブプロトコルを表示する「広告」を送信することもでき、ピアは両者が通信に使用できるプロトコルについて取り決めることができます。

ディスカバリーは、PING-PONGから始まります。 ピンポンが成功すると、新しいノードはブートノードに「結合」されます。 ネットワークに入る新しいノードの存在をブートノードに通知する最初のメッセージはPINGです。 このPINGには、新しいノード、ブートノード、および有効期限のタイムスタンプに関するハッシュ化された情報が含まれています。 ブートノードはPINGを受信し、PINGのハッシュを含むPONGを返します。 PINGPONGのハッシュが一致すると、新しいノードとブートノードの間の接続が検証され、両者は「ボンディングされた」と言われます。

一度ボンディングされると、新しいノードはFIND-NEIGHBOURSリクエストをブートノードに送信できます。 ブートノードから返されるデータには、新しいノードが接続できるピアのリストが含まれています。 ノードがボンディングされていない場合、FIND-NEIGHBOURSリクエストは失敗するため、新しいノードはネットワークに参加できません。

新しいノードは、ブートノードから近隣ノードのリストを受け取ると、それぞれのノードとPING-PONGを開始します。 PING-PONGが成功すると、新しいノードとその隣接ノードが結合され、メッセージの交換が可能になります。

1クライアント起動 --> ブートノードに接続 --> ブートノードにボンディング --> 隣接ノードを発見 --> 隣接ノードにボンディング

実行クライアントは現在、Discv4 (opens in a new tab)ディスカバリープロトコルを使用しており、Discv5 (opens in a new tab)プロトコルへの移行が活発に行われています。

ENR: イーサリアムノードレコード

イーサリアムノードレコード(ENR)は、署名(合意されたアイデンティティスキームに従って作成されたレコードコンテンツのハッシュ)、レコードへの変更を追跡するシーケンス番号、そしてキー:値ペアの任意のリスト、という3つの基本要素を含むオブジェクトです。 これは、新しいピア間で識別情報を容易に交換できる将来性のあるフォーマットであり、Ethereumノードで推奨されるネットワークアドレスフォーマットです。

ディスカバリーがUDPで構築されている理由

UDPはエラーチェック、失敗したパケットの再送、接続の動的な開閉をサポートしません。UDPは、受信に成功したかどうかにかかわらず、単にターゲットに対して連続的な情報ストリームを送信するだけです。 こうした最小限の機能により、オーバーヘッドも最小限に抑えられ、接続は非常に高速になります。 ノードが単に自分の存在を知らせ、相手との正式な接続を確立するためのディスカバリーにとっては、UDPで十分に要件を満たすことができます。 しかし、ディスカバリー以外の残りのネットワークスタックにとっては、UDPでは目的を満たすことはできません。 ノード間の情報交換は非常に複雑であるため、再送信やエラーチェックなどに対応できる、より高機能なプロトコルが必要です。 TCPに付随する追加のオーバーヘッドは、まさにこうした追加機能として必要な要件を満たしています。 したがって、P2Pスタックの大部分はTCPで動作することになります。

DevP2P

DevP2Pは、それ自体がピアツーピアネットワークの確立と維持するためにイーサリアムが実装しているプロトコルのスタックをすべてを包括しています。 新しいノードがネットワークに参加した後、その相互作用はDevP2P (opens in a new tab)スタックのプロトコルによって規定されます。 これらはすべてTCP上にあり、RLPxトランスポートプロトコル、ワイヤプロトコル、およびいくつかのサブプロトコルが含まれています。 RLPx (opens in a new tab)は、ノード間のセッションを開始、認証、維持するためのプロトコルです。 RLPxはデータをノード間で送信するための最小限の構造にエンコードする非常にスペース効率の良いRLP (再帰的な長さのプレフィックス)を使ってメッセージをエンコードします。

2つのノード間のRLPxセッションは、最初の暗号化ハンドシェイクで始まります。 このプロセスには、ノードがauthメッセージを送信し、ピアによって検証されることが含まれます。 検証に成功すると、ピアはauth-acknowledgementメッセージを生成し、イニシエーター・ノードに返します。 これは、ノードが非公開で安全に通信できるようにするための鍵交換プロセスです。 暗号化ハンドシェイクが成功すると、両ノードに「Hello」メッセージを互いに「ワイヤ上」で送信するようにトリガーします。 Helloメッセージの交換に成功すると、ワイヤプロトコルが開始されます。

Helloメッセージには以下が含まれます。

  • プロトコルバージョン
  • クライアントID
  • ポート
  • ノードID
  • サポートされるサブプロトコルのリスト

これらは両ノード間で相互作用を成功させるために、共有される機能を定義し、通信を構成するのに必要な情報です。 各ノードがサポートするサブプロトコルのリストを比較し、両ノードに共通するものをセッションで使用できるようにするサブプロトコルネゴシエーションというプロセスがあります。

ワイヤプロトコルは、Helloメッセージとともに、接続が終了することを相手に警告する「切断」メッセージも送信することができます。 ワイヤプロトコルは、セッションを開いたままにするために定期的に送信されるPINGとPONGメッセージも含んでいます。 したがって、RLPxとワイヤプロトコルの交換は、ノード間の通信の基礎を確立し、特定のサブプロトコルに従って交換される有用な情報のための土台を提供します。

サブプロトコル

ワイヤープロトコル

ピアが接続され、RLPxセッションが開始されると、ワイヤプロトコルはピアがどのように通信するかを定義します。 当初、ワイヤプロトコルは、チェーンの同期、ブロックの伝搬、トランザクションの交換という3つの主要なタスクを定義していました。 しかし、イーサリアムがプルーフ・オブ・ステーク(PoS)に移行すると、ブロック伝搬とチェーン同期はコンセンサスレイヤーの一部となりました。 トランザクションの交換は、依然として実行クライアントの範疇にあります。 トランザクション交換とは、ノード間で保留中のトランザクションを交換し、ブロックビルダーが次のブロックに含めるためにそれらの一部を選択できるようにすることを指します。 これらのタスクに関する詳細情報は、こちら (opens in a new tab)でご覧いただけます。 これらのサブプロトコルをサポートするクライアントは、JSON-RPCを介してそれらを公開します。

les (ライトイーサリアムサブプロトコル)

これは、ライトクライアントの同期用の最小限のプロトコルです。 フルノードはインセンティブなしにライトクライアントにデータを提供する必要があるため、従来このプロトコルはほとんど使用されてきませんでした。 実行クライアントのデフォルトの動作では、lesを介してライトクライアントデータを提供しません。 詳細は、lesの仕様 (opens in a new tab)でご覧いただけます。

Snap

snapプロトコル (opens in a new tab)は、ピアが最近の状態のスナップショットを交換できるようにするオプションの拡張機能で、ピアがマークルツリーの中間ノードをダウンロードすることなくアカウントとストレージのデータを検証できるようにします。

Wit (ウィットネスプロトコル)

ウィットネスプロトコル (opens in a new tab)は、ピア間で状態のウィットネスを交換できるオプションの拡張機能で、クライアントをチェーンの先端に同期させるのに役立ちます。

Whisper

ウィスパーは、ブロックチェーンに情報を書き込むことなくピア間で安全なメッセージングを提供することを目的としたプロトコルです。 DevP2Pワイヤープロトコルの一部でしたが、現在は非推奨となっています。 同様の目的を持つ、その他の関連プロジェクト (opens in a new tab)も存在します。

コンセンサスレイヤー

コンセンサスクライアントは、仕様が異なる別のピアツーピアネットワークに参加します。 コンセンサスクライアントは、ピアから新しいブロックを受け取り、自分がブロックを提案する番が来たらブロードキャストできるよう、ブロック・ゴシップに参加する必要があります。 実行レイヤーと同様に、ノードがピアを見つけてブロックや認証などを取引するための安全なセッションを確立できるよう、まずディスカバリー・プロトコルが必要です。

ディスカバリー

実行クライアントと同様に、コンセンサスクライアントはピアを見つけるために、UDP上でdiscv5 (opens in a new tab)を使用します。 コンセンサスレイヤーにおけるdiscv5の実装は、discv5をlibP2P (opens in a new tab)スタックに接続するアダプターを含み、DevP2Pを非推奨にしているという点でのみ、実行クライアントの実装と異なります。 実行レイヤーのRLPxセッションは廃止され、libP2Pのノイズセキュアチャネル・ハンドシェイクが採用されています。

ENR

コンセンサスノードのENRには、ノードの公開鍵、IPアドレス、UDPポートおよびTCPポート、そして2つのコンセンサス固有のフィールド(アテステーションサブネットビットフィールドとeth2キー)が含まれます。 前者は、ノードが特定の認証ゴシップ・サブネットワークに参加しているピアを見つけやすくします。 eth2キーには、ノードが使用しているEthereumのフォークバージョンに関する情報が含まれており、ピアが正しいEthereumに接続していることを保証します。

libP2P

libP2Pスタックは、ディスカバリー後のすべての通信をサポートします。 クライアントは、ENRで定義されたIPv4および/またはIPv6でダイヤルおよびリッスンできます。 libP2Pレイヤーのプロトコルは、ゴシップとリクエスト/レスポンスのドメインに細分化されます。

ゴシップ

ゴシップドメインは、ネットワーク全体に直ぐに広まる必要のあるすべての情報を含みます。 これには、ビーコンブロック、証明、アテステーション、イグジット、スラッシングが含まれます。 これはlibP2Pゴシップサブ v1を使って送信され、受信・送信するゴシップペイロードの最大サイズなどの各ノードにローカルに保存されている様々なメタデータに依存します。 ゴシップドメインに関する詳細情報は、こちら (opens in a new tab)でご覧いただけます。

リクエスト/レスポンス

リクエスト/レスポンス・ドメインには、クライアントがピアに特定の情報を要求するためのプロトコルが含まれます。 例えば、あるルートハッシュに一致する特定のビーコンブロックや、スロット範囲内のビーコンブロックのリクエストなどがあります。 レスポンスは常にsnappy(圧縮アルゴリズムの一つ)圧縮されたSSZエンコードバイトとして返されます。

コンセンサスクライアントでRLPよりSSZが好まれる理由

SSZは、シンプル・シリアライゼーションの略です。 SSZは、固定オフセットを使うことで、構造全体をデコードすることなく、エンコードされたメッセージの個々の部分を簡単にデコードすることができます。これは、エンコードされたメッセージから特定の情報を効率的に取得できるため、コンセンサスクライアントにとって非常に便利な機能です。 また、マークルプロトコルと統合するように特別に設計されており、マークル化に関連した効率化も得られます。 コンセンサスレイヤーのハッシュはすべてマークルルートであるため、これは大きな改善となります。 また、SSZは値の一意性も保証します。

実行クライアントとコンセンサスクライアントの接続

コンセンサスクライアントと実行クライアントは、並列に動作します。 コンセンサスクライアントが実行クライアントに指示を出し、実行クライアントがコンセンサスクライアントにトランザクション・バンドルを渡してビーコンブロックに含めることができるように、両者は接続されている必要があります。 両クライアント間の通信は、ローカルRPC接続を使用して実現することができます。 'Engine-API' (opens in a new tab)として知られるAPIは、2つのクライアント間で送信される命令を定義します。 両クライアントは単一のネットワークIDの背後に位置するため、各クライアントの個別のキー(eth1キーとeth2キー)を含むENR(イーサリアムノードレコード)を共有します。

制御フローの概要を以下に示します。括弧内は関連するネットワークスタックです。

コンセンサスクライアントがブロックプロデューサーではない場合:

  • コンセンサスクライアントがブロック・ゴシップ・プロトコル(コンセンサスp2p)を介してブロックを受信する
  • コンセンサスクライアントはブロックを事前検証します。つまり、ブロックが正しいメタデータを持つ有効な送信者から送られてきたことを確認します。
  • ブロックのトランザクションが実行ペイロードとして実行レイヤーに送信される(ローカルRPC接続)
  • 実行レイヤーはトランザクションを実行し、ブロックヘッダーの状態を検証します (つまり、ハッシュが一致するかをチェックします)。
  • 実行レイヤーは検証データをコンセンサスレイヤーに返し、ブロックは検証済みとみなされる(ローカルRPC接続)
  • コンセンサスレイヤーはブロックを自分のブロックチェーンの先頭に追加して証明し、そのアテステーション(証明)をネットワーク上にブロードキャストする(コンセンサスp2p)

コンセンサスクライアントがブロックプロデューサーである場合:

  • コンセンサスクライアントが次のブロック生成者であることを通知される(consensus p2p)
  • コンセンサスレイヤーが実行クライアントのcreate blockメソッドを呼び出す (ローカルRPC)
  • 実行レイヤーは、トランザクション・ゴシップ・プロトコルによって生成されたトランザクション・メンプールにアクセスする(実行p2p)
  • 実行クライアントはトランザクションをブロックにまとめ、トランザクションを実行し、ブロックハッシュを生成する
  • コンセンサスクライアントは実行クライアントからトランザクションとブロックハッシュを取得し、ビーコンブロックに追加する(ローカルRPC)
  • コンセンサスクライアントは、ブロック・ゴシップ・プロトコルでブロックをブロードキャストする(コンセンサスp2p)
  • 他のクライアントが、ブロック・ゴシップ・プロトコルで提案されたブロックを受信し、上記のように検証する(コンセンサスp2p)

十分な数のバリデータによってブロックが認証されると、チェーンの先頭に追加され、正当性が確認された後、最終的に確定(ファイナライズ)される。

Ethereum コンセンサス クライアント ネットワーキング層の図 Ethereum 実行クライアント ネットワーキング層の図

ethresear.ch (opens in a new tab)より、コンセンサスクライアントと実行クライアントのネットワークレイヤー概略図

参考リンク

DevP2P (opens in a new tab) LibP2p (opens in a new tab) コンセンサスレイヤーのネットワーク仕様 (opens in a new tab) KademliaからDiscv5へ (opens in a new tab) Kademliaに関する論文 (opens in a new tab) Ethereum P2P入門 (opens in a new tab) eth1とeth2の関係 (opens in a new tab) マージとeth2クライアント詳細に関するビデオ (opens in a new tab)

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