Tutto è iniziato con il white paper di Bitcoin, un documento esplicativo sul concetto di una tecnologia su cui che, oggi, non ci sono dubbi. Bitcoin e la sua tecnologia sottostante, la blockchain, sono diventati una delle più grandi rivoluzioni tecnologiche degli ultimi tempi. Questo concept permette di creare applicazioni dalle potenzialità incredibili, visto che c'è ancora molto da scoprire, anche al di fuori del settore finanziario, per il quale è stato inizialmente creato.
Ma come è iniziato tutto?
Come abbiamo spiegato nell'articolo su "Chi ha creato Bitcoin?", Satoshi Nakamoto ha pubblicato un documento in un forum nel 2008. In esso, ha teoricamente definito a Mezzo di pagamento globale senza intermediari tra gli utenti. Un ecosistema fatto di pezzi combinati mai visti fino ad oggi. Il documento, con una presentazione in stile accademico, si chiama "Bitcoin Paper", e puoi verificarlo qui.
Successivamente, vi lasciamo la versione tradotta in spagnolo del white paper di Bitcoin.
Bitcoin: un Sistema di Contanti Elettronico Peer-to-Peer
Satoshi Nakamoto
satoshin@gmx.com
www.bitcoin.org
Riassunto
Una versione puramente elettronica del contante consentirebbe l'invio diretto di pagamenti online, da un'entità all'altra. Tutto questo, senza dover passare attraverso un istituto finanziario. Le firme digitali forniscono parte della soluzione al problema, ma i vantaggi principali vengono persi se deve esistere una terza parte fidata per impedire la la doppia spesa:. Proponiamo una soluzione al problema della doppia spesa utilizzando una rete user-to-user.
La rete contrassegna l'ora delle transazioni che inserisce in una catena continua di prove di lavoro basate su calcoli hash. Così, si sta formando un record che non può essere modificato senza ricreare la prova completa del lavoro. La catena più lunga non serve solo come token e prova della sequenza di eventi, ma garantisce anche che provenga dal pool con la maggiore elaborazione della CPU.
Purché la maggior parte della potenza d'elaborazione della CPU sia sotto il controllo di nodi che non cooperano per attaccare la rete. In questo modo genereranno la catena più lunga e avranno un vantaggio sugli attaccanti. La rete stessa richiede una struttura minima. I messaggi vengono inviati sulla base del minimo sforzo e i nodi possono lasciare e ricongiungersi alla rete ogni volta che lo ritengono opportuno. Accettando sempre la catena più lunga di prove di lavoro, come prova di ciò che è accaduto durante la tua assenza.
Introduzione
Il commercio su Internet è arrivato a fare affidamento esclusivamente su istituzioni finanziarie, che fungono da terze parti fidate, per l'elaborazione dei pagamenti elettronici. Sebbene il sistema funzioni abbastanza bene per la maggior parte delle transazioni, soffre ancora delle debolezze intrinseche del modello basato sulla fiducia. Le transazioni completamente irreversibili non sono realmente possibili, perché le istituzioni finanziarie non possono evitare la mediazione nelle controversie.
Il costo della mediazione aumenta i costi di transazione. Ciò limita la dimensione pratica minima per transazione ed elimina la possibilità di effettuare piccole transazioni casuali, essendo un costo più elevato per questa perdita e l'impossibilità di effettuare pagamenti irreversibili per servizi non reversibili. Con la possibilità di inversione, il bisogno di fiducia si espande. I commercianti dovrebbero prendersi cura dei propri clienti, tormentandoli per ottenere più informazioni di quelle altrimenti necessarie.
Una certa percentuale di frode è accettata come inevitabile. Questi costi e incertezze nei pagamenti possono essere evitati se la persona utilizza denaro fisico. Ma non esiste alcun meccanismo per effettuare pagamenti attraverso un canale di comunicazione senza una terza parte fidata. Ciò che serve è un sistema di pagamento elettronico basato su prove crittografiche piuttosto che sulla fiducia. Ciò ha lo scopo di consentire alle due parti interessate di effettuare transazioni direttamente senza la necessità di una terza parte di fiducia. Le transazioni che sono computazionalmente impraticabili da annullare proteggerebbero i venditori dalle frodi. Allo stesso modo, i meccanismi di deposito a garanzia di routine potrebbero essere facilmente messi in atto per proteggere gli acquirenti.
In questo lavoro, proponiamo una soluzione al problema della doppia spesa utilizzando un timestamp server distribuito da utente a utente per generare una prova computazionale dell'ordine cronologico delle transazioni. Il sistema è sicuro fintanto che i nodi onesti controllano collettivamente più potenza di elaborazione (CPU) di qualsiasi gruppo di nodi attaccanti.
Transazioni
Definiamo una valuta elettronica come una catena di firme digitali. Ogni proprietario trasferisce la moneta al successivo firmando digitalmente un hash della transazione precedente e la chiave pubblica del successivo proprietario e aggiungendo entrambi alla fine della moneta. Un beneficiario può verificare le firme per verificare la catena di proprietà.
Il problema è che il beneficiario non può verificare se qualcuno dei precedenti proprietari non abbia speso due volte la moneta. La soluzione comune è introdurre un'autorità centrale di fiducia. Una specie di zecca, che controllerebbe se ogni transazione ha una doppia spesa o meno. Dopo ogni transazione, la moneta deve essere restituita alla zecca per generare una nuova moneta. In questo modo, si fa affidamento per non avere la doppia spesa solo sulle monete generate direttamente da questa zecca.
Il problema con questa soluzione è che il destino dell'intero sistema monetario dipende dalla società che gestisce la zecca, con tutte le transazioni che devono attraversarla, proprio come farebbe una banca. Pertanto, dobbiamo trovare un modo per far sapere al beneficiario che i precedenti proprietari non hanno firmato alcuna transazione precedente.
Per i nostri scopi, l'ultima o la prima transazione è quella che conta. Quindi non ci preoccuperemo di ulteriori tentativi di doppia spesa. L'unico modo per confermare l'assenza di una transazione è conoscere tutte le transazioni esistenti. Nel modello della zecca, era la zecca che era a conoscenza di tutte le transazioni e decideva quali venivano prima. Per raggiungere questo obiettivo senza una terza parte fidata, le transazioni devono essere annunciate pubblicamente [1], e avremo bisogno di un sistema di partecipanti che concordino su un'unica storia, dell'ordine in cui queste transazioni sono state ricevute. Il beneficiario deve sapere che al momento di ogni transazione, la maggior parte dei nodi concorda su quale sia stato ricevuto per primo.
Timestamp server
La soluzione che proponiamo inizia con un server timestamp. Funziona un server timestamp hashing di un blocco di dati da datare e pubblicarlo ampiamente, proprio come faresti in un giornale o in un post di Usenet [2-5]. Il timestamp dimostra che i dati ovviamente dovevano esistere in quel momento per essere inclusi nei dati. hash. Ogni timestamp include il timestamp precedente nel suo hash, formando una catena, in modo che ogni timestamp aggiuntivo rafforzi i precedenti.
Proof of Work
Per implementare un server timestamp da utente a utente, dovremo utilizzare un sistema di prova del lavoro simile a hashcash di Adam Back [6], piuttosto che usare un giornale o un post su Usenet. La prova del lavoro implica la scansione di un valore, tale che, quando si calcola un hash, come SHA-256, inizia con un certo numero di bit con valore zero. Il lavoro medio richiesto sarà esponenziale al numero di bit richiesti con valore nullo ma che può essere verificato eseguendo un singolo hash.
Per la nostra rete di timestamp implementiamo la proof-of-work aumentando il valore di un campo nonce, appartenente al blocco, fino a trovare un valore che dia il numero di bit richiesto con valore zero per l'hash dello stesso. Una volta che lo sforzo della CPU è stato speso per soddisfare la Proof of Work, il blocco non può essere modificato senza rifare tutto il lavoro. Poiché più blocchi sono concatenati dopo uno dato, il lavoro per modificare un blocco includerebbe la ripetizione di tutti i blocchi dopo questo.
La prova di lavoro risolve anche il problema di determinare come rappresentare la decisione della maggioranza. Se questa maggioranza fosse basata su un voto per indirizzo IP, potrebbe essere manomessa da qualcuno in grado di assegnare molti IP. La prova di lavoro è essenzialmente "una CPU-un voto". La decisione maggioritaria è rappresentata dalla catena più lunga, che ha la prova del lavoro con il massimo sforzo investito.
Se la maggior parte della potenza della CPU è controllata da nodi onesti, la catena onesta crescerà più velocemente e lascerà indietro qualsiasi altra catena in competizione. Per modificare un blocco in passato, un utente malintenzionato avrebbe dovuto ripetere la prova di lavoro del blocco e di tutti i blocchi successivi, per poi recuperare e surpassare il lavoro dei nodi onesti.
Mostreremo quindi che la probabilità che un attaccante più lento possa raggiungere la catena più lunga diminuisce in modo esponenziale man mano che si incorporano i blocchi successivi.
Per compensare la maggiore velocità dell'hardware e l'interesse variabile nell'esecuzione dei nodi nel tempo, la difficoltà della proof of work è determinata da una media mobile diretta da un numero medio di blocchi all'ora. Se vengono generati molto rapidamente, la difficoltà aumenta.
La rete
I passaggi che la rete esegue sono i seguenti:
- Le nuove transazioni vengono emesse a tutti i nodi.
- Ogni nodo raccoglie nuove transazioni in un blocco.
- Ogni nodo lavora per trovare una proof of work difficile per il suo blocco.
- Quando un nodo trova una proof of work, emette il blocco a tutti i nodi.
- Il blocco viene accettato dai nodi se tutte le transazioni nel blocco sono state convalidate e non spese.
- I nodi esprimono la loro accettazione del blocco lavorando alla creazione del blocco successivo nella catena, utilizzando l'hash del blocco accettato come l'hash precedente.
La stringa più lunga è sempre considerata quella corretta. e iniziano a lavorare per estenderlo. Se due nodi trasmettono contemporaneamente versioni diverse del blocco successivo, alcuni nodi potrebbero ricevere prima l'una o l'altra. In tal caso, lavorano sul primo che ricevono ma salvano l'altro ramo nel caso in cui si allunghi. Il pareggio si rompe quando viene trovata la successiva prova di lavoro e un ramo si allunga; i nodi che stavano lavorando sull'altro ramo vengono successivamente passati a quello che ora è più lungo.
Non è necessario che le emissioni di nuove transazioni raggiungano tutti i nodi. Quando raggiungono molti nodi, finiranno per entrare in un blocco in breve tempo. L'emissione dei blocchi è anche tollerante alla perdita di messaggi. Se un nodo non riceve un blocco, lo chiederà quando ne riceverà il successivo e si accorgerà di averne perso uno.
Incentivo
Per convenzione, la prima transazione nel blocco è una transazione speciale che genera una nuova valuta di proprietà del creatore del blocco, in questo modo si aggiunge un incentivo per i nodi a supportare la rete e fornisce un modo iniziale per distribuire e far circolare le monete, poiché non esiste l'autorità per crearle. Questa aggiunta stabile di una quantità costante di nuove monete è analoga ai cercatori d'oro che spendono risorse per metterla in circolazione. Nel nostro caso, le risorse sono il tempo della CPU e l'elettricità che vengono spesi.
L'incentivo può essere stabilito anche con i costi di transazione. Se il valore di output di una transazione è inferiore all'input, la differenza sarà una commissione di transazione che verrà aggiunta al valore di incentivo del blocco che lo contiene. Una volta che un numero predeterminato di monete è entrato in circolazione, l'incentivo può trasformarsi interamente in commissioni di transazione ed essere completamente privo di inflazione.
L'incentivo può anche aiutare ad incoraggiare i nodi a rimanere onesti. Se un attaccante egoista è in grado di raccogliere più potenza della CPU di tutti i nodi onesti, dovrebbe scegliere tra usarlo per frodare le persone rubando i loro pagamenti o usarlo per generare nuove monete. Dovresti trovare più redditizio giocare secondo le regole, poiché ti favoriranno con più monete rispetto alla combinazione di tutti gli altri nodi, piuttosto che compromettere il sistema e la validità della tua stessa ricchezza.
Richiesta di spazio su disco
Una volta che l'ultima transazione è stata sepolta sotto un numero sufficiente di blocchi, le transazioni spese prima di questa possono essere scartate per risparmiare spazio su disco. Per facilitare ciò senza rompere l'hash del blocco, le transazioni vengono controllate in un albero di Merkle[XNUMX] [XNUMX] [XNUMX], con solo la radice inclusa nell'hash del blocco. I vecchi blocchi possono essere compattati rimuovendo i rami dall'albero. Gli hash interni non devono essere salvati.
L'intestazione di un blocco senza transazioni sarà di circa 80 byte. Se assumiamo che ogni blocco venga generato ogni 10 minuti, 80 byte * 6 * 24 * 365 = 4.2 MB all'anno. Con i computer generalmente forniti con 2 GB di RAM nel 2008 e la legge di Moore che prevede una crescita attuale di 1.2 GB all'anno, l'archiviazione non dovrebbe essere un problema anche se le intestazioni dei blocchi devono rimanere in memoria.
Verifica dei pagamenti semplificata
È possibile verificare i pagamenti senza eseguire un nodo di rete completo. Un utente deve solo conservare una copia delle intestazioni di blocco della catena più lunga della prova di lavoro, che può essere ottenuta cercando i nodi della rete fino a convincersi che hanno la catena più lunga e ottenendo il ramo dell'albero di Merkle che collega la transazione al blocco in cui era datata. Sebbene tu non possa verificare tu stesso la transazione, collegandoti ad essa da qualche parte nella catena, puoi vedere che è stata accettata da qualche nodo sulla rete, quindi i blocchi aggiunti successivamente confermerebbero ulteriormente questa accettazione da parte della rete.
Pertanto, la verifica è affidabile fintanto che i nodi onesti controllano la rete, ma diventa più vulnerabile se la rete viene rilevata da un utente malintenzionato. Mentre i nodi di rete possono verificare le transazioni da soli, il metodo semplificato può essere ingannato da transazioni fabbricate da un utente malintenzionato fintanto che l'attaccante può dominare la rete. Una strategia per proteggersi è accettare avvisi dai nodi di rete quando rilevano un blocco non valido, chiedendo all'utente di scaricare l'intero blocco e le transazioni allertate per confermare l'incoerenza. Le aziende che ricevono spesso pagamenti vorranno eseguire i propri nodi per una sicurezza più indipendente e una verifica più rapida.
Combinare e dividere il valore
Sebbene sia possibile manipolare le valute individualmente, sarebbe difficile gestire transazioni separate per ogni centesimo di trasferimento. Per consentire la divisione e la combinazione del valore, le transazioni contengono vari input e output. In genere ci sarà un singolo input, da una precedente transazione più grande, o più input che combinano importi minori e almeno due output: una per il pagamento e una per restituire l'eventuale modifica all'emittente .
Bisogna tener conto del fatto che questo sistema è a ventaglio, quindi una transazione può dipendere da più transazioni, e questi a loro volta possono dipendere da molti altri, il che non è un problema. Non è mai necessario estrarre una singola copia completa della cronologia delle transazioni.
Privacy
Il modello bancario tradizionale raggiunge il suo livello di privacy limitando l'accesso alle informazioni alle parti coinvolte e alla terza parte di fiducia. La necessità di annunciare pubblicamente tutte le transazioni preclude questo metodo, ma la privacy può ancora essere mantenuta interrompendo il flusso di informazioni altrove: mantenere le chiavi pubbliche anonime. Si può vedere pubblicamente che qualcuno sta inviando un certo importo a un'altra persona, ma senza informazioni che riguardino la transazione a una determinata persona. Questo è simile al livello di informazioni visualizzate nelle borse, dove l'ora e l'entità delle singole transazioni, il "nastro", sono pubbliche, ma senza dire chi sono le parti.
Come firewall aggiuntivo, è necessario utilizzare una nuova coppia di chiavi per ogni transazione in modo che possano essere associate a un proprietario comune. Sono inevitabili alcuni tipi di associazione con transazioni multi-ticket, che possono rivelare che i loro biglietti appartengono allo stesso proprietario. Il rischio sarebbe che se viene rivelato il proprietario di una chiave, il linker potrebbe rivelare altre transazioni che gli appartenevano.
Calcoli
Consideriamo lo scenario in cui un utente malintenzionato cerca di generare una stringa alternativa più velocemente della stringa onesta. Anche se ciò fosse realizzato, non aprirebbe il sistema a cambiamenti arbitrari, come la creazione di valore dal nulla o il prelievo di denaro che non è mai appartenuto all'aggressore. I nodi non accetterebbero una transazione non valida come pagamentoe i nodi onesti non accetteranno mai un blocco che li contiene. Un utente malintenzionato può tentare di modificare solo le proprie transazioni per recuperare denaro che ha speso di recente.
La corsa tra una catena onesta e la catena di un attaccante si distingue come un Binomial Random Walk (passeggiata aleatoria binomiale). L'evento di successo è la catena onesta che estende un blocco aggiuntivo e aumenta il suo vantaggio di +1, e l'evento di fallimento è la catena dell'attaccante che estende un blocco riducendo la distanza di -1.
La probabilità che un attaccante possa colpirci, da un dato deficit, è analoga al problema Player Ruin. Supponiamo che un giocatore con credito illimitato inizi in deficit e potenzialmente giochi un numero infinito di tentativi per cercare di pareggiare. Possiamo calcolare con che probabilità riesca a raggiungere il breakeven, o che raggiunga la catena onesta, come segue [8]:
p = probabilità che un nodo onesto trovi il blocco successivo
q = probabilità che l'attaccante trovi il blocco successivo q
qz= probabilità che l'attaccante raggiunga da z blocchi indietro.
Data la nostra ipotesi che p > q, la probabilità diminuisce esponenzialmente, mentre aumenta il numero di blocchi che l'attaccante deve raggiungere. Con le probabilità contro di te, se non fai una giocata fortunata all'inizio, le tue possibilità diventano estremamente ridotte man mano che rimani indietro.
Consideriamo ora quanto tempo deve attendere il destinatario di una nuova transazione prima di essere sufficientemente certo che l'emittente non possa modificarla. Supponiamo che l'emittente sia un utente malintenzionato che vuole far credere al beneficiario di essere stato pagato per un po ', quindi cambiare la transazione per ripagarsi, dopo che è trascorso un po' di tempo. Il beneficiario verrà avvisato quando ciò accadrà, ma il mittente spera che sia troppo tardi.
Il beneficiario genera una nuova coppia di chiavi e consegna la chiave pubblica all'emittente subito dopo la firma. Così facendo impedisce all'emittente di preparare una blockchain in anticipo, lavorandoci continuamente fino a quando non sarà così fortunato da essere andato avanti abbastanza per poter eseguire la transazione. Una volta inviata la transazione, il mittente non autorizzato inizia a lavorare segretamente su una catena parallela che contiene una versione alternativa della transazione.
Il destinatario attende che la transazione venga aggiunta a un blocco e che z blocchi siano stati collegati dopo la transazione. Non è necessario conoscere l'esatta quantità di progressi compiuti dall'attaccante, ma supponendo che i blocchi onesti abbiano preso la media prevista per blocco, il potenziale progresso dell'attaccante sarà un Distribuzione di Poisson con un valore atteso di:
Per ottenere la probabilità che l'attaccante possa ancora raggiungerci ora, moltiplichiamo la densità di Poisson per la quantità di progresso che avrebbe potuto fare per la probabilità che potesse raggiungere quel punto:
Riorganizziamo per evitare la somma della coda infinita della distribuzione ...
Convertiamo in codice C ...
#include double AttackerSuccessProbability (double q, int z) {double p = 1.0 - q; doppia lambda = z * (q / p); doppia somma = 1.0; int io, k; for (k = 0; k <= z; k ++) {doppio poisson = exp (-lambda); for (i = 1; i <= k; i ++) poisson * = lambda / i; sum - = poisson * (1 - pow (q / p, z - k)); } restituisce la somma; }
Eseguiamo alcuni risultati, possiamo vedere che la probabilità cade esponenzialmente con z.
q=0.1 z=0 P=1.0000000 z=1 P=0.2045873 z=2 P=0.0509779 z=3 P=0.0131722 z=4 P=0.0034552 z=5 P=0.0009137 z=6 P=0.0002428 z=7 P=0.0000647 z=8 P=0.0000173 z=9 P=0.0000046 z=10 P=0.0000012 q=0.3 z=0 P=1.0000000 z=5 P=0.1773523 z=10 P=0.0416605 z=15 P=0.0101008 z=20 P=0.0024804 z=25 P=0.0006132 z=30 P=0.0001522 z=35 P=0.0000379 z=40 P=0.0000095 z=45 P=0.0000024 z=50 P=0.0000006
Risolviamo per P inferiore allo 0.1% ...
P > 0.001 q=0.10 z=5 q=0.15 z=8 q=0.20 z=11 q=0.25 z=15 q=0.30 z=24 q=0.35 z=41 q=0.40 z=89 q=0.45 z=340
Conclusioni
Abbiamo proposto un sistema di transazioni elettroniche che non dipende dalla fiducia. Iniziamo con il consueto quadro di monete realizzate sulla base dell'uso di firme digitali, che prevede un forte controllo della proprietà, ma che è incompleto se non c'è modo di prevenire la doppia spesa. Per risolvere questo problema, proponiamo una rete da utente a utente che utilizza la prova del lavoro per registrare una cronologia pubblica delle transazioni e che diventa rapidamente irrisolvibile dal punto di vista computazionale per un utente malintenzionato che voglia modificarla, se i nodi onesti controllano la maggior parte della CPU energia.
Una rete robusta per la sua semplicità non strutturata. I nodi possono lavorare tutti contemporaneamente con poco coordinamento. Non è necessario identificarli, poiché i messaggi non vengono indirizzati a un luogo particolare e devono essere recapitati solo al meglio. I nodi possono entrare e uscire dalla rete a piacimento, accettando la catena della prova di lavoro come prova di ciò che è accaduto mentre erano assenti. Votano con la loro potenza della CPU, esprimendo la loro accettazione di blocchi validi lavorando estendendo e rifiutando blocchi non validi rifiutandosi di lavorare su di essi. Eventuali regole o incentivi necessari possono essere applicati con questo meccanismo di consenso.
Riferimenti
- [1] W. Dai, "b-money", https://www.weidai.com/bmoney.txt 1998.
- [2] H. Massias, XS Avila e J.-J. Quisquater,“Design of a secure timestamping service with minimal trust requirements”, in 20th Symposium on Information Theory in the Benelux, maggio 1999.
- [3] S. Haber, WS Stornetta, "How to time-stamp a digital document", In Journal of Cryptology, vol 3, no 2, pages 99-111, 1991.
- [4] D. Bayer, S. Haber, WS Stornetta,“Improving the efficiency and reliability of digital time-stamping”, In Sequences II: Methods in Communication, Security and Computer Science, pagine 329-334, 1993.
- [5] S. Haber, WS Stornetta, "Secure names for bit-string", In Proceedings of the 4th ACM Conference on Computer and Communications Security, pagine 28-35, aprile 1997.
- [6] A. Back, "Hashcash - a denial of service counter-measure", https://www.hashcash.org/papers/hashcash.pdf 2002.
- [7] RC Merkle, "Protocols for public key cryptosystems," In Proc. 1980 Symposium on Security and Privacy, IEEE Computer Society, pagine 122-133, aprile 1980.
- [8] W. Feller,“An introduction to probability theory and its applications” 1957.