Zum Hauptinhalt springen

Lerne grundlegende Ethereum-Themen mit SQL

SQL
Abfragen
Transaktionen
data-and-analytics
Anfänger
Paul Apivat
11. Mai 2021
8 Minuten Lesezeit

Viele Ethereum-Tutorials richten sich an Entwickler, aber es mangelt an Bildungsressourcen für Datenanalysten oder für Personen, die Daten auf der Blockchain sehen möchten, ohne eine Anwendung oder einen Blockchain-Knoten auszuführen.

Dieses Tutorial hilft Lesern, grundlegende Ethereum-Konzepte wie Transaktionen, Blöcke und Gas zu verstehen, indem Daten auf der Blockchain mit der Structured Query Language (SQL) über eine von Dune Analytics (opens in a new tab) bereitgestellte Schnittstelle abgefragt werden.

Daten auf der Blockchain können uns helfen, Ethereum, das Netzwerk und die Ökonomie für Rechenleistung zu verstehen. Sie sollten als Grundlage dienen, um die Herausforderungen zu verstehen, denen Ethereum heute gegenübersteht (z. B. steigende Gaspreise), und, was noch wichtiger ist, die Diskussionen über Skalierungslösungen.

Transaktionen

Die Reise eines Benutzers auf Ethereum beginnt mit der Initialisierung eines benutzergesteuerten Kontos oder einer Entität mit einem ETH-Guthaben. Es gibt zwei Arten von Konten – benutzergesteuerte oder ein Smart Contract (siehe ethereum.org).

Jedes Konto kann in einer Blocksuchmaschine wie Etherscan (opens in a new tab) oder Blockscout (opens in a new tab) eingesehen werden. Blocksuchmaschinen sind ein Portal zu den Daten von Ethereum. Sie zeigen in Echtzeit Daten zu Blöcken, Transaktionen, Minern, Konten und anderen Aktivitäten auf der Blockchain an (siehe hier).

Ein Benutzer möchte jedoch möglicherweise die Daten direkt abfragen, um die von externen Blocksuchmaschinen bereitgestellten Informationen abzugleichen. Dune Analytics (opens in a new tab) bietet diese Möglichkeit für jeden mit etwas SQL-Wissen.

Als Referenz kann das Smart Contract-Konto der Ethereum Foundation (EF) auf Blockscout (opens in a new tab) eingesehen werden.

Es ist zu beachten, dass alle Konten, einschließlich des der EF, eine öffentliche Adresse haben, die zum Senden und Empfangen von Transaktionen verwendet werden kann.

Der Kontostand auf Etherscan umfasst reguläre Transaktionen und interne Transaktionen. Interne Transaktionen sind trotz des Namens keine tatsächlichen Transaktionen, die den Zustand der Chain ändern. Es handelt sich um Wertübertragungen, die durch die Ausführung eines Vertrags initiiert werden (Quelle (opens in a new tab)). Da interne Transaktionen keine Signatur haben, sind sie nicht in der Blockchain enthalten und können nicht mit Dune Analytics abgefragt werden.

Daher wird sich dieses Tutorial auf reguläre Transaktionen konzentrieren. Diese können wie folgt abgefragt werden:

1WITH temp_table AS (
2SELECT
3 hash,
4 block_number,
5 block_time,
6 "from",
7 "to",
8 value / 1e18 AS ether,
9 gas_used,
10 gas_price / 1e9 AS gas_price_gwei
11FROM ethereum."transactions"
12WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
13ORDER BY block_time DESC
14)
15SELECT
16 hash,
17 block_number,
18 block_time,
19 "from",
20 "to",
21 ether,
22 (gas_used * gas_price_gwei) / 1e9 AS txn_fee
23FROM temp_table

Dies liefert dieselben Informationen, die auf der Transaktionsseite von Etherscan bereitgestellt werden. Zum Vergleich sind hier die beiden Quellen:

Etherscan

Screenshot der Etherscan-Transaktionsansicht

Vertragsseite der EF auf Blockscout. (opens in a new tab)

Dune Analytics

Screenshot eines Dune Analytics-Abfrage-Dashboards

Du findest das Dashboard hier (opens in a new tab). Klicke auf die Tabelle, um die Abfrage zu sehen (siehe auch oben).

Transaktionen aufschlüsseln

Eine übermittelte Transaktion enthält mehrere Informationen, darunter (Quelle):

  • Empfänger: Die Empfangsadresse (abgefragt als "to")
  • Signatur: Während der Private-Key eines Senders eine Transaktion signiert, können wir mit SQL die öffentliche Adresse des Senders ("from") abfragen.
  • Wert: Dies ist die Menge an übertragenen ETH (siehe Spalte ether).
  • Daten: Dies sind beliebige Daten, die gehasht wurden (siehe Spalte data).
  • gasLimit – die maximale Menge an Gaseinheiten, die von der Transaktion verbraucht werden kann. Gaseinheiten repräsentieren Rechenschritte.
  • maxPriorityFeePerGas - die maximale Menge an Gas, die als Trinkgeld für den Miner enthalten sein soll.
  • maxFeePerGas - die maximale Menge an Gas, die man bereit ist, für die Transaktion zu zahlen (einschließlich baseFeePerGas und maxPriorityFeePerGas).

