Das wohl wichtigste Ereignis in der Ethereum-Geschichte, "The Merge", fand am 15. September 2022 statt. Es markierte den Übergang des Netzwerks von zu und veränderte grundlegend, wie Ethereum Konsens erzielt. Aber warum heißt es „ “ und nicht „The Transition“? Proof of Work Proof of Stake The Merge Vor dem Merge arbeitete Ethereum mit dem Proof of Work-Konsens, einem Mechanismus, der „Miner“ erforderte, um komplexe kryptografische Rätsel zu lösen, Transaktionen zu validieren und neue Blöcke zu erstellen. PoW ist zwar cool, hat aber viele Einschränkungen, wie z. B. den immensen Rechenleistungsverbrauch, der zu hohem Stromverbrauch und Umweltbedenken führt, einen geringen Transaktionsdurchsatz aufgrund der langsameren Verarbeitungszeit, was eine Herausforderung für die institutionelle Akzeptanz darstellt, und ein höheres Zentralisierungsrisiko, da er sich auf wenige mächtige Mining-Entitäten konzentrieren könnte usw. Diese und andere Gründe waren die Motivationen, die die Ethereum Foundation bereits drei Jahre nach ihrer Gründung dazu veranlassten, mit dem Aufbau eines neuen Konsens namens Proof of Stake zu beginnen, der die meisten der Probleme lösen sollte, mit denen PoW zu kämpfen hatte. Am 1. Dezember 2020 startete Ethereum seine erste Version von PoS, eine neue Kette namens Beacon Chain. Die Beacon Chain verarbeitete keine Benutzertransaktionen. Ihr alleiniger Zweck war es, Validatoren zu koordinieren und durch einen neuen Mechanismus namens Gasper Konsens zu erzielen. Transaktionen wurden weiterhin in der Haupt-Proof-of-Work-Kette verarbeitet, sodass beide Ketten, die Ethereum-Hauptkette und die Beacon Chain, parallel liefen. Fast zwei Jahre lang arbeiteten diese beiden Ketten unabhängig voneinander. Dann, am 15. September 2022, gab die ursprüngliche Kette ihren Mining-basierten Konsens auf und wurde direkt an die Beacon Chain angeschlossen. So wurden aus zwei Ketten eine. Deshalb heißt es The Merge und nicht The Transition. Heute arbeitet Ethereum als zweischichtige Blockchain. Die Konsensschicht, die früher die Beacon Chain war, kümmert sich um Blockvorschläge, Bestätigungen und Finalität. Die Ausführungsschicht, die ursprüngliche Ethereum-Kette, kümmert sich um die Transaktionsverarbeitung. Sie haben vielleicht von Eth2 und Eth1 gehört, aber die Ethereum Foundation hat diese Benennung abgeschafft, da sie zwei separate Netzwerke und nicht zwei Schichten eines Systems implizierte. Dieser Artikel konzentriert sich auf die Konsensschicht. Insbesondere darauf, wie die Beacon Chain als Zustandsautomat funktioniert. Was ist der BeaconState? Um zu verstehen, wie sich der Zustandsautomat verändert, müssen wir zuerst verstehen, was der Zustand beim Genesis der Kette tatsächlich enthält. Der Zustand der Beacon Chain wird durch ein einzelnes Objekt namens BeaconState dargestellt. Er enthält alles, was die Konsensschicht zum Funktionieren benötigt. Er wird manchmal als „Gott-Objekt“ bezeichnet. Die Spezifikation gruppiert die Felder nach ihrem Zweck, was der klarste Weg ist, sie zu durchlaufen. class BeaconState(Container): genesis_time: uint64 genesis_validators_root: Root slot: Slot fork: Fork latest_block_header: BeaconBlockHeader block_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] state_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT] eth1_data: Eth1Data eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH] eth1_deposit_index: uint64 validators: List[Validator, VALIDATOR_REGISTRY_LIMIT] balances: List[Gwei, VALIDATOR_REGISTRY_LIMIT] randao_mixes: Vector[Bytes32, EPOCHS_PER_HISTORICAL_VECTOR] slashings: Vector[Gwei, EPOCHS_PER_SLASHINGS_VECTOR] previous_epoch_attestations: List[PendingAttestation, MAX_ATTESTATIONS * SLOTS_PER_EPOCH] current_epoch_attestations: List[PendingAttestation, MAX_ATTESTATIONS * SLOTS_PER_EPOCH] justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH] previous_justified_checkpoint: Checkpoint current_justified_checkpoint: Checkpoint finalized_checkpoint: Checkpoint Versionierung: genesis_time: uint64 genesis_validators_root: Root slot: Slot fork: Fork Die ersten vier Variablen beantworten die Frage „Welche Kette ist das und wo befinden wir uns auf dieser Kette?“. Diese Felder verankern die Identität der Kette und sagen jedem Knoten, welche Protokollregeln er befolgen soll. Die Genesis-Zeit ist ein Unix-Zeitstempel, der zu Beginn der Kette festgelegt wird und sich nie ändert. Der Genesis-Zeitstempel der Beacon-Kette ist 1606824023, was genau dem 1. Dezember 2020 um 12:00:23 Uhr UTC entspricht. Wenn Sie jemals „block.timestamp“ aus einem Smart Contract abgefragt haben, wird dieser Wert aus diesem Feld berechnet. Die Genesis-Validator-Root wurde, genau wie der Zeitstempel, zu Beginn der Kette hinzugefügt. Sie fungiert im Grunde als Domänentrennzeichen; sie wird mit der Signatur des Validators während der Blockvorschläge und Bestätigungen vermischt, um die Ethereum-Mainnet von jeder anderen Kette zu unterscheiden. Ein Slot ist einfach ein Zähler, der uns sagt, wie die Zeit auf der Kette ist. Er wird alle 12 Sekunden inkrementiert, unabhängig davon, ob ein Block produziert wird. Ein Fork ist ein Objekt, das drei Felder enthält: die vorherige Kettenversion, die aktuelle Kettenversion und die Epoche. Als das erste Upgrade auf der Beacon Chain am 27. Oktober 2021 stattfand, wechselten die Versionen von Phase 0 zu Altair. Die aktuelle Version ist zum Zeitpunkt des Schreibens dieses Artikels Fulu, und die vorherige Version ist Electra. Genau wie die Validator-Root wird der Versionshash zu Signaturen hinzugefügt, um eine Fork-Version von einer anderen zu unterscheiden. Eine Epoche hingegen ist ein Bündel von 32 Slots, das sind , also etwa 6,4 Minuten. Hier finden Finalitätsprüfungen, Slashing-Strafen, die Exit-Warteschlange und alle anderen interessanten konsensspezifischen Dinge statt. Hier arbeitet Casper FFG, der letzte Teil von Gasper. 12 Sek x 32 Historie latest_block_header: BeaconBlockHeader block_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] state_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT] Dieser Abschnitt beantwortet die Frage: „Was ist auf dieser Kette passiert?“. Diese Variablen geben der Kette ein kompaktes Gedächtnis ihrer eigenen Vergangenheit und ermöglichen es den Validatoren, frühere Zustände zu referenzieren und zu überprüfen, ohne alles speichern zu müssen. Der Header des letzten Blocks speichert den Header des zuletzt verarbeiteten Blocks. Er wird verwendet, um doppelte Blöcke zu verhindern, da die Kette vor der Verarbeitung eines neuen Blocks prüft, ob die Eltern-Root des Blocks mit der Root des letzten Block-Headers übereinstimmt. Sowohl die Felder block_roots als auch state_roots sind Listen, die vergangene Block-Roots und State-Roots speichern, bis sie voll sind. In jedem Slot werden die Roots an dem Index in ihre jeweiligen Arrays geschrieben. Dies ermöglicht es der Kette, den Zustand jedes kürzlich vergangenen Slots innerhalb eines Zeitfensters von 27 Stunden nachzuschlagen. Die Historical Root hängt den zusammengefassten Hash des Arrays von Block Roots und State Roots an, wenn diese gefüllt sind. Die Liste ist unbegrenzt, wächst aber langsam, mit nur einem Eintrag alle 27 Stunden. slot%8192 Eth1 eth1_data: Eth1Data eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH] eth1_deposit_index: uint64 Vor dem Merge musste Eth2 (Beacon Chain) verfolgen, was auf Eth1 (PoW-Kette) geschah, insbesondere Einzahlungstransaktionen, bei denen neue Validatoren 32 ETH hinterlegten. Sie fragen sich vielleicht, warum die 32 ETH, die für PoS bestimmt waren, in der PoW-Kette und nicht in der Beacon Chain gesperrt wurden. Die Antwort ist einfach, weil die Beacon Chain selbst keine Token-Übertragung oder Transaktionsverarbeitung durchführen konnte, da sie keine Token-Einzahlungen nativ verarbeiten konnte. Eth1 data enthält drei Unterfelder: die , die Merkle-Root des Einzahlungsvertrags-Baums, die , die Gesamtzahl der an den Vertrag getätigten Einzahlungen, und den , den Hash des referenzierten Eth1-Blocks. deposit root deposit count block hash Die Beacon Chain kann nicht einfach die Ansicht eines Validators der Eth1-Kette als bare Münze nehmen, da verschiedene Validatoren aufgrund von Netzwerkverzögerungen unterschiedliche Zustände sehen könnten. Daher verwendet sie einen Abstimmungsmechanismus, der es Block-Proposern erlaubt, ihre Ansicht der aktuellen Eth1-Daten in ihren Block aufzunehmen. Diese Stimmen sammeln sich über einen Abstimmungszeitraum in dieser Liste an, und wenn ein Wert in diesem Zeitraum mehr als die Hälfte der Stimmen erhält, wird er zu den neuen Eth1-Daten. Am Ende des Abstimmungszeitraums wird die Liste geleert und die Abstimmung beginnt von neuem. Eth Deposit Index verfolgt, wie viele Einzahlungen vom Einzahlungsvertrag bisher verarbeitet wurden. Wenn die Kette einen neuen Block verarbeitet, prüft sie anhand des Einzahlungsindexes im Feld Eth1 data, ob unverarbeitete Einzahlungen vorhanden sind. Wenn die Einzahlungsanzahl höher ist, muss der Block die nächsten Einzahlungen bis zum maximalen Einzahlungsbetrag pro Block enthalten, der damals 16 betrug. Registry validators: List[Validator, VALIDATOR_REGISTRY_LIMIT] balances: List[Gwei, VALIDATOR_REGISTRY_LIMIT] Diese Variable speichert im Grunde eine Liste darüber, wer am Konsens teilnimmt und wie viel Einsatz sie haben. Eine coole Tatsache über das Validators-Feld ist, dass es nur wächst und niemals schrumpft. Selbst nachdem ein Validator sich zurückgezogen hat, bleibt sein Eintrag in der Liste. Derzeit gibt es 2.210.484 Einträge, von denen nur 962.941 aktiv sind. Das Validator-Feld hat acht Unterfelder: , was im Grunde der öffentliche Schlüssel des Validators ist; , wohin ihr Einsatz bei einem Rückzug geht; , ihr Guthaben abgerundet auf die nächste Gwei, das zur Berechnung von Belohnungen und Strafen verwendet wird und nur zu Epochengrenzen mit Hysterese aktualisiert wird, um ein Auf und Ab zu verhindern; , eine boolesche Flagge, die anzeigt, ob ein Validator geslasht wurde; , die Epochennummer, zu der der Validator zur Aktivierung berechtigt wurde; , die Epoche, in der er aktiviert wurde; , die Epoche, in der er die Kette verlassen hat; und schließlich , die Epoche, in der sein Guthaben abgehoben werden kann. pubKey withdrawable credentials effective balance slashed activation eligibility epoch activation epoch exit epoch withdrawable epoch Um zu erklären, warum wir ein Feld für das effektive Guthaben in der Validatorliste und ein Feld für die Guthaben direkt im Beacon State haben: Das Feld für das effektive Guthaben wird nicht sofort aktualisiert, wenn sich Ihr tatsächliches Guthaben ändert. Es gibt einen Puffer, um zu verhindern, dass es hin und her schwankt. Ohne Hysterese würde ein Validator, der sich um 32 ETH bewegt und aufgrund von Belohnungen und Strafen in jeder Epoche zwischen 31,99 und 32,01 schwankt, sein effektives Guthaben in jeder Epoche zwischen 31 und 32 wechseln lassen. Das würde bedeuten, das Validator-Objekt ständig neu zu Merklisieren und sein Gewicht bei Komiteeberechnungen in jeder Epoche zu ändern. Zufälligkeit randao_mixes: Vector[Bytes32, EPOCHS_PER_HISTORICAL_VECTOR] randao_mixes ist eine Liste fester Größe von 65.536 (etwa 2^16) Einträgen. Jedes Mal, wenn ein Validator einen Block vorschlägt, fügt er eine sogenannte „Randao-Offenbarung“ zur Liste hinzu. Diese Offenbarung ist im Grunde die aktuelle Epochennummer, die vom Validator signiert wurde. Nach der Signatur nimmt die Kette sie und XORt sie mit dem letzten Mix für die aktuelle Epoche, was einen neuen Mix ergibt. Alle Proposer in einer Epoche tun dasselbe, um den endgültigen akkumulierten Mix für die nächste Epoche zu erhalten. Der Randao-Mix wird verwendet, um das Komitee und die Block-Proposer für die nächste Epoche zu bestimmen. Das Komitee, das aus allen aktiven Validatoren besteht und in die 32 Slots aufgeteilt ist, wird durch den „Swap-or-Not“-Shuffle-Algorithmus bestimmt. Dieser Algorithmus vertauscht im Grunde den Validator-Index zufällig mit dem Mix. Für die Auswahl des Block-Proposers hasht die Kette den Randao-Mix, um einen Seed zu bilden. Dann durchläuft sie alle aktiven Validatoren, beginnend bei einem zufälligen Offset, der von diesem Seed abgeleitet ist. Für jeden Kandidaten wird geprüft, ob ein Hash des Seeds und des Validator-Index, geteilt durch das effektive Guthaben des Validators, einen Schwellenwert überschreitet. Wenn ja, wird der Validator zum Proposer, wenn nicht, wird er übersprungen. In der Praxis findet er schnell einen, da die meisten aktiven Validatoren ein Guthaben von 32 ETH haben. Slashings slashings: Vector[Gwei, EPOCHS_PER_SLASHINGS_VECTOR] Ein Validator wird aus zwei Gründen geslasht: Er schlägt zwei verschiedene Blöcke für denselben Slot vor, um einen Fork zu erstellen, oder er trifft widersprüchliche Bestätigungen. Das Slashing-Feld ist eine feste Liste von 8192 Einträgen, einer pro Epoche. Es enthält die Summe des gesamten effektiven Guthabens der Validatoren, das geslasht wurde. Dieses Feld wird zur Berechnung des Strafbetrags verwendet. Attestations previous_epoch_attestations: List[PendingAttestation, MAX_ATTESTATIONS * SLOTS_PER_EPOCH] current_epoch_attestations: List[PendingAttestation, MAX_ATTESTATIONS * SLOTS_PER_EPOCH] Jeder aktive Validator bestätigt einmal pro Epoche, und diese Bestätigungen treiben sowohl die Fork-Choice-Regel (LMD-GHOST) als auch den Finalitätsmechanismus (Casper FFG) an. Eine Attestation enthält sechs Unterfelder: den , für den der Validator attestiert; den , der Block, den der Validator als Spitze der Kette betrachtet, er gilt als LMD-GHOST-Stimme des Validators, die zur Bestimmung der Fork-Wahl verwendet wird; den , die Epochen-Checkpoint, die der Validator für gerechtfertigt hält, und den , die aktuelle Epoche, für die der Validator attestiert, beide zusammen bilden die Casper FFG-Stimme, die zur Finalität verwendet wird. Vereinfacht ausgedrückt, attestiert der Validator, dass die Quell-Epoche finalisiert werden soll und die Ziel-Epoche gerechtfertigt werden soll; die geben an, welcher Validator im Komitee attestiert hat. Da es billiger ist, Dinge als Bits in einem Byte zu kombinieren, wird das Aggregationsbit aus Speicherplatzgründen in einem Bitfeld gespeichert; schließlich haben wir die des Validators über die Attestationsdaten. slot beacon block root source target aggregation bits signature Finalität justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH] previous_justified_checkpoint: Checkpoint current_justified_checkpoint: Checkpoint finalized_checkpoint: Checkpoint Finalität bedeutet, dass ein Block und alle seine Transaktionen niemals rückgängig gemacht werden können. In der Beacon Chain ist die Finalität absolut. Sobald eine Epoche finalisiert ist, ist die einzige Möglichkeit, sie rückgängig zu machen, wenn 1/3 des gesamten gestakten ETH geslasht wird, was Milliarden von Dollar kosten würde. Justification bits ist ein Bitvektor der Länge 4, der im Grunde nur verfolgt, ob die letzten vier Epochen gerechtfertigt wurden. Der vorherige gerechtfertigte Checkpoint ist der Checkpoint, der zum Zeitpunkt der vorherigen Epoche gerechtfertigt wurde. Der aktuelle gerechtfertigte Checkpoint ist der zuletzt gerechtfertigte Checkpoint, während der finalisierte Checkpoint der zuletzt finalisierte Checkpoint ist. Eine Epoche wird gerechtfertigt, wenn 2/3 des gesamten aktiven Stakes eine Supermajoritätsverbindung bestätigen, die auf diese Epoche als Ziel verweist. Die Finalisierung erfolgt, wenn zwei gerechtfertigte Checkpoints hintereinander erzielt werden. In dem Moment, in dem der zweite gerechtfertigt wird, wird der erste zum finalisierten aufgewertet, obwohl es noch einige Nuancen gibt. Die Zustandsmaschine Da wir nun wissen, was der Zustand enthält, können wir uns ansehen, wie er sich verändert. Alle 12 Sekunden kommt ein neuer Slot. Wenn ein Block vorgeschlagen wird, nimmt die Zustandsübergangsfunktion den aktuellen Zustand und diesen Block, führt eine Validierung durch, aktualisiert und gibt einen neuen Zustand aus. Dieser Prozess wird von der Spezifikation in drei Stufen unterteilt: Slot-Verarbeitung, Block-Verarbeitung und Epochen-Verarbeitung. Slot-Verarbeitung Die Slot-Verarbeitung wird jedes Mal ausgeführt, wenn die Kette von einem Slot zum nächsten fortschreiten muss, unabhängig davon, ob ein Block produziert wurde oder nicht. Drei Dinge passieren, wenn ein Slot von N auf N+1 vorrückt. Erstens wird die Zustands-Root für Slot N aktualisiert, um eine Aufzeichnung dessen zu erhalten, wie der Slot zu diesem Zeitpunkt aussah. Zweitens wird der Header des letzten Blocks, der den Header des zuletzt verarbeiteten Blocks speichert, ebenfalls aktualisiert; denken Sie daran, dass dieses Feld verwendet wird, um doppelte Blöcke zu verhindern. Auch die Root dieses abgeschlossenen Headers wird in die Block-Root geschrieben. Drittens wird der Slot-Zähler um eins erhöht. Sie fragen sich vielleicht, was mit dem Zustand passiert, wenn ein Proposer seinen Slot verpasst. Nun, alle Zustände werden weiterhin aktualisiert, die Block-Roots dieses Slots beispielsweise enthalten die Root des gleichen letzten Block-Headers, da kein neuer Block eingegangen ist, um ihn zu ersetzen. Nachdem der Slot inkrementiert wurde, prüft die Kette, ob sie gerade eine Epochengrenze überschritten hat (kann leicht durch slot mod 32 == 0 erfolgen). Wenn ja, wird die Epochenverarbeitung ausgeführt, bevor etwas anderes passiert. Technisch gesehen wird für jeweils 32 Slots die Epochenverarbeitung neben der Slot-Verarbeitung ausgeführt, mit anderen Worten, die Epochenverarbeitung läuft nach dem Fortschritt des Slots, aber bevor der Block für diesen Slot verarbeitet wird. Eine letzte Anmerkung: Wenn wir an dem Punkt sind, an dem die Arrays für Zustands-Roots und Block-Roots gefüllt sind, d. h. an der Position slot mod 8192 == 0, bevor beide Arrays überschrieben werden, da sie zirkulär erscheinen, hasht die Kette die beiden Felder zusammen und hängt sie an den historischen Zustand an. Block-Verarbeitung Die Block-Verarbeitung wird ausgeführt, wenn tatsächlich ein Block für einen Slot vorgeschlagen wird. Nachdem die Slot-Verarbeitung den Zustand auf den richtigen Slot gebracht hat, nimmt die Block-Verarbeitung den signierten Block und wendet dessen Inhalt auf den Zustand an. Sie besteht aus zwei Hauptteilen: der Validierung des Block-Headers und der Verarbeitung des Block-Bodys. Bevor etwas anderes geschieht, prüft die Kette einige Dinge, z. B. ob der Block-Header mit dem aktuellen State-Slot übereinstimmt und ob der Index des Block-Proposers tatsächlich der Validator ist, den Randao ausgewählt hat. Schließlich prüft sie, ob die Eltern-Root des Blocks mit der Root des letzten Block-Headers übereinstimmt. Wenn sie validiert ist, wird der Block-Header als letzter Block-Header im Zustand gespeichert. Als Nächstes muss der Proposer eine Randao-Offenbarung enthalten, die, wie ich bereits sagte, im Grunde die aktuelle Epochennummer ist, die vom Validator signiert wurde. Die Kette überprüft die Signatur anhand des öffentlichen Schlüssels des Proposers. Es ist leicht zu erkennen, dass diese aktuelle Methode deterministisch ist, dass die Validator-Signatur für dieselbe Epochennummer immer gleich bleibt. Tatsächlich besteht der Sinn dieses Vorgehens darin, es jedem zu ermöglichen, den öffentlichen Schlüssel des Validators zu verwenden, um die Epochennummer zu überprüfen, die der Validator tatsächlich signiert hat. Beachten Sie, dass ein Proposer die Randao-Offenbarung nicht überspringen kann. Wenn er einen Block vorschlägt, muss er sie einbeziehen. Die einzige Möglichkeit, den Prozess zu überspringen, besteht darin, überhaupt keinen Block vorzuschlagen. Danach wird der Proposer auch seine Ansicht des Eth1-Chain-Einzahlungsvertragsstatus als Eth1-Daten-Stimme enthalten. Wenn ein Eth1-Datenwert in der Abstimmungsliste eine Mehrheit erreicht, wird er zu den neuen Eth1-Daten im Zustand. Während der Block-Verarbeitung enthält das Proposer-Slashing-Feld Beweise dafür, dass ein Validator zwei verschiedene Block-Header für denselben Slot signiert. Die Kette überprüft beide Signaturen, und wenn sie gültig sind, slasht sie sie, indem sie zuerst ihre Slashing-Flagge auf true setzt und ihr effektives Guthaben zum Slashing-Array hinzufügt. Ebenso werden für die Attester bei widersprüchlichen Attestationen die widersprüchlichen Attestationen überprüft und die schuldigen Validatoren anhand ihrer Signaturen identifiziert, und dann werden diese Validatoren auf die gleiche Weise und nach demselben Verfahren wie beim Proposer-Slashing geslasht. Neue Attestationen im Block werden validiert, die Attestation wird in eine ausstehende Attestation umgewandelt, indem zwei neue Felder hinzugefügt werden: die Einbeziehungsverzögerung und der Proposer-Index, und dann werden sie entweder an die Attestation der aktuellen Epoche oder an die Attestation der vorherigen Epoche angehängt. Danach passiert nicht viel mehr, da sie den Zustand nicht sofort beeinflussen, sondern dort verbleiben, bis die Epochenverarbeitung sie auswertet. Neue Validator-Einzahlungen vom Eth1-Einzahlungsvertrag werden verarbeitet. Der Block muss alle ausstehenden Einzahlungen bis zu einem Maximum von 16 enthalten. Die Kette überprüft den Merkle-Beweis jeder Einzahlung anhand der Einzahlungs-Root, um sicherzustellen, dass er korrekt ist. Wenn die öffentlichen Schlüssel des Einzahlers neu sind, wird ein neuer Validator-Eintrag sowie das entsprechende Guthaben hinzugefügt. Ein Validator kann signalisieren, dass er die Kette verlassen möchte, indem er einen signierten freiwilligen Ausstieg einreicht. Die Kette prüft, ob der Validator mindestens 256 Epochen aktiv war und ob die aktuelle Epoche mindestens die angegebene Ausstiegs-Epoche ist. Wenn alles stimmt, werden die Ausstiegs-Epoche und die auszahlbare Epoche des Validators festgelegt. Nachdem alle oben genannten Punkte verarbeitet wurden, gibt es noch ein letztes, aber wichtiges Detail: Die von den anderen Knoten berechnete Zustands-Root wird mit der im Block enthaltenen Zustands-Root verglichen. Wenn sie nicht übereinstimmen, wird der gesamte Block abgelehnt. Epochen-Verarbeitung Die Epochen-Verarbeitung wird an der Epochengrenze ausgelöst, also bei jedem Schritt „slot mod 32 = 0“. Sie läuft während der Slot-Verarbeitung, wenn der Slot-Zähler in eine neue Epoche wechselt. Dies ist die komplexeste Phase, da hier die meisten interessanten Konsensdinge passieren. Zuerst greifen Rechtfertigung und Finalisierung. Hier leistet Casper FFG seine Arbeit. Der Prozess mag komplex klingen, ist aber sehr einfach. Vereinfacht ausgedrückt, betrachtet die Kette die Attestationen der vorherigen Epoche und zählt die effektiven Guthaben der Validatoren, die mit dem korrekten Ziel attestiert haben. Wenn diese Summe mindestens 2/3 des gesamten aktiven Guthabens beträgt, wird die Ziel-Epoche gerechtfertigt, und wenn zwei aufeinanderfolgende Epochen gerechtfertigt sind, wird die frühere finalisiert. Einfach! Eine Tatsache, die ich im Block-Verarbeitungsstadium nicht erwähnt habe: Für jede Stufe sammeln die Validatoren Belohnungen an. Sie werden dafür belohnt, dass sie Attestationen einschließen, Slashing-Beweise hinzufügen oder sogar eine normale Basisbelohnung erhalten. Diese angesammelten Belohnungen werden von der Kette über die vorherige Epoche im Epochen-Verarbeitungsstadium ausgewertet und ihr Guthaben entsprechend angepasst. Wenn die Kette seit mehr als vier Epochen nicht finalisiert hat, tritt das sogenannte „Inactivity Leak“ in Kraft. Zusätzlich zu den normalen Strafen für verpasste Attestationen erhalten nicht teilnehmende Validatoren eine zusätzliche Inaktivitätsstrafe, die quadratisch mit jeder Epoche seit der letzten finalisierten Epoche ansteigt. Mit anderen Worten: Je länger es dauert, bis ein Block finalisiert wird, desto härter ist die Strafe. Sie fragen sich vielleicht, was der Sinn dahinter ist. Wenn ein Block längere Zeit nicht finalisiert wurde, bedeutet das, dass es keine Mehrheitsabstimmung für diesen Block gibt, und da die Abstimmung zur Finalisierung anhand des Gewichts des effektiven Guthabens eines Validators gemessen wird, d. h. wie viel ETH der Validator hat, reduziert eine Verringerung seines effektiven Guthabens seine Stimmkraft. Ethereum nutzt dies also als Mittel, um die Blockfinalisierung zu erzwingen. Bemerkenswert ist, dass während eines Inactivity Leaks selbst korrekte Attester keine Belohnungen erhalten. Alles verschiebt sich in den reinen Strafmodus, um die Neuverteilung zu beschleunigen. Eine weitere wichtige Veranstaltung in dieser Phase ist die Aktivierung von Validatoren, deren Aktivierungsberechtigungs-Epoche erreicht wurde. Ebenso werden Validatoren, deren Ausstiegs-Epoche erreicht ist, aus dem aktiven Validator-Set entfernt. Als Nächstes: Denken Sie daran, dass sich das effektive Guthaben nicht mit jedem Slot und jeder Epoche aktualisiert, da Hysterese gilt. Es aktualisiert sich nur, wenn das tatsächliche Guthaben ausreichend über dem aktuellen effektiven Guthaben des Aufwärts-Schwellenwerts gestiegen ist. Das effektive Guthaben erhöht sich um 1 ETH, und wenn es unter den Abwärts-Schwellenwert fällt, verringert es sich um 1 ETH. Schließlich wird der Randao-Mix der aktuellen Epoche in den Slot der nächsten Epoche kopiert. Wie Sie deutlich sehen können, ist die Epochenverarbeitung der komplizierteste Teil des Zustandsautomaten und rechnerisch unfreundlich, was daher immer zu viel Optimierungsarbeit für die Ingenieure führt, die die Chain-Clients entwickeln. Von Phase 0 bis Fulu Der BeaconState, den wir bisher durchlaufen haben, ist die Version Phase 0, die ursprüngliche. Aber die Beacon Chain ist ein lebendiges System. Jede Konsensschicht-Gabelung hat den BeaconState modifiziert, entweder durch Hinzufügen neuer Felder, Entfernen alter oder einfach durch Ändern der Funktionsweise einiger bestehender Felder. Zum Beispiel wurden in der Altair-Gabelung die Listen für die bisherige und die aktuelle Epochen-Attestation vollständig entfernt und durch die bisherige und aktuelle Epochen- ersetzt. Der Unterschied besteht darin, dass die frühere vollständige Attestationsobjekte speicherte, während der neue Teilnahmetyp sie nur in Bitform speichert. Jetzt erhält jeder Validator nur noch drei Bits pro Epoche, die angeben, ob er die Quelle, das Ziel und den Kopf richtig erfasst hat. Dies führte zu einer drastischen Reduzierung der Speichermenge. Bellatrix, die Merge-Gabelung, führte das Feld für die Ausführungsnutzlast in den BeaconState ein. Dieses Feld wird verwendet, um die Konsensschicht und die Ausführungsschicht zu verbinden. Die Eth1-Felder wurden beibehalten, aber ihre Rollen wurden verringert, da sie nicht mehr benötigt wurden. Teilnahme Die Capella-Gabelung führte die Auszahlungsfähigkeiten für den Validator ein. Sie wird durch Hinzufügen eines neuen Feldes namens next withdrawal index zum BeaconState erfasst. Die Historical Roots wurden durch Historical Summaries ersetzt, die Block Root und State Root in einer Struktur speichern, anstatt sie zusammen zu hashen. Die Deneb-Gabelung hingegen hatte fast keine Auswirkungen auf den BeaconState, da sich die Gabelung hauptsächlich mit Blobs befasste. In Electra und Fulu bestand die wichtigste Änderung darin, das maximale effektive Guthaben von 32 ETH auf 2048 ETH zu erhöhen, was zur Einführung neuer Felder im BeaconState führte. Jede Gabelung baute auf der vorherigen auf, und der BeaconState wuchs von 21 Feldern in Phase 0 auf über 30 in Fulu. Eine Sache ist konstant: Von Phase 0 bis Fulu ist der Zustand gewachsen, Gabelungen fügen Felder hinzu, Gabelungen entfernen Felder, aber die Architektur ist gleich geblieben. Schlussfolgerung Die Beacon Chain wird oft als komplex bezeichnet, ja, ich stimme zu, weil sie komplex ist. Aber im Kern ist es im Grunde ein Kreislauf: Ein Zustand existiert, eine Eingabe kommt an, der bestehende Zustand wird aktualisiert, um einen neuen Zustand zu erzeugen, und dann wiederholt sich das! Einfach! Was die Beacon Chain wirklich bemerkenswert macht, ist nicht ein einzelnes Feld, sondern wie alles miteinander verbunden ist, um uns diese großartige „Technik“ zu bieten, die wir heute haben! Referenzen Ethereum Consensus Specifications (Phase 0) Ethereum Annotated Specification von Ben Edgington eth2book.info Gasper: Combining GHOST and Casper (Original Paper) Casper the Friendly Finality Gadget (Original Paper) Lighthouse Client Implementation Ethereum Beacon Chain Explorer Ethereum Foundation Blog über The Merge Ethereum Annotated Spec von Vitalik Buterin