Ethereum (ETH)

Pro

Seconda criptovaluta per importanza

Computer distribuito

Turing completeness

Ecosistema

Web 3.0 e DApps

Ethereum 2.0

Contro

Instabilità

Fees alte

Dimensioni catena

Non molto scalabile

Ethereum Foundation

Indice

Storia

L’idea di Ethereum è nata in un periodo in cui Bitcoin stava iniziando a riscuotere successo e ad attirare l’interesse di molti sviluppatori che, compresa la portata innovativa di Bitcoin e della blockchain, cercavano di estenderne le funzionalità, portandole oltre alla semplice idea di una criptovaluta e di un sistema di pagamenti digitali.

A tal fine, gli sviluppatori si trovavano di fronte a due opzioni:

  • costruire sull’infrastruttura offerta da Bitcoin, andando off-chain, su layer successivi, cosa che però portava a una perdita di alcuni dei vantaggi dati dalla blockchain;
  • costruire una nuova blockchain cercando di superare le limitazioni di Bitcoin che impedivano di estenderne le funzionalità (dimensione dei blocchi, tempo di creazione dei blocchi, linguaggio di scripting non Touring-complete, ecc.).

Un esempio della realizzazione della prima opzione fu Mastercoin, considerata spesso come la prima alt-coin, protocollo costruito on top di Bitcoin (per chi conosce di più il mondo dell’informatica, è paragonabile al rapporto tra il protocollo HTTP e il TCP/IP) che aggiungeva nuove funzionalità a quelle esistenti in Bitcoin, tra le quali una versione rudimentale degli smart contracts[1].

In questo contesto, sul finire del 2013, Vitalik Buterin , un programmatore russo appassionato di Bitcoin, allora diciannovenne, pensò a un modo per estendere le capacità di Bitcoin e Mastercoin, e condivise un whitepaper[2] in cui parlava per la prima volta di Ethereum, una blockchain general-purpose e Turing-complete.

Il whitepaper attirò l’attenzione di molti sviluppatori, tra i quali Gavin Wood (uno degli autori del libro Mastering Ethereum) che iniziò a collaborare con Vitalik, diventando co-fondatore, co-designer e CTO del progetto.

Combinando tecnologie già esistenti con tecnologie innovative, Vitalik e i suoi collaboratori svilupparono così Ethereum e il 30 luglio 2015 venne minato il primo blocco della catena.

Come funziona

Abbiamo visto le ragioni per cui è nato Ethereum ma ora cerchiamo di capire di cosa si tratta.

Ethereum è un sistema computazionale decentralizzato e permissionless che esegue programmi chiamati smart contracts.

Ethereum utilizza una blockchain general-purpose per registrare cambiamenti di stato, apportati da una virtual machine (EVM, Ethereum Virtual Machine).

Ethereum inoltre include una criptovaluta built-in, Ether, che assolve due scopi principali:

  • fornire un primo livello di liquidità per permettere scambi tra vari tipi di digital assets;
  • fornire un meccanismo per pagare le transaction fees (che vedremo in seguito).

Ethereum si propone come una sorta di super-computer distribuito, sul quale possono essere “installate” ed eseguite delle applicazioni decentralizzate (DApps) con funzioni economiche ma non esclusivamente.

Si capisce dunque che Ethereum ha allo stesso tempo molti punti in comune con Bitcoin ma anche molte differenze.

Condivide con la prima criptovaluta il fatto di essere un network peer-to-peer, permissionless e trustless, così come il fatto di basare il cambiamento di stato del sistema su un algoritmo di consenso Byzantine fault-tolerant. Centrale inoltre è l’utilizzo della crittografia, proprio come in Bitcoin.

Inoltre, Bitcoin può essere visto come una macchina distribuita che possiede uno stato (che rappresenta il possesso della criptovaluta), aggiornato tramite il consenso distribuito, in cui le transazioni causano un aggiornamento di questo stato.

Ethereum concettualmente è molto simile, con la differenza che non viene tenuta traccia esclusivamente dello stato del possesso della criptovaluta ma anche di dati arbitrari.

Qui si arriva alle differenze: mentre Bitcoin è nato con lo scopo di creare una criptovaluta e una rete di pagamenti digitali salvata in un registro condiviso e sincronizzato, Ethereum volge il suo interesse alla creazione di un computer decentralizzato che permette di svolgere più operazioni, cosa che si riflette nell’utilizzo di un linguaggio di scripting Turing-complete, utilizzato per la scrittura degli smart contracts, laddove Bitcoin possiede invece un linguaggio di scripting più essenziale e non Turing-complete.

Possiamo dire quindi che la grande innovazione proposta da Ethereum è quella di combinare l’architettura di un programma salvato in un computer general-purpose con una blockchain decentralizzata.

Da questa breve e riassuntiva descrizione di Ethereum emergono numerosi concetti che verranno approfonditi singolarmente nel corso di questa overview.

Indice:

  1. Turing completeness e gas
  2. Ether e accounts
  3. Transazioni
  4. Network
  5. Protocollo di consenso
  6. Smart contracts, DApps e Web 3.0
  7. Ethereum Virtual Machine (EVM)
  8. Tokens
  9. Oracoli
  10. Processo di sviluppo, forks e governance
  11. Ethereum 2.0

Turing completeness e gas

Abbiamo parlato di Turing Completeness, concetto fondamentale per Ethereum, e in generale in ambito informatico, ma che potrebbe non essere così immediato.

Alan Turing fu un matematico inglese, considerato il padre dell’informatica.

Tra le tante cose che fece, elaborò il concetto di macchina di Turing (Turing Machine), un modello astratto che definisce una macchina in grado di eseguire algoritmi leggendo e scrivendo simboli[3].

In informatica si riconosce un sistema come Turing-complete se è in grado di implementare una qualsiasi macchina di Turing, ovvero se è in grado di risolvere qualsiasi problema che ammetta soluzione (a prescindere dal tempo e dalla memoria che dovrà impiegare per risolverlo).

Ci sono però dei casi in cui i problemi sono irrisolvibili e uno di questi è l’halting problem, che possiamo riassumere come l’impossibilità di creare un algoritmo in grado di determinare se un programma scritto in un linguaggio Turing-compete giungerà al termine con qualsiasi input o se invece continuerà all’infinito la sua esecuzione[4].

Considerata l’esistenza di questo problema, l’idea di un sistema Turing-complete, che inizialmente può sembrare esclusivamente positiva, dato che permette di risolvere qualsiasi problema che abbia soluzione, mostra anche un’evidente criticità.

Per fare un esempio pratico, un programma può portare a un loop infinito dal quale non uscirà mai.

Proprio per questo motivo, nonostante la Turing completeness sia molto facile da ottenere, spesso i rischi che ne derivano sono considerati così elevati da preferire sistemi non Turing-complete.

Ciò diventa ancora più evidente se si parla di un sistema aperto come nel caso di una blockchain permissionless.

Così si spiega la scelta di Satoshi Nakamoto di integrare in Bitcoin un linguaggio di scripting non Turing-complete, limitando le funzionalità ma favorendo la sicurezza del sistema. Tra le funzionalità mancanti, si può evidenziare, non a caso, l’assenza dei loop.

Nell’overview di Bitcoin abbiamo spiegato come questo linguaggio di scripting venga utilizzato per bloccare e sbloccare gli UTXO (Unspent Transaction Outputs), stabilendo delle condizioni per cui qualcuno può spendere dei bitcoin.

Sappiamo inoltre che ogni transazione deve essere validata da ogni nodo della rete.

È evidente la pericolosità della Turing completeness. Pensiamo alla possibilità di un loop infinito in uno di questi script che sbloccano gli UTXO: un nodo che dovesse eseguirlo si ritroverebbe intrappolato in un loop infinito che consumerebbe le sue risorse computazionali, risultando di fatto in un attacco DoS.

Considerato questo rischio, Ethereum opta lo stesso per la Turing completeness, introducendo un meccanismo, chiamato gas, volto all’evitare problemi come quello appena descritto.

Quando la EVM (Ethereum Virtual Machine) esegue uno smart contract, tiene il conto di ogni istruzione, ognuna delle quali ha un costo calcolato in gas.

L’EVM interrompe l’esecuzione di uno smart contract se il costo in gas è superiore al gas a disposizione di chi ha richiesto l’esecuzione.

In questo modo, uno script contenente un loop infinito, avrebbe un costo infinito per essere richiamato.


Ether e accounts

Abbiamo visto quindi che interagire con i programmi contenuti in questo computer distribuito costa gas.

Ma come si entra in possesso di gas?

Non è possibile comprare gas esternamente a Ethereum, non è in vendita su exchange o altre piattaforme.

Il gas si può comprare solo internamente a Ethereum, precisamente internamente a una transazione, come vedremo meglio in seguito.

Per ora, la cosa fondamentale da comprendere è che, per comprare gas, è necessario possedere l’unità monetaria di Ethereum: Ether.

Correggiamo subito un errore che si vede spesso fare: è sbagliato riferirsi alla criptovaluta con il nome “Ethereum”, termine che fa riferimento al sistema. Il nome della criptovaluta è Ether (ETH).

1 ETH può essere diviso in unità più piccole, fino ad arrivare alla più piccola in assoluto, detta wei, che equivale a un quintilionesimo di Ether.

Per la precisione, nel sistema Ethereum non si ragiona in Ether ma in wei, quindi, all’interno delle transazioni, vedremo le cifre espresse in wei.

Segue una tabella con i rispettivi nomi e le varie unità:

Valore (in wei)EsponenteNomeSoprannome
11WeiWei
1,000103Kilowei o femtoetherBabbage
1,000,000106Megawei o picoetherLovelace
1,000,000,000109Gigawei o nanoetherShannon
1,000,000,000,0001012Microether o microSzabo
1,000,000,000,000,0001015Milliether o milliFinney
1,000,000,000,000,000,0001015EtherEther
1,000,000,000,000,000,000,0001021KiloetherGrand
1,000,000,000,000,000,000,000,0001024Megaether 

Come abbiamo detto, Ether serve a pagare le transaction fees ma anche per fornire un primo livello di liquidità per consentire scambi economici all’interno del sistema.

