La scalabilità, o la capacità di scalare, è una delle questioni più importanti quando si tratta di protocolli criptoeconomici come Bitcoin ed Ethereum. Infatti, per rimanere rilevanti, questi protocolli non possono permettere alle loro rispettive reti di subire un carico transazionale troppo grande e quindi diventare troppo centralizzati. La domanda che ci si deve porre quando si parla di scaling up è quindi: Come può la rete aumentare in modo sicuro la sua capacità di elaborazione mantenendo una sufficiente decentralizzazione?
Al momento, le reti Bitcoin ed Ethereum stanno lottando per tenere il passo con la domanda e possono sperimentare una congestione caratterizzata da tempi di conferma più lunghi e commissioni di transazione più elevate. Per Ethereum, forse l’episodio più emblematico di questo problema è Cryptokitties, l’applicazione decentralizzata per la raccolta e il commercio di gatti virtuali, che ha monopolizzato la rete nel dicembre 2017.
Lo sharding, o partizionamento, è la soluzione prevista dagli sviluppatori di Ethereum per ovviare al problema. Questa tecnica non è nuova e viene utilizzata per i database: si tratta di partizionare i dati orizzontalmente per distribuire lo stoccaggio in memoria. Per Ethereum, la cui ambizione è quella di essere un computer globale, lo sharding consisterebbe nel parallelizzare sia lo stoccaggio che l’esecuzione dei contratti autonomi senza perdere la sicurezza.
Insieme a Casper e eWASM, questo partizionamento è uno degli elementi principali di Ethereum 2.0, l’evoluzione di Ethereum verso una maggiore efficienza e scalabilità che dovrebbe arrivare con l’aggiornamento Serenity.
Qual è il problema?
I sistemi cripto-economici basati sulle blockchain sono, per progettazione, sistemi piuttosto inefficienti. Per funzionare senza un’autorità centrale, per resistere agli attacchi esterni, devono essere sufficientemente distribuiti.
Per questo motivo sono soggetti a un principio noto come “trilemma della blockchain” formalizzato da Vitalik Buterin. Questo trilemma afferma che un sistema blockchain può avere solo 2 delle seguenti 3 proprietà:
- Decentralizzazione: il sistema può funzionare dove ogni partecipante ha accesso solo a una determinata quantità di risorse di calcolo (come un computer portatile o un piccolo server virtuale).
- Scalabilità: il sistema può elaborare transazioni in un ordine di grandezza strettamente superiore alle risorse possedute da un singolo partecipante.
- Sicurezza: il sistema è sicuro contro un aggressore con meno risorse di quelle corrispondenti al livello transazionale della rete.
Le cosiddette soluzioni “ingenue” sono state considerate per rimediare al problema, ma non per risolverlo completamente:
- Attività separata tra diverse rete (“altcoins”). Distribuendo i validatori su diverse reti, questa soluzione riduce la sicurezza complessiva del sistema.
- Aumentare il limite della dimensione del blocco. Dopo una certa soglia (da determinare), questa soluzione diminuisce la decentralizzazione della rete aumentando il livello delle risorse di calcolo richieste per mantenere un nodo.
- Eseguire il mining unito su diverse rete. Per Vitalik Buterin, questa è una forma mascherata di aumentare il limite della dimensione del blocco, che diminuisce la decentralizzazione costringendo i validatori a gestire altre catene per rimanere redditizi.
Sono state escogitate altre soluzioni più ingegnose ma anche più complesse. Questo è in particolare il caso delle cosiddette soluzioni di “secondo strato”. Per Ethereum, questi sono la rete Raiden, che è una rete di canali di stato e si basa sugli stessi principi della rete Lightning, e Plasma, il sistema di side-chain. Queste soluzioni hanno i loro problemi che non verranno descritti qui in dettaglio.
È in questo contesto che entra in gioco il partizionamento, che è la soluzione preferita dagli sviluppatori affinché Ethereum possa scalare senza alcuna perdita in termini di decentralizzazione o di sicurezza.
Cos'è il partizionamento, o sharding?
Ethereum è un computer globale decentralizzato il cui stato globale è aggiornato da tutti i nodi della rete. Questo stato viene cambiato continuamente attraverso le transazioni (chiamate anche operazioni). La blockchain, la storia che elenca tutte queste transazioni dalla creazione del sistema, permette ai nodi della rete di sincronizzarsi.
Ethereum è quindi caratterizzato da due cose: il suo stato e la sua storia. In Ethereum, lo stato è la mappatura dagli indirizzi (0x…) al loro saldo, al loro nonce, e al loro codice e dati se sono contratti indipendenti. Lo stato è sufficiente per determinare se una transazione è valida o no.
Oggi, lo stato e la storia pesano rispettivamente 215 GB e 2,4 TB. Molti nodi della rete si accontentano di memorizzare solo lo stato del sistema (modalità “pruned”). Solo i cosiddetti nodi “archiviatori” si prendono la briga di memorizzare l’intera blockchain.
L’idea dietro il partizionamento è di suddividere sia la storia che lo stato di Ethereum in una moltitudine di frammenti indipendenti (shard). Ognuno di questi frammenti è convalidato da una parte (variabile) della rete, il che rende possibile la parallelizzazione delle operazioni e la distribuzione del carico totale del sistema. Il numero di shard dipende dal rapporto tra le risorse di calcolo minime richieste per ogni partecipante e il numero medio di transazioni effettuate sulla rete.
Da un lato, ogni frammento si comporta allora come una catena a sé stante: ha il suo stato locale, ha la sua storia, e impiega una parte della rete da convalidare. D’altra parte, l’insieme dei frammenti deve comportarsi allo stesso modo del sistema globale, il che rende l’applicazione dell’idea piuttosto difficile come vedremo nella prossima sezione.
Esistono altre proposte che assomigliano al partizionamento proposto dai team di sviluppo di Ethereum. In particolare, Zilliqa ha implementato una forma di partizionamento che divide i compiti computazionali tra diverse sottoreti, ma mantiene un unico stato. Allo stesso modo, l’uso di un albero Merklix (noto anche come albero Merkle-Patricia), che è presente nella roadmap di Bitcoin Cash, dovrebbe consentire il partizionamento della validazione dei blocchi in futuro.
Come funziona?
Il partizionamento si basa in primo luogo sulla creazione di una catena principale chiamata catena beacon, che gestisce la distribuzione dei compiti in Ethereum. Su questa catena, i validatori sono selezionati casualmente per avere il diritto di creare blocchi su un dato frammento. Allo stesso modo, per ogni frammento, un centinaio di attestatori sono scelti per certificare la validità del blocco: perché il blocco sia valido e perché la ricompensa sia distribuita, almeno 67 di loro devono pubblicare la loro firma sulla catena beacon. La blockchain agisce quindi come un intermediario tra i frammenti e il sistema globale.

