Wenn ich den Geth-Code und verschiedene Beiträge hier lese, glaube ich, dass ich jetzt ein gutes Verständnis dafür habe, wie die Daten in Ethereum gespeichert werden (bitte korrigieren Sie mich, wenn ich mich irgendwann irre).
Auf der untersten Ebene haben wir eine Key-Value-Datenbank
Auf der nächsten Ebene haben wir eine generische Datenstruktur namens trie
Und auf der Ethereum-Blockchain-Ebene haben wir so etwas wie (nur relevante Teile genannt):
block -> state trie -> account* -> storage trie
[Q1] : Für Zustandsversuche stellen die Pfade die Kontoadressen dar. Was sind die Pfade im Speicherversuch? Speicherindizes?
[Q2] : Wenn wir einen einfachen Vertrag der Form haben:
contract C {
uint256 public x = 100;
}
Wenn wir zwei Instanzen dieses Vertrags instanziieren. Werden sie denselben Storage-Root-Hash haben? Wenn ja, teilen sie genau dasselbe Schlüssel/Wert-Paar in der Datenbank (auf der untersten Ebene) bzw. denselben Trie-Knoten im Speicher-Trie?
Bei Zustandsversuchen stellen die Pfade die Kontoadressen dar. Was sind die Pfade im Speicherversuch? Speicherindizes?
Das ist richtig, außer dass die Adressen und Indizes gehasht werden, bevor sie im Trie gespeichert werden. Dies geschieht zum Schutz vor DoS: Warum werden Schlüssel in Merkle Patricia Trie gehasht?
Wenn wir zwei Instanzen dieses Vertrags instanziieren. Werden sie denselben Storage-Root-Hash haben?
Ja.
werden sie genau dasselbe Schlüssel/Wert-Paar in der Datenbank (auf der untersten Ebene) bzw. denselben Trie-Knoten im Speicher-Trie teilen?
Ja, da der Trie-Stamm für beide Verträge gleich ist, teilen sie sich die Schlüssel/Werte in der zugrunde liegenden Datenbank. Es scheint zunächst kontraintuitiv oder unsicher zu sein, dass 2 Verträge "denselben Speicher teilen". Da die Trie-Struktur jedoch unveränderlich ist, wird immer dann, wenn ein neuer Eintrag zum Trie hinzugefügt wird, eine modifizierte Instanz mit eigener Wurzel erstellt. Der alte unmodifizierte Trie ist noch in der zugrunde liegenden Datenbank vorhanden und andere Verträge können immer noch darauf verweisen.
Sie können versuchen, 2 Verträge mit demselben Speicher zu erstellen und dann ihre Speicherwurzeln und Inhalte mit diesem nodejs-Code https://ethereum.stackexchange.com/a/40280/18932 zu lesen
Verträge haben tatsächlich einen Speicher-Root-Hash und einen Code-Root-Hash (der weniger ein Root-Hash als vielmehr ein regulärer Hash ist, da Code ein Blob ist). Wenn zwei Verträge genau denselben Code und damit denselben Code-Hash haben, sollte der Blob, der diesem Hash entspricht, vom Knoten nur einmal in der Datenbank gespeichert werden, aber ich kann nicht sagen, ob dies tatsächlich der Fall ist oder nicht das.
Dasselbe gilt für den Status-Root-Hash eines Vertrags, aber da sich dieser von Block zu Block ändern kann, kann es in der db etwas komplizierter sein. Ich gehe davon aus, dass es nicht dupliziert wird, da die Datenbank größtenteils ein Schlüsselwertspeicher ist, aber ich kann mir nicht sicher sein.
ivicaa
medwedew1088
ivicaa