Va detto infine che Ether differisce da bitcoin in quanto il primo ha una supply inflazionaria mentre il secondo una supply deflazionaria.

Ciò comporta che bitcoin ha una supply massima fissata (di circa 21 milioni di BTC totali) mentre Ether non ha una supply illimitata, ma un tetto massimo annuale di 18 milioni di ETH.

Inoltre, con il genesis block di Ethereum sono stati creati 60 milioni di Ether e altri 12 milioni sono stati assegnati al fondo per lo sviluppo e poi distribuiti tra i primi contribuitori e la Ethereum foundation[5].

Oltre a questi primi Ether rilasciati, per capire la politica di distribuzione monetaria di Ethereum bisogna parlare del concetto di mining, essendo le due cose molto legate. Il tema verrà perciò approfondito nel capitolo dedicato all’algoritmo di consenso di Ethereum.

Diventa dunque necessario avere uno strumento per identificare il possesso all’interno del sistema, cosa che viene realizzata tramite l’utilizzo di account, creati con funzioni crittografiche, come nel caso di Bitcoin.

In Ethereum esistono due tipi di account:

  • Externally Owned Account (EOA) = identificati da una chiave privata che garantisce il controllo sui fondi e i contratti. Sono gli account che creano i partecipanti al sistema Ethereum;
  • Contract account = sono gli account degli smart contracts, identificati da uno smart contract code, che gli EOA non posseggono. I contract account non posseggono una chiave privata.

In qualsiasi dei due casi, un account ha i seguenti 4 campi[6]:

  • nonce = un contatore che indica il numero delle transazioni inviate da un account (nel caso di un EOA) o il numero di contratti creati da un account (nel caso di un contract account);
  • balance = il bilancio di Ether dell’account, indicato in wei;
  • codeHash = il codice di un account, campo vuoto negli EOA account e utilizzato invece nei contract account. Si tratta del codice del contratto che verrà eseguito dalla EVM, come vedremo in seguito;
  • storageRoot = data store permanente, utilizzato solo dai contract accounts e vuoto negli EOA.

Come nel caso di Bitcoin, anche in Ethereum una delle tecnologie fondamentali è la crittografia.

Abbiamo accennato alle chiavi private e gli indirizzi ma è necessario approfondire l’argomento, in quanto rappresentano uno dei fondamenti della blockchain, nonché uno dei motivi che ne determinano la sicurezza.

La crittografia non è usata solo per criptare informazioni ma anche per poter comprovare l’autenticità dei dati e la conoscenza di essi, senza rivelarli.

In ambito blockchain è fondamentale la public key cryptography (PKC) ed Ethereum non fa eccezione.

La PKC, diventata di pubblico dominio nel corso degli anni ’70, è basata sull’utilizzo di una coppia di chiavi: chiave privata e chiave pubblica.

La chiave pubblica, paragonabile al numero di un conto bancario, è utile per identificare pubblicamente un account (in modo, ad esempio, da ricevere fondi).

La chiave privata, paragonabile al PIN del conto bancario, è necessaria per utilizzare i fondi che si posseggono.

Una delle particolarità della PKC è che queste coppie di chiavi sono basate su funzioni matematiche facili da calcolare in una direzione ma difficili (se non praticamente impossibili) da calcolare nella direzione opposta, per questo viene anche chiamata crittografia asimmetrica e si parla di one-way functions.

In particolare, vi è una serie di funzioni basate sull’elliptic curve multiplication, a loro volta basate sul problema del logaritmo discreto[7].

Questo tipo di funzioni sono particolarmente sicure e sono alla base del funzionamento della blockchain.

In Ethereum, così come in Bitcoin, si parte da una chiave privata, dalla quale si deriva una chiave pubblica, dalla quale si deriva un address.

L’address viene utilizzato solitamente all’interno delle transazioni per indicare i destinatari dei pagamenti.

La chiave privata viene utilizzata per autorizzare dei pagamenti, attraverso la creazione di digital signatures, delle specie di impronte digitali che certificano che siamo stati effettivamente noi ad autorizzare un pagamento, perché possono essere generate solo da chi conosce la chiave privata di un account. Ovviamente la chiave privata resta segreta, perché basterà la conoscenza di un address e di una digital signature ad esso collegato per garantire l’autenticità di un’operazione, ovvero garantire che sia stato effettivamente il proprietario di una certa somma di denaro a voler pagare con il proprio denaro.

Come si fa dunque a creare un EOA (Externally Owned Account)?

Per prima cosa bisogna scegliere una chiave privata, che è un numero compreso tra 1 e 2256.

In questa fase la cosa importante è che la scelta del numero sia effettuata con un adeguato livello di entropia e randomicità. Si consiglia, ad esempio, di lanciare una moneta per 256 volte e segnare ogni volta il risultato (0 o 1). Così si ottiene la chiave privata in sistema binario.

Utilizzando un wallet, questa operazione viene svolta automaticamente ma bisogna sempre accertarsi che il livello di entropia utilizzato nella generazione del numero sia adeguato.

A prima vista potrebbe sembrare rischioso scegliere un numero randomicamente, in quanto si potrebbe pensare che qualcun altro potrebbe arrivare al nostro stesso numero.

Con l’adeguato livello di entropia ciò è impossibile. Si tratta di un numero nell’ordine di 1077, laddove l’universo visibile si stima che contenga 1080 atomi.

Una volta scelta la chiave privata, si ottiene la chiave pubblica attraverso elliptic curve multiplication, una moltiplicazione molto particolare, irreversibile (perché non esiste l’operazione opposta, la divisione), rappresentata dall’espressione:

K = k * G

Dove K è la chiave pubblica, k è la chiave privata e G è un punto costante della curva ellittica.

Ethereum utilizza la stessa curva ellittica di Bitcoin (secp256k1).

Dalla moltiplicazione si otterranno le coordinate di un nuovo punto sulla curva che, serializzate, daranno come risultato la chiave pubblica.

Per ottenere l’address si utilizza invece una funzione crittografica di hash.

Si tratta di funzioni one-way che prendono in input dati di dimensione arbitraria e restituiscono come output stringhe di dimensione fissa.

Essendo one-way, anche queste funzioni sono irreversibili, oltre ad avere altre caratteristiche fondamentali. Ad esempio, dato uno stesso input, verrà prodotto sempre lo stesso output, cambiando anche solo di un carattere l’input, cambierà totalmente l’output.

Ethereum usa la funzione di hash Keccak-256 per molte cose.

Tra i vari utilizzi si ha la generazione dell’address a partire da una chiave pubblica.

Gli address di Ethereum sono identificatori univoci derivati da una chiave pubblica (nel caso di EOA) o dai contratti (nel caso di Contract accounts) usando la funzione di hash Keccak-256.

Va ricordato infatti che i Contract accounts non posseggono la coppia di chiavi privata-pubblica ma solo l’address.

In particolare, data la chiave pubblica come input a Keccak-256, verrà prodotto un hash del quale verranno presi solo gli ultimi 20 bytes, i quali saranno l’Ethereum address. Spesso questi 20 bit sono preceduti dalla “0x” per identificare che sono codificati in esadecimale.

Specifichiamo che tutto il processo di creazione di un EOA non deve avvenire online, bensì è un processo matematico che si può effettuare offline.

Una volta creato un EOA, bisogna scegliere un wallet, un’applicazione che aiuta a gestire il proprio account Ethereum, fornendo una via di comunicazione col sistema Ethereum.

Esistono diversi wallet, il più diffuso è Metamask, che si installa come estensione del browser.

Senza scendere nei dettagli, che potete trovare nelle lezioni dedicate ai wallet, bisogna sottolineare che si devono scegliere dispositivi sicuri in cui utilizzare i wallet, perché questi detengono le chiavi che identificano il nostro account.

Il possesso in Ethereum, come in Bitcoin, è stabilito dall’avere queste chiavi, dunque è fondamentale conservarle nel modo più sicuro per evitare da una parte il rischio di perderle e dall’altra quello che vengano rubate.


Transazioni

A questo punto abbiamo un’idea chiara di quali siano le tipologie esistenti di account in Ethereum.

Una volta che si possiede un account, ci interessa sapere come viene trasferita la proprietà in Ethereum, ovvero come avvengono le transazioni.

Si può partire facendo un paragone con Bitcoin, visto che, in questo aspetto, le due blockchain divergono totalmente.

Nel dettaglio Bitcoin si basa sugli Unspent Transaction Outputs (UTXO), ovvero gli output di transazioni fatte che non sono ancora stati spesi.

Si può dire che lo stato di Bitcoin in un determinato momento sia dato dall’elenco di tutti gli UTXO.

Dagli UTXO si deriva il bilancio dei singoli account.

In Ethereum invece si ha un modello account based, in cui lo stato globale in un determinato momento è dato dal bilancio di tutti gli account.

Se Bitcoin si può paragonare a come funziona il contante (dove i vari UTXO rappresentano delle monete e delle banconote), il modello di Ethereum è assimilabile a un conto bancario.

Fatta questa precisazione, andiamo a esporre il modo in cui funzionano le transazioni di Ethereum, transazioni che costituiscono la base del sistema in quanto sono ciò che lo fa funzionare, ciò che crea gli smart contracts, li fa eseguire dalla EVM e soprattutto ciò che provoca un cambiamento dello stato globale del sistema.

rawTx = {
  nonce: '0x00',
  gasPrice: '0x09184e72a000', 
  gasLimit: '0x2710',
  to: '0x0000000000000000000000000000000000000000', 
  value: '0x00', 
  data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057'
  r: '0x09ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9c',
  s: '0x440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428',
  v: '0x25'
}

Una transazione in Ethereum ha una struttura di base che deve contenere certi dati. Questi dati vengono serializzati e trasmessi al network di Ethereum. La versione della transazione serializzata per il network è l’unico standard esistente per una transazione.

