Web3js

如何解碼交易收據中日誌下的數據參數?

  • February 21, 2022

我經歷了很多問題,但我無法得到答案。

web3版本——0.20.6

根據未索引的文件事件參數,儲存在日誌下的數據參數中。我想遍歷塊並儲存來自事件的數據。如何解碼data參數?

我瀏覽了這個連結 https://codeburst.io/deep-dive-into-ethereum-logs-a8d2047c7371 但無法理解他是如何解碼這些數據的。

event Record(string location, uint256 temperature);

function recordData(string location, uint256 temperature) public {
   emit Record(location, temperature);
}

給出輸入:London, 25

數據:

“0x00000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000001d0000000000000000000000000000000000000000000000000000000000000064c6f6e646f6e000000000000000000000000000000000000000000000000”

話題: 0xaa39dce7cd051e04c98757533bc6e3eb213cccafa31717ca09ef4dde19f123f5

日誌下的數據參數

我在 remix 中執行了相同的參數事務,並且日誌沒有任何數據參數。收據中有輸入參數。輸入參數必須是我傳遞的參數,對嗎?

輸入:

“0xbc820aa40000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000000064c6f6e646f6e000000000000000000000000000000000000000000000000”

在此處輸入圖像描述

我在這裡先向您的幫助表示感謝!

如果你想處理原始數據,我建議使用像ethereumjs-abi這樣的庫。用於編碼/解碼的規則在solidity abi中。

在您的情況下,您的數據分成 20 字節/40 十六進制的塊看起來像

0000000000000000000000000000000000000000000000000000000000000040
000000000000000000000000000000000000000000000000000000000000001d
0000000000000000000000000000000000000000000000000000000000000006
4c6f6e646f6e0000000000000000000000000000000000000000000000000000

第一個參數location是一個字元串,因為字元串是可變長度的,它們儲存的是偏移量而不是值。0x00..040 = 64參數的偏移量也是如此location

第二個參數temperature是 uint256,它適合 32 個字節,所以它的值直接儲存。值是0x00..001d = 29

該事件沒有更多參數,其餘數據由location未直接包含的參數使用。

參數location在偏移量0x40 = 64,我們有這個數據

0000000000000000000000000000000000000000000000000000000000000006
4c6f6e646f6e0000000000000000000000000000000000000000000000000000

字元串是字節數組,第一個槽是長度,在這種情況下0x00..06 = 6是我們字元串的長度。剩下的是我們字元串的數據,前六個字節是4c6f6e646f6e. 使用web3.toAscii("4c6f6e646f6e") == 'London'.

在 Remix 中,您會看到按此處所述分隔的事件日誌:

事件記錄(字元串位置,uint256溫度);

您會看到索引 (0,1) 和名稱(位置、溫度)提供的值。長度是不言自明的。

您處於“深度潛水”中,並且您獲得的原始數據非常“接近金屬”。更高級別的抽象可以讓您更接近資訊的應用程序級別視圖。你可以使用 Truffle 之類的東西和它的“truffle-contract”包裝器。

在這種情況下,軟體客戶端 (JavaScript) 將對數據的分隔方式具有內置意識,並會為您解包。

它會是這樣的:

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
}

希望能幫助到你。

引用自:https://ethereum.stackexchange.com/questions/58854