Wir können diese spezifischen Informationen für Transaktionen an die öffentliche Adresse der Ethereum Foundation abfragen:

1SELECT
2 "to",
3 "from",
4 value / 1e18 AS ether,
5 data,
6 gas_limit,
7 gas_price / 1e9 AS gas_price_gwei,
8 gas_used,
9 ROUND(((gas_used / gas_limit) * 100),2) AS gas_used_pct
10FROM ethereum."transactions"
11WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
12ORDER BY block_time DESC

Blöcke

Jede Transaktion ändert den Zustand der Ethereum Virtual Machine (EVM) (Quelle). Transaktionen werden an das Netzwerk übertragen, um verifiziert und in einen Block aufgenommen zu werden. Jede Transaktion ist mit einer Blocknummer verknüpft. Um die Daten zu sehen, könnten wir eine bestimmte Blocknummer abfragen: 12396854 (der aktuellste Block unter den Transaktionen der Ethereum Foundation zum Zeitpunkt dieses Schreibens, 11.05.21).

Wenn wir außerdem die nächsten beiden Blöcke abfragen, können wir sehen, dass jeder Block den Hash des vorherigen Blocks (d. h. den Parent-Hash) enthält, was veranschaulicht, wie die Blockchain gebildet wird.

Jeder Block enthält einen Verweis auf seinen übergeordneten Block (Parent-Block). Dies wird unten zwischen den Spalten hash und parent_hash gezeigt (Quelle):

parent_hash

Hier ist die Abfrage (opens in a new tab) auf Dune Analytics:

1SELECT
2 time,
3 number,
4 hash,
5 parent_hash,
6 nonce
7FROM ethereum."blocks"
8WHERE "number" = 12396854 OR "number" = 12396855 OR "number" = 12396856
9LIMIT 10

Wir können einen Block untersuchen, indem wir Zeit, Blocknummer, Schwierigkeit, Hash, Parent-Hash und Nonce abfragen.

Das Einzige, was diese Abfrage nicht abdeckt, ist die Liste der Transaktionen, die eine separate Abfrage unten erfordert, und die State Root. Ein vollständiger oder Archiv-Blockchain-Knoten speichert alle Transaktionen und Zustandsübergänge, sodass Anwendungen den Zustand der Chain jederzeit abfragen können. Da dies großen Speicherplatz erfordert, können wir Chain-Daten von Zustandsdaten trennen:

  • Chain-Daten (Liste von Blöcken, Transaktionen)
  • Zustandsdaten (Ergebnis des Zustandsübergangs jeder Transaktion)

Die State Root fällt in Letzteres und sind implizite Daten (nicht auf der Blockchain gespeichert), während Chain-Daten explizit sind und auf der Chain selbst gespeichert werden (Quelle (opens in a new tab)).

Für dieses Tutorial konzentrieren wir uns auf Daten auf der Blockchain, die mit SQL über Dune Analytics abgefragt werden können.

Wie oben erwähnt, enthält jeder Block eine Liste von Transaktionen. Wir können diese abfragen, indem wir nach einem bestimmten Block filtern. Wir versuchen es mit dem aktuellsten Block, 12396854:

