Almanacco > Inediti
15 Febbraio 2018

Come creare una criptomoneta

Scarica l'inedito in PDF!

Per scaricare l’articolo in pdf bisogna essere iscritti alla newsletter di cheFare, completando il campo qui sotto l’iscrizione è automatica.

Inserisci i dati richiesti anche se sei già iscritto e usa un indirizzo email corretto e funzionante: ti manderemo una mail con il link per scaricare il PDF.

Se inserisci il tuo indirizzo mail riceverai la nostra newsletter. Questa è la nostra informativa privacy

Tutti parlano in questi giorni parlano di criptomonete. Per chi volesse essere “apprendista stregone” presentiamo di seguito una breve guida su come creare una propria valuta virtuale. Per ragioni di semplicità, questo articolo descriverà come effettuare la procedura sul sistema operativo Mac OS X, dovrebbe essere possibile replicare il processo senza difficoltà su qualsiasi altro sistema operativo (in particolare su Linux). In ogni caso, più che alle tecniche di ogni singolo passo (l’accumularsi di prove ed errori rappresenta l’assoluta norma) conviene invece focalizzarsi più sul senso di quello che stiamo facendo. L’idea di questo articolo non è di trasformare i lettori in sviluppatori nel giro di poche pagine, quanto nel capire cosa stiamo facendo e perché lo stiamo facendo. A tale proposito abbiamo deciso di modificare non direttamente il codice di Bitcoin, ma di un suo fork (derivato dalle medesime librerie di base) Litecoin. La scelta ha esclusivamente ragioni di comodità, la differenza principale rispetto a Bitcoin è che questo sistema per effettuare l’hashing non utilizza la funzione SHA-256, ma un’altra nota come Scrypt, una funzione di derivazione di chiave basata su password.

Ora interroghiamoci su quali potrebbero essere le caratteristiche di questa nuova valuta.

Quasi a esorcizzare la potenza terribile contenuta nel denaro, la maggior parte delle valute presentano dei simboli sacri, o comunque sembrano fare riferimento a un universo soprannaturale. Decidiamo di pagare il nostro personale omaggio a questa tradizione rivolgendoci anche noi al soprannaturale, dedicando la moneta a una divinità che ci ha sempre aiutato nei momenti di difficoltà, Cthulhu.

Fonte: Cthulhu Offerings http://cthulhu.tk Cthulhu Offerings è un altro progetto che fonde la tecnologia delle criptomonete con le ispirazioni tratte dalla mitologia creata da Howard Phillips Lovecraft. L’iniziativa non ha alcuna relazione con il CthulhuCoin qui descritto.

