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

ブロック

最終編集者: @HiroyukiNaito(opens in a new tab), 2024年5月26日

ブロックとは、チェーンの1つ前のハッシュとトランザクションのバッチのことです。 ハッシュはブロックデータから暗号的に生成されるため、チェーンのブロックはお互いに繋がっています。 前のブロックのハッシュを用いるため、どれかのブロックが改ざんされるとデータの整合性が取れなくなるため、ブロックチェーンを実行しているすべての人が改ざんに気づくことになります。

前提知識

この記事は初心者向けに記載していますが、 より理解を深めるために、まずアカウントトランザクションそしてイーサリアムの導入を読むことをお勧めします。

ブロックを使用する背景

ブロックはすべてのイーサリアムネットワークへの参加者が同期された状態を維持し、トランザクションの正確な履歴に同意できるように、複数のトランザクションをブロックにバッチとして格納します。 これは、何十件(もしくは数百) ものトランザクションが一度にコミット、合意、同期されることを意味します。

状態の変更を引き起こすブロック内のトランザクションを示す図 イーサリアムEVM(opens in a new tab)からの図解

コミットの間隔をあけ、すべてのネットワーク参加者がコンセンサスに至るまでの十分な時間を確保しています。たとえトランザクション要求が毎秒数十回発生したとしても、ブロックはイーサリアム上で12秒に1回生成され、コミットされます。

ブロックの仕組み

トランザクション履歴を保持するため、ブロックは厳密に順序付けられ、作成されたすべての新規ブロックに親ブロックへの参照(ハッシュ)が含まれます。 同様に、ブロック内のトランザクションも厳密に順序付けられています。 まれな例外を除き、 常時ネットワーク上のすべての参加者は、正確な数のブロックとその履歴に合意しており、現在のトランザクションリクエストを次のブロックにバッチ処理しています。

ランダムに選ばれたバリデータがブロックをまとめると、そのブロックは残りの他のネットワークに伝播されます。すべてのノードはこのブロックをブロックチェーンの最後尾に追加します。そして、新しいバリデータが選ばれ、次のブロックを生成します。 このブロック生成とコミットメント/コンセンサスプロセスは、現在イーサリアム「プルーフ・オブ・ステーク (PoS) 」プロトコルによって定義されています。

プルーフ・オブ・ステーク(PoS)プロトコル

プルーフ・オブ・ステークとは、以下のことを意味します。

  • 検証を行うノードは、不正行為をしない担保として、デポジットコントラクトに32 ETHのステーキングが必要。 明らかに不誠実な行為を行うと、担保のステーキングの一部またはすべてが失うことになるため、ネットワークの保護を目的としている。
  • すべてのスロット(12秒間隔)において、ランダムに1つのバリデータがブロックの提案者として選出される。 選ばれたバリデータが、トランザクションを1つにまとめ、実行し新たな「状態」を決定し、 この情報をブロックに格納し、他のバリデータに渡す。
  • 新しいブロックに関する情報を受け取った他のバリデータは、トランザクションを再実行し、グローバル状態への変更提案について同意することを確認する。 ブロックが有効であった場合、それを自分のデータベースに追加する。
  • バリデータが同一スロットで2つの競合するブロックの情報を受け取った場合は、フォーク・チョイス・アルゴリズムを使用して、最も多額のETHステーキングにより支持されている方を選択する。

プルーフ・オブ・ステーク(PoS)の詳細

ブロックが保持するパラメータ

ブロックにはたくさんの情報が含まれており、 大まかには、以下のようなフィールドがあります。

フィールド説明
スロット (slot)ブロックが所属するスロット
proposer_indexブロックを提案するバリデータのID
parent_root先行ブロックのハッシュ値
state_root状態オブジェクトのルートハッシュ
規格の概要以下に定義されているように、複数のフィールドを含むオブジェクト

ブロックのbodyには独自のフィールドがいくつかあります。

フィールド説明
randao_reveal次のブロック提案者の選択に使用される値
eth1_dataデポジットコントラクトの情報
グラフィティブロックのタグ付けに使われる任意のデータ
proposer_slashingsスラッシュされるバリデータのリスト
attester_slashingsスラッシュされる証明者のリスト
アテステーション現在のブロックに賛成しているアテステーションのリスト
入金デポジットコントラクトに対する新しい入金のリスト
voluntary_exitsネットワークに存在するバリデータのリスト
sync_aggregateライトクライアントへの提供に使用されるバリデータのサブセット
execution_payload実行クライアントから渡されるトランザクション

attestationsフィールドには、ブロック内のすべてのアテステーションのリストが含まれます。 アテステーションは、複数のデータを含むそれぞれの独自のデータ型があり、 それぞれのアテステーションには以下が含まれています。

フィールド説明
aggregation_bitsこのアテステーションに参加しているバリデータのリスト
データ複数のサブフィールドを持つコンテナ
署名証明する全バリデータによる署名の集約 

attestationdataフィールドには、以下が含まれます。

