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

ブロック提案

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

ブロックは、ブロックチェーンにおける基本的な単位です。 ブロックとは、各ノード間で受け渡しされ、合意され、各ノードのデータベースに追加される情報を区切った単位です。 このページでは、ブロックがどのように生成されるのかを説明します。

前提知識

ブロックの提案は、プルーフ・オブ・ステークのプロトコルの一部です。 このページの内容を理解するためには、プルーフ・オブ・ステークおよびブロックのアーキテクチャを読んでおくとよいでしょう。

誰がブロックを生成するのか?

ブロックは、バリデータのアカウントが提案します。 バリデータのアカウントは、実行クライアントおよびコンセンサス・クライアントの一部としてバリデータ・ソフトウェアを実行し、少なくともデポジット・コントラクトの残高が少なくとも32イーサ以上であるノードのオペレータが管理します。 ただし、各バリデータがすべてのブロックを提案する訳ではありません。 イーサリアムでは、時間をスロットおよびエポック単位で把握します。 1スロットは12秒であり、1エポックは32スロット(6.4分)です。 各スロットは、イーサリアムに新規ブロックを追加する期間を表します。

無作為の選出

各スロットにおいてブロックを提案するために、1名のバリデータがほぼ無作為に選出されます。 各ノードによる番号の生成が真に無作為であればノード間においてコンセンサスを実現することが不可能になるため、ブロックチェーンにおいては真の無作為性は存在しません。 むしろ、ここでの目的は、バリデータの選出プロセスを予測不可能にすることです。 イーサリアムでは、RANDAOと呼ばれるアルゴリズムを用いてバリデータ選出の無作為性を実現します。これは、ブロック提案者のハッシュと、ブロックごとに更新されるシードと混合するアルゴリズムです。 この混合された値に基づき、バリデータの全リストから特定のバリデータを選出します。 バリデータは、シードに対する特定の種類の不正操作から保護するために、2エポック前の時点で選出が確定します。

バリデータは各スロットにおいてRANDAOに追加されますが、グローバルなRANDAO値は各エポックにつき1回のみ更新されます。 次のブロック提案者のインデックスを算出するために、RANDAO値はスロット番号とミックスされ、スロットごとに固有値が得られます。 特定のバリデータが選出される確率は、単に1/NNは、アクティブなバリデータの合計数)ではありません。 これは、各バリデータの有効なイーサ残高によって加重されるためです。 有効な残高の上限は32イーサです(つまり、残高<32イーサの場合、残高=32イーサの場合よりも加重が低くなりますが、残高>32でああっても残高=32イーサの場合よりも加重は大きくなりません。

各スロットにおいて選出されるブロック提案者は1名のみです。 通常、1名のブロック生成者が、専用のスロットにおいて1つのブロックを生成し、リリースします。 同一スロットにおいて2つのブロックを生成することはスラッシングの対象となる不正行為であり、これを「曖昧化」と呼びます。

ブロックはどのように生成されるのか?

ブロック提案者は、自分がローカルで実行するフォーク選択のアルゴリズムの観点に基づき、チェーンの最も最近の先頭部分に構築される署名済みのビーコンブロックを送信すると想定されています。 フォーク選択のアルゴリズムは、ひとつ前のスロットで未処理であったキュー内のアテステーションすべてに適用され、その履歴から、累積したアテステーションの加重が最も大きいブロックを特定します。 特定されたブロックは、提案者が作成する新規ブロックに対する親ブロックとなります。

ブロック提案者は、自分のローカルなデータベースおよびチェーンビューに基づきデータを収集して、ブロックを作成します。 ブロックの内容は、以下のコードスニペットのように表示されます。

1class BeaconBlockBody(Container):
2 randao_reveal: BLSSignature
3 eth1_data: Eth1Data
4 graffiti: Bytes32
5 proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS]
6 attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS]
7 attestations: List[Attestation, MAX_ATTESTATIONS]
8 deposits: List[Deposit, MAX_DEPOSITS]
9 voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS]
10 sync_aggregate: SyncAggregate
11 execution_payload: ExecutionPayload
すべて表示

