Validazione di transazioni e blocchi
Come avevamo anticipato nel precedente articolo, ogni qualvolta una transazione arriva a un nodo della rete, questo provvede a validarla, ossia esegue tutta una serie di controlli formali sulla struttura della transazione, per decidere se questa rispetti o meno le regole del sistema. Alcuni esempi di questi controlli sono:
- la lista degli UTXO d’ingresso non può essere vuota;
- la lista degli UTXO d’uscita non può essere vuota;
- tutti gli UTXO di input non devono essere presenti in nessuna delle transazioni precedentemente confermate (non è ammessa la doppia spesa);
- la somma dei satoshi negli UTXO d’ingresso deve essere maggiore o uguale alla somma dei satoshi negli UTXO d’uscita;
- la dimensione della transazione in bytes deve essere inferiore o uguale al limite massimo consentito (definito a livello di algoritmo).
Oltre a quelli appena visti, ci sono altri controlli, per un totale di alcune decine di regole da rispettare: una lista esaustiva, anche se non definitiva, può essere trovata a pagina 178 del libro Mastering Bitcoin 2nd Edition di Andreas M. Antonopoulos [0]. Va osservato che questo elenco è dinamico nel tempo, ossia le regole possono essere aggiunte, modificate o rimosse per gestire nuove necessità che emergano nell’ecosistema Bitcoin. Ad esempio, potrebbe essere necessario rafforzare o aggiungere nuove regole per prevenire particolari tipi di attacchi informatici, oppure rilassarne o rimuoverne altre per ampliare la tipologia di transazioni gestibili dal sistema.
Se anche uno solo di questi controlli non è rispettato, la transazione viene scartata dal nodo e non propagata al resto della rete; in caso contrario, invece, viene diffusa. Per le transazioni che risultano valide, se il nodo che le riceve è di tipo miner, ossia partecipa al processo di mining, le raccoglie in una particolare memoria, detta mempool transactions, in attesa di essere utilizzate per formare un nuovo blocco della catena.
Controlli sui blocchi
Un processo analogo a quello appena visto per le transazioni viene eseguito da ogni nodo anche su tutti i blocchi che riceve. Le uniche differenze rispetto al processo precedente sono il set di regole da rispettare, definito ad hoc per queste particolari strutture, e la destinazione finale dei blocchi validi, che entreranno a far parte della blockchain.
Di seguito, alcuni degli esempi più significativi delle regole sui blocchi:
- la prima transazione del blocco deve essere la coinbase transaction, ossia un particolare tipo di transazione generabile solo dai miner;
- i successivi 50 KB di spazio in ogni blocco devono essere riservati alle transazioni priotitarie (a breve vedremo quali sono);
- la dimensione del blocco in bytes deve essere inferiore o uguale al limite massimo consentito di 1 MB (definito a livello di algoritmo);
- l’hash header del blocco deve rispettare il livello di difficoltà attuale del sistema (vedremo più avanti cosa questo vuol dire).
Selezione delle transazioni da eseguire
Prima di analizzare come avviene il processo di mining, ossia cosa sia e come si risolve la prova di lavoro (o proof of work o POW), vediamo come ogni nodo seleziona il set di transazioni che utilizza per costruire il blocco.
Innanzitutto definiamo cosa sia una transazione prioritaria. Una transazione viene definita prioritaria rispetto alle altre se almeno uno dei suoi UTXO d’ingresso è più vecchio di tutti gli altri UTXO presenti nel mempool del blocco. Dato che, per rispettare una delle regole di validazione, i primi 50 KB dello spazio dedicato alle transazioni deve essere utilizzato per quelle prioritarie, la prima cosa che un miner fa è scegliere dal proprio mempool un numero sufficiente di queste entità. Grazie a questo vincolo, il sistema risulta più equo e meno manipolabile. Infatti, prioritizzare le transazioni più vecchie vuol dire consentire a chiunque, anche a chi non può pagare le commissioni di rete, di veder eseguita prima o poi la propria operazione: più tempo passa dalla creazione della stessa, più i suoi UTXO diventano vecchi.
Successivamente, il miner sceglie a proprio piacere le altre transazioni, fino a riempire lo spazio a esse dedicato all’interno del blocco. Normalmente, la regola seguita per selezionare queste altre entità dal mempool è di massimizzare le commissioni da esse ottenute, così da guadagnare più bitcoin possibili, nel caso in cui riesca a risolvere per primo la prova di lavoro.
Una nota importante: ogni qualvolta una transazione viene selezionata per essere aggiunta a un blocco, questa viene automaticamente rimossa dal mempool!
Coinbase transaction
Infine il miner calcola la coinbase transaction, ossia la prima transazione che dovrà far parte del blocco, per soddisfare l’ennesima regola di validazione dello stesso. Questa transazione rappresenta la quantità di satoshi che il miner dovrà ricevere nel caso in cui sia effettivamente lui a risolvere la proof of work attuale. Il calcolo dei bitcoin presenti in questa entità è dato dalla somma delle commissioni derivanti dalle altre transazioni selezionate più la ricompensa attuale per aver aggiunto l’ennesimo blocco alla catena; vedremo più avanti cos’è e quanto vale questo parametro. Dato che chiunque può partecipare al mining del network, l’utilizzo di questa entità per distribuire i nuovi bitcoin emessi dal sistema rende tale processo il più equo possibile.
Una peculiarità della coinbase transaction è di essere l’unica a non avere UTXO di input e ad avere un solo UTXO di output!
Il mining di Bitcoin
Selezionate le transazioni che fanno parte del blocco in costruzione, si può procedere al calcolo dei parametri della sua intestazione. Per semplificare la spiegazione di questo processo, ricapitoliamo velocemente quali sono i campi dell’header:
- il numero della versione del software di validazione;
- l’hash dell’header del blocco precedente;
- il merkle root delle transazioni del blocco;
- l’istante di generazione del blocco, nel formato timestamp;
- l’obiettivo di difficoltà attuale del sistema;
- il nonce del blocco, ossia un numero intero non negativo, che può essere impostato a piacimento dal miner.
Per quanto riguarda il numero della versione del software di validazione, l’hash dell’header del blocco precedente e l’obiettivo di difficoltà attuale del sistema, questi risultano noti a priori e indipendenti dal contenuto del blocco in questione.
Infatti, il primo cambia solo quando viene aggiornato il software di Bitcoin, il secondo è determinato non appena il blocco precedente entra a far parte della blockchain, e il terzo è ricalcolato una volta ogni circa due settimane in base alla potenza di calcolo del network (più avanti faremo un approfondimento su questo parametro).
Viceversa, gli altri tre parametri vanno calcolati basandosi sulle informazioni contenute nel blocco. In particolare, il merkle root delle transazioni è calcolabile solamente una volta definite tutte le transazioni presenti all’interno del blocco, e il timestamp di generazione del blocco è automaticamente impostato non appena il parametro precedente è valorizzato. A questo punto, il nonce risulta essere l’unico parametro “incognito” nella costruzione del blocco.
“Minare” un blocco
Fare il mining di un blocco Bitcoin — quel che comunemente viene definito “minare” — non vuol dire altro che determinare un nonce tale per cui l’hash dell’header del blocco risulti minore, o uguale, al target di difficoltà attuale del sistema. L’operatività del generico miner è così riassumibile: imposta il nonce a un valore intero non negativo, calcola l’hash dell’header attuale, e controlla se questo rispetta il target di difficoltà. In caso affermativo, il processo di mining è concluso, il miner ha trovato la soluzione, e quindi, oltre ad aggiungere il blocco alla catena, si aggiudica i bitcoin della sua coinbase transaction; altrimenti, si itera il processo appena visto, previa modifica del nonce.
Se, durante questa ricerca, un altro miner trova la soluzione per primo, allora l’operazione di mining del nodo s’interrompe, e quest’ultimo deve aggiornare sia la propria copia della blockchain che il relativo mempool.
Due ulteriori note imporanti
In tutto questo processo, ci sono due note da tenere ben presenti.
Per prima cosa, si ricorda che l’impostazione iniziale del nonce è a discrezione del miner, così come la variazione successiva; quindi, in teoria, ogni miner lavora su un proprio insieme di nonces distinto da quello degli altri miner.
Come secondo aspetto, va notato che esistono sicuramente più nonces che risolvono il puzzle crittografico: il problema è trovarne almeno uno ed essere i più veloci a farlo!
Problema computazionale
Sebbene questo processo sembri semplice, in realtà risulta essere un problema computazionalmente molto oneroso. Infatti, non solo ogni miner esegue una miriade di calcoli crittografici, ma questa operazione si ripete continuamente circa ogni 10 minuti (tempo medio di elaborazione di un blocco Bitcoin). A oggi, maggio 2023, per eseguire il mining di un singolo elemento della blockchain, sono richiesti mediamente alcuni milioni di miliardi di miliardi di calcoli crittografici, motivo per cui questo processo viene definito prova di lavoro o proof of work (o POW). Infatti, ognuna delle precedenti elaborazioni richiede il consumo di una certa quantità d’energia, che rappresenta appunto la prova dello svolgimento di un lavoro.
Risolvere la “doppia spesa”
Grazie all’utilizzo della proof of work, combinata con la blockchain, Bitcoin è riuscito dove tutti i suoi predecessori hanno fallito, ossia ha risolto elegantemente il problema della doppia spesa [1] delle monete, senza dover ricorre all’ausilio di una terza parte (centralizzata) che faccia da garante. Infatti, durante la fase di validazione delle transazioni, è possibile controllare nella blockchain se le monete che si vogliono spendere sono effettivamente in possesso dell’entità che vuole spenderle (si controlla la doppia spesa rispetto al passato), mentre durante la fase di mining, potendo un solo blocco vincere la gara e non potendo avere lo stesso UTXO d’ingresso conteggiato più volte all’interno delle sue transazioni, eventuali doppie spese nel presente sono impossibili.
Risolvere i rischi per Bitcoin
Dato che Bitcoin è un sistema peer-to-peer, ossia una rete di computer che cooperano su internet, e che ogni attore di questa infrastruttura risulta (quasi) anonimo, il network si trova continuamente esposto a tutta una serie di minacce informatiche, nonché a operare in condizioni di mancanza di fiducia costante tra le part: non a caso si parla di sistema trustless. L’inventore di Bitcoin, Satoshi Nakamoto, ha risolto elegantemente questi problemi, utilizzando in maniera massiva la teoria dei giochi [2] nella programmazione del sistema.
In parole povere, ha costruito un insieme di incentivi/disincentivi, per promuovere fra i partecipanti i comportamenti onesti (cooperazione), anziché quelli disonesti (defezione). Questi incentivi sono di natura economica, e vengono messi in atto proprio attraverso il processo di mining. Infatti, essendo questo molto dispendioso in termini energetici, chi segue le regole e supporta il sistema può competere per vincere la prova di lavoro e guadagnare la reward del blocco, mentre chi agisce slealmente, cercando di eseguire transazioni non legali o sabotare il network, si ritrova ad aver sprecato energia elettrica senza la possibilità di ottenere la ricompensa: transazioni o blocchi farlocchi vengono intercettati e scartati da tutti gli attori onesti della rete.
Di seguito un elenco dei principali benefici che il mining conferisce a Bitcoin:
- evita l’esecuzione di transazioni fraudolente: non è possibile eseguire la doppia spesa;
- mette in sicurezza il network da attacchi DoS/DDoS [3] che cercano di congestionare il sistema: avendo ogni transazione un costo monetario, è impossibile intasare la rete senza spendere una fortuna;
- emette nuova moneta distribuendola in maniera equa fra tutti i suoi partecipanti: grazie all’utilizzo della coinbase transaction;
- esegue gli scambi monetari fra gli utilizzatori del network: tutte le transazioni nel blocco aggiunto alla catena andranno nello stato confermato e i loro destinatari potranno spendere i bitcoin ricevuti;
- garantisce l’immutabilità dello strato economico del sistema: essendo maggiori gli incentivi economici ad agire onestamente, si porta la rete a mettersi al riparo da un attacco al 51% (vedremo successivamente cosa questo vuole dire);
- permette il raggiungimento del consenso distribuito (approfondiremo quest’argomento nel prossimo articolo).
Conclusioni
Comprese la validazione e il mining del sistema Bitcoin, non ci rimane che parlare del consenso distribuito e dei fork. Questi temi saranno affrontati nel prossimo articolo.
Riferimenti
[0] Andreas M. Antonopoulos, Mastering Bitcoin, 2nd edition. O’Reilly, 2017
https://www.oreilly.com/library/view/mastering-bitcoin-2nd/9781491954379/
[1] Definizione di Doppia spesa da Wikipedia
https://it.wikipedia.org/wiki/Doppia_spesa.
[3] Definizione di Attacco DoS e DDoS da Wikipedia
https://it.wikipedia.org/wiki/Denial_of_service.
[2] Definizione di Teoria dei giochi da Wikipedia
https://it.wikipedia.org/wiki/Teoria_dei_giochi