Inoltre, il partizionamento della blockchain di Ethereum richiede un passaggio al proof-of-stake. In particolare, richiede l’algoritmo proof-of-stake attualmente in sviluppo chiamato Casper. Anche se lo sharding può essere usato in un sistema proof-of-work, ci sono due ragioni chiave per cui questo algoritmo è preferibile:
In un modello proof-of-work, un frammento specifico potrebbe essere attaccato più facilmente.
In Casper, che richiede una lista di validatori che hanno fatto un deposito cauzionale, è molto più facile selezionare questi validatori per la distribuzione ai diversi frammenti.
Quando il sistema è in funzione, ogni gruppo di transazioni è assegnato a un frammento specifico. Un esempio grossolano di allocazione sarebbe 256 frammenti che condividono le transazioni in base al loro ID. In questo modo, tutte le transazioni con un ID che inizia con 0x00 verrebbero processate dal frammento 1, quelle che iniziano con 0x01 andrebbero nel frammento 2, ecc.
Ovviamente, una transazione elaborata in un frammento può avere un impatto su un contratto in un altro frammento. Quindi, il partizionamento richiede un sistema di comunicazione tra i frammenti (comunicazione cross-shard) per armonizzare lo stato globale di Ethereum. Questo sistema di comunicazione coinvolge le ricevute, che sono oggetti che rappresentano l’effetto di una transazione che non sono memorizzati direttamente nello stato, ma sono comunque conservati in un altro luogo. Queste ricevute sono già utilizzate da Ethereum come registri di eventi.
Conclusione:
Permettere alle blockchain di scalare non è una cosa facile da fare, ma il partizionamento sembra destinato a migliorare notevolmente la scalabilità di Ethereum. Secondo Vitalik Buterin, permetterebbe di moltiplicare la capacità transazionale di Ethereum per 100 e, combinata con la rete sidechain Plasma, per 10.000!
Anche se lo sviluppo del partizionamento sta progredendo (Prysmatic Labs ha già creato un client funzionante), è improbabile che la sua implementazione in Ethereum veda la luce prima del 2020 o addirittura del 2021. Un aggiornamento per creare la catena di tag e implementare Casper dovrà comunque precedere questo.