Catena di blocchi - "Blockchain"


La catena di blocchi rappresenta il registro pubblico di Bitcoin, una registrazione delle transazioni ordinata e con data e ora.  Questo sistema viene utilizzato per prevenire la doppia spesa e la modifica dei record delle transazioni precedenti.



Ogni nodo completo nella rete Bitcoin memorizza in modo indipendente una catena di blocchi contenente solo blocchi convalidati da quel nodo. Quando diversi nodi hanno tutti gli stessi blocchi nella loro catena di blocchi, sono considerati in consenso. Le regole di convalida che seguono questi nodi per mantenere il consenso sono chiamate regole di consenso.


L'illustrazione sopra mostra una versione semplificata di una catena a blocchi.

Un blocco di una o più nuove transazioni viene raccolto nella parte dei dati di transazione di un blocco. Viene realizzato l’hash della copia di ogni transazione, gli hash vengono poi accoppiati e viene generato un nuovo hash, così via fino ad avere un singolo hash, ovvero la “merkle root” del “merkle tree”.

La merkle root è memorizzata nell'intestazione del blocco. Ogni blocco memorizza anche l'hash dell'intestazione (header) del blocco precedente, concatenando i blocchi. Ciò garantisce che una transazione non possa essere modificata senza modificare il blocco che la registra e tutti i blocchi successivi.

Anche Le transazioni sono concatenate. I wallet Bitcoin danno l'impressione che i satoshi siano inviati da e verso i portafogli, in realtà i bitcoin passano da una transazione all'altra. Ogni transazione spende i satoshi precedentemente ricevuti in una o più transazioni precedenti, quindi l'input di una transazione è l'output di una transazione precedente.


Una singola transazione può creare più output, come nel caso di invio a più indirizzi, ma ogni output di una determinata transazione può essere utilizzata come input una sola volta nella catena di blocchi. Ogni riferimento successivo è una doppia spesa proibita: un tentativo di spendere lo stesso satoshi due volte.


Gli output sono legati agli identificatori di transazione (TXID), che sono gli hash delle transazioni firmate.

Poiché ogni output di una determinata transazione può essere speso una sola volta, gli output di tutte le transazioni incluse nella blockchain possono essere classificati come output di transazioni non spesate (UTXO) o output di transazioni spesi. Affinché un pagamento sia valido, deve utilizzare solo UTXO come input.


Ignorando le transazioni coinbase (descritte più avanti), se il valore degli output di una transazione supera i suoi input, la transazione verrà rifiutata, ma se gli input superano il valore delle uscite, qualsiasi differenza di valore può essere richiesta come commissione di transazione dal minatore che crea il blocco contenente quella transazione.





Proof of work


La catena di blocchi è gestita in modo collaborativo da peer anonimi sulla rete. Il protocollo richiede che ciascun blocco dimostri che è stata investita una quantità significativa di lavoro per assicurare che i peer non attendibili che desiderano modificare blocchi passati debbano lavorare più duramente dei pari onesti che solo voglio aggiungere nuovi blocchi alla catena di blocchi.



Il concatenamento di blocchi rende impossibile modificare le transazioni incluse in qualsiasi blocco senza modificare tutti i blocchi successivi. Di conseguenza, il costo per modificare un particolare blocco aumenta con ogni nuovo blocco aggiunto alla catena di blocchi, potenziando l'effetto della prova di lavoro (proof of work).

La dimostrazione del lavoro usato in Bitcoin sfrutta la natura apparentemente casuale degli hash crittografici. Un buon algoritmo crittografico di hash converte dati arbitrari in un numero apparentemente casuale. Se i dati vengono modificati in qualsiasi modo e l'hash viene rigenerato, viene prodotto un nuovo numero apparentemente casuale, quindi non c'è modo di modificare i dati per rendere prevedibile il numero di hash.

