(Schlüssel, Wert)-Paar im Kontospeicher und entsprechend modifizierter Merkle-Patricia-Baum

Im Yellow Paper (Abschnitt 4.1, storageRoot) wird darauf hingewiesen

storageRoot: Ein 256-Bit-Hash des Stammknotens eines Merkle-Patricia-Baums, der die Speicherinhalte des Kontos codiert (eine Zuordnung zwischen 256-Bit-Ganzzahlwerten), die in den Trie als Zuordnung aus dem 256-Bit-Hash von Keccak codiert ist die 256-Bit-Ganzzahlschlüssel zu den RLP-codierten 256-Bit-Ganzzahlwerten. Der Hash wird formal mit σ[a]_s bezeichnet.

Was ich aus dem Obigen verstehen kann, ist, dass für alle Schlüsselwertpaare der Speicherzuordnung (k , v) (Kecak (k), RLP (v)) im modifizierten Merkle-Trie des Speichers verwendet wird, wobei Keccak (k) fungiert als Schlüssel für den Wert RLP(v)

Meine Fragen sind:

1.Was sind das (k,v) im Speicherinhalt des Kontos, dh Schlüssel und Werte?

Eine Erklärung mit einem Beispiel wäre wirklich hilfreich.

2.Warum wird Keccak(k) als Schlüssel des Merkle-Patricia-Baums verwendet, anstatt direkt das k zu verwenden?

Danke im Voraus.

Antworten (1)

Was sind das im Speicherinhalt des Kontos (k,v), dh Schlüssel und Werte?

Der Vertragscode kann diese nach Belieben verwenden. Beispielsweise nimmt der Compiler in diesem Solidity-Code den Index 0 für var1und den Index 1 für var2:

pragma solidity 0.4.20;

contract Test {

  uint public var1;
  address public var2;

  function test() public {
    var1 = 5;
    var2 = address(6);
  }
}

Also die (k,v)-Paare nach dem Aufruf test():

(0,5)
(1,6)

Weitere Details finden Sie in diesem Artikel: https://medium.com/@hayeah/diving-into-the-ethereum-vm-part-2-storage-layout-bc5349cb11b7

2.Warum wird Keccak(k) als Schlüssel des Merkle-Patricia-Baums verwendet, anstatt direkt das k zu verwenden?

Es wird im Design Rationale -Dokument im Wiki von Ethereum erklärt:

Verwendung von sha3(k) als Schlüssel im "sicheren Baum" (verwendet in den Zustands- und Kontospeicherversuchen): Dies macht es viel schwieriger, den Versuch zu tun, indem maximal ungünstige Ketten von divergierenden Knoten 64 Ebenen tief eingerichtet und wiederholt aufgerufen werden SLOAD und SSTORE darauf. Beachten Sie, dass dies das Aufzählen des Baums erschwert; Wenn Sie in Ihrem Client eine Aufzählungsfunktion haben möchten, besteht der einfachste Ansatz darin, eine Datenbankzuordnung sha3 (k) -> k zu verwalten.


Vorherige Antwort

Ich bin mir nicht sicher, aber ich vermute, dass die Verwendung von Hashes zu einem ausgewogeneren Trie führt. Wenn Sie sich einen Patricia-Trie vorstellen, bei dem Einträge nacheinander vom Index hinzugefügt werden, ist eine Seite des Tries oft schwerer als die andere. Bei der Verwendung von Hashes hingegen werden neue Elemente an einer zufälligen Position hinzugefügt. Einfügungen/Löschungen/Suchvorgänge sorgen für eine konsistentere Leistung in einem ausgewogenen Trie.

Es ist auch möglich, dass die Verwendung von Hashes zu einem kleineren Trie führt, da vermutlich mehr Blatt- und Erweiterungsknoten vorhanden sind, während es bei einem indexbasierten Trie mehr Zweigknoten gibt.

Um zu demonstrieren, wie die Verwendung zusammenhängender Indizes als Schlüssel zu einem unausgeglichenen Trie führt, stellen wir uns eine Situation vor, in der es auf einer Ebene des Tries einen Zweigknoten gibt, bei dem nur das erste und das zweite Nibble auf einige andere Knoten zeigen:

<hash0> branch [<hash1>, <hash2>, NULL,..<13 NULLs>, value]

Wenn sich dieser Zweig auf Ebene n des Tries befindet (es können 64 Ebenen vorhanden sein, da Schlüssel 32 Bytes groß sind, Wurzel auf Ebene 0 liegt), werden 2 ^ ((64 - n) * 4 - 8)Einfügungen in den Trie vorgenommen, bis das 3. Halbbyte nicht NULL wird.

Wenn sich dieser Zweig beispielsweise an der Wurzel befindet, müssen Sie 2 ^ 248Schlüssel einfügen, bevor das 3. Halbbyte nicht NULL wird, was einfach unmöglich ist (es ist jedoch unmöglich, dass sich eine solche Verzweigung überhaupt auf der Wurzelebene befindet, da sie 2 ^ 247Schlüssel benötigt um diesen Zustand zu erreichen, aber es ist für höhere Ebenen des Versuchs möglich). Im Allgemeinen ist es viel wahrscheinlicher, dass Nibbles auf der linken Seite nicht NULL sind als Nibbles auf der rechten Seite, was bedeutet, dass der Trie auf der linken Seite schwerer ist.

Danke für die Antwort. Gibt es für den ersten Teil irgendwelche Quellen, wo ich genauer nachlesen kann? Für den zweiten Teil werden die Verzweigungsknoten sicher größer sein, aber was ich bekomme, ist, wenn wir zusammenhängende Indizes zum Speichern des Werts verwenden, erhalten wir einen ausgewogeneren Versuch, wenn wir die k-Werte direkt als Schlüssel für verwenden der Merkle-Baum.
@sourav Ich habe die Antwort mit einem Link zum Speicherlayout in Solidity aktualisiert. Für den 2. Teil habe ich meine Gedanken im Update- Abschnitt unten hinzugefügt. Ich bin mir nicht sicher, ob meine Logik richtig ist, aber Sie können darauf hinweisen, wenn Sie Fehler darin finden.
@sourav hat die Antwort gefunden, warum gehashte Schlüssel verwendet werden github.com/ethereum/wiki/wiki/Design-Rationale . Es dient dem DoS-Schutz. Meine Antwort aktualisiert.