Con il cuore colmo di devozione per i grandi antichi, andiamo quindi sulla pagina del progetto Litecoin (https://github. com/litecoin-project/litecoin), e cloniamo in locale il codice sorgente sul nostro desktop. In alternativa, possiamo anche scaricare tutto il pacchetto come un unico file zip. I tasti sul browser sono i seguenti:

Chiamiamo la directory in cui andiamo a clonare il progetto rinominandolo CthulhuCoin. Teoricamente, dovremmo creare un fork sul GitHub del progetto Litecoin chiamandolo CthulhuCoin, e poi lavorare direttamente lì sopra. Tuttavia ai fini della nostra piccola panoramica questi passaggi non sono strettamente necessari.

In alternativa, è possibile procedere anche da riga di comando. Vi sarà sufficiente creare una directory di nome CthulhuCoin con questo comando:

mkdir CthulhuCoin

E lanciare quindi il seguente comando:

git clone https://github.com/litecoin-project/ litecoin.git CthulhuCoin/

Il processo di download porterà via qualche minuto. Se non lo avete già, installate brew, che vi aiuterà nella gestione dei pacchetti con le dipendenze (Nota: non c’è garanzia che queste istruzioni restino valide anche in futuro. Potrebbero cambiare nomi e indirizzi):

ruby -e “$(curl -fsSL https://raw. githubusercontent.com/Homebrew/install/master/ install)”

Una volta superato questo passaggio, diamo il seguente comando per installare le librerie necessarie a rendere Litecoin compilabile.

brew install autoconf automake libtool boost miniupnpc openssl pkg-config protobuf qt

ora spostatevi nella directory CthulhuCoin dove il sorgente è stato scaricato e date il seguente comando

./autogen.sh

Qualora il file autogen non risulti eseguibile date il seguente comando:

chmod +x autogen.sh.

Questo renderà il file configurabile. Adesso lanciate questo comando, prestando attenzione al doppio trattino davanti sia a with-gui che a enable-debug:

./configure –with-gui –enable-debug

Per una questione di OpenSSL impiegate dal sistema operativo, la procedura su Mac OS X potrebbe fallire, allora date i seguenti comandi e rilanciate il passo di configure:

export LDFLAGS=-L/usr/local/opt/openssl/lib export CPPFLAGS=-I/usr/local/opt/openssl/include

Fate anche attenzione alle librerie qt che avete installate, potrebbero creare un conflitto di versione: brew info qt.

Adesso rimpiazziamo tutte le occorrenze di “litecoin” con il nome della nostra nuova valuta. Il risultato finale così sarà sicuramente più gradito al nostro oscuro signore.
Prestate attenzione che il comando configure sia stato completato correttamente senza errori. Se dovesse fallire con un messaggio del tipo:

checking for Berkeley DB C++ headers… no

configure: error: libdb_cxx headers missing

Allora installate la seguente dipendenza mancante:

brew install berkeley-db4

Da riga di comando, spostiamoci nella cartella /src del nostro progetto e diamo i seguenti tre comandi da terminale.

Nel caso il find/replace fallisca, con un errore del tipo sed: RE error: illegal byte sequence provare a ripetere dando prima il comando export LC_ALL=C.

Dopo aver dato il comando make, il nostro client si chiamerà cthulhucoind e cthulhucoin-qt. Sull’isola di R’lyeh l’oscuro signore ne sarà sicuramente felice! Allo stesso modo è possibile sostituire nel codice il logo di Litecoin con uno a vostra scelta modificando le immagini sotto le cartelle src/qt/res/icons e in src/qt/res/images. Vi consiglio di sostituire le immagini con altre equivalenti per nomi, formato e dimensioni. Per esempio, sappiamo già che lo splash screen (l’immagine di quando l’applicazione viene caricata) si chiama splash.png e misura 480×320 pixel (da sostituire in src/qt/res/images) mentre le icone (bitcoin. png e bitcoin.ico) devono andare sotto src/qt/res/icons. Noi abbiamo usato la banconota di Cthulhu che avete appena visto.

Dopo aver verificato che il pacchetto scaricato sia compilabile, possiamo aprire e modificare il file con un ambiente di sviluppo. Negli esempi che seguono abbiamo provato con il QT Editor. Tenete presente che è solo uno degli ambienti di sviluppo possibili, e che lo stiamo usando per ragioni storiche e quasi sentimentali: infatti la primissima versione del client Bitcoin si chiamava appunto Bitcoin-QT. Voi potete usare qualsiasi ambiente di sviluppo, ma se non avete intenzione di distribuire commercialmente il vostro codice e vi impegnate a rispettare la licenza LGPL, potete scaricare gratuitamente una versione gratuita del software qui: www.qt.io/download-open-source.

Una volta terminata la lunghissima procedura di installazione, possiamo aprire il nostro nuovo ambiente di sviluppo.

Non preoccupatevi, potrebbe forse sembrarvi ostico, ma non lo è. Ora procediamo con l’importazione del progetto. Aperto l’IDE clicchiamo tasto destro sullo spazio bianco a sinistra, “New Project”.

Nella finestra successiva scegliamo l’opzione “Import Project”:

Come ultimo passo, importiamo tutti i file sotto la cartella Src

E così il nostro progetto, casa dei futuri grandi antichi, è importato!

CthulhuCoin

Innanzitutto dobbiamo decidere una sigla per la nostra cripto-moneta. Tutte le valute infatti hanno una sigla di tre caratteri che le caratterizzano (Eur, Usd, Chf, Gbp e così via). Noi non saremo certo da meno! Decidiamo di chiamare la nostra Cthul-huCoin con la sigla CTH. Andiamo nel menu “Advanced find”, e sostituiamo tutte le occorrenze della vecchia sigla della valuta LTC (Litecoin) con la sigla CTH (CthulhuCoin).

Quindi clicchiamo “Replace”, tenendo sempre impostato il flag “Preserve case”. Occhio a effettuare una ricerca “case sensitive”, altrimenti si rischia di modificare parti che non andrebbero toccate.

In questo modo la nuova valuta ha avuto il proprio battesimo! Se finora abbiamo giocato con le proprietà “cosmetiche”, adesso andiamo finalmente a modificare le variabili “monetarie” della nostra nuova moneta dedicata al dio oscuro, prima tra tutte, la quantità totale di denaro circolante.

Ora apriamo il file amount.h e troviamo il valore massimo preimpostato per Litecoin, 84 milioni di Litecoin circolanti. Se avessimo aperto il codice originale di Bitcoin sarebbero stati 21 milioni.

/** No amount larger than this (in satoshi) is valid */

static const CAmount MAX_MONEY = 84000000 * COIN;

Poiché vogliamo che l’oscuro signore rechi il suo messaggio di morte a più persone possibile, aumentiamo di due cifre la già considerevole massa monetaria. Speriamo che il dio Cthulhu apprezzi anche l’inflazione, visti gli oltre 8 miliardi di monete che abbiamo appena messo in circolazione con la sua indescrivibile effigie.

Adesso apriamo il file main.cpp e andiamo nel metodo get-BlockValue. Verifichiamo la presenza di un campo nSubsidy.

CAmount nSubsidy = 50 * COIN;

Questa è la ricompensa elargita a chi è in grado di effettuare il mining del blocco. Inizialmente il valore è di 50 e si ridurrà con il tempo. Poiché i grandi antichi sanno ricompensare generosamente la lealtà dei propri malvagi e poco longevi devoti, portiamo questo valore a 200.

CAmount nSubsidy = 200 * COIN;

Questo è il valore iniziale della ricompensa. Già che ci siamo, notiamo immediatamente sotto il meccanismo che dimezza la ricompensa con il passare del tempo.

int halvings = nHeight / Params().

SubsidyHalvingInterval();

Adesso cerchiamo di modificare l’intervallo di tempo nel quale un nuovo blocco dovrebbe essere generato. Apriamo il file chainparams.cpp e vediamo alcuni tra i parametri più interessanti della nostra nuova creatura.

Il primo è il parametro nTargetSpacing, che calcola il tempo medio nel quale dovrebbe essere possibile risolvere il problema computazionale di un nuovo blocco di transazioni. Il parametro nTargetTimespan invece regola l’intervallo di tempo durante il quale dovrebbe essere ricalcolata e aggiustata la difficoltà del problema che genera la proof-of-work.

Poiché Cthulhu sa ricompensare con generosità divina i malvagi adoratori, abbassiamo ulteriormente questo già basso valore a un minuto mezzo (nel codice originale di Bitcoin è 10 minuti). Tuttavia, considerando che l’oscura divinità cefalopode ha dormito per eoni e eoni potrebbe non essere pronta per riconsiderare così spesso la difficoltà dei problemi computazionali che sottopone ai suoi fanatici discepoli. Quindi alziamo questo valore a dieci giorni nella classe CChainParams, lasciando il TargetSpacing inalterato. Troviamo gli stessi parametri anche per la TestNet( CTestNetParams) e il Regression Testing (CRegTestParams). Se intendiamo usare Testnet, conviene modificare i parametri anche lì.

nTargetTimespan = 10 * 24 * 60 * 60; // 10

giorni espressi in secondi

nTargetSpacing = 2.5 * 60; // 150 secondi

In pratica il ricalcolo della difficoltà avverrà d’ora in poi ogni nTargetTimespan diviso nTargetSpacing, ovvero ogni 96 minuti (o 5760 secondi che dir si voglia).

Appena sotto questi parametri troviamo la porta di default su cui il nostro client sarà in ascolto per stabilire connessioni. Cambiamo questo valore a 1890: anche se è una well known port (ovvero una porta in un range tale per cui probabilmente qualche altro client la starà usando come default) ci permetterà almeno di rendere omaggio all’anno di nascita di Lovecraft. Anche questo valore ricorre come nella nota precedente negli stessi insiemi di parametri (più nell’Unit Testing, in questo caso).

nDefaultPort = 1890;

Una curiosità: avrete sicuramente notato un valore vAler-tPubKey.

vAlertPubKey = ParseHex(“045337216002ca6a71d63

edf062895417610a723d453e722bf4728996c58661cdac

3d4dec5cecd449b9086e9602b35cc726a9e0163e1a4d40 f521fbdaebb674658”);

Nel codice Bitcoin originario questa è la chiave pubblica dedicata alle comunicazioni di servizio che devono raggiungere tutti i nodi del network. Chi fosse in possesso della chiave privata associata a quella pubblica, sarebbe in grado di mandare un messaggio a tutti quanti i nodi connessi alla rete Bitcoin (o Litecoin, come in questo caso, o CthulhuCoin). Nel codice originario di Bitcoin, questa chiave privata fu condivisa da Satoshi Nakamoto con il nuovo lead developer Gavin Andresen prima di ritirarsi dalla gestione attiva del codice.

Adesso aprite il file primitives/block.h e osservate questa dichiarazione:

/** The maximum allowed size for a serialized block, in bytes (network rule) */

static const unsigned int MAX_BLOCK_SIZE = 1000000;

Questo valore imposta il limite massimo di un blocco di bitcoin a 1 megabyte. Provate ad aggiungere uno 0 in fondo, e portare così il limite a 10. Complimenti, avete appena replicato quella sorta di scisma della comunità Bitcoin che è stata la proposta BIP101. Ovviamente, i problemi nella comunità Bitcoin nascono non certo dal modificare questo parametro, ma da come introdurre la modifica mantenendo la retrocompatibilità con la rete esistente. Noi qui abbiamo la fortuna di non avere una rete esistente a cui continuare a garantire servizio.

Nel file main.h troviamo l’indicatore coinbase maturity. Indica dopo quante transazioni consolidate possiamo spendere i nostri soldi di ricompensa. Poiché Cthulhu è uno che non va di fretta e si prende i suoi tempi (solitamente interi eoni) per fare le sue cose, alziamo questo limite da 10 a 200.

/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */

static const int COINBASE_MATURITY = 200;

Ora la parte cruciale: il genesis block. A partire da questo primo blocco, tutte le altre transazioni che seguiranno risulteranno corrette.

La definizione si trova in chainsparam.cpp.

Notiamo che il messaggio iniziale di Litecoin è diverso da quello di Bitcoin:

Quello impostato inizialmente da Satoshi Nakamoto infatti recitava: “The Times, 03/Jan/2009: ‘Chancellor on brink of second bailout for banks’”. Adesso scegliamo qualcosa di meno fighetto e più in linea con la nostra vera religione e modifichiamo le seguenti tre proprietà

const char* pszTimestamp = “Ph’nglui mglw’nafh Cthulhu R’lyeh wgah’nagl fhtagn”;
txNew.vout[0].nValue = 200 * COIN;
genesis.nTime = 1447282346;

Il nuovo valore di genesis.nTime è stato ottenuto prendendo un unix time stamp, ovvero il numero di secondi passato dal 1° gennaio 1970. Una semplice ricerca su Internet permetterà sicuramente di ottenere il valore aggiornato. Il valore nValue è stato semplicemente posto al valore della ricompensa “minato” per ogni blocco che abbiamo definito.

Adesso salviamo tutti i file aperti (save all), chiudiamo l’edi-tor grafico e torniamo alla riga comandi. Proviamo a lanciare i comandi:

./autogen.sh

./configure –with-gui=qt4
make

Dopo qualche minuto, la compilazione terminerà e finalmente avrete un file eseguibile. Dentro la cartella Src, troverete un file cthulhucoind, potete provare a lanciarlo con il comando

./cthulhucoind. In alterantiva una versione grafica del vostro client è disponibile sotto src/qt/cthulhucoin-qt.

Ora eseguite ./cthulhucoin-qt

Se le vostre librerie grafiche qt sono corrette il client do-vrebbe partire senza problemi. Se avete Segmentation Fault e altre amenità, controllate il livello delle vostre librerie QT (brew info qt), e nel caso rilanciate un ./configure –with-gui=qt4 o –with-gui=qt5 a seconda di quale versione avete installata, prima di rilanciare il processo di build.
Occhio che se installate con qt5 le proprietà da esportare potrebbero essere leggermente diverse a causa di brew:

export CPPFLAGS=”-I/usr/local/opt/openssl/include -I/ usr/local/opt/qt5/include”

export LDFLAGS=”-L/usr/local/opt/openssl/lib -L/usr/

local/opt/qt5/lib”

Dalla cartella CthulhuCoin:

./autogen.sh

./configure –with-gui=qt4 ( oppure ./configure –with-gui=qt5)
Make

Alcuni warning saranno comunque mostrati durante quest’ultimo passaggio e possono essere ignorati.

A questo punto è inutile incrociare le dita: la prima esecuzione di CthulhuCoin fallirà miseramente per un problema di assert.

Non temete! Come il sonno lungo eoni di Cthulhu, anche questo era stato previsto!

Aprite il file debug.log che trovate nella cartella dati. La cartella dati dovrebbe essere: /Users/<vostro_utente>/Library/ Application Support/Cthulhucoin.

Qui troverete il seguente file:

LoadBlockIndexDB(): hashBestChain=12a765e31f fd4059bada1e25190f6e98c99d9714d334efa41a195a 7e7e04bfe2 height=0 date=2011-10-07 07:31:05 progress=0.000000

Tornate nel codice, sotto chainParams.cpp. Troverete diverse di queste assertion, che fanno riferimento al vecchio valore di hash del genesis block.

assert(hashGenesisBlock == uint256(“0x12a765e3 1ffd4059bada1e25190f6e98c99d9714d334efa41a195a 7e7e04bfe2”));

Queste assert verificano che il valore del genesis block sia congruo, e che quindi il codice non presente problemi, altrimenti fallisce l’esecuzione senza procedere oltre.

Potete o commentare direttamente tutte queste assert (premettendo alla riga i caratteri // ) o sostituire l’hash con il nuovo valore di hash del genesis block, che dovrebbe apparire fuori nel file debug.log che il client crea all’avvio. Tenete presente che nel file chainParams.cpp queste assert sono presenti in tre classi: CMainParams, CTestNetParams e CRegTestParams, con timestamp e nonce diversi, quindi valori di hash differenti. Vanno commentati o sistemati in tutti e tre questi scenari. In alternativa potete impostare appena prima delle assert la stampa di questi valori, sempre nel file chainParams.cpp:

printf(“CthulhuCoin hashGenesisBlock:%s \n”, hashGenesisBlock.ToString().c_str()); printf(“CthulhuCoin hashMerkleRoot:%s \n”, genesis.hashMerkleRoot.ToString().c_str());

Questo farà sì che appena prima di chiudersi l’applicazione vi segnali quali siano i valori di hash del blocco:

CthulhuCoin hashGenesisBlock: da554b67a4e70285085ce249b09fa44411100ef24cee236656e6e18b09eee 08a

CthulhuCoin hashMerkleRoot:
99a7eda105300e1e0df f7b295596f61f3ea935304658ee5052226e9782a656f6

Ora potete semplicemente copiare e incollarli (premettendo 0x a essi) nelle due assert

assert(hashGenesisBlock == uint256( “0xda 554b67a4e70285085ce249b09fa44411100ef24cee-236656e6e18b09eee08a” ));
assert(genesis.hashMerkleRoot==uint256( “0x99a7eda105300e1e0dff7b295596f61f3ea-935304658ee5052226e9782a656f6”));

Ricompilate tramite i comandi: autogen.sh, configure –with-gui=qt4 o qt5 a seconda degli ambienti, make., e verificate di riuscire ad avviare il client.

Stanchi? Speriamo proprio di no, perché questo non era nemmeno l’inizio dell’avventura. Lo scopo di questo breve giro turistico, basato su materiali già presenti in rete, era semplicemente quello di farvi capire quali leve avete a disposizione. I problemi, quando ci si avventura dentro il codice possono essere innumerevoli e imprevedibili, ma è solo grazie al fatto che qualcuno ha perso del tempo per risolverli e per condividere la soluzione che adesso ci possiamo godere un’autentica meraviglia tecnologica come il Bitcoin. In fondo non è questo il senso di una comunità open source? E ora andate là fuori e utilizzate il vostro cyber-grimorio!


Immagine di copertina: ph. Kevin da Unsplash

La newsletter di cheFare

Le attività e gli articoli di cheFare nella tua mail

Ti piace cheFare?

Seguici su Facebook!

Questo articolo appartiene a:

Percorsi > Innovazione sociale

Potrebbero interessarti anche questi articoli

Che cos’è Kilowatt

21 Maggio 2019
officine creative catania università

Un’associazione ha permesso all’Università di Catania di contrastare la povertà educativa

17 Maggio 2019
innovazione culturale diffusa

Per immaginare nuove città abbiamo bisogno della pianificazione culturale urbana

15 Maggio 2019