Una delle tecnologie su cui si basano le cryptovalute, tra cui Bitcoin, e’ l’ algoritmo chiamato Proof-Of-Work (POW), ma di cosa si tratta?

Funzione Hash

Per capire come la proof-of-work è in grado di mettere in sicurezza la rete Bitcoin, bisogna capire come funziona il suo elemento principale, la funzione hash. La funzione hash può essere vista come una scatola che frulla e mischia quello che gli si mette dentro (input) e restituisce in uscita (output) un altro valore di dimensione fissa.
Esistono diversi tipi di funzioni hash, ma la maggior parte ha le seguenti caratteristiche:

  1. Indipendentemente dalle dimensioni dell’input, l’output avrà sempre la stessa grandezza. Ad esempio SHA-256 (la funzione hash usata in Bitcoin) ha un output di 256 bit. Questo significa che esistono infiniti valori di ingresso che generano lo stesso valore in uscita, ma se l’insieme dei possibili valori di uscita è sufficientemente ampio, trovare due valore identici sarà praticamente impossibile. In realtà alcune funzioni hash si sono dimostrate vulnerabili proprio a questo attacco, chiamato collision attack (ad esempio MD5).
  2. Dato un output non è possibile risalire all’input che lo ha generato, se non provando tutte le combinazioni possibili.
  3. Una piccola modifica del valore di ingresso, cambia interamente il valore di uscita. E’ impossibile dati 2 valori di uscita capire che gli input sono simili.
  4. E’ impossibile trovare due valori di ingresso tali per cui il valore di uscita sia identico.

Vediamo alcuni esempi di hash SHA-256:

sha256(“https://www.cryptoitalia.org”) = 1.140285 e+76
sha256(“cerutti gino”) = 3.372745e+76
sha256(“Cerutti Gino”) = 1.062060e+77

Nei tre esempi abbiamo modificato dimensioni e contenuto degli input passati alla funzione SHA256 ed in uscita abbiamo semplici numeri (mostrati in notazione scientifica).

Notare che in ingresso avremmo potuto inserire l’intera Divina Commedia ed il risultato sarebbe stato indistinguibile dagli altri.

Puzzle Friendliness

Immaginiamo di voler fare una sfida di questo tipo: in una competizione tra più soggetti vince chi trova una seconda parola da appendere a “Cerutti Gino”, in modo che il suo hash abbia un valore inferiore a 1.0e+76. Le possibili soluzioni al quiz sono infinite, ma l’unico modo per trovarne una (come abbiamo visto non e’ possibile dato un output risalire al suo input) e’ effettuare diversi tentativi finché non abbiamo un risultato che ci soddisfa. Ad esempio aggiungendo dei numeri si ottengono i seguenti risultati (qui un semplice script in ruby per replicare):

sha256(“Cerutti Gino”) = 1.062060e+77
sha256(“Cerutti Gino 0”) = 3.513323e+76
sha256(“Cerutti Gino 1”) = 7.238681e+75
sha256(“Cerutti Gino 2”) = 1.148018e+77
sha256(“Cerutti Gino 3”) = 1.155217e+77
sha256(“Cerutti Gino 4”) = 1.618563e+76
sha256(“Cerutti Gino 5”) = 1.011127e+77
sha256(“Cerutti Gino 6”) = 1.155818e+77
sha256(“Cerutti Gino 7”) = 2.284173e+76
sha256(“Cerutti Gino 8”) = 7.995554e+76
sha256(“Cerutti Gino 9”) = 7.452182e+76
sha256(“Cerutti Gino 10”) = 1.056836e+77

Il biglietto vincente e’ quello con il valore “Cerutti Gino 1”. Da notare che più è basso il valore che ci poniamo come soglia nel quiz e piu difficile sara’ trovare una soluzione valida. Il limite e’ la ricerca di un valore uguale a 0, che equivarrebbe violare la regola 4 tra quelle dette sopra.

POW di Bitcoin

In Bitcoin l’input della funzione hash non è altro che l’header di un blocco, il quale contiene anche uno spazio di memoria chiamato nonce. Questo valore è quello che i miner modificano alla ricerca di una combinazione che generi un hash con un valore inferiore al valore specificato in nBits (valore sempre contenuto nell’header), il quale è derivato dalla difficulty della rete.
La rete Bitcoin oggi richiede degli output di valore talmente basso che i miner stanno lavorando ad un ritmo di circa 8,464,247,238,000,000,000 hash per ogni secondo.

Aggiustamento della difficulty

Nell’esempio che abbiamo fatto, abbiamo definito come valido qualsiasi risultato il cui hash risultante ha un valore inferiore a 1.0e+76. La rete Bitcoin per mantenere una generazione di blocchi mediamente costante a 6 blocchi per ora modifica questo valore regolarmente. Il parametro da cui e’ dedotto il nuovo valore del puzzle e’ chiamato difficulty e cambia ogni 2016 blocchi. Il calcolo della nuova difficulty avviene controllando il tempo passato per generare questi 2016 blocchi e cambiando il valore precedente in proporzione. Ad esempio se l’hash power e’ aumentato del 10% ci dovremmo aspettare circa 6.6 blocchi ogni ora anziché i 6 previsti, quindi l’algoritmo deve aumentare la difficulty e diminuire il valore soglia del puzzle.

Perché c’è bisogno della POW in Bitcoin?

Innanzitutto per dimostrare di aver speso energia elettrica nella creazione di un nuovo blocco, inserendo quindi una barriera economica a protezione della rete, infatti un attaccante che volesse scrivere o riscrivere dei blocchi validi dovrebbe “spendere” milioni di dollari in elettricità. Questa barriera poi si adatterà man mano che il valore dell’intera rete aumenta, perché quando il mining diventa profittevole economicamente nuovi attori entreranno in gioco, aumentando anche la difficoltà.
In secondo luogo variando la difficoltà del quiz, la rete si auto-aggiusta mantenendo costanti un flusso di circa 6 blocchi nuovi ogni ora, e scandendo cosi il tempo nella blockchain.