Imparare gli argomenti fondamentali di Ethereum con SQL
Molti tutorial su Ethereum si rivolgono agli sviluppatori, ma mancano risorse educative per gli analisti di dati o per le persone che desiderano visualizzare i dati onchain senza eseguire un client o un nodo.
Questo tutorial aiuta i lettori a comprendere i concetti fondamentali di Ethereum, tra cui transazioni, blocchi e gas, interrogando i dati onchain con lo structured query language (SQL) attraverso un'interfaccia fornita da Dune Analytics (opens in a new tab).
I dati onchain possono aiutarci a comprendere Ethereum, la rete e la sua economia basata sulla potenza di calcolo, e dovrebbero fungere da base per comprendere le sfide che Ethereum affronta oggi (ad es. l'aumento dei prezzi del gas) e, cosa più importante, le discussioni sulle soluzioni di ridimensionamento.
Transazioni
Il viaggio di un utente su Ethereum inizia con l'inizializzazione di un account controllato dall'utente o di un'entità con un saldo in ETH. Esistono due tipi di account: controllati dall'utente o smart contract (vedi ethereum.org).
Qualsiasi account può essere visualizzato su un block explorer come Etherscan (opens in a new tab) o Blockscout (opens in a new tab). I block explorer sono un portale per i dati di Ethereum. Mostrano, in tempo reale, dati su blocchi, transazioni, minatori, account e altre attività onchain (vedi qui).
Tuttavia, un utente potrebbe voler interrogare i dati direttamente per riconciliare le informazioni fornite dai block explorer esterni. Dune Analytics (opens in a new tab) offre questa capacità a chiunque abbia una certa conoscenza di SQL.
Come riferimento, l'account dello smart contract della Fondazione Ethereum (EF) può essere visualizzato su Blockscout (opens in a new tab).
Una cosa da notare è che tutti gli account, incluso quello della EF, hanno un indirizzo pubblico che può essere utilizzato per inviare e ricevere transazioni.
Il saldo dell'account su Etherscan comprende transazioni regolari e transazioni interne. Le transazioni interne, nonostante il nome, non sono effettive transazioni che cambiano lo stato della catena. Sono trasferimenti di valore avviati dall'esecuzione di un contratto (fonte (opens in a new tab)). Poiché le transazioni interne non hanno una firma, non sono incluse nella blockchain e non possono essere interrogate con Dune Analytics.
Pertanto, questo tutorial si concentrerà sulle transazioni regolari. Queste possono essere interrogate in questo modo:
WITH temp_table AS (
SELECT
hash,
block_number,
block_time,
"from",
"to",
value / 1e18 AS ether,
gas_used,
gas_price / 1e9 AS gas_price_gwei
FROM ethereum."transactions"
WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
ORDER BY block_time DESC
)
SELECT
hash,
block_number,
block_time,
"from",
"to",
ether,
(gas_used * gas_price_gwei) / 1e9 AS txn_fee
FROM temp_table
Questo produrrà le stesse informazioni fornite nella pagina delle transazioni di Etherscan. Per un confronto, ecco le due fonti:
Etherscan
Pagina del contratto della EF su Blockscout. (opens in a new tab)
Dune Analytics
Puoi trovare la dashboard qui (opens in a new tab). Clicca sulla tabella per vedere l'interrogazione (vedi anche sopra).
Analisi delle transazioni
Una transazione inviata include diverse informazioni, tra cui (fonte):
- Destinatario: L'indirizzo di ricezione (interrogato come "to")
- Firma: Mentre le chiavi private di un mittente firmano una transazione, ciò che possiamo interrogare con SQL è l'indirizzo pubblico del mittente ("from").
- Valore: Questo è l'importo di ETH trasferito (vedi la colonna
ether). - Dati: Si tratta di dati arbitrari di cui è stato calcolato l'hash (vedi la colonna
data) - gasLimit – la quantità massima di unità di gas che può essere consumata dalla transazione. Le unità di gas rappresentano i passaggi computazionali
- maxPriorityFeePerGas - la quantità massima di gas da includere come commissione prioritaria al minatore
- maxFeePerGas - la quantità massima di gas che si è disposti a pagare per la transazione (comprensiva di baseFeePerGas e maxPriorityFeePerGas)
Possiamo interrogare queste informazioni specifiche per le transazioni verso l'indirizzo pubblico della Fondazione Ethereum:
SELECT
"to",
"from",
value / 1e18 AS ether,
data,
gas_limit,
gas_price / 1e9 AS gas_price_gwei,
gas_used,
ROUND(((gas_used / gas_limit) * 100),2) AS gas_used_pct
FROM ethereum."transactions"
WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
ORDER BY block_time DESC
Blocchi
Ogni transazione cambierà lo stato della Ethereum Virtual Machine (EVM) (fonte). Le transazioni vengono trasmesse alla rete per essere verificate e incluse in un blocco. Ogni transazione è associata a un numero di blocco. Per vedere i dati, potremmo interrogare un numero di blocco specifico: 12396854 (il blocco più recente tra le transazioni della Fondazione Ethereum al momento in cui scriviamo, 11/5/21).
Inoltre, quando interroghiamo i due blocchi successivi, possiamo vedere che ogni blocco contiene l'hash del blocco precedente (ovvero, l'hash genitore), illustrando come si forma la blockchain.
Ogni blocco contiene un riferimento al suo blocco genitore. Questo è mostrato di seguito tra le colonne hash e parent_hash (fonte):
Ecco l'interrogazione (opens in a new tab) su Dune Analytics:
SELECT
time,
number,
hash,
parent_hash,
nonce
FROM ethereum."blocks"
WHERE "number" = 12396854 OR "number" = 12396855 OR "number" = 12396856
LIMIT 10
Possiamo esaminare un blocco interrogando l'ora, il numero del blocco, la difficoltà, l'hash, l'hash genitore e il nonce.
L'unica cosa che questa interrogazione non copre è l'elenco delle transazioni, che richiede un'interrogazione separata di seguito, e la radice di stato (state root). Un nodo completo o di archivio memorizzerà tutte le transazioni e le transizioni di stato, consentendo ai client di interrogare lo stato della catena in qualsiasi momento. Poiché ciò richiede un ampio spazio di archiviazione, possiamo separare i dati della catena dai dati di stato:
- Dati della catena (elenco di blocchi, transazioni)
- Dati di stato (risultato della transizione di stato di ogni transazione)
La radice di stato rientra in questi ultimi e rappresenta dati impliciti (non memorizzati onchain), mentre i dati della catena sono espliciti e memorizzati sulla catena stessa (fonte (opens in a new tab)).
Per questo tutorial, ci concentreremo sui dati onchain che possono essere interrogati con SQL tramite Dune Analytics.
Come affermato in precedenza, ogni blocco contiene un elenco di transazioni; possiamo interrogarlo filtrando per un blocco specifico. Proveremo con il blocco più recente, 12396854:
SELECT * FROM ethereum."transactions"
WHERE block_number = 12396854
ORDER BY block_time DESC`
Ecco l'output SQL su Dune:
L'aggiunta di questo singolo blocco alla catena cambia lo stato della Ethereum Virtual Machine (EVM). A volte dozzine, centinaia di transazioni vengono verificate contemporaneamente. In questo caso specifico, sono state incluse 222 transazioni.
Per vedere quante hanno effettivamente avuto successo, aggiungeremmo un altro filtro per contare le transazioni riuscite:
WITH temp_table AS (
SELECT * FROM ethereum."transactions"
WHERE block_number = 12396854 AND success = true
ORDER BY block_time DESC
)
SELECT
COUNT(success) AS num_successful_txn
FROM temp_table
Per il blocco 12396854, su 222 transazioni totali, 204 sono state verificate con successo:
Le richieste di transazione si verificano dozzine di volte al secondo, ma i blocchi vengono confermati circa una volta ogni 15 secondi (fonte).
Per verificare che venga prodotto un blocco circa ogni 15 secondi, potremmo prendere il numero di secondi in un giorno (86400) diviso per 15 per ottenere un numero medio stimato di blocchi al giorno (~ 5760).
Il grafico dei blocchi di Ethereum prodotti al giorno (dal 2016 a oggi) è:
Il numero medio di blocchi prodotti quotidianamente in questo periodo di tempo è di ~5.874:
Le interrogazioni sono:
# query to visualize number of blocks produced daily since 2016
SELECT
DATE_TRUNC('day', time) AS dt,
COUNT(*) AS block_count
FROM ethereum."blocks"
GROUP BY dt
OFFSET 1
# average number of blocks produced per day
WITH temp_table AS (
SELECT
DATE_TRUNC('day', time) AS dt,
COUNT(*) AS block_count
FROM ethereum."blocks"
GROUP BY dt
OFFSET 1
)
SELECT
AVG(block_count) AS avg_block_count
FROM temp_table
Il numero medio di blocchi prodotti al giorno dal 2016 è leggermente superiore a quel numero, attestandosi a 5.874. In alternativa, dividendo 86400 secondi per una media di 5874 blocchi si ottengono 14,7 secondi, ovvero circa un blocco ogni 15 secondi.
Gas
I blocchi hanno dimensioni limitate. La dimensione massima del blocco è dinamica e varia in base alla domanda della rete tra 12.500.000 e 25.000.000 di unità. I limiti sono necessari per evitare che dimensioni dei blocchi arbitrariamente grandi mettano a dura prova i nodi completi in termini di spazio su disco e requisiti di velocità (fonte).
Un modo per concettualizzare il limite di gas del blocco è pensarlo come l'offerta di spazio disponibile nel blocco in cui raggruppare le transazioni. Il limite di gas del blocco può essere interrogato e visualizzato dal 2016 a oggi:
SELECT
DATE_TRUNC('day', time) AS dt,
AVG(gas_limit) AS avg_block_gas_limit
FROM ethereum."blocks"
GROUP BY dt
OFFSET 1
Poi c'è il gas effettivo utilizzato quotidianamente per pagare il calcolo eseguito sulla catena di Ethereum (ad es. l'invio di una transazione, la chiamata a uno smart contract, il conio di un NFT). Questa è la domanda di spazio disponibile nei blocchi di Ethereum:
SELECT
DATE_TRUNC('day', time) AS dt,
AVG(gas_used) AS avg_block_gas_used
FROM ethereum."blocks"
GROUP BY dt
OFFSET 1
Possiamo anche giustapporre questi due grafici per vedere come si allineano domanda e offerta:
Pertanto possiamo comprendere i prezzi del gas come una funzione della domanda di spazio nei blocchi di Ethereum, data l'offerta disponibile.
Infine, potremmo voler interrogare i prezzi medi giornalieri del gas per la catena di Ethereum; tuttavia, farlo comporterà un tempo di interrogazione particolarmente lungo, quindi filtreremo la nostra interrogazione in base alla quantità media di gas pagata per transazione dalla Fondazione Ethereum.
Possiamo vedere i prezzi del gas pagati per tutte le transazioni effettuate verso l'indirizzo della Fondazione Ethereum nel corso degli anni. Ecco l'interrogazione:
SELECT
block_time,
gas_price / 1e9 AS gas_price_gwei,
value / 1e18 AS eth_sent
FROM ethereum."transactions"
WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
ORDER BY block_time DESC
Riepilogo
Con questo tutorial, comprendiamo i concetti fondamentali di Ethereum e come funziona la blockchain di Ethereum interrogando e prendendo confidenza con i dati onchain.
La dashboard che contiene tutto il codice utilizzato in questo tutorial può essere trovata qui (opens in a new tab).
Per un ulteriore utilizzo dei dati per esplorare il Web3 trovami su Twitter (opens in a new tab).