Una transazione viene trasmessa al network come un messaggio binario che contiene:

  • nonce = un valore scalare uguale al numero di transazioni inviate dal creatore della transazione;
  • gasPrice = prezzo del gas che il creatore della transazione vuole pagare;
  • gasLimit = l’ammontare massimo di gas che il creatore della transazione vuole pagare;
  • recipient = l’address del destinatario;
  • value = l’ammontare di Ether da inviare al destinatario;
  • data = un payload di dati binari di lunghezza variabile;
  • v,r,s = i tre componendi della ECDSA digital signature applicata dal creatore della transazione.

La transazione viene serializzata usando uno schema di codifica Recursive Length Prefix (RLP), quindi i campi appena elencati non sono visibili nella transazione serializzata, perché sono codificati in RLP.

Si può notare inoltre che non è presente l’indirizzo di chi crea la transazione, perché da v,r,s si ricava la chiave pubblica da cui si ricava l’address.

Vediamo ora nel dettaglio i campi sopra elencati.

Il nonce è un attributo del creatore della transazione e ha senso solo in relazione al suo indirizzo. È un valore calcolato dinamicamente che indica il numero delle transazioni confermate (on-chain) originate dall’indirizzo di chi crea la transazione.

Se si creano le transazioni manualmente è importante tenere traccia del nonce, perché è fondamentale che le transazioni siano processate sequenzialmente, sulla base del nonce.

Prendiamo un esempio pratico: mettiamo il caso in cui creo una transazione con nonce 0 e la trasmetto alla rete che la validerà e la inserirà in un blocco. A questo punto la transazione sarà confermata. Se poi trasmetterò alla rete una transazione con nonce 2, questa non verrà confermata ma resterà nel mempool dei nodi, ovvero il luogo in cui stanno le transazioni ancora non confermate, perché manca una transazione proveniente dal mio indirizzo, che abbia nonce 1.

Nel momento in cui trasmetterò alla rete una transazione con nonce 1, verrà confermata prima questa e poi successivamente quella con nonce 2 che era rimasta nel mempool.

Vi sono poi i due campi legati al gas, che possiamo vedere come la benzina che alimenta la EVM, come già visto precedentemente.

Con gasPrice si specifica il prezzo al quale il creatore della transazione vuole comprare gas. Il prezzo è misurato in wei per unità di gas. Maggiore è il gasPrice, più velocemente verrà confermata la transazione.

In periodi in cui il network è poco congestionato, tuttavia, è possibile che le transazioni vengano inserite in un blocco anche se il gasPrice è settato a zero, caso in cui si parla di fee-free transaction.

Il gasLimit specifica invece il massimo numero di unità di gas che il creatore della transazione vuole comprare per completare la transazione.

Per transazioni dirette verso un EOA, il gas limit è fissato a 21000. Per le transazioni rivolte verso un Contract account, è impossibile da determinare con accuratezza.

Il prezzo da pagare per una transazione, dunque, si può calcolare moltiplicando la gas fee * gasPrice. Nel caso in cui il risultato sia maggiore degli Ether posseduti dall’account che crea la transazione, questa non risulterà valida.

Il campo recipient non è altro che l’Ethereum address da 20 byte del destinatario della transazione, che sia un EOA o un Contract address.

Questo campo non viene validato dal protocollo Ethereum, quindi deve essere validato a livello della user interface che viene utilizzata per creare la transazione.

Ciò significa che se non avviene questa verifica e si inserisce un indirizzo non esistente (basta che sia di 20 byte), la transazione verrà effettuata lo stesso e verranno persi gli Ether, perché Ethereum non ha modo di sapere se l’indirizzo viene utilizzato o meno.

Il campo value contiene la quantità di ether che il creatore della transazione vuole inviare al destinatario.

Il campo data invece contiene dei dati che servono, solitamente, a specificare come interagire con uno smart contract.

Entrambi questi ultimi due campi non sono obbligatori e possiamo avere 4 combinazioni:

ValueDataNome transazioneDestinatarioEffetto
  PaymentEOA, Contract AccountSi utilizza di solito per inviare degli Ether a un EOA. Se si invia a un Contract account, verrà prima verificato se il contratto ha delle azioni di default da svolgere, altrimenti andrà solo ad aumentare il bilancio dell’account.
  InvocationContract accountSolitamente i dati inviati sono rivolti a Contract account e sono una funzione del contratto da eseguire e gli argomenti da passare alla funzione.
  Payment & invocationContract accountUnione delle due voci precedenti.
    Spreco di gas

Va poi indicato un caso speciale di transazione, quello di creazione di un nuovo smart contract sulla blockchain.

Questo tipo di transazione ha la particolarità di avere sempre lo stesso recipient, chiamato zero address perché l’address è 0x0.

Questo indirizzo non appartiene a nessuno e non può spendere Ether, né creare transazioni, serve solo per indicare che la transazione è di creazione di uno smart contract.

Questa transazione necessita solo del campo data, non di quello value. Nel caso possieda anche il campo value, gli Ether inviati andranno a costituire il bilancio iniziale del nuovo contratto.

Una volta creata la raw transaction con i campi visti finora, processo che può avvenire offline, è necessario creare la digital signature che serve a certificare l’autenticità della transazione, nonché la sua provenienza (senza ovviamente specificare la chiave privata).

La digital signature, in Ethereum, viene creata tramite Elliptic Curve Digital Signature Algorithm (ECDSA).

Viene presa la transazione vista finora, effettuato l’RLP-encoding. Il risultato viene passato come input alla funzione di hash Keccak-256 che restituisce un hash.

Viene poi computata la ECDSA signature, firmando l’hash ottenuto con la private key del creatore della transazione e il risultato è il v,r,s visto precedentemente, che viene aggiunto alla transazione e dal quale si possono ricavare la chiave pubblica del creatore della transazione e la sua digital signature. Con questi due dati è possibile verificare l’autenticità della transazione.

Tutto ciò che si è visto finora, avviene offline. La rete di Ethereum entra in gioco nel momento in cui si deve trasmettere la transazione alla rete.

Per farlo basterà inviarla a un nodo della rete, il quale la verificherà e, qualora la transazione risultasse valida, la propagherà ai nodi con cui è in comunicazione.

Prima di approfondire questo passaggio però, bisogna spiegare come funziona la rete di Ethereum.


Network

La rete di Ethereum è una rete peer-to-peer, decentralizzata e permissionless, costituita da nodi in comunicazione tra loro attraverso un gossip protocol.

A dire il vero, esistono diverse reti basate sul protocollo Ethereum, che seguono e si conformano secondo le specificazioni formali definite nel Yellow Paper di Ethereum.

Queste reti possono comunicare tra di loro oppure no.

Esistono inoltre diversi client di Ethereum e non è detto che ogni client funzioni per ogni blockchain basata su Ethereum.

Per entrare a far parte di una delle reti Ethereum-based, bisogna installare su un device un nodo di qualsiasi tipo.

Esistono infatti diversi tipi di nodi, che svolgono funzioni diverse.

Vi sono i full nodes che sono quelli che contribuiscono alla robustezza, alla salute e alla sicurezza delle blockchain da cui dipendono, perché possiedono una copia integrale del registro, quindi possono aiutare altri nodi a ottenere i dati e possono inoltre verificare indipendentemente tutte le transazioni e i contratti.

Un full node permette poi di interagire direttamente con i contratti pubblicati sulla blockchain, senza necessità di intermediari, nonché di pubblicare i contratti sulla blockchain sempre senza intermediari.

Ovviamente però, installare un full node comporta dei requisiti hardware onerosi, in continua crescita.

Attualmente, i requisiti raccomandati sono:

  • CPU con 4+ cores
  • 16GB+ RAM
  • SSD da almeno 1 TB
  • 25+ Mbit/sec velocità di download internet

Una volta installato il nodo, questo dovrà sincronizzarsi con il resto della rete, processo che impiega molto tempo, perché deve essere verificata ogni transazione.

Esistono poi i Remote Ethereum Clients, delle versioni più leggere che hanno requisiti hardware più esigui ma che possono svolgere solo alcune delle funzioni di un full client e ovviamente non posseggono una copia del registro delle transazioni.

Va specificato che i Remote Ethereum Clients non sono come i light client di Bitcoin. I light client infatti validano gli header dei blocchi usando le Merkle proofs. I Remote Ethereum Clients invece non validano né gli header dei blocchi né le transazioni ma si affidano completamente a full nodes che danno accesso ai dati della blockchain.

Si può intuire dunque che perdono molto in sicurezza e anonimato.

I Remote Clients possono essere di vari tipi e avere più o meno funzioni. Si va dagli smarphone wallets che possono essenzialmente gestire coppie di chiavi, creare, firmare e trasmettere alla rete transazioni, a browser wallets più complessi, come MetaMask, che permettono di interagire con le DApps e offrire servizi esterni come block explorers.

Torniamo dunque alla transazione vista precedentemente. L’opzione più sicura è quella di possedere un full node, in modo da trasmettere autonomamente la transazione alla rete.

In assenza di un full node, bisognerà usare un Remote Ethereum Client che invierà la transazione a un full node.

In ognuno dei due casi, il full node validerà la transazione e, se risulterà valida, la salverà in locale e la propagherà ai nodi con cui è in comunicazione, detti neighbors (in media almeno 13).

Questi valideranno a loro volta la transazione, la salveranno in locale e la propagheranno ai loro vicini. Nel giro di pochi secondi la transazione arriverà a tutto il netowrk tramite questo meccanismo di propagazione, detto gossip protocol, basato sullo scambio di messaggi tra i nodi.

Tra i nodi della rete che ricevono la transazione però, ci sono dei nodi particolari, detti mining nodes, che ci portano al prossimo argomento: il consenso in Ethereum.


Protocollo di consenso

Siamo arrivati al punto in cui tutta la rete ha ricevuto la transazione, che è stata validata da tutti i nodi.

Tra i vari nodi, ve ne sono alcuni, detti mining nodes, che svolgono l’attività di mining. Sostanzialmente, ogni miner è in competizione con gli altri e la sfida è la risoluzione di un puzzle crittografico. I miner selezionano delle transazioni valide ma non ancora confermate, le inseriscono in un nuovo blocco e partono con la risoluzione del puzzle crittografico. Quando un miner arriva alla soluzione, la inserisce nel suo blocco e lo diffonde nella rete.

