Ich ging viele Fragen durch, aber ich konnte keine Antwort bekommen.
web3-Version --0.20.6
Gemäß der Dokumentation werden Ereignisparameter, die nicht indiziert sind, in Datenparametern unter Protokollen gespeichert. Ich möchte über Blöcke iterieren und Daten von Ereignissen speichern. Wie kann ich den data
Parameter entschlüsseln?
Ich bin diesen Link https://codeburst.io/deep-dive-into-ethereum-logs-a8d2047c7371 durchgegangen, konnte aber nicht verstehen, wie er diese Daten entschlüsselt hat.
event Record(string location, uint256 temperature);
function recordData(string location, uint256 temperature) public {
emit Record(location, temperature);
}
Eingabe erfolgt:London, 25
Daten:
"0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000064c6f6e646f6e0000000000000000000000000000000000000000000000000000"
Thema:0xaa39dce7cd051e04c98757533bc6e3eb213cccafa31717ca09ef4dde19f123f5
Ich habe dieselbe Parametertransaktion in Remix ausgeführt und Protokolle haben keine Datenparameter. In Empfang gibt es Eingabeparameter. Der Eingabeparameter muss der Parameter sein, den ich übergeben habe, habe ich Recht?
Eingang:
"0xbc820aa40000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000064c6f6e646f6e0000000000000000000000000000000000000000000000000000"
Danke für die Hilfe im Voraus!
Wenn Sie mit Rohdaten umgehen möchten, würde ich vorschlagen, eine Bibliothek wie ethereumjs-abi zu verwenden . Die zum Kodieren/Dekodieren verwendeten Regeln befinden sich in solidity abi .
In Ihrem Fall sehen Ihre Daten in Blöcke von 20 Bytes/40 Hex aufgeteilt aus
0000000000000000000000000000000000000000000000000000000000000040
000000000000000000000000000000000000000000000000000000000000001d
0000000000000000000000000000000000000000000000000000000000000006
4c6f6e646f6e0000000000000000000000000000000000000000000000000000
Der erste Parameter location
ist ein String, da Strings eine variable Länge haben, speichern sie anstelle des Wertes einen Offset. Ebenso 0x00..040 = 64
der Offset zum location
Parameter.
Der zweite Parameter temperature
ist uint256 und passt in 32 Bytes, sodass sein Wert direkt gespeichert wird. Wert ist dann 0x00..001d = 29
.
Das Ereignis hat keine weiteren Parameter und der Rest der Daten wird von den Parametern verwendet, location
die nicht direkt eingeschlossen wurden.
Der Parameter location
ist am Offset 0x40 = 64
und wir haben diese Daten
0000000000000000000000000000000000000000000000000000000000000006
4c6f6e646f6e0000000000000000000000000000000000000000000000000000
Strings sind Arrays von Bytes, der erste Slot ist die Länge in diesem Fall 0x00..06 = 6
ist die Länge unseres Strings. Der Rest sind die Daten unseres Strings, die ersten sechs Bytes sind 4c6f6e646f6e
. Verwenden web3.toAscii("4c6f6e646f6e") == 'London'
.
In Remix sehen Sie das Ereignisprotokoll wie hier beschrieben getrennt:
Ereignisaufzeichnung (String-Position, uint256-Temperatur);
Sie sehen die Werte nach Index (0,1) und nach Name (Standort, Temperatur). Länge ist selbsterklärend.
Sie befinden sich in einem "Deep Dive" und erhalten ziemlich "nahe am Metall" Rohdaten. Eine Abstraktion auf höherer Ebene kann Sie einer Ansicht der Informationen auf Anwendungsebene näher bringen. Sie können so etwas wie Truffle mit seinem „Truffle-Contract“-Wrapper verwenden.
In diesem Fall hat der Software-Client (JavaScript) ein eingebautes Bewusstsein dafür, wie die Daten abgegrenzt sind, und entpackt sie für Sie.
Es wäre so etwas wie:
var reportLog;
reportLog = myContractInstance.Report({}); // possibility of filters
reportLog.watch(function(err,res) {
// you get here when an event is received
console.log(res.args); // res.args.location, res.args.temperature
}
Ich hoffe es hilft.
Shubham Tschadokar
Ismael
values = eth_abi.decode_abi(types, log['data'])
, die die Daten aus den Argumenttypen dekodiert.