Setup dell’ambiente
Ci sono molti modi per per poter lavorare con Ethereum. Quello che troverete maggiormente descritto passa dall’installazione di un client in grado di allineare localmente la Blockchain: chi volesse provare si deve armare di pazienza, dato che si tratta di alcuni GigaByte di dati; per questa ragione occorrerà una certa dose di tempo per avere un ambiente completamente allineato e funzionante.
Esistono molti client in grado di allineare Ethereum [1], quelli più diffusi sono go-ethereum e Parity. Nel nostro caso useremo go-ethereum [2], il client ufficiale di Ethereum sviluppato in Go. Se avete già utilizzato Ethereum, ne avrete sicuramente sentito parlare, magari anche con il suo nome breve: GETH.
Volendo, avremmo anche potuto utilizzare Ethereum(J) [3] sviluppato interamente in Java, ma ho preferito basare tutti i riferimenti sul prodotto maggiormente utilizzato e documentato.
La rete di test Ethereum
Ethereum, oltre alla rete principale sulla quale vengono effettuate transazioni in ETH, dispone di una rete di test pensata per gli sviluppatori. Si tratta di una rete meno sicura, nella quale un ETH non ha un valore economico. Per questa ragione il processo di mining è molto più leggero ed esistono alcuni servizi online che ci permettono di utilizzarla anche senza installare nulla in locale. In questo modo è facile avere dei crediti e per utilizzarli all’interno dei propri test.
Dopo aver installato il client andremo a dire a GETH di creare una copia della Blockchain di test, tramite il comando:
geth --testnet
Essendo l’operazione costosa in termini di tempo e disco, vi consiglio di lanciare il comando e dimenticarvelo, almeno per qualche ora, o per qualche giorno: dipende dalla banda di cui disponete.
Durante l’esecuzione, salvo diverse indicazioni, verrà creata e aggiornata la cartella Ethereum sotto la cartella AppData\Roaming dell’utente corrente.
Nel mio caso i dati vengono memorizzati in:
C:\\Users\\Matteo\\AppData\\Roaming\\Ethereum\\testnet\\geth\\chaindata
Interfacce di comunicazione
Il client Ethereum, oltre a fare lo sporco lavoro di allineare la Blockchain, mette a disposizione una serie di interfacce di programmazione tramite JSON–RPC [4].
Queste interfacce permettono di interagire con il network Ethereum con qualsiasi linguaggio di programmazione, essendo realizzate tramite protocolli standard e largamente diffusi.
Lato Java è così nata la libreria Web3j [5], liberamente scaricabile da GitHub, in grado di utilizzare queste interfacce, tramite oggetti Java.
In questo modo, la scrittura di programmi in grado di interagire con Ethereum è decisamente semplificata, anche in ambiente Android, per il quale esiste una versione apposita di Web3j.
Ethereum wallet
Il primo servizio che chiederemo a Web3j è quello di creazione di un wallet. Il wallet rappresenta il portafoglio virtuale che ogni utilizzatore di Blockchain deve avere per poter criptare e verificare dei dati all’interno della catena.
Viene protetto tramite una password di decrittazione, e contiene la chiave privata con la quale firmare le proprie transazioni e la chiave pubblica con la quale verificarle, oltre ad altri elementi crittografici che ne garantiscono la coerenza e il versionamento.
Creare un wallet
La creazione del wallet è ottenibile da riga comando tramite il comando wallet create di Web3j:
C:\web3j-3.3.1\bin>web3j.bat wallet create _ _____ _ _ | | |____ (_) (_) __ _____| |__ / /_ _ ___ \ \ /\ / / _ \ '_ \ \ \ | | | / _ \ \ V V / __/ |_) |.___/ / | _ | || (_) | \_/\_/ \___|_.__/ \____/| |(_)|_| \___/ _/ | |__/ Please enter a wallet file password: Please re-enter the password: Please enter a destination directory location [C:\Users\Matteo\AppData\Roaming\Ethereum\testnet\keystore]: Wallet file UTC--2018-04-07T13-29-19.241613200Z--f2a4b44365b640585160782690f88677e4757bc2.json successfully created in: C:\Users\Matteo\AppData\Roaming\Ethereum\testnet\keystore
Il wallet è rappresentato da un file JSON, inserito di default nello stesso ramo di cartelle della rete che andremo ad utilizzare, nel nostro caso testnet.
Da notare che, essendo un formato di file documentato, esistono molti sistemi online per generare un wallet; se volete fare una prova senza installare nulla, potete provate MyEtherWallet [6].
Controllare il bilancio del wallet
Allo stesso modo è possibile avere un bilancio del proprio wallet utilizzando siti come Etherscan.io o Ethplorer.io, indicando il proprio indirizzo pubblico.
Nel nostro caso l’indirizzo è
0xf2a4b44365b640585160782690f88677e4757bc2
e utilizza la rete di test; per questo motivo useremo l’indirizzo di verifica della rete ropsten:
https://ropsten.etherscan.io/address/0xf2a4b44365b640585160782690f88677e4757bc2
Se fosse stato un indirizzo della rete principale il servizio da utilizzare sarebbe stato diverso. Ad esempio, se avessimo usato Etherscan.io o Ethplorer.io, gli indirizzi di verifica sarebbero stati rispettivamente:
https://etherscan.io/address/0xf2a4b44365b640585160782690f88677e4757bc2 https://ethplorer.io/address/0xf2a4b44365b640585160782690f88677e4757bc2
Setup dei servizi RPC
Una volta sincronizzata la rete testnet e creato il wallet di sviluppo, possiamo iniziare a lavorare con Web3j.
Nell’esecuzione precedente di geth abbiamo però scelto di partire con la sola sincronizzazione della Blockchain; modifichiamo ora il comando per attivare anche i servizi RPC, cambiando la riga nel seguente modo:
geth --testnet --rpcapi personal,db,eth,net,web3 –rpc
Questa chiamata, oltre alla sincronizzazione della Blockchain testnet, attiva anche i servizi su canale HTTP all’indirizzo:
http://localhost:8545/
Volendo, esiste un’alternativa ad avere un client installato: utilizzarne uno remoto, ad esempio grazie ai servizi forniti infura.io [7]: dopo aver effettuato una registrazione, alla quale lasciare la propria email, viene inviato un token d’accesso. Tale token viene poi utilizzato per comporre un indirizzo univoco da usare come per le vostre chiamate alla rete di test:
https://ropsten.infura.io/<vostro token>
A questo punto abbiamo tutti gli elementi per poter iniziare a scrivere del codice che si aggancia alla copia locale di Ethereum o ai servizi di Infura.io.
Iniziamo ad usare Web3j
Come nel caso di MBBockchain [8], ho creato un repository di test su GitHub dove ho salvato questo progetto [9]. All’interno del progetto vengono mostrati alcuni usi della libreria Web3j, utilizzando direttamente i servizi ropsten.be, in modo da non installare nulla sul vostro PC.
Utilizzare Web3j è abbastanza semplice. Come prima operazione è necessario includere la libreria all’interno del vostro progetto, inserendo la dipendenza nello script maven:
<dependency> <groupId>org.web3j</groupId> <artifactId>core</artifactId> <version>3.3.1</version> </dependency>
o Gradle:
compile ('org.web3j:core:3.3.1')
Il passo successivo è scrivere le righe di codice necessarie a collegarsi alla rete Ethereum creando un oggetto Web3j, passando dal suo build. Nel caso si voglia utilizzare il demone locale di geth, basterà utilizzare il costruttore di default:
// defaults to http://localhost:8545/ Web3j web3 = Web3j.build(new HttpService());
Nel caso in cui, invece, si vogliano utilizzare i servizi di infura.io, basterà indicare la root precedentemente creata tramite la registrazione sul sito:
Web3j web3 = Web3j.build(new HttpService("https://ropsten.infura.io/<vostro token>"));
Per verificare se tutto è andato a buon fine, possiamo chiedere a Web3j la versione di client alla quale siamo connessi. Nel mio caso, interrogando il client locale, avrò questa indicazione:
Geth/v1.8.3-stable-329ac18e/windows-amd64/go1.10
Nel caso dell’utilizzo di infura.io avrò invece
Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.2
Creiamo delle transazioni
Come spiegato durante questo corso, per poter disporre di una criptovaluta valida all’interno di una Blockchain occorre “minarla” o comperarla.
Lavorando sulla Blockchain di test abbiamo il vantaggio che le operazioni di PoW [10] hanno un costo estremamente ridotto ed esistono alcuni servizi in grado di regalarci 1 ETH in modo da poter fare dei test senza dover “minare” nulla. Uno di questi servizi è quello fornito da
http://faucet.ropsten.be:3001/
Collegandosi tramite browser a quell’indirizzo e lasciando il proprio indirizzo pubblico della rete di test è possibile ricevere gratuitamente 1 ETH.
La transazione vera e propria
Ora che abbiamo a disposizione questo credito, possiamo iniziare a creare transazioni con un altro account della rete. Per poter fare questa operazione, ho creato un secondo wallet che conterrà la transazione in arrivo e risponde all’indirizzo
0xef0164faf54177b413bd789f318245eb59297fce
Forti di un bilancio positivo e di un wallet mittente e destinatario, possiamo chiedere a Wb3j di inviare la somma di 1 centesimo di ETH. Per fare questo occorre creare un oggetto Credentials:
Credentials credentials = null;
e inizializzarlo con il wallet che avevamo precedentemente creato e la password utilizzata all’atto della creazione: contro ogni regola di sicurezza, con l’unico fine di semplificare gli esempi, ho usato la password “password”…
credentials = WalletUtils.loadCredentials("password", "UTC--2018-04-07T13-29-19.241613200Z--f2a4b44365b640585160782690f88677e4757bc2.json");
Con queste credenziali possiamo chiedere una transazione, usando l’istanza dell’oggetto Web3j appena creato, le credenziali del mittente, l’indirizzo pubblico del destinatario, il valore da inviare e l’unità di misura in cui lo stiamo esprimendo:
TransactionReceipt transactionReceipt = Transfer.sendFunds( web3, credentials, "0xef0164faf54177b413bd789f318245eb59297fce", BigDecimal.valueOf(0.01), Convert.Unit.ETHER).send();
In uscita avremo un oggetto che descrive la transazione appena effettuata, riportando i dati che abbiamo inserito, più l’hash della transazione del blocco nel quale è stata inserita e la sua numerazione progressiva rispetto ai blocchi della Blockchain:
TransactionReceipt{ transactionHash='0x7b73f1ee0fc84d818b8052c62aa1481c13bb6d46cd489ac75b54ee4f2db55a8e', transactionIndex='0x3', blockHash='0x2bb265fbd69171d4ece8c96c886028e5e35a35e3e7fd26c45ea25c8926533dd2', blockNumber='0x2de24b', cumulativeGasUsed='0x182a3', gasUsed='0x5208', contractAddress='null', root='null', status='0x1', from='0xf2a4b44365b640585160782690f88677e4757bc2', to='0xef0164faf54177b413bd789f318245eb59297fce', logs=[], logsBloom='0x000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000' }
Come si può notare dalla figura 4, le transazioni che vengono effettuate all’interno della rete Ethereum hanno un costo transazionale che varia in base alla transazione effettuata. Per trasferire 1 centesimo di valuta, abbiamo comunque speso 0,00021 ETH.
Questo costo di transazione è attribuito a chi chiede il servizio, nel nostro caso all’indirizzo che ha chiesto il trasferimento fondi, che quindi si trova decurtato il suo account di 1 centesimo più 0,0021 ETH.
Conclusioni
Lo scopo di questa puntata del corso Blockchain era quello di mostrare il setup e l’utilizzo minimo di un’architettura come Ethereum e di come sia possibile interagire con essa tramite Java. Web3j è un prodotto che permette questo tipo di utilizzo, e ha il vantaggio di essere semplice, open e disponibile in sorgente.
Nelle prossime puntate vedremo come integrare, all’interno di MBBlockchain, alcuni dei concetti affrontati durante questa puntata, in modo da migliorare il nostro progetto e arrivare sempre più vicini all’obiettivo di realizzare una Blockchain da zero.