Per capire meglio questo meccanismo però, bisogna prima capire il concetto di algoritmo di consenso, che spiegheremo qui in modo superficiale. Per approfondimenti rimandiamo alla lezione sugli algoritmi di consenso.

Con algoritmo di consenso si fa riferimento a una serie di regole che tutti i partecipanti al network di una blockchain devono rispettare, perché sono ciò che rende il sistema trustless, ovvero sicuro e affidabile senza il bisogno di un’autorità centrale a cui affidarsi.

Il problema del consenso non è esclusivo della blockchain ma riguarda tutto il mondo dei sistemi distribuiti e la questione fondamentale è quella di far arrivare tutti gli attori di un sistema a un accordo (il consenso, appunto) riguardo a un cambiamento dello stato globale del sistema.

Bisogna dunque arrivare a uno stato comune, mantenendo però la decentralizzazione. In questo processo bisogna considerare la possibile presenza di attori malevoli che, per interessi personali o per volontà di distruggere il sistema, possono agire contro al sistema.

Sono state proposte varie soluzioni a questo problema e quella proposta da Satoshi Nakamoto con Bitcoin, la celebre proof of work (PoW), si può dire che sia l’innovazione più grande apportata dalla prima blockchain.

Il funzionamento di PoW lo abbiamo descritto ad alto livello poche righe sopra, si tratta quindi di una competizione per la risoluzione di un puzzle crittografico che comporta un grande dispendio di energia e che prevede un sistema di ricompense per incentivare questo dispendio di energia, che comunque comporta un rischio perché, se si perde la competizione, l’energia che avremo usato sarà persa e nessuno ce la ripagherà, con una conseguente perdita economica.

PoW non è l’unico algoritmo di consenso esistente e in realtà nasce come alternativa a Proof of Stake (PoS), algoritmo basato su uno stake finanziario, ovvero sul bloccare dei fondi per diventare dei validatori.

Nel PoS in ogni nuovo round i validatori propongono e votano i nuovi blocchi e il peso del voto dipende dalla quantità di fondi messa in stake.

In questo caso il rischio dei validatori è quello che il blocco votato venga rifiutato dalla maggioranza dei validatori, caso in cui si perdono i fondi messi in stake.

L’incentivo invece è quello di guadagnare a ogni nuovo blocco una ricompensa, proporzionale alla quantità di fondi messa in stake.

In entrambi i casi i meccanismi sono pensati per bilanciare rischi e benefici, in modo da incentivare gli attori ad agire onestamente e a svolgere il lavoro che, di fatto, permette a una blockchain di rimanere in vita e di progredire.

Ethereum è nato utilizzando un algoritmo PoW chiamato Ethash anche se, fin dall’inizio, è stato previsto un passaggio a un algoritmo PoS, che al momento non è ancora del tutto pronto e al quale Buterin e altri sviluppatori stanno lavorando da anni.

In questa overview inizieremo approfondendo prima Ethash, per poi dare qualche informazione riguardo al futuro algoritmo PoS.

Ma prima ancora di tutto ciò è necessario spiegare come sono fatti i blocchi.

Come abbiamo detto, i miner raggruppano un certo numero di transazioni in attesa di essere confermate e le inseriscono in un blocco. I dati delle transazioni però non sono le uniche informazioni presenti al suo interno.

Innanzitutto bisogna pensare al blocco come ciò che realmente cambia lo stato globale del sistema. Le transazioni sono un cambiamento di stato ma per essere effettive devono essere inserite all’interno di un blocco.

Vediamo ora la struttura dei dati di un blocco:

Il blocco è composto da un Header e un Body.

Nell’Header sono contenuti molti dati riguardanti il blocco:

  • parentHash = l’identificatore univoco del blocco precedente, fondamentale per legare crittograficamente i blocchi tra di loro, da qui il termine “blockchain” (per approfondire questo aspetto rimandiamo alla lezione dedicata alla definizione di blockchain);
  • ommersHash = l’hash Keccak256 di tutti i blocchi ommers;
  • beneficiary = l’address di chi riceverà le ricompense per aver minato il blocco (quindi l’indirizzo di un account del miner);
  • stateRoot = l’intero stato del sistema: i bilanci degli account, i contratti con il loro codice e i nonce degli account;
  • receiptsRoot = hash del root node del transaction receipt trie (le ricevute di tutte le transazioni incluse nel blocco);
  • Transaction Root = hash del root node del transaction trie (rappresentazione della lista delle transazioni incluse nel blocco);
  • logsBloom = un filtro per i log delle transazioni;
  • difficulty = la difficoltà richiesta per minare il blocco;
  • blockNumber = la lunghezza della blockchain in blocchi;
  • gasLimit = il limite di consumo di gas del blocco;
  • gasUsed = il totale del gas consumato dalle transazioni del blocco;
  • timestamp = il timestamp di quando il blocco è stato minato;
  • extraData = contiene dati arbitrari riguardo al blocco;
  • mixHash = l’hash che identifica univocamente il blocco;
  • nonce = è il risultato del puzzle crittografico che devono risolvere i miner, un hash che, combinato con il mixHash, prova inequivocabilmente che il blocco è valido perché è stata fornita una proof-of-work valida.
{

  "difficulty": 134290,
  "extraData": "0xd783010506846765746887676f312e372e33856c696e7578",
  "gasLimit": 4038569465,
  "gasUsed": 23114,
  "hash": "0xa5d727b111f123e11b6dc5d271697b82a6238f83ab342088e0a1538afce7862d",
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000004000000000000200000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000",
  "miner": "0x4c558858289c4180d0d2b994a4e009e078731191",
  "mixHash": "0xba14e2b605aeacfa68f8345a9e30dd2d37dc4f3f4eba9e8ac8e744ded90ae566",
  "nonce": "0x38de415ea086671a",
  "number": 63,
  "parentHash": "0xa7186a94afe92f0c0fedd1b8aa96e9aa92321e63a0b79d3f68ffe888bfb0239a",
  "receiptsRoot": "0x303d0444bf28744722fd53a46144ead61f3515a82b9640603028ebf91f212126",
  "sha3Uncles": "0x3633e886ef643c067d6fb7bfc1d2a6bf3eba939bf3cbb522f3894779ac1dd090",
  "size": 1709,
  "stateRoot": "0xcd4abaafec19113743df0235f06482f3a0b49e546e708055aa7a2382b232601e",
  "timestamp": 1484750319,
  "totalDifficulty": 8362288,
  "transactions": ["0x1bd5825eac201f0f0e1e2c4a9ed5de026edc3f7fb02c4b912ca55c0f50a021fc"],
  "transactionsRoot": "0xbaf6819c91ed625a97e974bbc4efd5808970b3b4991b1e2aca0dd537750aafc7",
  "uncles": ["0x6f0a9ab0e468112fdcbbecd81ebebf929ca9a38e6a4c864e8164309d3bed42c6", "0xb4dd60c91ab18de3f72ba27ab5934bec66ab01798d18b599d1d298bd29e56204"]
}

Nel Body del blocco sono invece presenti:

  • lista delle transazioni inserite dal miner all’interno del blocco;
  • lista degli Ommers = gli ommers in Ethereum sono l’equivalente dei blocchi orfani di Bitcoin. Due miner possono risolvere la competizione per uno stesso blocco insieme, creando una biforcazione temporanea nella catena. Vincerà la biforcazione più lunga (o meglio, quella con la somma del costo computazionale maggiore, che spesso coincide con la più lunga) e quindi uno dei blocchi prodotti dai miner verrà rimosso e diventerà ommer. Vi è la possibilità di inserire questi blocchi ommer all’interno del blocco vincente, in modo che il miner che ha minato il blocco ommer riceva una ricompensa parziale[7].

Un miner dunque selezionerà delle transazioni non confermate, presenti nel mempool locale, le unirà in una lista di transazioni, compilerà gli altri campi del blocco e comincerà a provare a risolvere il puzzle crittografico.

Per farlo, dovrà utilizzare una tecnica detta brute force, ovvero dovrà procedere per tentativi.

Ciò che deve fare infatti, una volta compilato il blocco, è trovare un mixHash per il blocco che soddisfi il target di difficoltà. Per fare ciò dovrà inserire nel blocco un nonce casuale e passarlo dentro la funzione di hash che darà il risultato.

Dovrà compiere questa operazione n volte, fin tanto che l’hash risultante non soddisferà il target.

Quando un blocco verrà aggiunto alla catena, partirà un nuovo round in cui i miner competeranno per il blocco successivo.

Questo processo avviene in media una volta ogni 14 secondi[9].

Si tratta di un processo computazionalmente molto oneroso che costituisce una prova del lavoro svolto dal miner (proof-of-work), dei costi che ha dovuto pagare (di elettricità e di hardware) che lo incentivano ad agire onestamente.

Buterin ha sottolineato, fin dal whitepaper di Ethereum, il fatto che in Bitcoin si siano creati accentramenti di potere computazionale, dovuti soprattutto alla diffusione di hardware ASIC (application-specific integrated circuits) dedicato apposta al mining e molto più performante delle GPU (schede grafiche) che si utilizzavano precedentemente.

L’avvento di questa tipologia di hardware specifico ha creato un limite per i miner non professionisti, ponendo un rischio per la decentralizzazione del sistema.

La soluzione proposta da Buterin con Ehash è un algoritmo “ASIC resistant”, il che significa che è più difficile creare hardware specifico per risolvere i puzzle crittografici, in modo da favorire l’utilizzo di GPU che sono più accessibili a tutti.

Inoltre, come già detto, è stato pianificato fin dall’inizio un passaggio a un algoritmo PoS, cosa che cancellerà da Ethereum la necessità del mining.

In questo senso i produttori di hardware specifico sono stati inizialmente meno incentivati a investire nello sviluppo di hardware dedicato a Ethereum, sapendo che sarebbe diventato inutile in futuro.

Però, con la nascita di altre criptovalute e token Ethereum-based, i produttori di hardware ASIC hanno iniziato a investire maggiormente su Ethereum e con il passare del tempo sono a venute a crearsi lo stesso concentrazioni di potere assimilabili ai mining pools di Bitcoin.