Per dimostrare che hai fatto del lavoro extra per creare un blocco, devi creare un hash dell'intestazione del blocco che non superi un determinato valore. Ad esempio, se il valore hash massimo consentito è 2256-1, è possibile provare di aver provato fino a due combinazioni producendo un valore hash inferiore a 2255.


È anche possibile stimare la probabilità che un determinato tentativo di hash generi un numero inferiore alla soglia target. Bitcoin presuppone una probabilità lineare dove più basso è il limite di soglia, più tentativi di hash (in media) dovranno essere provati.


I nuovi blocchi verranno aggiunti alla catena di blocchi solo se il loro hash è almeno altrettanto impegnativo di un valore di difficoltà previsto dal protocollo di consenso. Ogni 2.016 blocchi, la rete utilizza i timestamp memorizzati in ciascuna intestazione del blocco per calcolare il numero di secondi trascorsi tra la generazione del primo e l'ultimo di quegli ultimi 2.016 blocchi. Il valore ideale è 1,209,600 secondi (due settimane).


•Se sono state necessarie meno di due settimane per generare i 2.016 blocchi, il valore di difficoltà previsto aumenta proporzionalmente (fino al 300%) in modo che i successivi 2.016 blocchi richiedano esattamente due settimane per generare se gli hash vengono controllati alla stessa velocità.


•Se occorrono più di due settimane per generare i blocchi, il valore di difficoltà atteso viene diminuito proporzionalmente (fino al 75%) per lo stesso motivo.