ブロック提案者が現在のエポック番号に署名することによって作成する検証可能なランダム値をrandao_revealフィールドで受け取ります。 eth1_dataは、ブロック提案者における入金コントラクトのビューに対する投票であり、入金コントラクトのマークルツリーにおけるルートと、新規の入金に対する検証を可能にする入金件数の総数が含まれています。 graffitiは、ブロックにメッセージを追加するための使用できるオプション項目です。 proposer_slashingsおよび attester_slashingsは、提案者によるチェーンビューに基づき、特定のバリデータがスラッシュ対象の違反行為を実行したことを証明する項目です。 depositsは、ブロック提案者が認識しているバリデータによる新規の入金リストであり、voluntary_exitsは、ブロック提案者がコンセンサスレイヤーのゴシップネットワークにおいて、退出を希望する意向を確認したバリデータのリストです。 sync_aggregateは、どのバリデータが、以前に同期委員会(軽量のクライアントデータを担当するバリデータのサブセット)に指定されたことがあり、データの署名を実行したことがあるのかを示すベクトルです。

execution_payloadは、トランザクションに関する情報が実行クライアントとコンセンサス・クライアントとの間で受け渡されることを可能にします。 execution_payloadは、ビーコンブロック内にネスティングされるブロックの実行データです。 execution_payload内の各フィールドは、イーサリアムのイエローペーパーで概説されたブロックの構造を反映しています。ただし、オマーブロックを含まず、難易度の代わりにprev_randaoを含む点が異なります。 実行クライアントは、自身のゴシップネットワークで耳にしたトランザクションのローカルプールにアクセスすることができます。 これらのトランザクションはローカルで実行され、ポストステートと呼ばれる更新後の状態ツリーを生成します。 これらのトランザクションは、execution_payloadにおいてトランザクションという名称のリストに含まれており、当該のポストステートはstate-rootフィールドに書き込まれます。

これらのデータはすべてビーコンブロックで収集、署名された上で、ブロック提案者のピアユーザーのブロードキャストされ、受信したピアはさらにそのピアユーザーに送信します。

詳細については、ブロックの構造をご覧ください。

生成されたブロックには、何が起きるのか?

生成されたブロックはブロック提案者のローカルデータベースに追加され、コンセンサスレイヤーのゴシップネットワークを通じてピアユーザーにブロードキャストされます。 ブロックを受け取ったバリデータは、そのブロックに含まれるデータを検証します。具体的には、親ブロックが適切かどうか、適切なスロットに対応しているか、提案者インデックスが予期されたものであるか、RANDAO開示が有効か、および提案者がスラッシュ対象になっていないか、について確認します。 execution_payloadのバンドルが解除され、バリデータの実行クライアントが当該リストに含まれるトランザクションを実行して、提案される状態変更についてチェックします。 当該ブロックがこれらのチェックにすべて合格した場合、各バリデータはブロックを自身の正規チェーンに追加します。 以上のプロセスを、次のスロットでも繰り返します。

ブロック報酬

ブロック提案者は、この作業に対する報酬を獲得します。 base_reward は、アクティブなバリデータの数と、それらのバリデータにおける有効な残高に基づいて計算されます。 その上で、ブロック提案者は、当該ブロックに含まれる1件の有効なアテステーションごとにbase_rewardの一部を受け取ります。当該ブロックをアテステーションするバリデータの数が多ければ多いほど、ブロック提案者の報酬は増えます。 スラッシングが必要なバリデータを報告したユーザーに対しても報酬が提供されます。この報酬額は、スラッシングされたバリデータにおける有効な残高の512分の1となります。

報酬およびペナルティの詳細

参考文献

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