Riguardo al mining va aggiunto un altro dettaglio. Abbiamo detto che i miner, in cambio del loro lavoro, ricevono un incentivo economico. Come per Bitcoin, è attraverso questo incentivo che avviene la distribuzione di nuovi Ether, che vengono creati dal nulla (minati, appunto) ogni volta che viene aggiunto un nuovo blocco alla catena.

A differenza di Bitcoin però, come spiegato precedentemente, non è prevista una max supply per Ether, almeno attualmente.

L’attuale distribuzione monetaria di Ether procede con un +4.5% all’anno, con 2 nuovi Ether per ogni blocco più 1.75 Ether addizionali per blocco ommer[10].

La ricompensa per blocco è stata già cambiata più volte, seguendo i processi della governance di Ethereum, che vedremo in seguito:

  • Blocchi da 0 a 4369999 = 5 Ether di ricompensa;
  • Blocchi da 4370000 a 7280000 = 3 Ether;
  • Blocchi da 7280000 a ora = 2 Ether.

Nonostante non si sappia ancora cosa succederà di preciso in futuro, è previsto, in accordo con le specifiche per Eth 2.0, una grande diminuzione delle ricompense con l’avvento dell’algoritmo PoS, con una distribuzione legata allo stake totale del network:

ETH validatingMax annual issuanceMax annual network issuance %Max annual return rate (for validators)
1,000,000181,0190.17%18.10%
3,000,000313,5340.30%10.45%
10,000,000572,4330.54%5.72%
30,000,000991,4830.94%3.30%
100,000,0001,810,1931.71%1.81%

In particolare sono previsti 2 eventi in relazione a Eth 2.0:

  • Fase 0, in cui ci sarà un aumento della percentuale di distribuzione annuale;
  • Fase 1.5, in cui verranno rimosse le ricompense legate alla PoW.

Riguardo al passaggio a PoS, che avverrà in un prossimo futuro, non è scopo di questa overview discutere dei vantaggi e gli svantaggi di PoS e PoW, quindi ci limitiamo a dire che l’algoritmo PoS proposto si chiama Casper, è in ricerca e sviluppo da anni ed è stato sviluppato in due direzioni:

  • Casper FFG = proposto come un algoritmo ibrido tra PoW e PoS, da implementare in una fase di transizione;
  • Casper CBC = algoritmo esclusivamente PoS.

Buterin ha dichiarato che CBC sembra avere delle proprietà teoriche migliori mentre FFG sembra essere più facile da implementare[11].


Smart contracts, DApps e Web 3.0

Come anticipato nel paragrafo dedicato agli account, esistono due tipi di account. Uno di questi è quello dei contratti, anche detti smart contracts. Cerchiamo di capire meglio di che cosa si tratta.

L’espressione “smart contract” non è nata con Ethereum ma è stata coniata negli anni ’90 dal crittografo Nick Szabo, che li definì come “un set di promesse, in forma digitale, che includono protocolli entro i quali le parti rispettano altre promesse”[12].

Con la nascita e lo sviluppo delle blockchain, il concetto di smart contract si è evoluto molto, arrivando ad Ethereum in cui il significato è cambiato quasi totalmente, infatti gli smart contracts di Ethereum non sono dei contratti, né sono intelligenti.

Si tratta piuttosto di veri e propri programmi che vengono eseguiti deterministicamente dall’EVM, sul computer mondiale e decentralizzato formato dalla rete di Ethereum.

Gli smart contracts di Ethereum sono immutabili, essendo salvati sulla blockchain. Ciò vuol dire che, una volta scritto il codice e salvato sulla blockchain, non si può più cambiare.

La EVM esegue programmi scritti in un bytecode di basso livello chiamato EVM bytecode. Nonostante sia possibile scrivere gli smart contracts direttamente in EVM bytecode, si tratta di un linguaggio molto complicato e difficilmente comprensibile dagli umani, motivo per cui sono nati diversi linguaggi ad alto livello che ne facilitano la scrittura.

È stato infatti preferito inventare nuovi linguaggi, piuttosto che utilizzare linguaggi già esistenti, perché gli smart contracts operano in un modo minimalistico e limitato, per cui era più facile creare un linguaggio apposta che adattare un linguaggio general-purpose.

Tra i vari linguaggi nati vanno citati Solidity, LLL, Serpent, Vyper e Bamboo. Tra questi, il più utilizzato risulta senza dubbio Solidiy, creato da Gavin Wood, co-fondatore di Ethereum, e diventato il linguaggio di riferimento per la scrittura di smart contracts in Ethereum ma anche in altre blockchain simili.

Solidity viene sviluppato e mantenuto su GitHub[13].

Ovviamente è necessario compilare il codice Solidity in EVM bytecode, affinché l’EVM riesca a eseguirlo.

Segue un esempio di un semplice smart contract scritto in Solidity:

pragma solidity >=0.4.0 <0.6.0; 

contract SimpleStorage {
    uint storedData;
    function set(uint x) public {
        storedData = x;
    }
    function get() public view returns (uint) {
        return storedData;    
}}

Supponiamo di avere un account EOA e di aver scritto questo smart contract. Come si salva sulla blockchain e cosa succederà una volta salvato?

Alla prima domanda abbiamo già dato una risposta: esiste uno speciale tipo di transazione, detta contract creation transaction, che richiede un particolare indirizzo nel campo del destinatario (0x0).

Una volta inviata alla rete la transazione per creare lo smart contract, verrà creato un nuovo indirizzo, il contract address del nostro smart contract. Questo sarà identificato da un Ethereum address, che può essere usato come destinatario di una transazione.

L’account del contratto avrà un indirizzo ma non avrà la coppia chiave privata-pubblica.

Va specificato inoltre che il creatore del contratto non avrà privilegi sul contratto stesso, almeno non a livello di protocollo Ethereum. Per avere dei privilegi, questi dovranno essere specificati all’interno del contratto.

A questo punto abbiamo creato il contratto, che risiede sulla blockchain. È necessario chiarire qualche punto:

  • Il contratto non verrà mai eseguito da solo, dovrà essere sempre chiamato da una transazione, che ne richiederà una delle funzioni o invierà dei fondi al contratto;
  • I contratti possono chiamare, all’interno del codice, altri contratti, ma ad avviare la catena di chiamate sarà sempre una transazione creata da un EOA;
  • L’indirizzo del contratto ha un bilancio, quindi può ricevere fondi;
  • Chiamare un contratto costa gas e più operazioni svolge il contratto, più gas costa l’esecuzione. Da ciò ne deriva che è preferibile scrivere codice più semplice possibile, per ridurre i costi di esecuzione;
  • In caso di errore nell’esecuzione di un contratto, verrà effettuato il roll back delle operazioni, ovvero verranno annullate, come se la transazione non fosse mai cominciata. Tuttavia, la transazione sarà lo stesso registrata come tentata e il gas speso verrà comunque sottratto al bilancio dell’account che ha creato la transazione;
  • Il codice di un contratto, una volta inserito in un blocco, non può più essere cambiato. L’autore del contratto, tuttavia, può decidere di eliminare il codice, utilizzando una funzione chiamata SELFDESTRUCT. L’operazione di eliminazione del contratto prevedere un costo negativo di gas, ovvero il creatore del contratto verrà risarcito di una somma di gas, come incentivo per gli sviluppatori a rimuovere i contratti inutilizzati. Va specificato però che l’account del contratto non verrà eliminato, semplicemente verrà cancellato il codice al suo interno;
  • Come detto, eseguire un contratto costa gas. Se il costo è maggiore rispetto al gas indicato in una transazione come maxGas, l’esecuzione del contratto verrà interrotta e il gas speso fino a quel punto verrà sottratto dal bilancio dell’account che ha creato la transazione.

Durante la creazione di Ethereum, l’idea iniziale di smart contract di Buterin è stata via via espansa, arrivando al concetto di decentralized application (DApp).

Alla base del concetto di DApp vi è un radicale cambiamento della concezione del web, si potrebbe dire un capovolgimento del modo in cui lo si è inteso finora.

L’idea fondamentale è quella di decentralizzare il modo in cui funzionano le applicazioni, da tutti i punti di vista.

Ciò riguarda tutti gli aspetti di un’applicazione e quindi:

  • Backend
  • Frontend
  • Database
  • Message communications
  • Name resolution

Spesso si sente parlare di DApp a sproposito, in riferimento ad applicazioni che comunicano con degli smart contracts ma che sono ancora legate alla logica tradizionale delle applicazioni centralizzate.

Vediamo ora nel dettaglio i vari aspetti di un’applicazione e come dovrebbero essere sviluppati per ottenere una vera DApp.

Con backend, in ambito informatico, si fa riferimento alla business logic e allo stato dell’applicazione. Solitamente si concretizza in un programma server-side. Nel caso delle DApp, questo programma viene sostituito da uno o più smart contracts.

Con frontend si intende l’interfaccia visualizzata dagli utenti, che permette di interagire con il backend. Solitamente vengono utilizzate tecnologie web come HTML, CSS e JavaScript. In una DApp, questo non cambia. Esistono apposite librerie (la più celebre è web3 per JavaScript) che permettono di integrare il frontend di un’applicazione con un backend costituito da smart contracts, passando per i web browser come MetaMask.

Riguardo al database, ovvero dove vengono immagazzinati i dati, è chiaro che gli smart contracts non sono adatti ad assolvere questa funzione, visto l’elevato costo di gas.
Solitamente, nelle applicazioni tradizionali, vengono usati dei database centralizzati.
Una DApp dovrebbe preferire dei database decentralizzati, piattaforme P2P come IPFS[14] o la piattaforma Swarm[15], che non a caso fa parte della suite di tool Go-Ethereum[16], creata dalla Ethereum Foundation.

I message communication protocols sono dei componenti delle applicazioni volti allo scambio di messaggi tra applicazioni o diverse istanze della stessa applicazione. Solitamente vengono utilizzati dei server centralizzati ma anche in questo caso, una DApp dovrebbe preferire delle alternative decentralizzate, come ad esempio Whisper[17], un altro tool appartenente a Go-Ethereum.

