Vai al contenuto

Radice di stato

La radice di stato è l'impegno compatto di Ethereum sullo stato globale dopo un blocco. Spiega come viene calcolata, cosa provano le prove di account e storage e cosa non garantisce.

Aggiornato

Solo a scopo educativo; non costituisce consulenza né raccomandazione d’investimento. Gli investimenti possono comportare perdite.

Risposta diretta

Una radice di stato è un impegno crittografico di 32 byte nell’header di un blocco Ethereum sullo stato globale dopo l’elaborazione del blocco. Lo stato globale associa gli indirizzi agli account. Ogni account impegna nonce, saldo, radice di storage e hash del codice; la radice di storage di ogni contratto impegna a sua volta gli slot di storage dell’account.

La radice è un digest, non uno snapshot scaricabile. Consente ai nodi di confrontare risultati calcolati in modo indipendente e a un verificatore di controllare una prova di account o storage rispetto a un blocco fidato. Da sola non ricostruisce lo stato, non prova la disponibilità dei dati o la finalità del blocco e non dimostra che un contratto sia economicamente sicuro.

“Radice di stato” dipende dal protocollo. Ethereum attualmente impegna lo stato del livello di esecuzione con un trie Merkle-Patricia modificato. Altre reti possono usare modelli di stato, codifiche, funzioni hash o strutture autenticate differenti; lo stesso termine non rende intercambiabili le loro radici o prove.

Come funziona

Un client di esecuzione parte dallo stato del blocco padre, convalida ed esegue il nuovo blocco secondo le regole attive del protocollo e applica le modifiche risultanti ad account e storage. In forma schematica:

S_n = Υ(S_(n-1), B_n)

Qui S_(n-1) è lo stato padre, B_n è l’intera elaborazione definita dal protocollo per il nuovo blocco e S_n è lo stato risultante. Il client codifica deterministicamente lo stato nel trie e ne calcola l’hash radice. Un header valido deve contenere lo stesso risultato; una differenza rende il blocco non valido per quel client.

Nel trie di stato di Ethereum, il percorso di un account deriva dall’indirizzo, mentre l’account codificato contiene nonce, saldo, radice di storage e hash del codice. Il codice del contratto è referenziato dal suo hash e ogni contratto ha un trie di storage separato. Con questa struttura annidata, la modifica di uno slot può cambiare la radice di storage del contratto, poi l’account codificato e infine la radice di stato globale.

La radice di stato è distinta dalle radici delle transazioni e delle ricevute nello stesso header. La prima impegna i dati ordinati delle transazioni; la seconda le ricevute di esecuzione. Nessuna può sostituire l’altra.

EIP-1186 definisce eth_getProof, che può restituire una prova di account e le prove di storage richieste per un blocco specifico. Il verificatore necessita comunque di un hash del blocco o una radice di stato autenticati, delle regole corrette per trie e codifica e di una politica adeguata di conferma o finalità.

Esempio

Supponiamo che una transazione trasferisca ETH da Alice a Bob. L’esecuzione corretta può modificare nonce e saldo di Alice, il saldo di Bob e quello del destinatario della commissione. Se la transazione chiama un contratto, possono cambiare anche gli slot e la radice di storage del contratto. Questi aggiornamenti producono una nuova radice di stato globale anche se la maggior parte degli account non viene toccata.

Due client onesti che partono dallo stesso stato padre ed elaborano lo stesso blocco valido con le stesse regole dovrebbero calcolare la stessa radice. Se uno accredita un importo errato o usa una codifica sbagliata del trie, la sua radice differirà dall’header e dovrà rifiutare il blocco anziché accettare tacitamente lo stato locale.

Per verificare il saldo di Bob senza scaricare tutto lo stato globale, si possono ottenere l’header e una prova di account. Ricalcolare il percorso della prova mostra se l’account codificato è coerente con la radice di stato dell’header. Non dimostra che l’header scelto sia canonico o finalizzato; ciò deriva dai controlli della catena e della finalità del verificatore.

Rischi

  • Radice non fidata: Una prova valida rispetto a una radice scelta da un attaccante o obsoleta dimostra il riferimento sbagliato. Legare la radice a hash del blocco, ID della catena e numero del blocco verificati.
  • Riorganizzazioni e finalità: Una prova può essere corretta per un blocco che poi esce dalla catena canonica. Adeguare profondità di conferma o finalità alla tolleranza alle perdite dell’applicazione.
  • Errori di codifica: Hash degli indirizzi, RLP, percorsi a nibble, nodi incorporati e chiavi di storage devono seguire esattamente il protocollo. Una libreria generica per prove Merkle binarie non basta.
  • Dati mancanti: La radice impegna lo stato ma non rende disponibili nodi del trie, stato storico o servizi di generazione delle prove. I nodi sottoposti a pruning potrebbero non servire prove vecchie.
  • Garanzie eccessive: L’accordo delle radici rileva esecuzioni incoerenti; non verifica i contratti, autentica gli oracoli, protegge un endpoint RPC, garantisce il valore degli asset o impedisce operazioni autorizzate da chiavi compromesse.

Idee sbagliate comuni

  • La radice di stato memorizza tutti i saldi. È un impegno di dimensione fissa su un trie codificato; i dati sottostanti vanno ottenuti separatamente.
  • Radici uguali dimostrano database identici. Impegnano lo stesso stato globale logico secondo il protocollo, ma i client possono archiviarlo, indicizzarlo, potarlo o conservarlo in cache in modo diverso.
  • Una radice diversa identifica la transazione errata. Rivela un disaccordo sullo stato finale impegnato, non dove è iniziata la divergenza; per la diagnosi occorre tracciare l’esecuzione.
  • Una prova di account valida dimostra finalità e sicurezza. Dimostra solo coerenza con una radice. Scelta della catena, finalità, attualità dei dati, comportamento del contratto e rischio economico sono questioni separate.

Argomenti correlati

Fonti

Navigazione

Cerca nella wiki...