![]() |
|||||
|
Bibliografia
|
Articoli - Saggi
AppendiceFunzionamento del protocollo BitcoinQuanto accennato nei capitoli precedenti potrebbe essere già più che sufficiente per creare un comprensibile senso di disorientamento in chi nonostante tutto fosse determinato a comprendere a fondo il funzionamento del protocollo Bitcoin. Ci si potrebbe chiedere: per quale motivo c'è bisogno di tanta matematica e informatica per mettere insieme una moneta seppur elettronica come Bitcoin? Potremo forse chiarire meglio la questione partendo da quanto avviene in una ordinaria transazione tra due soggetti - i classici Alice e Bob di tutti gli esempi di crittografia - che utilizzino un mezzo di pagamento che ovviamente non sia la cartamoneta fisica, ad esempio un bonifico bancario o anche PayPal. In questo caso ciò che succede dietro le quinte del programma di home banking di Alice, è una transazione che coinvolge la sua banca e quella di Bob. Dopo aver autenticato Alice, il software verifica che nel suo conto esista la disponibilità richiesta, poniamo 100 €, quindi, in caso affermativo, provvede ad inoltrare la somma specificata a Bob attraverso il protocollo del circuito interbancario. La banca di Bob, ricevuta la richiesta, verifica che esista il conto dell'utente Bob e, in caso affermativo, vi versa la somma che gli è dovuta. A questo punto il conto di Alice viene ridotto di 100 € mentre quello di Bob viene aumentato dello stesso importo e la transazione viene confermata. Ora immaginiamo di voler eseguire la medesima transazione eliminando la necessità di enti terzi ovvero le banche. Avremo cioè la necessità di effettuare la comunicazione di un messaggio (il denaro) tra due soggetti certi (Alice e Bob) attraverso la rete in modo che il destinatario (Bob) sia l'unico beneficiario del denaro inviato dal mittente (Alice). Per riuscire in questo intento possiamo far ricorso alla crittografia asimmetrica e alla firma digitale Nel prossimo paragrafo vedremo quindi come implementare una prima rudimentale trasmissione cifrata di informazioni (la nostra moneta) per esemplificare i concetti base di una criptovaluta. Estenderemo poi questo primo esempio, aggiungendo via via nuove funzionalità, fino a fargli raggiungere la complessità del protocollo Bitcoin. Invio di un messaggio cifrato e firmatoSupponiamo dunque che il messaggio che Alice desidera trasmettere a Bob sia un ordine di pagamento - in realtà, come vedremo meglio in seguito, è la comunicazione nella sua interezza a rappresentare la moneta. Alice provvede a generare in qualche modo - vedremo in seguito come - una coppia di chiavi crittografiche e, con KA-, la sua chiave privata, firma digitalmente il suo messaggio m (ordine di pagamento) per Bob (vedi fig. 2). Possiamo supporre che Alice non usi un mezzo di comunicazione puntuale per raggiungere Bob (come ad esempio la posta elettronica), ma che metta l'informazione a disposizione dell'intera rete. Figura 2: Invio di un messaggio cifrato e firmato.
Bob recupera dalla rete il messaggio e vi applica KA+, la chiave pubblica di Alice. Ciò che ottiene e il messaggio di partenza (l'ordine di pagamento). Questo semplice protocollo, in virtù dei meccanismi crittografici che adotta, assicura Bob che:
Da notare che Bob può determinare senza ombra di dubbio che il messaggio è di Alice senza conoscere la sua chiave privata. Egli infatti ne stabilisce la provenienza utilizzando unicamente la chiave pubblica di Alice. La catena delle transazioniCiò che è avvenuto tra Alice e Bob e che abbiamo appena descritto è una transazione. Prima di considerare i punti deboli di questa prima versione del protocollo, possiamo già intuire da quanto esposto che se dal nostro progetto di criptovaluta vogliamo eliminare del tutto gli enti terzi, ci si pone il problema di chi certifichi che in un dato momento nella disponibilità di Alice ci sia effettivamente la quantità di moneta che essa desidera poi trasferire. Non essendoci un registro centralizzato dei ''conti correnti'' quest'informazione non può che essere distribuita in tutta la rete. Ovvero ogni singolo nodo possiede una copia del registro globale delle transazioni. Quindi, per certificare che Alice possieda in un dato momento x bitcoin, è necessario ripercorrere tutte le transazioni per verificare che la sua disponibilità di moneta ammonti proprio a quella quantità x. Ci serve cioè introdurre una catena delle transazioni (vedi fig. 3). Supponiamo quindi che, in questa nuova versione del protocollo, ciascun utente della rete si doti di una coppia di chiavi crittografiche e si faccia identificare da quella pubblica. Proprio come fosse un indirizzo di posta elettronica, l'indirizzo di Alice sarà la sua chiave pubblica KA+, quella di Bob KB+, e così via. La transazione che abbiamo considerato nel paragrafo precedente è una delle tante che vengono concluse nella rete, diciamo la n+1-esima. La transazione che ha lasciato una certa disponibilità ad Alice è chiaramente quella precedente, la n-esima. Per generare la transazione che porterà dei bitcoin a Bob, Alice crea un messaggio prendendo la chiave pubblica di Bob e la transazione (messaggio) precedente che attesta la sua disponibilità, quindi fa un hash di entrambi e infine firma il tutto con la propria chiave privata KA-. Chiunque partecipi alla rete, per quanto visto nel capitolo precedente, può verificare in autonomia che Bob ha ricevuto il denaro da Alice senza dover conoscere la chiave privata di quest'ultima. Bob a sua volta può confezionare una nuova transazione e trasferire ad un altro soggetto, Carol, la moneta che ha a disposizione e così via. Riassumendo: in una transazione Bitcoin la chiave privata serve per certificare la volontà di trasferire la proprietà della moneta al prossimo beneficiario, mentre la chiave pubblica ha la duplice funzione di indirizzo del beneficiario e di strumento per la verifica del trasferimento. Il registro globale delle transazioni è quindi pubblico sebbene anonimo poiché non c'è modo di risalire all'identità reale degli utenti della rete (vedi fig. 4). In realtà ciascun utente può utilizzare - farsi identificare - da più di una chiave pubblica, può cioè dotarsi di più pseudonimi. Tale pratica è anzi consigliata per ragioni di sicurezza per cui si può arrivare ad impiegare un indirizzo diverso per ogni transazione. Il registro delle transazioni rivisto assume quindi la forma visibile in fig. 5.
La struttura della transazione in dettaglioI grafici delle figure 4 e 5 tradiscono una possibilità fin qui non descritta e tuttavia visibile nei pagamenti che Bob ha effettuato contemporaneamente verso Carol e Alice. E' possibile infatti trasferire una certa quantità di moneta a più di un beneficiario semplicemente creando un messaggio più complesso di quello visto fino adesso. La struttura della transazione in effetti prevede:
Figura 6: Struttura della transazione.
In fig. 6 vediamo una transazione caratterizzata da due input che sono entrambi pseudonimi di Bob, opportunamente firmati con le relative chiavi private. In uscita vediamo due output, di cui uno diretto verso un terzo pseudonimo di Bob. In effetti una particolarità delle transazioni Bitcoin, è che il totale degli input deve pareggiare quella degli output. Quindi se ho la necessità di trasferire solo una parte degli input, posso prevedere un mio pseudonimo tra gli output per far quadrare la transazione. Il protocollo fin qui elaborato tuttavia non è ancora utilizzabile in pratica poiché è inaffidabile. Ad esempio non protegge gli utilizzatori dai seguenti comportamenti malevoli:
Per ovviare a questi inconvenienti è necessario addentrarsi nella parte più complessa del protocollo Bitcoin. La catena dei blocchi
Figura 7: Doppia spesa.
La possibilità di spendere due volte la stessa moneta è rappresentata graficamente nella fig.7. In essa l'utente malevolo B tenta di spendere due volte 12 bitcoin trasferendoli dal suo pseudonimo B2 a due beneficiari, prima a C1 e poi ad A1. Quest'ultima è la transazione fraudolenta. Eliminare questa grave vulnerabilità dalla bozza del nostro protocollo risulta particolarmente ostico in assenza di una parte terza che agisca da ente certificatore. Con quest'ultimo presupposto, nessun altro può svolgere questo ruolo se non la rete stessa degli utenti nella sua globalità. Demandare la verifica della catena delle transazioni all'intera rete risulta comunque complicato. Potrebbe infatti accadere che, effettuato il doppio pagamento, una parte dei nodi vedano per un certo tempo solamente la transazione verso A1, gli altri invece quella verso C1. Risalendo la catena delle transazioni, entrambi i gruppi di nodi potrebbero facilmente e rapidamente verificare che gli importi a disposizione di B sono effettivamente corretti, salvo poi non sapere quale delle due sia la transazione fraudolenta. Un criterio che possiamo introdurre consiste nel considerare come valido solo il pagamento avvenuto per primo in ordine di tempo. Nel nostro caso, solo la transazione effettuata verso C1 è da considerarsi valida. Dobbiamo apportare quindi una prima modifica al protocollo ordinando le transazioni in ordine di tempo. La modifica si traduce in una serializzazione delle transazioni alle quali viene attribuito un identificativo univoco derivato da un hash di tipo SHA-256 dell'intera transazione (vedi fig. 8). Tuttavia questa modifica non è sufficiente. Potrebbe capitare che, per problemi di latenza sulla rete, l'ordine in cui vengono ricevute le transazioni non sia esattamente quello in cui esse sono state create. Marcare le transazioni con un timestamp [1] non risolverebbe nulla poiché un utente fraudolento potrebbe facilmente crearne uno opportuno.
Figura 9: Blocchi di transazioni.
Tuttavia, dopo un po' di tempo, la rete avrebbe evidenza certa della transazione corretta sebbene B2 potrebbe aver già ricevuto un bene in contropartita del pagamento fraudolento ricevuto dall'utente A1. Ovvero prima che la relativa transazione sia stata invalidata dalla rete. Ma qui fa capolino la soluzione: per impedire la doppia spesa è necessario introdurre artificialmente una latenza temporale prima di validare una transazione in sospeso. Una volta validata dalla rete, la transazione viene confermata. Il protocollo Bitcoin ha implementato questa soluzione introducendo il concetto di catena dei blocchi. Le transazioni ancora da confermare vengono raggruppate in un blocco, mentre sarà l'intera rete a stabilire la sua corretta posizione nella catena. La catena dei blocchi funzionalmente rappresenta l'accordo dei nodi della rete sulla corretta sequenza in cui devono trovarsi i singoli blocchi. La conferma di quale sia il prossimo blocco deve essere ottenuta a prezzo di un certo ''lavoro'' speso dai nodi durante il processo di validazione. Questo lavoro consiste nel risolvere un problema matematico creato dal protocollo stesso. La sua durata è proprio la latenza temporale di cui abbiamo descritto la necessità per impedire la doppia spesa. Ma andiamo con ordine. La prova di lavoroUn blocco è strutturato in modo da avere una intestazione (header) che contiene un po' il sommario del suo contenuto: quante transazioni sono presenti con i loro identificativi, l'identificativo del blocco precedente, la versione del protocollo in uso ed altre informazioni ancora (vedi fig. 10). Abbiamo già visto nel capitolo precedente come ciascuna transazione sia stata battezzata con un identificativo univoco ottenuto applicando un hash SHA256 a tutto il suo contenuto informativo. Si tratta ora di replicare questa stessa operazione di hashing a livello di blocco, ma con una sostanziale differenza. Supponiamo che un utente - un nodo - della rete abbia preso in carico un blocco contenente un certo numero di transazioni in sospeso e vediamo nel dettaglio quali operazioni deve compiere per validarlo. Innanzitutto deve verificare che tutte le transazioni nel blocco siano corrette. Ciò significa risalire la catena delle transazioni presente nella propria copia locale del registro globale per verificare che sia tutto in regola. Una volta stabilito che gli importi movimentati dalle transazioni sono corretti, l'utente comunica a tutti gli altri nodi che il blocco è valido e che possono aggiornare a loro volta la propria copia del registro delle transazioni. Per far questo il protocollo Bitcoin impone all'utente di risolvere un problema matematico legato all'hashing del blocco. Supponiamo che l'header del blocco sia costituito dalla stringa:
Concateniamo questa stringa con un nonce [2], ad esempio 1000. Applicando l'hash alla stringa che ne risulta otteniamo:
Il protocollo Bitcoin impone ora che le prime n cifre della stringa risultante siano degli zero. Ciò si può ottenere solamente attraverso un certo numero di prove partendo da un nonce pari a 0 ed incrementandolo di 1 ad ogni tentativo fino a quando non si ottiene una stringa con il desiderato numero di zero in testa. Ad esempio, supponiamo che per la stringa precedente per n = 5 il nonce giusto sia 1234. Avremo quindi:
Il numero n è variabile ed impostato automaticamente dal protocollo in modo che la computazione abbia mediamente un certo costo temporale [3]. Il tempo da impiegare dipende infatti da quanto fortunati si è: il nonce giusto potrebbe essere trovato già con pochi tentativi oppure dopo un bel po' di prove. Il nonce per ottenere un certo numero di zero sulla stringa data è unico. Non appena un nodo della rete lo individua lo comunica a tutti gli altri e questi ultimi possono facilmente verificare che il calcolo è corretto. E' importante notare che cosa comporti legare la validazione di un blocco ad un costo computazionale. Una volta impiegata la CPU per un certo tempo nella prova di lavoro, se cambia il blocco - ad esempio a seguito di un attacco fraudolento - è necessario rieseguire tutto il lavoro. E quando altri blocchi nel frattempo si sono accodati al primo, è necessario modificare pure questi ultimi poiché i blocchi sono collegati tra di loro nella catena (vedi fig. 11). Il costo computazionale diventa allora esorbitante e tale da rendere impossibile sostenerlo poiché antieconomico. Nel suo documento di specifiche, Nakamoto scrive:
Prima di considerare in dettaglio come la catena dei blocchi gestisca eventuali biforcazioni o attacchi fraudolenti, ricapitoliamo il meccanismo del "server di marcatura oraria peer-to-peer" come Satoshi Nakamoto chiama il meccanismo sopra descritto.
Supponiamo ora che per qualche motivo - latenza nella rete o tentativo di attacco -, si produca una biforcazione nella catena dei blocchi (vedi fig. 12). La biforcazione avviene sui blocchi 3a e 3b e su ciascun ramo che ne deriva si accoda una parte dei nodi della rete creando i blocchi in sospeso 4a e 4b (fig. a). La regola per riconciliare la catena prevede che se si verifica una biforcazione, i nodi della rete devono tener traccia dei rami che si generano. Ma, non appena possibile, i nodi devono far evolvere unicamente il ramo che risulta più lungo nella loro copia della catena dei blocchi. Nel nostro esempio, la catena evolve creando il blocco 4b cui si accodano altri utenti della rete che creano il blocco 5 (fig. b). A questo punto i nodi accodatisi sul blocco 4a si spostano sull'altro ramo perché risulta ormai il più lungo (fig. c). Infine i nodi aggiungono il blocco 6 mentre il blocco 3a viene invalidato e le sue transazioni verranno nuovamente inserite in un blocco di transazioni in sospeso (fig. d). Il protocollo Bitcoin stabilisce che una transazione non può ritenersi confermata fino a quando essa non si trova all'interno di un blocco nel ramo più lungo ed esistono come minimo 5 blocchi che lo seguono nella catena più lunga. Si può quindi anche dire che una transazione viene confermata quando ci siano almeno 6 blocchi confermati dopo di esso. Poiché ci vogliono circa 10 minuti per confermare un blocco, per avere ragionevole certezza che una transazione venga confermata, è necessario attendere circa un'ora dalla sua creazione. Man mano che passa il tempo e ci si allontana dal primo blocco, la transazione diventa via via più ''sicura'' fino alla conferma definitiva. Per transazioni con importi consistenti si raccomanda infatti di attendere tutte e 6 le conferme.
Il caso particolare di biforcazione dovuta a doppia spesa ad opera di una transazione fraudolenta non è molto diverso dal caso appena trattato, comprese alcune varianti come ad esempio doppia spesa in cui ci si inserisce come beneficiario fra gli output di una transazione. In ogni caso la catena dei blocchi evolverà fino a invalidare una delle transazioni che hanno prodotto il doppio pagamento. Ma che cosa ci guadagnano i nodi della rete a svolgere un impegnativo lavoro di validazione che richiede un impiego non indifferente - energia elettrica, potenti PC, etc. - di risorse? Mining ovvero la creazione di bitcoinAbbiamo visto che in sostanza la validazione dei blocchi è il risultato di una sorta di competizione tra i nodi della rete. Il protocollo Bitcoin ritiene che la prova-di-lavoro - che comporta spese in energia elettrica, hardware, manutenzione dei server, etc. - sia una attività a tutti gli effetti e che debba essere pertanto remunerata. Per questo motivo, nel momento in cui un nodo vince la lotteria del nonce, viene ricompensato dal protocollo con 50 bitcoin. L'attività di validazione dei blocchi prende il nome di mining [4]. La remunerazione di questa attività si dimezza ogni 4 anni: nel 2009, quando Bitcoin è apparso, la remunerazione era di 50 bitcoin ora è di 25 bitcoin. Da notare che il mining è l'unico modo che Bitcoin mette a disposizione per creare nuova moneta. Il dimezzamento progressivo della remunerazione ha diverse conseguenze. La quantità di bitcoin complessivamente ''estraibili'' è limitata. Poiché in media si valida un blocco ogni 10 minuti, tenendo conto del dimezzamento della moneta, la quantità massima di bitcoin estraibili è di circa 21 milioni. La massa monetaria complessiva è attualmente in crescita ma nel 2140 verrà creato l'ultimo bitcoin [5] (vedi fig. 13).
Per incentivare la continuazione dell'attività di mining anche dopo tale data, è previsto che gli utenti possano aggiungere alle loro transazioni un piccolo importo - una sorta di tassa di trasferimento - affinché i nodi della rete mantengano ancora interesse a validare l'operazione sottoposta alla rete. In futuro le transazioni non saranno verosimilmente più gratuite ma la commissione che si andrà a pagare è in percentuale molto più basse rispetto a quelle degli strumenti ordinari per effettuare pagamenti (carte di credito, PayPal, etc.). Da tenere presente che la più piccola frazione di Bitcoin è il satoshi ovvero un centomilionesimo di Bitcoin. Nella figura 14 è stata evidenziata in rosso la particolare transazione che costituisce la ricompensa per il minatore che ha validato il relativo blocco. Tale transazione, detta anche coinbase, presenta negli input solamente il minatore che l'ha estratta senza indicare alcun predecessore a sottolineare il suo carattere di creazione ex nihilo. Mining poolsPoiché la difficoltà di generare moneta sta aumentando progressivamente - attualmente è necessario un periodo di almeno 2 anni utilizzando computer non troppo performanti -, molti utenti della rete si associano tra di loro per formare dei cosiddetti ''gruppi di minatori'' (in inglese mining pools). In questo modo la potenza computazionale del gruppo aumenta e la possibilità si successo nell'attività estrattiva diventa più concreta. In caso di esito positivo, la ricompensa viene frazionata tra tutti i partecipanti del gruppo in base alla potenza elaborativa portata da ciascuno di loro. Il linguaggio di scriptingIl protocollo Bitcoin è stato disegnato in modo che le proprie transazioni possano usufruire di un linguaggio di scripting [6]. Esempi di script possono essere una macro in Visual Basic piuttosto che un frammento JavaScript richiamato da una pagina HTML. Uno script Bitcoin è essenzialmente una lista di istruzioni associate ad ogni transazione che descrivono come il prossimo beneficiario che desidera spendere il denaro che sta per essere trasferito potrà aver accesso ad esso. Lo script più semplice che possiamo immaginare è di fatto il comportamento che abbiamo sin qui descritto, ovvero la gestione per così dire ''ordinaria'' delle transazioni. Ma sono possibili transazioni ben più complesse al punto che si può parlare a tutti gli effetti di contratti legali implementati elettronicamente (detti anche smart contract in inglese). Ad esempio, fra i diversi tipi di contratti che Bitcoin consente di implementare, si segnalano:
Note:[1] Il timestamp è una sequenza di caratteri che rappresentano una data più un orario per identificare il momento in cui è avvenuto un un certo evento. Si può semplificare dicendo che è l'unione di 7 valori (anno, mese, giorno, ora, minuto, secondo e microsecondo). Ad esempio, un formato possibile per un campo timestamp è il seguente: dd.mm.yyyy.hh:mm.ss.mmm ovvero 11.01.2013.10:35.23.123. [2] Un nonce è un numero arbitrario utilizzato una sola volta in una comunicazione crittografica. [3] Guardando il grafico ci si potrebbe domandare da dove provengano i primi 50 bitcoin. Il blocco numero 0 - talvolta identificato anche con il numero 1 - detto anche genesys block, è stato probabilmente generato dagli stessi creatori di Bitcoin. Curiosamente però, ed eticamente, per una particolarità del protocollo, i 50 bitcoin della ricompensa non possono essere spesi dal loro legittimo proprietario. [4] Dall'inglese, ''attività estrattiva, attività mineraria''. [5] Più correttamente, il protocollo Bitcoin impone che il nonce renda il risultato dell'operazione di hashing inferiore ad un numero prefissato ''basso'' definito come target. [6] Con linguaggio di scripting, in informatica si intende un linguaggio di programmazione interpretato destinato a vari usi attraverso brevi porzioni di codice denominate script. Per approfondimenti sul tema:
|