Vi è infine il problema della name resolution, tradizionalmente svolto dal Domain Name System (DNS). Si tratta di un processo che consiste nell’associare a un indirizzo IP un nome. Quando ci rechiamo su un sito web, specifichiamo il suo nome, dietro al quale si nascondono dei numeri che costituiscono il suo indirizzo IP.
Quella del DNS è una soluzione centralizzata, alla quale si contrappone l’alternativa decentralizzata offerta dal Etereum Naming Service (ENS)[18], la cui trattazione approfondita va oltre gli scopi di questa overview.

Al momento esistono poche reali DApp e molte applicazioni che utilizzano smart contracts ma che sono centralizzate negli altri aspetti.

L’idea di DApp come applicazione totalmente decentralizzata ci porta al concetto di web 3.0, termine coniato da Gavin Wood, nome che ormai conosciamo molto bene.

Attualmente ci troviamo in una fase di passaggio dalla seconda generazione del web, il web 2.0, alla terza generazione.

Con la diffusione di internet, nel corso degli anni ’90, si affermò un tipo di web conosciuto come web 1.0, dominato da siti statici in cui gli utenti potevano solo consultare delle informazioni offerte dai server (entità centrali), in un flusso comunicativo unidirezionale, dall’alto al basso.

Il passaggio al web 2.0 è avvenuto con siti in cui il flusso comunicativo è diventato bidirezionale, siti dinamici in cui gli utenti possono interagire e partecipare. L’esempio emblematico sono i social networks. Ci troviamo tuttavia ancora all’interno di un paradigma fortemente centralizzato.

Il web 3.0 pensato da Gavin Wood è un web decentralizzato, dominato dalle DApp che abbiamo appena spiegato, in cui il paradigma client-server verrà sostituito progressivamente dal paradigma peer-to-peer.

Ethereum si pone alla base di questo cambiamento di paradigma.



Ethereum Virtual Machine (EVM)

Abbiamo nominato più volte la Ethereum Virtual Machine (EVM), cerchiamo di capire di cosa si tratta.

La EVM è il cuore di Ethereum, il motore computazionale, la parte di Ethereum che gestisce il deploy e l’esecuzione degli smart contracts.

È alla EVM che si devono gli aggiornamenti dello stato globale di Ethereum, ad eccezione degli aggiornamenti derivanti da transazioni che si limitano a trasferire Ether tra due EOA, per le quali non è necessaria la EVM.

La EVM è dunque il computer decentralizzato di cui abbiamo parlato, contenente tutti i contratti (oggetti eseguibili), ognuno con il suo data store permanente.

La EVM è simile, per certi versi, alla Java Virtual Machine[19], ovvero un motore computazionale, un runtime environment che esegue del codice compilato in EVM bytecode.

L’EVM inoltre funziona come un computer single-thread, come, ad esempio, JavaScript.

Ciò comporta il fatto che deve terminare l’esecuzione di un’istruzione prima di passare alla seguente.

Proprio questo motivo bisogna fare una precisazione a quanto detto finora. Abbiamo parlato di Ethereum come Turing-complete, in realtà è quasi Turing-complete.

Un sistema Turing-complete deve poter eseguire qualsiasi programma con almeno una soluzione, il problema è il tempo di esecuzione del programma. Come già accennato, l’halting problem consiste proprio nell’impossibilità di calcolare il tempo di esecuzione di un programma.

Pensiamo a uno smart contract contenente un loop infinito, essendo l’EVM single thread, ciò comporterebbe che l’EVM sarebbe bloccata sull’esecuzione di questo smart contract per sempre, rendendola soggetta ad attacchi DoS.

L’EVM è quindi quasi Turing-complete per via del meccanismo del gas, già spiegato precedentemente, che limita il numero di istruzioni eseguibili, applicando un costo di esecuzione.

Quando viene chiamata l’esecuzione di uno smart contract, con una transazione, viene istanziata l’EVM, caricando lo storage dall’account del contratto e le variabili d’ambiente necessarie.

L’EVM inizia a eseguire il codice, tenendo traccia del costo in gas di ogni operazione. Nella transazione un apposito campo specifica quanto l’utente che ha creato la transazione vuole spendere in gas.

Se il costo di esecuzione supera l’ammontare specificato dall’utente, l’EVM interrompe subito l’esecuzione del codice, in caso contrario lo prosegue fino al termine dell’operazione.

Nel primo caso, ogni operazione viene annullata e lo stato di Ethereum cambia solo per quanto riguarda i dati dell’utente che ha avviato la transazione, perché gli vengono sottratti gli Ether necessari per pagare il gas consumato per arrivare fino al punto d’interruzione.

Nel secondo caso invece, una volta giunta a conclusione l’operazione, viene aggiornato lo stato globale di Ethereum tenendo conto delle modifiche effettuate.

Possiamo pensare all’EVM come a un motore che esegue queste operazioni in una copia sandbox dello stato globale di Ethereum. Le modifiche vengono fatte in questa sandbox e solo se l’operazione giunge a termine correttamente vengono riportate anche nello stato reale di Ethereum.


Tokens

Tra le varie funzionalità offerte dal computer globale di Ethereum, una delle più importanti è la possibilità di creare dei token.

La parola “token” significa “segno” o “simbolo” ma in ambito blockchain ha assunto un significato sempre più specifico.

I token in una blockchain sono delle astrazioni che possono essere possedute e che rappresentano monete, assets o diritti d’accesso.

Le funzionalità che possono svolgere i token sono molteplici e qui faremo solo una panoramica ad alto livello per dare un’idea di uno degli aspetti di Ethereum che sta riscuotendo più successo in assoluto.

Facendo come sempre riferimento al libro Mastering Ethereum, possiamo individuare diverse funzioni che possono essere assolte da un token:

  • Moneta = possono essere usati per creare delle nuove monete su una blockchain;
  • Risorse = possono rappresentare risorse prodotte da un’economia;
  • Asset = possono rappresentare un asset intrinseco o estrinseco, tangibile o intangibile;
  • Diritti d’accesso = possono rappresentare i diritti d’accesso a una proprietà digitale o fisica;
  • Equity = possono rappresentare le azioni di un’organizzazione digitale;
  • Votazioni = possono rappresentare i diritti di voto in un sistema digitale;
  • Collezionabili = possono rappresentare oggetti (fisici o digitali) da collezione;
  • Identità = possono rappresentare identità digitali;
  • Attestazioni = possono rappresentare l’attestato di un fatto emanato da una certa autorità;
  • Utility = possono essere usati per accedere a un servizio.

Negli ultimi anni sono nati centinaia di token con funzioni e scopi diversi e spesso un singolo token svolge contemporaneamente più di una delle funzionalità elencate.

Vi sono degli aspetti fondamentali da approfondire:

  • Fungibilità e non fungibilità dei token;
  • Intrinsecità o non estrinsecità dei token;
  • Validità legale dei token;
  • Utility ed equity.

Si definisce fungibile un bene le cui unità individuali sono interscambiabili tra di loro.
I token possono essere sia fungibili, ad esempio un token che assolve il ruolo di moneta, in cui le varie unità sono interscambiabili e uguali tra di loro, oppure non fungibili, nel caso dei non-fungible tokens (NFT).

Attorno agli NFT è nato un grande interesse negli ultimi anni, con casi celebri come quello dei CryptoPunks. Il fatto di poter associare a un bene un codice che lo identifica univocamente, rende perfetti gli NFT per varie applicazioni, dall’ambito artistico (ad esempio identificare univocamente un’opera d’arte) a quello del gaming.

Gli NFT stanno diventando sempre più diffusi e si legano ad altri concetti come quello di metaverso, ai quali dedichiamo un’intera sezione del nostro sito. Per questo motivo rimandiamo gli interessati alla lezione introduttiva sugli NFT per approcciarsi a questo mondo.

Un altro aspetto importante di un token è l’intrinsecità o l’estrinsecità.

Si definisce intrinseco un token che rappresenta un bene digitale interno alla blockchain, governato dunque dalle regole del consenso di una blockchain.

Inversamente, è estrinseco un token che rappresenta qualcosa di esterno alla blockchain.

Questo secondo caso porta al concetto di rischio di controparte, ovvero al rischio di inosservanza dei termini contrattuali di una delle parti coinvolte in un contratto, cosa che, nel caso dei token intrinseci, viene evitata dalle regole del consenso della blockchain.

Va inoltre considerata la validità legale di un token. C’è una sempre maggior tendenza a tokenizzare qualsiasi cosa, che sia un bene digitale o uno fisico. Bisogna considerare però che le leggi che valgono in una blockchain non sono al momento riconosciute da nessun sistema legale.

In poche parole, bisogna fare i conti con le leggi esistenti riguardo alla proprietà in un determinato stato o sistema giuridico, che, attualmente, non contemplano i token delle blockchain.

Questo è un tema caldo, che in futuro accenderà sicuramente molte discussioni e che potrebbe portare a una revisione del concetto di proprietà.

Al momento, si capisce l’entusiasmo per i token ma bisogna essere molto cauti perché non è detto che la loro validità sia assoluta.

Un ultimo aspetto degno d’attenzione è quello degli utility e degli equity tokens.

La maggior parte dei progetti su Ethereum viene infatti lanciata con dei token legati al progetto stesso. Solitamente questi token sono di due tipologie:

  • Utility tokens = sono token richiesti per poter accedere a un servizio o a una risorsa;
  • Equity tokens = sono token che rappresentano le azioni o la proprietà, ad esempio di un’azienda.

Il primo caso non è problematico ma il secondo si scontra spesso con le giurisdizioni di molti stati, che regolano la distribuzione delle equity.

Per questo motivo, spesso degli equity tokens vengono spacciati per utility tokens, in modo da aggirare le giurisdizioni.

Anche in questo caso bisogna stare molto attenti e informarsi bene riguardo ai progetti sui quali si sceglie di investire.

Veniamo ora agli aspetti più tecnici dei token. Ancora una volta bisogna dire che i token non sono nati con Ethereum e che le radici si possono trovare in Bitcoin.

