[Ethereum] How to decode data parameter under logs in transaction receipt

dapp-developmentdappseventslogsweb3js

I went through many questions but I couldn't get my answer.

web3 version — 0.20.6

According to documentation event parameters that are not indexed, store in data parameters under logs. I want to iterate over blocks and store data from events.
How can I decode the data parameter?

I went through this link https://codeburst.io/deep-dive-into-ethereum-logs-a8d2047c7371 but was unable to understand how he decoded that data.

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

Input is given: London, 25

data:

"0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000064c6f6e646f6e0000000000000000000000000000000000000000000000000000"

topic:
0xaa39dce7cd051e04c98757533bc6e3eb213cccafa31717ca09ef4dde19f123f5
data parameter under logs

I ran the same parameter transaction in remix and logs don't have any data parameter. In receipt there is input parameter. The input parameter must be the parameter that I passed, am i correct?

input:

"0xbc820aa40000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001d00000000000000000000000000000000000000000000000000000000000000064c6f6e646f6e0000000000000000000000000000000000000000000000000000"

enter image description here

Thanks for the help in advance!

Best Answer

If you want to deal with raw data I'd suggest to use a library like ethereumjs-abi. The rules used to encode/decode are in the solidity abi.

In your case your data split into chunks of 20 bytes/40 hex look like

0000000000000000000000000000000000000000000000000000000000000040
000000000000000000000000000000000000000000000000000000000000001d
0000000000000000000000000000000000000000000000000000000000000006
4c6f6e646f6e0000000000000000000000000000000000000000000000000000

The first parameter location is a string, since strings are of variable length they store an offset instead of the value. So 0x00..040 = 64 is the offset to the location parameter.

The second parameter temperature is uint256, and it fits in 32 bytes so its value is stored directly. Value is then 0x00..001d = 29.

The event doesn't have more parameters and the rest of the data is used by the parameters like location that were not included directly.

The parameter location is at offset 0x40 = 64 and we have this data

0000000000000000000000000000000000000000000000000000000000000006
4c6f6e646f6e0000000000000000000000000000000000000000000000000000

Strings are array of bytes, the first slot is length in this case 0x00..06 = 6 are the length of our string. The rest are the data of our string, the first six bytes are 4c6f6e646f6e. Using web3.toAscii("4c6f6e646f6e") == 'London'.

Related Topic