Unformatierte Blockchain-Daten lesen · Lektion 2 von 6
Blöcke und Header als Daten
8 Min. Lesezeit
Blöcke sind die Einheit, in der eine Blockchain Zeit und Reihenfolge festhält. Daher hängt jede Zeitleiste, jede Tagesgesamtzahl und jede Aussage „vor oder nach“, die Analysten treffen, davon ab, dass sie Blöcke richtig lesen. Blöcke können außerdem ersetzt werden: Der jüngste Teil jeder Chain ist vorläufig. Wenn Sie wissen, was ein Header enthält, wie zuverlässig sein Zeitstempel ist und wann ein Block sicher als Grundlage dienen kann, bleiben vorläufige Daten aus Ihren Ergebnissen heraus.
Was ein Header enthält
Ein Block-Header ist ein kurzer Datensatz, der den Block zusammenfasst und ihn mit seinem Vorgänger verknüpft. Ein Bitcoin-Header ist genau 80 Bytes groß und enthält sechs Felder:
| Feld | Größe | Bedeutung für Analysten |
|---|---|---|
| version | 4 bytes | Regelsatz und Signalisierungsbits für Soft Forks |
| previous block hash | 32 bytes | Verknüpfung mit dem Vorgänger; aus diesen Verknüpfungen wird die Chain aufgebaut |
| merkle root | 32 bytes | Commitment zu jeder Transaktion im Block |
| time | 4 bytes | Vom Miner gewählter Unix-Zeitstempel |
| bits | 4 bytes | Kompakte Kodierung des Schwierigkeitsziels |
| nonce | 4 bytes | Wert, den Miner variieren, um einen gültigen Hash zu finden |
Der Block-Hash ist kein Header-Feld: Er ist der doppelte SHA-256-Hash der 80 Header-Bytes. Explorer zeigen ihn in umgekehrter Byte-Reihenfolge an, weshalb er mit Nullen beginnt. Bitcoin Cores getblock ergänzt abgeleitete Werte wie height, mediantime, chainwork und confirmations.
Ein Ethereum-Header enthält mehr Felder, da er auch den Zustand und die Receipts festschreibt. Die Felder, die Analysten am häufigsten verwenden:
| Feld | Bedeutung |
|---|---|
number, parentHash | Höhe und Verknüpfung mit dem Vorgänger |
timestamp | Unix-Zeit in Sekunden |
miner | Vom Block-Proposer gewählter Gebührenempfänger (die Bezeichnung stammt aus der Zeit vor Proof of Stake) |
stateRoot, transactionsRoot, receiptsRoot | Commitments zu Zustand, Transaktionen und Receipts |
logsBloom | Bloom-Filter, mit dem Clients Blöcke ohne passende Logs überspringen können |
gasLimit, gasUsed | Kapazität und Verbrauch |
baseFeePerGas | Verbrannte Base Fee pro Gas (London, August 2021) |
withdrawalsRoot | Validator-Auszahlungen (Shanghai, April 2023) |
blobGasUsed, excessBlobGas, parentBeaconBlockRoot | Blob-Abrechnung und Consensus-Verknüpfung (Cancun, März 2024) |
requestsHash | Requests von der Ausführungs- an die Consensus-Ebene, EIP-7685 (Prague, Mai 2025) |
Felder sind erst ab dem Upgrade vorhanden, mit dem sie eingeführt wurden. Daher muss eine Datenpipeline akzeptieren, dass sie in älteren Blöcken fehlen. Seit dem Merge sind difficulty und nonce null, und mixHash enthält den Zufallswert der Beacon Chain. Daten aus der Zeit vor dem Merge weisen ein weiteres Merkmal auf: Ommer- (Uncle-)Blöcke, gültige Blöcke, die ein Wettrennen verloren, aber von einem späteren Block über sha3Uncles und die Liste uncles referenziert wurden. Ihre Miner erhielten eine reduzierte Belohnung ohne Transaktion. Daher müssen Analysen von Mining-Belohnungen diese Blöcke berücksichtigen; seit dem Merge ist die Liste immer leer.
Höhe versus Hash
Die Höhe (Ethereum-number) ist eine Position: die Anzahl der Blöcke seit dem Genesis-Block. Der Block-Hash ist eine Identität. Zwei verschiedene Blöcke können dieselbe Höhe haben, wenn sich die Chain verzweigt, und nur einer von ihnen wird Teil der Main Chain. Ein Hash hingegen identifiziert für immer genau einen Block.
Verwenden Sie die Höhe der Einfachheit halber und für Bereiche („Blöcke 21.000.000 bis 21.000.999“) und den Hash zur Identifikation. Speichern Sie in Ihrer Datenbank beides und verwenden Sie den Hash als Schlüssel. Wenn Sie in einem Bericht einen Block angeben, nennen Sie beides: „Höhe 880.214, Hash 0000…3f1a.“ Der Bitcoin-RPC-Aufruf getblockhash gibt den Hash zurück, der sich aktuell auf einer bestimmten Höhe befindet; nahe der Chain-Spitze kann sich dieser ändern. Ethereum bietet sowohl eth_getBlockByNumber als auch eth_getBlockByHash.
Zeitstempel und ihre Zuverlässigkeit
Der Zeitstempel eines Blocks ist die Zeit, die ein Analyst jeder darin enthaltenen Transaktion zuordnet. Wie genau er ist, hängt von der Chain ab.
Bitcoin-Zeitstempel werden vom Miner unter Einhaltung zweier Regeln festgelegt: Die Zeit muss nach dem Median der vorherigen 11 Blöcke liegen (der Median Time Past), und Nodes weisen Blöcke zurück, deren Zeitstempel mehr als zwei Stunden vor ihrer eigenen Uhr liegt (ältere Versionen von Bitcoin Core verwendeten stattdessen eine von Peers abgeleitete „netzw adjusted“ Zeit). Daher kann ein Block einen früheren Zeitstempel als sein Vorgänger tragen, und ein einzelner Zeitstempel kann um eine Stunde oder mehr abweichen. Verwenden Sie für die Reihenfolge die Höhe; Bitcoin Cores mediantime nimmt als monotone Uhr nie ab. Geben Sie Bitcoin-Zeiten in Berichten mit einer Genauigkeit an, die durch die Daten gestützt wird.
Ethereum hat seit dem Merge (September 2022) feste Slots von 12 Sekunden. Der Zeitstempel eines Blocks entspricht der Genesis-Zeit plus 12 Sekunden multipliziert mit seiner Slot-Nummer. Zeitstempel sind exakt und regelmäßig; eine Lücke von 24 oder 36 Sekunden zwischen aufeinanderfolgenden Blöcken bedeutet, dass ein oder zwei Slots keinen Block hatten. Vor dem Merge legten Miner Zeitstempel nach weniger strengen Regeln fest. Auf Rollups legt der Sequencer die Zeitstempel nach den jeweiligen Regeln des Rollups fest.
Zwei Hinweise gelten überall. Die Blockzeit ist der Zeitpunkt, zu dem eine Transaktion aufgenommen wurde, nicht der Zeitpunkt, zu dem sie signiert oder gesendet wurde. Und „first seen“-Zeitangaben in Explorern stammen von den jeweiligen Mempool-Beobachtern: Sie sind nützliche Hinweise, gelten aber nur für den jeweiligen Beobachter.
Reorganisationen
Eine Reorganisation (Reorg) tritt ein, wenn Nodes von der Chain, der sie gefolgt sind, zu einem konkurrierenden Zweig wechseln. Die ersetzten Blöcke werden als stale oder umgangssprachlich als verwaist bezeichnet.
Bei Bitcoin finden zwei Miner gelegentlich fast gleichzeitig Blöcke auf nahezu derselben Höhe. Nodes folgen dem Zweig mit der größten kumulativen Arbeit (chainwork). Wenn der nächste Block einen der beiden Zweige verlängert, wird der Block im anderen Zweig stale. Seine Transaktionen erscheinen gewöhnlich erneut im gewinnenden Zweig, möglicherweise aber in einem anderen Block und an einer anderen Position – oder gar nicht, wenn stattdessen eine widersprüchliche Transaktion bestätigt wurde. Bitcoin Core führt bekannte Zweige mit getchaintips auf, und getblock meldet für einen Block, der nicht zur Main Chain gehört, confirmations von −1.
Bei Ethereum sind Reorganisationen dank Proof of Stake seltener und normalerweise nur einen Block tief. Logs, die über Subscriptions oder Filter zugestellt werden, enthalten removed: true, wenn sie durch eine Reorganisation entfernt werden – ein Signal, das Datenpipelines verarbeiten müssen.
Finalität für Analysen
Finalität ist der Punkt, ab dem ein Block als dauerhaft betrachtet werden kann.
- Die Bitcoin-Finalität ist probabilistisch. Mit jedem zusätzlichen Block (einer Bestätigung) wird das Ersetzen exponentiell kostspieliger. Sechs Bestätigungen sind eine übliche Konvention für Wertübertragungen, und neu geschürfte Coins (Coinbase-Ausgaben) können 100 Blöcke lang nicht ausgegeben werden.
- Ethereum verfügt über explizite wirtschaftliche Finalität. Slots werden zu Epochen mit 32 Slots (6,4 Minuten) zusammengefasst; Validatoren stimmen über Epochen-Checkpoints ab, die zunächst gerechtfertigt und dann finalisiert werden, normalerweise nach etwa zwei Epochen, also ungefähr 13 Minuten. Um einen finalisierten Block rückgängig zu machen, müsste mindestens ein Drittel aller gestakten ETH vernichtet werden.
Ethereum JSON-RPC stellt dies über Block-Tags bereit, die anstelle einer Blocknummer verwendet werden können: earliest (Genesis), latest (der neueste Block, dem der Node folgt), safe, finalized und pending. Die Bedeutung von safe hängt vom Consensus-Client ab: Viele geben den jüngsten gerechtfertigten Checkpoint zurück, der einige Minuten hinter latest liegt; einige wenige Clients übernehmen eine schnelle Bestätigungsregel, durch die safe nur Sekunden hinter der Spitze liegt. Prüfen Sie, was Ihr Node zurückgibt, anstatt etwas vorauszusetzen.
| Verwendung | Bitcoin | Ethereum |
|---|---|---|
| Echtzeit-Alarmierung | 0–1 Bestätigungen, mit Behandlung von Reorganisationen | latest, mit Behandlung von Reorganisationen |
| Operative Entscheidungen | Richtlinienbasierte Tiefe, oft 3–6 | safe oder finalized |
| Berichte und Statistiken | Deutlich mehr als 6 oder ein festgelegter älterer Grenzwert | finalized |
Die folgende Abfrage zählt tägliche Transaktionen nur bis zu einem Grenzwert, der mit eth_getBlockByNumber("finalized", false) vom Node abgerufen wird:
-- Tägliche Transaktionszahlen, niemals über den finalisierten Block hinaus
SELECT DATE_TRUNC('day', b.block_time) AS day_utc,
COUNT(*) AS tx_count
FROM transactions t
JOIN blocks b ON b.block_hash = t.block_hash
WHERE b.block_number <= :finalized_block
GROUP BY DATE_TRUNC('day', b.block_time)
ORDER BY day_utc;
Durch den Join über block_hash statt über die Höhe bleiben Transaktionen aus stale Blöcken bei der Zählung außen vor. DATE_TRUNC gibt es in PostgreSQL und mehreren Data-Warehouses; andere Engines verwenden TIMESTAMP_TRUNC oder eine Umwandlung in ein Datum.
Umgang mit verwaisten Daten
Jede Datenpipeline, die aktuelle Blöcke aufnimmt, wird mit Reorganisationen konfrontiert. Ein robustes Design erledigt vier Dinge: Es speichert für jeden Block block_hash und parent_hash; es prüft bei jedem neuen Block, ob dessen Parent-Hash mit dem gespeicherten Hash eine Höhe darunter übereinstimmt; stimmt er nicht überein, geht es bis zum gemeinsamen Vorgänger zurück, markiert die Zeilen der ersetzten Blöcke als nicht-kanonisch und nimmt den neuen Zweig auf; und es behält die ersetzten Zeilen in einer Audit-Tabelle, statt sie zu löschen. Die folgende Prüfung findet Brüche in der gespeicherten Chain:
-- Blöcke ohne gefundenen Vorgänger: Lücken oder nicht behandelte Reorganisationen
SELECT c.block_number, c.block_hash, c.parent_hash
FROM blocks c
LEFT JOIN blocks p ON p.block_hash = c.parent_hash
WHERE p.block_hash IS NULL
AND c.block_number > (SELECT MIN(block_number) FROM blocks);
Die Audit-Tabelle ist für Fallanalysen wichtig. Angenommen, eine Einzahlung wurde nach einer Bestätigung gutgeschrieben, der Block wurde stale und stattdessen wurde eine widersprüchliche Transaktion bestätigt, die dieselben Coins ausgibt. Eine zwischengespeicherte Seite eines Explorers zeigt möglicherweise weiterhin die erste Transaktion. Nur gespeicherte Daten zu stale Blöcken ermöglichen es Analysten zu erklären, warum eine „bestätigte“ Einzahlung auf der endgültigen Chain nie existiert hat.
Prüfungsschwerpunkt: die sechs Bitcoin-Header-Felder und dass der Block-Hash berechnet und nicht gespeichert wird; wichtige Ethereum-Header-Felder und die Upgrades, mit denen sie eingeführt wurden; Höhe als Position versus Hash als Identität; Bitcoin-Zeitstempelregeln (Median Time Past, Zwei-Stunden-Grenze) und warum Zeitstempel nicht chronologisch geordnet sein können; Ethereums 12-Sekunden-Slots und exakte Zeitstempel; Reorganisationen, stale Blöcke und Logs mitremoved: true; Bestätigungstiefe, Epochen, gerechtfertigte und finalisierte Checkpoints sowie die JSON-RPC-Tagslatest,safeundfinalized; Erkennen und Aufzeichnen verwaister Daten.