如何解碼交易收據中日誌下的數據參數?
我經歷了很多問題,但我無法得到答案。
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 }
希望能幫助到你。