rust-web3 icon indicating copy to clipboard operation
rust-web3 copied to clipboard

Getting Events from Transaction Receipts

Open creese opened this issue 4 years ago • 2 comments

I would like to use the events method to get an event from a transaction receipt. I can get the transaction receipt all right, but when I try to get event data, I see the familiar Abi error: Invalid data result. What is the right way to use this method? I couldn't find any tests or examples.

This is the ABI for the event I want:

{
  "name": "FooEvent",
  "type": "event",
  "inputs": [
    {
      "indexed": true,
      "internalType": "address",
      "name": "from",
      "type": "address"
    },
    {
      "indexed": true,
      "internalType": "address",
      "name": "to",
      "type": "address"
    },
    {
      "indexed": false,
      "internalType": "uint256",
      "name": "amount",
      "type": "uint256"
    }
  ],
  "anonymous": false
},

This is the transaction receipt. The event I care about is emitted by the contract at 0x9bc21c339fac72c963e749af847191f452871950:

Some(
    Receipt {
        transaction_hash: 0xb0b9cd4716691b6f52714a2b7e04154d60cbeffc3239836a660169312696988d,
        transaction_index: 0,
        block_hash: Some(
            0x2ee8c5507603ef7ce63f9398b7c87433bd407ca1d3e6150f4d05cb3eb5be2663,
        ),
        block_number: Some(
            45,
        ),
        cumulative_gas_used: 74275,
        gas_used: Some(
            74275,
        ),
        contract_address: None,
        logs: [
            Log {
                address: 0xc04c83c52fc7ee1a7a2aa131d4ccc2c2069872a9,
                topics: [
                    0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,
                    0x000000000000000000000000ba09de4b140597630c56aff1b3a01296ba28982d,
                    0x0000000000000000000000009bc21c339fac72c963e749af847191f452871950,
                ],
                data: Bytes(
                    [
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        69,
                        99,
                        145,
                        130,
                        68,
                        244,
                        0,
                        0,
                    ],
                ),
                block_hash: Some(
                    0x2ee8c5507603ef7ce63f9398b7c87433bd407ca1d3e6150f4d05cb3eb5be2663,
                ),
                block_number: Some(
                    45,
                ),
                transaction_hash: Some(
                    0xb0b9cd4716691b6f52714a2b7e04154d60cbeffc3239836a660169312696988d,
                ),
                transaction_index: Some(
                    0,
                ),
                log_index: Some(
                    0,
                ),
                transaction_log_index: None,
                log_type: None,
                removed: None,
            },
            Log {
                address: 0xc04c83c52fc7ee1a7a2aa131d4ccc2c2069872a9,
                topics: [
                    0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925,
                    0x000000000000000000000000ba09de4b140597630c56aff1b3a01296ba28982d,
                    0x0000000000000000000000009bc21c339fac72c963e749af847191f452871950,
                ],
                data: Bytes(
                    [
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                    ],
                ),
                block_hash: Some(
                    0x2ee8c5507603ef7ce63f9398b7c87433bd407ca1d3e6150f4d05cb3eb5be2663,
                ),
                block_number: Some(
                    45,
                ),
                transaction_hash: Some(
                    0xb0b9cd4716691b6f52714a2b7e04154d60cbeffc3239836a660169312696988d,
                ),
                transaction_index: Some(
                    0,
                ),
                log_index: Some(
                    1,
                ),
                transaction_log_index: None,
                log_type: None,
                removed: None,
            },
            Log {
                address: 0x9bc21c339fac72c963e749af847191f452871950,
                topics: [
                    0xf62badb063ea4b26543119fa0f194f8c19665e8c9d635362e24e7681d6cfb6af,
                    0x000000000000000000000000021c09fbf76579b49c2cd0980d8efe527145652f,
                    0x000000000000000000000000ba09de4b140597630c56aff1b3a01296ba28982d,
                ],
                data: Bytes(
                    [
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        69,
                        99,
                        145,
                        130,
                        68,
                        244,
                        0,
                        0,
                    ],
                ),
                block_hash: Some(
                    0x2ee8c5507603ef7ce63f9398b7c87433bd407ca1d3e6150f4d05cb3eb5be2663,
                ),
                block_number: Some(
                    45,
                ),
                transaction_hash: Some(
                    0xb0b9cd4716691b6f52714a2b7e04154d60cbeffc3239836a660169312696988d,
                ),
                transaction_index: Some(
                    0,
                ),
                log_index: Some(
                    2,
                ),
                transaction_log_index: None,
                log_type: None,
                removed: None,
            },
        ],
        status: Some(
            1,
        ),
        root: None,
        logs_bloom: 0x00000000000000000100000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000200200000000000000000000000008014000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000010000000200000000000000000000004000000100000000000000000000000000000000000120002000000000200000000000000000000000000020000000000000000000000000002000000000000000000000000000000020000000000000000000000210010000000000000000000000000080000000000000000000000000000100000,
    },
)

This is the code:

// -snip-
let txn = contract
    .call("foo", (args.amount,), from, Options::default())
    .await?;

let receipt = web3.eth().transaction_receipt(txn).await?;

let logs: Vec<Log> = receipt
    .unwrap()
    .logs
    .into_iter()
    .filter(|x| x.address == args.address)
    .collect::<Vec<_>>();

let log = logs.first().unwrap();

let events: Vec<(Address, Address, U256)> = contract
    .events("FooEvent", log.topics[0], log.topics[1], log.topics[2])
    .await?;
// -snip-

creese avatar Oct 17 '20 22:10 creese

I was able to get it working by borrowing from the implementation of web3::contract::Contract::events. I'm not sure why I wasn't able to use that method directly. Could there be a type mismatch that only shows at runtime?

Here my solution:

// -snip-
    let txn = contract
        .call("foo", (args.amount,), from, Options::default())
        .await?;

    let receipt = web3.eth().transaction_receipt(txn).await?;

    let logs = receipt
        .unwrap()
        .logs
        .into_iter()
        .filter(|x| x.address == args.address)
        .collect::<Vec<_>>();

    let event: (Address, Address, U256) = Detokenize::from_tokens(
        contract
            .abi()
            .event("FooEvent")
            .unwrap()
            .parse_log(ethabi::RawLog {
                topics: logs.first().unwrap().topics.clone(),
                data: logs.first().unwrap().data.0.clone(),
            })?
            .params
            .into_iter()
            .map(|x| x.value)
            .collect::<Vec<_>>(),
    )
    .unwrap();
// -snip-

creese avatar Oct 18 '20 03:10 creese

When will it be settled

YeautyYE avatar Feb 01 '22 13:02 YeautyYE