フィールド説明
スロット (slot)アテステーションに関連するスロット
インデックス証明するバリデータのインデックス
beacon_block_rootこのオブジェクトを含むビーコンブロックのルートハッシュ
情報源最後に正当化されたチェックポイント
target最新のエポック境界ブロック

execution_payloadのトランザクションを実行すると、グローバル状態が更新されます。 すべてのクライアントは「新しい状態」が「新しいブロック」のstate_rootフィールドの状態と一致することを確認するために、execution_payloadのトランザクションを再実行します。 このようにして、クライアントは「新しいブロック」が有効であり、ブロックチェーンに追加しても安全であることを判断します。 execution payload自体は、いくつかのフィールドを持つオブジェクトです。 実行データに関する重要な要約情報を含むexecution_payload_headerもあります。 これらのデータ構造は、以下のように構成されています。

execution_payload_headerには、以下のフィールドが含まれます。

フィールド説明
parent_hash親ブロックのハッシュ
fee_recipientトランザクションフィーの支払先アカウントアドレス
state_rootこのブロックに変更を適用した後のグローバルステートに対するルートハッシュ
receipts_rootトランザクションレシートツリーのハッシュ
logs_bloomイベントログを含むデータ構造
prev_randaoランダムなバリデータ選出で使われた値
block_number現在のブロック番号
gas_limitこのブロックで許可されているガスの最大値
gas_usedこのブロックで実際に使われたガスの量
タイムスタンプブロックタイム
extra_data生バイトで表される任意の追加データ
base_fee_per_gasベースフィーの値
block_hash実行ブロックのハッシュ
transactions_rootペイロードに含まれるトランザクションのルートハッシュ
withdrawal_rootペイロードに含まれる引き出しのルートハッシュ

execution_payload自体には、以下のものが含まれます(注:トランザクションのルートハッシュの代わりに実際のトランザクションリストと引き出し情報を含んでいることを除けば、ヘッダーと同じ)。

フィールド説明
parent_hash親ブロックのハッシュ
fee_recipientトランザクションフィーの支払先アカウントアドレス
state_rootこのブロックに変更を適用した後のグローバルステートに対するルートハッシュ
receipts_rootトランザクションレシートツリーのハッシュ
logs_bloomイベントログを含むデータ構造
prev_randaoランダムなバリデータ選出で使われた値
block_number現在のブロック番号
gas_limitこのブロックで許可されているガスの最大値
gas_usedこのブロックで実際に使われたガスの量
タイムスタンプブロックタイム
extra_data生バイトで表される任意の追加データ
base_fee_per_gasベースフィーの値
block_hash実行ブロックのハッシュ
処理実行されるトランザクションのリスト
引き出し引き出しオブジェクトのリスト

withdrawalsリストには、次のように構造化されたwithdrawalsオブジェクトが含まれています。

フィールド説明
address引き出されたアカウントアドレス
金額引き出し金額
インデックス引き出しのインデックス値
validatorIndexバリデータのインデックス値

ブロックタイム

ブロックタイムとは、ブロックの生成間隔のことです。 イーサリアムでは、12秒単位で時間を分割し、その単位を「スロット」と呼びます。 各スロットでは、1人のバリデータが選ばれ、ブロックを提案します。 すべてのバリデータがオンラインで完全に稼働している場合、すべてのスロットにブロックが1つ生成され、ブロックタイムは12秒となります。 しかし、バリデータがブロックを提案するタイミングでオフラインになっていることがあり、その場合、スロットが空になることがあります。

この実装は、ブロックタイムが不規則であり、プロトコルがターゲットとして定めるマイニングの難易度によって調整されるプルーフ・オブ・ワークを基としたシステムとは異なります。 イーサリアムの平均ブロックタイム(opens in a new tab)は、12秒という新しいブロックタイムで安定しており、これは、プルーフ・オブ・ワークからプルーフ・オブ・ステークへの移行が明確に示される最も良い例です。

ブロックサイズ

最後に重要なのは、ブロックのサイズには制限があるということです。 各ブロックの目標サイズは1,500万ガスですが、ネットワークの需要に合わせて、ブロックの上限である3,000万ガス(目標ブロックサイズの2倍)まで増減します。 ブロックのガスリミットは、前のブロックのガスリミットから1/1024の割合で上下に調整することができます。 したがって、バリデータはコンセンサスによってブロックのガスリミットを変更することができます。 ブロックの全トランザクションで消費されたガスの総量は、ブロックのガスリミットを超えてはいけません。 ブロックが勝手に大きくなりすぎるのを防ぐという点で、この制限は重要です。 ブロックサイズが大きすぎると、スペースと速度の要件により、パフォーマンスの低いフルノードはネットワークに追いつけなくなり、 次のスロットに間に合うように処理するために必要な計算能力も高くなります。 これが中央集権的な力につながってしまうことから、ブロックサイズに上限を設けています。

参考文献

役に立ったコミュニティリソースがあれば、 ぜひこのページに追加してください。

  • トランザクション
  • ガス
  • プルーフ・オブ・ステーク

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