Wie erhalte ich die Speicherindizes/Schlüssel?

Ich möchte die Speicherdaten eines Vertrages erkunden. Ich habe Geth vollständig synchronisiert und interagiere damit über RPC. Es gibt die Funktion "eth.getStorageAt(addr, index, block)", aber Sie müssen ihr einen Index übergeben. Leider scheint dieser Index keine inkrementierende Ganzzahl zu sein, wie ich dachte. Ich habe als Beispiel versucht, auf den Speicher des DAO zuzugreifen, und Sie können den Speicher hier anzeigen: https://live.ether.camp/account/0xbb9bc244d798123fde783fcc1c72d3bb8c189413 (Stellen Sie sicher, dass Sie den „Smart-Modus“ ausschalten). Wie Sie sehen können, sind die ersten paar Indizes des Speichers die Zahlen 0-22, wobei einige dazwischen fehlen, aber dann werden sie zu Hashes. Wenn Sie nun einen Knoten ausführen, müssen Sie in der Lage sein, über den gesamten Speicher zu iterieren, und daher müssen Sie in der Lage sein, diese Indizes zu berechnen.

tl;dr: Ich möchte über die gesamte Speicherung eines Vertrags iterieren, wie würde ich das machen?

Antworten (1)

Sie müssen den Schlüssel kennen, und dann basieren die Speicherindizes auf keccak256dem Schlüssel. Es gibt weitere Details je nach Mapping und Array-Typen mit dynamischer Größe und siehe:

https://solidity.readthedocs.io/en/v0.6.8/internals/layout_in_storage.html

Variablen mit statischer Größe (alles außer Mapping und Array-Typen mit dynamischer Größe) werden fortlaufend im Speicher angeordnet, beginnend bei Position 0.

...

Aufgrund ihrer unvorhersehbaren Größe verwenden Mapping und Array-Typen mit dynamischer Größe eine keccak256-Berechnung, um die Startposition des Werts oder der Array-Daten zu finden. Diese Startpositionen sind immer volle Stack-Slots.

Dieselbe Solidity-Dokumentation enthält weitere Details und das folgende Beispiel:

contract C {
  struct s { uint a; uint b; }
  uint x;
  mapping(uint => mapping(uint => s)) data;
}

Die Position von data[4][9].bist beikeccak256(uint256(9) . keccak256(uint256(4) . uint256(1))) + 1


Vertragsdaten sind grundsätzlich über die dort bereitgestellten Funktionen abzurufen; Es wird nie so einfach sein, an Interna zu stochern. Es gibt auch keine Konvention, dass Speicherindizes auf die gleiche Weise berechnet werden müssen wie Solidity.

Die oben verlinkte Dokumentation benötigt wirklich einige funktionierende Javascript/Web3-Beispiele. Es lässt wichtige Implementierungsdetails aus, die nur erraten werden können, was ich erfolglos versucht habe. Wäre toll, wenn jemand funktionierende Beispiele für diese Frage geben könnte. Speziell für dynamische Arrays und Mappings.
1. Es gibt ein Beispiel im verlinkten Dokument . 2. Vertragsdaten sollten generell über die bereitgestellten Funktionen aufgerufen werden; Das Herumstöbern in Interna wird nie so einfach sein. 3. Auf Github oben rechts gibt es Bearbeiten, damit jeder weitere Beispiele hinzufügen kann. 4. Es gibt keine wirkliche Konvention, dass Indizes auf die gleiche Weise berechnet werden müssen wie Solidity
Danke, wenn jemand ein funktionierendes Beispiel zur Verfügung stellt, werde ich gerne eine PR an die Doco auf Github senden.