La stessa cryptovaluta di Bitcoin può essere vista come un token e inoltre sono state sviluppate su Bitcoin molte piattaforme basate sui token.

Nonostante ciò, i token sono esplosi con Ethereum, in cui si sono diffusi dei veri e propri standard per la realizzazione dei token.

Qui indichiamo solo i due standard più noti, anche se ce ne sono molti altri:

  • ERC20
  • ERC721

Innanzitutto spieghiamo cos’è uno standard. Si tratta di un’interfaccia che può essere implementata da uno smart contract e che lo obbliga ad implementare una serie di funzionalità.

Non è obbligatorio creare un token basandosi su uno standard esistente, è possibile, anche se più difficile, creare un token partendo da zero.

Gli standard offrono delle soluzioni già ampiamente diffuse e testate e rendono più facile la creazione di un token.

Esistono inoltre delle implementazioni di questi standard particolarmente diffuse, che facilitano ulteriormente la realizzazione di un token.

Un’altra cosa fondamentale da comprendere è che i token funzionano in modo diverso rispetto a Ether, perché Ether funziona a livello del protocollo Ethereum, i token invece funzionano a livello degli smart contracts.

Facciamo un esempio: il bilancio di Ether di un account è gestito a livello di protocollo, il bilancio di un token invece è gestito da uno smart contract.

Ne derivano molte considerazioni, due particolarmente importanti:

  • Quando si fa una transazione per scambiare dei token, l’indirizzo del destinatario non sarà quello dell’effettivo destinatario, bensì quello dello smart contract che gestisce il token;
  • Per fare una transazione in cui si scambiano dei token è necessario possedere comunque degli Ether perché, attualmente, il gas si può comprare solo in Ether e sono richiesti per qualsiasi transazione.

Fatte queste precisazioni, passiamo ai due standard più diffusi.

L’ERC20 è stato introdotto nel 2015 e sta per Ethereum Request for Comments. È stato postato su GitHub e gli è stato assegnato il numero di issue 20[20], da cui ne è derivato il nome.

L’ERC20 è lo standard più diffuso per la realizzazione di token fungibili, ad esempio di nuove monete.

Si tratta di un’interfaccia che deve essere implementata da un contratto:

contract ERC20 {
    function totalSupply() constant returns (uint theTotalSupply);
    function balanceOf(address _owner) constant returns (uint balance);
    function transfer(address _to, uint _value) returns (bool success);
    function transferFrom(address _from, address _to, uint _value) returns (bool success);
    function approve(address _spender, uint _value) returns (bool success);
    function allowance(address _owner, address _spender) constant returns (uint remaining);
    event Transfer(address indexed _from, address indexed _to, uint _value);
    event Approval(address indexed _owner, address indexed _spender, uint _value);
}

In sostanza, un contratto che implementa questa interfaccia sarà obbligato ad avere i metodi specificati nell’interfaccia, ad esempio un metodo “transfer” che serve a trasferire i token da un indirizzo a un altro.

Nonostante l’ampia diffusione di ERC20, questo standard ha diversi problemi, ad esempio il fatto che, quando si trasferiscono dei token, non viene realmente aggiornato lo stato degli account interessati, bensì lo stato del contratto.

Senza scendere nei dettagli, queste limitazioni e criticità hanno portato a una ricerca di nuovi standard e continuano a venir fatte nuove proposte.

L’ERC721[21] è invece lo standard più diffuso per i non fungible tokens, viene dunque utilizzato per registrare la proprietà di un bene che viene identificato univocamente da un id da 256 bit.

interface ERC721 /* is ERC165 */ {
    event Transfer(address indexed _from, address indexed _to, uint256 _deedId);
    event Approval(address indexed _owner, address indexed _approved,uint256 _deedId);
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
    function balanceOf(address _owner) external view returns (uint256 _balance);
    function ownerOf(uint256 _deedId) external view returns (address _owner);
    function transfer(address _to, uint256 _deedId) external payable;
    function transferFrom(address _from, address _to, uint256 _deedId) external payable;
    function approve(address _approved, uint256 _deedId) external payable;
    function setApprovalForAll(address _operateor, boolean _approved) payable;
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

Anche in questo caso va specificato che nulla impedisce di non seguire uno standard e realizzare un NFT partendo da zero.

Inoltre, gli standard sono delle specifiche minime per un’implementazione, ovvero l’implementazione dovrà avere dei metodi indicati dall’interfaccia ma nulla vieta che poi implementi altri metodi non presenti nell’interfaccia.

Ciò serve a garantire un’interoperabilità tra i contratti dei token che agiranno in una maniera standard e prevedibile.


Oracoli

Gli smart contracts potrebbero aver bisogno di accedere a dati specifici per poter funzionare. Immaginiamo, ad esempio, un contratto che si basa su una scommessa sul prezzo dell’oro. Sarà necessario quindi avere un modo per accedere ai dati relativi al prezzo dell’oro.

A svolgere questa funzione ci pensano gli oracoli, dei sistemi che forniscono dati da fonti esterne alla blockchain agli smart contracts.

È evidente l’importanza delle veridicità di questi dati che, idealmente, dovrebbero provenire da oracoli trustless e decentralizzati.

Possiamo pensare agli oracoli come un ponte che mette in comunicazione la blockchain con i dati off-chain del mondo reale.

L’argomento è molto complesso e lo approfondiremo in lezioni dedicate, qui ci limitiamo a introdurre questo tema fondamentale.

Le applicazioni pratiche per cui un oracolo si rende necessario sono potenzialmente illimitate.

Gli oracoli possono servire per fornire dati del mondo reale (andamenti dei prezzi di asset, dati di altre blockchain, dati statici, dati meteo, dati riguardanti eventi politici, ecc.) e possono servire anche per svolgere operazioni computazionalmente onerose, dati degli input, e restituire degli output.

In questo secondo caso si tratta di portare off-chain delle computazioni troppo complesse per essere eseguite da uno smart contract on-chain, cosa che comporterebbe un costo spropositato in gas.

Ciò che dovrebbe fare un oracolo dunque è:

  • Collezionare dati da una fonte off-chain;
  • Trasferire i dati on-chain con un messaggio firmato;
  • Rendere i dati disponibili inserendoli in uno smart contract.

Si possono individuare diverse tipologie di oracoli, in base al tipo di dati che devono fornire:

  • Immediate-read = forniscono dati necessari per una decisione immediata. Le informazioni richieste sono cercate quando vengono richieste e forse non serviranno più;
  • Publish-subscribe = forniscono informazioni che devono essere aggiornate frequentemente, come un feed RSS;
  • Immediate-read = forniscono una quantità di informazioni talmente grande da essere impossibile da immagazzinare in uno smart contract, rendendo necessaria quindi un’infrastruttura off-chain.

Queste tre tipologie sono in ordine di complessità, dalla più facile alla più complessa.

Vi sono poi casi ancora più complicati in cui, come dicevamo, gli oracoli non devono solo fornire dati ma vengono usati per effettuare delle computazioni e restituire dei risultati.

Ci sono vari progetti che hanno cercato di risolvere questi problemi, in modo centralizzato o decentralizzato.

Qui riportiamo i casi di Provable[22], Truebit[23] e in particolare ChainLink[24].

ChainLink sta diventando sempre più diffuso e si tratta di un oracolo decentralizzato che, molto probabilmente, diventerà fondamentale nel mondo della blockchain e che sicuramente approfondiremo in separata sede.


Processo di sviluppo, forks e governance

Come in tutte le blockchain decentralizzate, è importante capire come avvengono i cambiamenti alle regole del protocollo, come il sistema può evolvere e cambiare nel tempo.

Ethereum funziona, da questo punto di vista, in modo abbastanza diverso rispetto a Bitcoin.

Bitcoin, nel corso degli anni, si è guadagnato il titolo di prima blockchain e criptovaluta anche per il fatto di aver dimostrato una grande stabilità e sicurezza, data da una linea d’azione prevalentemente conservativa.

Ogni cambiamento è studiato con grande attenzione e raramente si assiste a degli hard fork, ovvero a cambiamenti drastici che portano la catena a prendere due diramazioni che continueranno per le loro rispettive strade.

Vengono preferiti invece i soft fork, ovvero dei cambiamenti al protocollo che sono retrocompatibili. Ciò significa che i nodi che non adotteranno questi cambiamenti potranno continuare a far parte della rete e a comunicare con gli altri nodi.

Ethereum invece ha una linea d’azione molto meno conservativa. I cambiamenti vengono implementati con più facilità e con meno discussioni, anche quando ciò comporta un obbligo di aggiornare i client alle nuove regole del consenso, con un conseguente hard fork per chi non accetta le nuove regole.

Questa maggiore flessibilità e tendenza al cambiamento ha vantaggi e svantaggi.

È un problema, ad esempio, per chi sviluppa smart contracts, perché potrebbe trovarsi obbligato ad abbandonare i contratti creati e a doverne creare di nuovi in accordo con le nuove regole.

Manca insomma la stabilità che contraddistingue Bitcoin.

Cerchiamo ora di capire come vengono prese le decisioni in Ethereum.

Possiamo individuare due principali tipologie di governance in ambito blockchain:

  • Governance on-chain
  • Governance off-chain

La differenza è immediata: nel primo caso le decisioni vengono prese attraverso un processo di votazione che avviene on-chain (un caso emblematico è il nuovo esperimento di governance on-chain di Algorand, a cui abbiamo dedicato una lezione), nel secondo la votazione avviene all’esterno della blockchain, anzi, spesso non avviene proprio una votazione diretta ma una discussione “informale”, come dice lo stesso Vitalik Buterin in un post che ha dedicato all’argomento[25].

Ethereum, come Bitcoin, ha preferito questa seconda possibilità.

Ovviamente, trovandoci in un sistema decentralizzato, il potere deve essere distribuito e non accentrato nelle mani di un solo gruppo dell’ecosistema Ethereum.

Abbiamo così diversi gruppi di attori, coinvolti nel processo di governance, che hanno dei propri interessi, spesso in conflitto tra loro:

