Wie entschlüsselt man Datenparameter unter Protokollen im Transaktionsempfang?

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 dataParameter 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
Datenparameter unter Protokolle

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"

Geben Sie hier die Bildbeschreibung ein

Danke für die Hilfe im Voraus!

Antworten (2)

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 locationist ein String, da Strings eine variable Länge haben, speichern sie anstelle des Wertes einen Offset. Ebenso 0x00..040 = 64der Offset zum locationParameter.

Der zweite Parameter temperatureist 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, locationdie nicht direkt eingeschlossen wurden.

Der Parameter locationist am Offset 0x40 = 64und wir haben diese Daten

0000000000000000000000000000000000000000000000000000000000000006
4c6f6e646f6e0000000000000000000000000000000000000000000000000000

Strings sind Arrays von Bytes, der erste Slot ist die Länge in diesem Fall 0x00..06 = 6ist die Länge unseres Strings. Der Rest sind die Daten unseres Strings, die ersten sechs Bytes sind 4c6f6e646f6e. Verwenden web3.toAscii("4c6f6e646f6e") == 'London'.

Vielen Dank Ismael für die Erklärung. Jetzt verstand ich es besser. Können Sie bitte sagen, welche Methode in der Beschreibung dieses Links verwendet wird, um Daten zu dekodieren? codeburst.io/deep-dive-into-ethereum-logs-a8d2047c7371
Der Artikel enthält eine Zeile values = eth_abi.decode_abi(types, log['data']), die die Daten aus den Argumenttypen dekodiert.

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.

danke für die Antwort. Ich kannte die Watch-and-Get-Funktion, aber ich hatte gehofft, die Eingabe vom Parameter "data" zu erhalten. Ich habe den folgenden Filter ausprobiert, aber er gibt nur Daten vom letzten Block aus: reportLog = myContractInstance.Report({fromBlock:1, toBlock:'latest'});