3

I want to parse event logs that are generated by the contract shown below, which assigns different sections of calldataload to the 4 Topics, and the Data section, of the event logs.

Topic 0 receives the FUNCTIONHASHES that are shown in Solidity, but I am not clear how the other 3 Topics, and the Data section, are assigned.

For example, the following function uses the note modifier, which emits the event log. Where in the event log will the values of 'what' and 'data' be placed, and what is placed in the Data section of the event log?

function file(bytes32 what, uint256 data) external note {
    require(live == 1, "Pot/not-live");
    require(now == rho, "Pot/rho-not-updated");
    if (what == "dsr") dsr = data;
    else revert("Pot/file-unrecognized-param");
}

This contract emits the event logs:

contract LibNote {
    event LogNote(
        bytes4   indexed  sig,
        address  indexed  usr,
        bytes32  indexed  arg1,
        bytes32  indexed  arg2,
        bytes             data
    ) anonymous;

    modifier note {
    _;
    assembly {
        // log an 'anonymous' event with a constant 6 words of calldata
        // and four indexed topics: selector, caller, arg1 and arg2
        let mark := msize                         // end of memory ensures zero
        mstore(0x40, add(mark, 288))              // update free memory pointer
        mstore(mark, 0x20)                        // bytes type data offset
        mstore(add(mark, 0x20), 224)              // bytes size (padded)
        calldatacopy(add(mark, 0x40), 0, 224)     // bytes payload
        log4(mark, 288,                           // calldata
             shl(224, shr(224, calldataload(0))), // msg.sig
             caller,                              // msg.sender
             calldataload(4),                     // arg1
             calldataload(36)                     // arg2
            )
       }
      }
    }

1 Answer 1

3

Using remix.ethereum.org, here is an example that can help.

enter image description here

The input, which is the same as calldata, is 0x29ae811475944220b52381f169021a7c3f2947dfd0d2b1fb95e6cd92358e0a7997c8a9a1000000000000000000000000000000000000000000000000000000000000000f. (This is calling file( 0x75944220b52381f169021a7c3f2947dfd0d2b1fb95e6cd92358e0a7997c8a9a1, 15))

calldataload is the EVM opcode for getting 32 bytes from calldata.

The parameter to calldataload is an offset: typically the first 4 bytes of calldata is a function selector, so calldataload(4) is used to get the 32 bytes starting from the fifth byte (in this example, 0x75944...).

calldata(36) then gets the next 32 bytes, which is 15 in hex, padding the uint to 32 bytes, that's how it becomes 0x000...f.

See What is calldata? and How calldata is stored in memory? for other examples of calldata.

The logs are:

[
    {
        "from": "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a",
        "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e029ae811475944220b52381f169021a7c3f2947dfd0d2b1fb95e6cd92358e0a7997c8a9a1000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "topics": [
            "0x29ae811400000000000000000000000000000000000000000000000000000000",
            "0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c",
            "0x75944220b52381f169021a7c3f2947dfd0d2b1fb95e6cd92358e0a7997c8a9a1",
            "0x000000000000000000000000000000000000000000000000000000000000000f"
        ]
    }
]

The last two topics are the what and data arguments of file.

2
  • Thank you for the explanation. Two additional questions: 1. Is Topic 1 the Ethereum Address of the person who called the function? 2. What is placed in the Data section of the event log?
    – Tester
    Nov 14, 2019 at 13:41
  • 1. Yes (topics[1] ca35b... is msg.sender). 2. With the code it looks like 0x20 and 244 (which is 0xe0) is logged as the first bytes of the log data, then the calldata, and a whole bunch of zeroes: you should try to contact whoever wrote the contract for why and further explanations.
    – eth
    Nov 16, 2019 at 12:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.