  • Gli Ether holders;
  • Gli user di applicazioni sulla blockchain di Ethereum;
  • Gli sviluppatori di applicazioni che girano sulla blockchain di Ethereum;
  • I full nodes;
  • Gli autori delle Ethereum Improvement Proposals (EIPs);
  • I miner;
  • Gli sviluppatori del protocollo (core developers).

Chiunque può proporre dei cambiamenti al protocollo di Ethereum in qualsiasi momento. La cosa difficile è trovare seguito e convincere i vari gruppi dell’utilità del cambiamento proposto.

Uno strumento molto importante le Ethereum Improvement Proposals (EIPs), ovvero degli standard che specificano nuove funzionalità o nuovi processi in Ethereum. Contengono specifiche tecniche per i cambi proposti e funzionano come “fonte di verità” per la comunità[26].

Tutti gli upgrade del network di Ethereum e gli standard sono discussi e sviluppati seguendo il processo EIP.

Il processo formale è composto da 5 fasi successive[27]:

  • Proposta di un Core EIP = viene proposto formalmente un cambio al protocollo di Ethereum, esposto nel dettaglio in un Core EIP. Questa specifica rappresenta ciò che i protocol developers implementeranno se l’EIP verrà accettato;
  • Presentare l’EIP ai protocol developers = bisogna presentare il proprio EIP ai developers, attraverso i vari canali utilizzati. I developers possono considerare i cambiamenti per il futuro, ritenerli importanti subito oppure rigettarli;
  • Iterare le fasi precedenti fino a una proposta finale = dopo aver ricevuto un feedback da vari stakeholders, probabilmente bisognerà applicare dei cambiamenti all’EIP, fino a quando non si arriverà a una proposta finale;
  • Inclusione dell’EIP in un nuovo Network Upgrade = a questa fase si arriva se l’EIP viene approvato e implementato, quindi schedulato come parte di un nuovo upgrade. Solitamente si uniscono diversi EIPs in un unico upgrade;
  • Attivazione del network upgrade = l’upgrade viene effettuato e l’EIP diventa attivo. Solitamente gli upgrade vengono priva provati sulla Testnet e poi sulla Mainnet.

Quando questo processo arriva a termine, possono verificarsi i due casi spiegati precedentemente: quello di un soft fork, se i cambiamenti sono retrocompatibili, o quello di un hard fork, se i cambiamenti non sono retrocompatibili.

Uno dei casi di Hard Fork più celebri in Ethereum è stato quello del DAO Hack, che tratteremo in una lezione dedicata[28].

Importante infine è il peso decisionale dei miners, perché possono scegliere se approvare o meno i cambiamenti di protocollo, installandoli sul loro nodo o rifiutandoli.

Il loro potere però è mediato dal fatto di dipendere dagli altri gruppi che partecipano alla governance.

Ad esempio, anche se la maggior parte dei miner dovesse essere d’accordo sul rifiutare un cambiamento e dar vita a un hard fork, non è detto che sulla loro catena ci sarebbero transazioni. In quel caso, sarebbe per loro un suicidio dal punto di vista economico.

Come nel caso di Bitcoin, la governance si regge proprio su questo delicato equilibrio tra le parti coinvolte.

In ogni caso, come si può facilmente notare, la tendenza di Ethereum ad essere meno conservativo rispetto a Bitcoin ha portato a un gran numero di forks nel corso della sua breve vita.


Ethereum 2.0

Chiudiamo questa overview con un paragrafo dedicato a Ethereum 2.0.

Con Ethereum 2.0 (o Eth2) si intende una serie di aggiornamenti interconnessi, volti a migliorare Ethereum rendendolo più scalabile, sicuro e sostenibile.

In origine questo set di aggiornamenti si chiamava Serenity ed è stato iniziato a studiare nel 2014[29], dalla nascita di Ethereum.

Il cambiamento più grande è il passaggio da Proof of Work a Proof of Stake, come già detto più volte, però a supporto di questo cambiamento radicale vi sono molte altre modifiche.

Qui cercheremo di dare una visione dall’alto, senza entrare troppo nel dettaglio. Più avanti dedicheremo sicuramente una lezione all’argomento.

Ethereum, con il passare del tempo, si è trovato a dover affrontare molti problemi, alcuni dei quali Vitalik Buterin attribuiva a Bitcoin e che poi si sono verificati anche su Ethereum.

Cercando di elencarne alcuni possiamo indicare:

  • Congestione della rete con conseguente aumento delle transaction fees, diventate insostenibili per la maggior parte degli utenti;
  • Dimensioni della catena cresciute considerevolmente, rendendo difficile installare un full node, con conseguente rischio di centralizzazione;
  • Consumo energetico molto elevato, dovuto all’algoritmo di consenso Proof of Work.

Per spiegare come sono stati pensati e sviluppati gli aggiornamenti, bisogna tenere conto di un concetto fondamentale quando si parla di blockchain, ovvero il celebre trilemma della blockchain, secondo il quale sarebbe impossibile ottenere un sistema allo stesso tempo:

  • Decentralizzato;
  • Sicuro;
  • Scalabile.

Con Ethereum 2.0, gli sviluppatori hanno cercato di tenere conto di questi tre punti, andando ad apportare delle modifiche che porterebbero a dei miglioramenti in tutti i tre sensi, più ulteriori miglioramenti per quanto riguarda la sostenibilità ambientale.

Citando quanto detto sul sito di Ethereum: “Gli aggiornamenti a Eth2 renderanno Ethereum scalabile, sicura e decentralizzata. Lo sharding la renderà più scalabile, aumentando il numero di transazioni al secondo e contestualmente diminuendo la quantità di energia necessaria per eseguire un nodo e convalidare la catena. La beacon chain renderà Ethereum sicura, coordinando i validatori dei diversi shard. Lo staking abbatterà le barriere alla partecipazione, creando una rete più grande e più decentralizzata”[30].

I concetti fondamentali sono quelli di:

  • Beacon chain;
  • Sharding;
  • Staking.

I tre concetti sono relazionati tra loro e cooperano per ottenere i fini specificati precedentemente.

La Beacon Chain è una nuova blockchain proof-of-stake e sarà la spina dorsale di Ethereum 2.0. È già stata realizzata e si possono esplorare i dati di questa nuova blockchain qui[31].

Ovviamente non ha sostituito la blockchain principale di Ethereum, al momento le due catene coesistono.

Come dicevamo, la Beacon Chain si basa su un protocollo Proof of Stake in cui dunque il mining viene sostituito con lo staking, a cui abbiamo già accennato, che dovrebbe da un lato riuscire a rendere il sistema più sostenibile dal punto di vista ambientale, riducendo drasticamente i consumi energetici, e dall’altro più sicuro, perché chi agisce malevolmente rischia di perdere tutti i propri fondi messi in stake, l’equivalente del distruggere le attrezzature per minare nel caso di PoW.

Insomma, delle sanzioni più gravi per i trasgressori che dovrebbero disincentivare azioni malevole.

Lo sharding invece consiste nel suddividere il carico di Ethereum su più catene, 64 per la precisione.

Ogni catena avrà un carico pari a quello dell’attuale Ethereum, avrà i suoi validatori e l’esecuzione di un nodo diventerà più semplice e meno onerosa dal punto di vista dell’hardware, visto che si dovrà scaricare solo uno shard.

Il fatto di alleggerire il peso dei nodi dovrebbe andare a vantaggio della decentralizzazione, permettendo a chiunque di installare un nodo senza grossi problemi.

Inoltre, lo sharding va a vantaggio anche della scalabilità, aumentando il numero di transazioni che possono essere processate al secondo, uno dei grandi colli di bottiglia di Ethereum attualmente.

Al momento, il termine previsto per il passaggio completo a Ethereum 2.0 è il 2023.

Gli argomenti meritano una trattazione molto più approfondita e verranno dedicate delle lezioni dedicate a tutti gli aspetti di Ethereum 2.0.


Note

[1] https://en.bitcoinwiki.org/wiki/Mastercoin

[2] https://ethereum.org/en/whitepaper/

[3] https://it.wikipedia.org/wiki/Macchina_di_Turing

[4] https://en.wikipedia.org/wiki/Halting_problem

[5] https://docs.ethhub.io/ethereum-basics/monetary-policy/

[6] https://ethereum.org/en/developers/docs/accounts/#an-account-examined

[7] https://it.wikipedia.org/wiki/Logaritmo_discreto

[8] https://ethereum.org/en/glossary/#ommer

[9] https://www.investopedia.com/terms/b/block-time-cryptocurrency.asp#:~:text=Each%20cryptocurrency%20has%20a%20different,generated%20by%20the%20hashing%20algorithm.

[10] https://docs.ethhub.io/ethereum-basics/monetary-policy/

[11] https://github.com/ethereumbook/ethereumbook/blob/develop/14consensus.asciidoc#casper-ethereums-proof-of-stake-algorithm

[12] https://www.fon.hum.uva.nl/rob/Courses/InformationInSpeech/CDROM/Literature/LOTwinterschool2006/szabo.best.vwh.net/smart_contracts_2.html

[13] https://github.com/ethereum/solidity

[14] https://ipfs.io/

[15] https://github.com/ethereum/go-ethereum/tree/master/swarm

[16] https://geth.ethereum.org/

[17] https://github.com/ethereum/whisper

[18] https://docs.ens.domains/

[19] https://en.wikipedia.org/wiki/Java_virtual_machine

[20] https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md

[21] https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md

[22] https://provable.xyz/

[23] https://truebit.io/

[24] https://chain.link/

[25] https://vitalik.ca/general/2017/12/17/voting.html

[26] https://ethereum.org/en/eips/

[27] https://ethereum.org/en/governance/#formal-process

[28] https://www.youtube.com/watch?v=rNeLuBOVe8A

[29] https://blog.ethereum.org/2015/03/03/ethereum-launch-process/

[30] https://ethereum.org/it/eth2/vision/

[31] https://beaconscan.com

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

WHITE PAPER
Il white paper di Ethereum è stato pubblicato da Vitalik Buterin nel 2013.

Inoltre è stato scritto anche un documento più tecnico, che viene aggiornato periodicamente: lo Yellow Paper.

RISORSE PER SVILUPPATORI
Guida per developers