1SELECT * FROM ethereum."transactions"
2WHERE block_number = 12396854
3ORDER BY block_time DESC`

Hier ist die SQL-Ausgabe auf Dune:

Screenshot einer Liste von Ethereum-Transaktionen

Das Hinzufügen dieses einzelnen Blocks zur Chain ändert den Zustand der Ethereum Virtual Machine (EVM). Dutzende, manchmal Hunderte von Transaktionen werden auf einmal verifiziert. In diesem speziellen Fall waren 222 Transaktionen enthalten.

Um zu sehen, wie viele tatsächlich erfolgreich waren, würden wir einen weiteren Filter hinzufügen, um erfolgreiche Transaktionen zu zählen:

1WITH temp_table AS (
2 SELECT * FROM ethereum."transactions"
3 WHERE block_number = 12396854 AND success = true
4 ORDER BY block_time DESC
5)
6SELECT
7 COUNT(success) AS num_successful_txn
8FROM temp_table

Für Block 12396854 wurden von insgesamt 222 Transaktionen 204 erfolgreich verifiziert:

Screenshot einer erfolgreichen Ethereum-Transaktion

Transaktionsanfragen treten dutzende Male pro Sekunde auf, aber Blöcke werden ungefähr alle 15 Sekunden festgeschrieben (Quelle).

Um zu sehen, dass ungefähr alle 15 Sekunden ein Block produziert wird, könnten wir die Anzahl der Sekunden an einem Tag (86400) durch 15 teilen, um eine geschätzte durchschnittliche Anzahl von Blöcken pro Tag (~ 5760) zu erhalten.

Das Diagramm für die pro Tag produzierten Ethereum-Blöcke (2016 - heute) ist:

Diagramm, das die tägliche Ethereum-Blockproduktion zeigt

Die durchschnittliche Anzahl der täglich produzierten Blöcke in diesem Zeitraum beträgt ~5.874:

Diagramm, das die tägliche Ethereum-Blockproduktion zeigt

Die Abfragen lauten:

1# query to visualize number of blocks produced daily since 2016
2
3SELECT
4 DATE_TRUNC('day', time) AS dt,
5 COUNT(*) AS block_count
6FROM ethereum."blocks"
7GROUP BY dt
8OFFSET 1
9
10# average number of blocks produced per day
11
12WITH temp_table AS (
13SELECT
14 DATE_TRUNC('day', time) AS dt,
15 COUNT(*) AS block_count
16FROM ethereum."blocks"
17GROUP BY dt
18OFFSET 1
19)
20SELECT
21 AVG(block_count) AS avg_block_count
22FROM temp_table

Die durchschnittliche Anzahl der pro Tag produzierten Blöcke seit 2016 liegt mit 5.874 leicht über dieser Zahl. Alternativ ergibt die Division von 86400 Sekunden durch durchschnittlich 5874 Blöcke 14,7 Sekunden oder ungefähr einen Block alle 15 Sekunden.

Gas

Blöcke sind in ihrer Größe begrenzt. Die maximale Blockgröße ist dynamisch und variiert je nach Netzwerknachfrage zwischen 12.500.000 und 25.000.000 Einheiten. Limits sind erforderlich, um zu verhindern, dass beliebig große Blockgrößen vollständige Blockchain-Knoten in Bezug auf Speicherplatz und Geschwindigkeitsanforderungen belasten (Quelle).

Eine Möglichkeit, das Block-Gaslimit zu konzeptualisieren, besteht darin, es sich als das Angebot an verfügbarem Blockplatz vorzustellen, in dem Transaktionen gebündelt werden können. Das Block-Gaslimit kann von 2016 bis heute abgefragt und visualisiert werden:

Diagramm, das das durchschnittliche Ethereum-Gaslimit im Zeitverlauf zeigt

1SELECT
2 DATE_TRUNC('day', time) AS dt,
3 AVG(gas_limit) AS avg_block_gas_limit
4FROM ethereum."blocks"
5GROUP BY dt
6OFFSET 1

Dann gibt es das tatsächliche Gas, das täglich verbraucht wird, um für Berechnungen auf der Ethereum-Chain zu bezahlen (z. B. das Senden einer Transaktion, das Aufrufen eines Smart Contracts, das Prägen eines NFTs). Dies ist die Nachfrage nach verfügbarem Ethereum-Blockplatz:

Diagramm, das das täglich verbrauchte Ethereum-Gas zeigt

1SELECT
2 DATE_TRUNC('day', time) AS dt,
3 AVG(gas_used) AS avg_block_gas_used
4FROM ethereum."blocks"
5GROUP BY dt
6OFFSET 1

Wir können diese beiden Diagramme auch nebeneinanderstellen, um zu sehen, wie Angebot und Nachfrage übereinstimmen:

gas_demand_supply

Daher können wir Gaspreise als eine Funktion der Nachfrage nach Ethereum-Blockplatz bei gegebenem Angebot verstehen.

Schließlich möchten wir vielleicht die durchschnittlichen täglichen Gaspreise für die Ethereum-Chain abfragen. Dies führt jedoch zu einer besonders langen Abfragezeit, sodass wir unsere Abfrage auf die durchschnittliche Menge an Gas filtern, die pro Transaktion von der Ethereum Foundation bezahlt wird.

Diagramm, das den täglichen Gasverbrauch der Ethereum Foundation zeigt

Wir können die Gaspreise sehen, die im Laufe der Jahre für alle Transaktionen an die Adresse der Ethereum Foundation gezahlt wurden. Hier ist die Abfrage:

1SELECT
2 block_time,
3 gas_price / 1e9 AS gas_price_gwei,
4 value / 1e18 AS eth_sent
5FROM ethereum."transactions"
6WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
7ORDER BY block_time DESC

Zusammenfassung

Mit diesem Tutorial verstehen wir grundlegende Ethereum-Konzepte und wie die Ethereum-Blockchain funktioniert, indem wir Daten auf der Blockchain abfragen und ein Gefühl dafür bekommen.

Das Dashboard, das den gesamten in diesem Tutorial verwendeten Code enthält, ist hier (opens in a new tab) zu finden.

Für weitere Datennutzung zur Erkundung von Web3 findest du mich auf Twitter (opens in a new tab).

Letzte Aktualisierung der Seite: 3. März 2026

War dieses Tutorial hilfreich?