ブロックの提案
ブロックはブロックチェーンの基本単位です。ブロックはノード間で受け渡され、合意され、各ノードのデータベースに追加される個別の情報単位です。このページでは、ブロックがどのように生成されるかを説明します。
前提条件
ブロックの提案は、プルーフ・オブ・ステーク (PoS) プロトコルの一部です。このページを理解するために、プルーフ・オブ・ステークとブロックのアーキテクチャについて読むことをお勧めします。
誰がブロックを生成するのか?
バリデータアカウントがブロックを提案します。バリデータアカウントは、実行クライアントおよびコンセンサスクライアントの一部としてバリデータソフトウェアを実行し、デポジット・コントラクトに少なくとも32 ETHをデポジットしたノードオペレーターによって管理されます。ただし、各バリデータがブロックを提案する責任を負うのは時々です。イーサリアムは、スロットとエポックで時間を測定します。各スロットは12秒で、32スロット(6.4分)で1エポックを構成します。すべてのスロットは、イーサリアムに新しいブロックを追加する機会となります。
ランダムな選択
各スロットでブロックを提案するために、単一のバリデータが疑似ランダムに選ばれます。各ノードが真にランダムな数値を生成した場合、コンセンサスに至ることができないため、ブロックチェーンには真のランダム性というものは存在しません。代わりに、バリデータの選択プロセスを予測不可能にすることを目的としています。イーサリアムにおけるランダム性は、ブロック・プロポーザーからのハッシュと、ブロックごとに更新されるシードを混合するRANDAOと呼ばれるアルゴリズムを使用して実現されます。この値は、バリデータの全体セットから特定のバリデータを選択するために使用されます。特定の種類のシード操作から保護する方法として、バリデータの選択は2エポック前に固定されます。
バリデータは各スロットでRANDAOに追加しますが、グローバルなRANDAO値は1エポックに1回だけ更新されます。次のブロック・プロポーザーのインデックスを計算するために、RANDAO値はスロット番号と混合され、各スロットで一意の値が生成されます。個々のバリデータが選択される確率は、単純に1/N(N = アクティブなバリデータの総数)ではありません。代わりに、各バリデータの有効ETH残高によって重み付けされます。最大有効残高は32 ETHです(つまり、balance < 32 ETHはbalance == 32 ETHよりも低い重みになりますが、balance > 32 ETHはbalance == 32 ETHよりも高い重みにはなりません)。
各スロットで選択されるブロック・プロポーザーは1つだけです。通常の条件下では、単一のブロック生成者が専用のスロットで単一のブロックを作成してリリースします。同じスロットに対して2つのブロックを作成することは、スラッシングの対象となる違反行為であり、多くの場合「エキボケーション」として知られています。
ブロックはどのように作成されるのか?
ブロック・プロポーザーは、ローカルで実行されているフォーク選択アルゴリズムのビューに従って、チェーンの最新のヘッドの上に構築される署名済みのビーコン・ブロックをブロードキャストすることが期待されます。フォーク選択アルゴリズムは、前のスロットから残っているキューに入れられたアテステーションを適用し、その履歴の中でアテステーションの累積された重みが最も大きいブロックを見つけます。そのブロックが、プロポーザーによって作成される新しいブロックの親になります。
ブロック・プロポーザーは、自身のローカルデータベースとチェーンのビューからデータを収集してブロックを作成します。ブロックの内容は以下のスニペットに示されています。
class BeaconBlockBody(Container):
randao_reveal: BLSSignature
eth1_data: Eth1Data
graffiti: Bytes32
proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS]
attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS]
attestations: List[Attestation, MAX_ATTESTATIONS]
deposits: List[Deposit, MAX_DEPOSITS]
voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS]
sync_aggregate: SyncAggregate
execution_payload: ExecutionPayload
randao_revealフィールドは、ブロック・プロポーザーが現在のエポック番号に署名することによって作成する検証可能なランダム値を取ります。eth1_dataは、デポジットのマークル・トライのルートや、新しいデポジットの検証を可能にするデポジットの総数を含む、ブロック・プロポーザーのデポジット・コントラクトのビューに対する投票です。graffitiは、ブロックにメッセージを追加するために使用できるオプションのフィールドです。proposer_slashingsとattester_slashingsは、プロポーザーのチェーンのビューに従って、特定のバリデータがスラッシングの対象となる違反を犯したという証明を含むフィールドです。depositsは、ブロック・プロポーザーが認識している新しいバリデータのデポジットのリストであり、voluntary_exitsは、ブロック・プロポーザーがコンセンサス・レイヤーのゴシップネットワークで聞いた、エグジットを希望するバリデータのリストです。sync_aggregateは、どのバリデータが以前にシンク・コミッティ(ライト・クライアントのデータを提供するバリデータのサブセット)に割り当てられ、データの署名に参加したかを示すベクトルです。
execution_payloadは、トランザクションに関する情報を実行クライアントとコンセンサス・レイヤークライアント間で受け渡すことを可能にします。execution_payloadは、ビーコン・ブロック内にネストされる実行データのブロックです。execution_payload内のフィールドは、オマー(ommers)が存在せず、difficultyの代わりにprev_randaoが存在することを除いて、イーサリアムのイエロー・ペーパーで概説されているブロック構造を反映しています。実行クライアントは、自身のゴシップネットワークで聞いたトランザクションのローカルプールにアクセスできます。これらのトランザクションはローカルで実行され、ポストステート(post-state)と呼ばれる更新されたステート・トライを生成します。トランザクションはtransactionsと呼ばれるリストとしてexecution_payloadに含まれ、ポストステートはstate-rootフィールドで提供されます。
これらのデータはすべてビーコン・ブロックに収集され、署名され、ブロック・プロポーザーのピアにブロードキャストされ、ピアはそれをさらに自身のピアに伝播させます。
ブロックの構造についてさらに読む。
ブロックはどうなるのか?
ブロックはブロック・プロポーザーのローカルデータベースに追加され、コンセンサス・レイヤーのゴシップネットワークを介してピアにブロードキャストされます。バリデータがブロックを受信すると、ブロックが正しい親を持っているか、正しいスロットに対応しているか、プロポーザーのインデックスが期待されるものであるか、RANDAOの公開が有効であるか、プロポーザーがスラッシングされていないかなど、内部のデータを検証します。execution_payloadはバンドル解除され、バリデータの実行クライアントはリスト内のトランザクションを再実行して、提案された状態の変更を確認します。ブロックがこれらすべてのチェックに合格したと仮定すると、各バリデータはブロックを自身の正規のチェーンに追加します。その後、次のスロットでプロセスが再び開始されます。
ブロック報酬
ブロック・プロポーザーは、その作業に対する支払いを受け取ります。アクティブなバリデータの数とその有効残高の関数として計算されるbase_rewardがあります。その後、ブロック・プロポーザーは、ブロックに含まれる有効なアテステーションごとにbase_rewardの一部を受け取ります。ブロックをアテステーションするバリデータが多いほど、ブロック・プロポーザーの報酬は大きくなります。また、スラッシングされるべきバリデータを報告した場合の報酬もあり、スラッシングされたバリデータごとに1/512 * effective balanceに等しくなります。