(Nota: un errore di off-by-one nell'implementazione di Bitcoin Core fa sì che la difficoltà venga aggiornata ogni 2.016 blocchi usando timestamp da soli 2.015 blocchi, creando un leggero sfasamento.)


Poiché ogni intestazione di blocco deve dare un hash con valore inferiore alla soglia di target e poiché ogni blocco è collegato al blocco che lo ha preceduto, richiede (in media) tanta potenza di hashing per propagare un blocco modificato quanto l'intera rete Bitcoin ha speso tra il tempo in cui il blocco originale è stato creato e il tempo presente.

 

Solo se hai acquisito la maggior parte della potenza di hashing della rete potresti eseguire in modo affidabile un attacco del 51% contro la cronologia delle transazioni (sebbene, si noti, anche meno del 50% della potenza di hashing abbia ancora buone possibilità di eseguire tali attacchi).


L'intestazione del blocco fornisce diversi campi facili da modificare, ad esempio un campo nonce dedicato, pertanto ottenere nuovi hash non richiede l'attesa di nuove transazioni. Inoltre, solo l'intestazione del blocco di 80 byte è sottoposta a hash per la prova di lavoro, quindi includere un grande volume di dati di transazione in un blocco non rallenta l'hashing con extra Input/Output e inserire dati di transazione aggiuntivi richiede solo il ricalcolo dell’hash antenato nel merkle tree.



Block Height And Forking


Qualsiasi minatore che ha eseguito con successo l’hash di un'intestazione di blocco con valore inferiore alla soglia target può aggiungere l'intero blocco alla catena di blocchi. Questi blocchi sono comunemente indicizzati dall'altezza del loro blocco (block height), ovvero il numero di blocchi tra loro e il primo blocco Bitcoin (blocco 0, più comunemente noto come blocco genesi).


Ad esempio, il blocco 2016 è il luogo in cui la difficoltà potrebbe essere stata modificata per la prima volta.


Blocchi multipli possono presentare la stessa altezza del blocco, come è comune quando due o più minatori producono ciascuno un blocco all'incirca nello stesso tempo. Questo crea una biforcazione (fork) apparente nella catena di blocchi, come mostrato nella figura sopra.

Quando i minatori producono blocchi simultanei alla fine della catena di blocchi, ciascun nodo sceglie individualmente quale blocco accettare. In assenza di altre considerazioni, discusse di seguito, i nodi solitamente usano il primo blocco che “vedono”.

Successivamente un minatore produce un altro blocco che si lega a uno solo dei blocchi concorrenti simultaneamente. Questo rende quel lato della catena più “forte” dell'altro. Supponendo che un fork contenga solo blocchi validi, i peer normali seguiranno sempre la catena più difficile per ricreare e rigettare i blocchi obsoleti che appartengono alle catena più corta. (I blocchi obsoleti sono talvolta chiamati anche blocchi orfani, questo termine viene anche usato per veri blocchi orfani senza un blocco genitore conosciuto).

Le biforcazioni (fork) a lungo termine sono possibili se diversi minatori lavorano a scopi incrociati, come ad esempio alcuni minatori che lavorano diligentemente per estendere la catena di blocchi nello stesso momento in cui altri minatori tentano un attacco del 51 percento per rivedere la cronologia delle transazioni.

Poiché più blocchi possono avere la stessa altezza durante una biforcazione della catena, l'altezza del blocco non deve essere utilizzata come identificatore univoco globale. Invece, i blocchi sono di solito referenziati dall'hash della loro intestazione (spesso con l'ordine dei byte invertito e in esadecimale).



Dati di transazione


Ogni blocco deve includere una o più transazioni. La prima di queste transazioni deve essere una transazione coinbase, anche chiamata transazione di generazione, che dovrebbe raccogliere e spendere il premio del blocco (composto da un sussidio per il blocco e qualsiasi commissione di transazione pagata per le transazioni incluse in questo blocco).


L'UTXO di una transazione coinbase ha la condizione speciale che non possa essere speso (utilizzato come input) per almeno 100 blocchi. Ciò impedisce temporaneamente a un minatore di spendere le commissioni di transazione ed il premio del blocco che potrebbe essere successivamente considerato obsoleto (e quindi la transazione coinbase distrutta) dopo un fork della catena a blocchi.


I blocchi non devono necessariamente contenere transazioni oltre alla coinbase, ma i minatori includono quasi sempre transazioni aggiuntive al fine di incassare le loro commissioni di transazione.


Tutte le transazioni, inclusa la transazione coinbase, sono codificate in blocchi nel formato row transactions binario.


Il formato raw transaction viene sottoposto a hash per creare l'identificativo della transazione (txid). Da questi txid, l'albero di merkle viene costruito accoppiando ciascun txid con un altro txid e poi eseguendo l'hashing insieme. Se c'è un numero dispari di txid, il txid senza un partner viene sottoposto a hash con una copia di se stesso.

Il processo si ripete finché rimane solo un hash, la radice di merkle (merkle root).


Come discusso nella sottosezione SPV (Simplified Payment Verification), l'albero di merkle consente ai client di verificare da soli che una transazione è stata inclusa in un blocco ottenendo la radice di merkle da un'intestazione di blocco e un elenco degli hash intermedi da un peer completo. Non è necessario fidarsi del peer completo: è costoso falsificare le intestazioni dei blocchi e gli hash intermedi non possono essere falsificati o la verifica fallirà.


Ad esempio, per verificare la transazione D è stata aggiunta al blocco, un client SPV ha solo bisogno di una copia degli hash C, AB ed EEEE oltre alla radice di merkle; il cliente non ha bisogno di sapere nulla su nessuna delle altre transazioni. Se le cinque transazioni in questo blocco fossero tutte della massima dimensione, il download dell'intero blocco richiederebbe oltre 500.000 byte, ma il download di tre hash e l'intestazione del blocco richiedono solo 140 byte.




Modifiche alle regole di consenso


Per mantenere il consenso, tutti i nodi completi convalidano i blocchi usando le stesse regole di consenso. Tuttavia, a volte le regole di consenso vengono modificate per introdurre nuove funzionalità o impedire l'abuso della rete.


Quando vengono implementate le nuove regole, ci sarà probabilmente un periodo di tempo in cui i nodi non aggiornati seguiranno le vecchie regole e i nodi aggiornati seguiranno le nuove regole, creando due possibili modi in cui il consenso (quindi la catena) può rompersi:

1.Un blocco che segue le nuove regole di consenso è accettato dai nodi aggiornati ma respinto dai nodi non aggiornati. Ad esempio, all'interno di un blocco viene utilizzata una nuova funzione di transazione: i nodi aggiornati comprendono la funzione e la accettano, ma i nodi non aggiornati la rifiutano perché violano le vecchie regole.

2.Un blocco che viola le nuove regole di consenso viene respinto dai nodi aggiornati ma accettato dai nodi non aggiornati. Ad esempio, all'interno di un blocco viene utilizzata una funzione di transazione abusiva: i nodi aggiornati lo rifiutano perché violano le nuove regole, ma i nodi non aggiornati lo accettano perché seguono le vecchie regole.

Nel primo caso, il software di mining che ottiene i dati della catena di blocchi da quei nodi non aggiornati si rifiuta di costruire sulla stessa catena. Ciò crea una divergenza permanentemente nelle catene, una per i nodi non aggiornati e una per i nodi aggiornati, denominata hard fork.


 

Nel secondo caso, il rifiuto da parte dei nodi aggiornati, è possibile mantenere la catena di blocchi senza divergenze permanenti se i nodi aggiornati controllano la maggior parte di hash rate.


Questo perché, in questo caso, i nodi non aggiornati accettano come validi tutti gli stessi blocchi dei nodi aggiornati, quindi i nodi aggiornati possono creare una catena più “forte” che i nodi non aggiornati accetteranno come la migliore catena di blocchi valida (quella con più proof of work). Questo processo è definito soft fork.




Rilevazione delle biforcazioni (fork)


I nodi non aggiornati possono utilizzare e distribuire informazioni errate durante entrambi i tipi di fork, creando diverse situazioni che potrebbero portare a perdite finanziarie e destabilizzazioni della rete.


In particolare, i nodi non aggiornati possono inoltrare e accettare transazioni considerate non valide dai nodi aggiornati e quindi non diventeranno mai parte della migliore e universalmente riconosciuta catena di blocchi. I nodi non aggiornati possono anche rifiutare di inoltrare blocchi o transazioni che sono già stati aggiunti alla miglior catena di blocchi, o che lo saranno presto, e quindi fornire informazioni incomplete.


Bitcoin Core include nel codice una funzione che rileva un hard fork osservando la proof of work della catena. Se un nodo non aggiornato riceve intestazioni della catena di blocchi che dimostrano almeno sei proof of work di blocchi superiori alla catena che considera valida, il nodo segnala un avviso nei risultati di getnetworkinfo RPC ed esegue il comando -alertnotify se impostato. Ciò avverte l'operatore che il nodo non aggiornato non può passare a quella che è probabilmente la migliore catena di blocchi.


I nodi completi possono anche controllare i numeri di versione di blocco e transazione. Se i numeri di versione del blocco o della transazione visti in diversi blocchi recenti sono superiori ai numeri di versione utilizzati dal nodo, si può presumere che non utilizzi le attuali regole di consenso. Bitcoin Core segnala questa situazione tramite il comando getnetworkinfo RPC e -alertnotify se impostato.

In entrambi i casi, blocchi e dati di transazioni non dovrebbero essere considerati affidabili se provengono da un nodo che apparentemente non sta utilizzando le attuali regole di consenso.

I client SPV che si connettono a nodi completi possono rilevare un probabile fork, collegandosi a diversi nodi completi e assicurandosi che siano tutti sulla stessa catena con la stessa altezza del blocco (più o meno). Se c'è una divergenza, il client può disconnettersi dai nodi con catene più deboli.

I client SPV devono anche monitorare gli aumenti del numero di versione del blocco e della transazione per garantire che elaborino le transazioni ricevute e creino nuove transazioni utilizzando le attuali regole di consenso.


Tradotto da: bitcoin.org