1

I need to get a list of all events of a specific custom type. In the documentation, it said that I can query the System pallet's storage for events. I am looking for an example (in Rust) of how to get a list of specific events. I am planning to do this in an OCW and I need this for the current block but also need it for all blocks.

Listening to events The Substrate RPC does not directly expose an endpoint for querying events. If you used the default implementation, you can see the list of events for the current block by querying the storage of the System pallet. Otherwise, the Polkadot-JS API supports a WebSocket subscription on runtime events.

I tried this:

    let evts = <frame_system::Pallet<T>>::read_events_no_consensus();
    for evt in evts {
        frame_support::log::info!("evt={:?}", evt.event);
    }

which works BUT it prints:

evt=<wasm:stripped>
evt=<wasm:stripped>
evt=<wasm:stripped>
evt=<wasm:stripped>
evt=<wasm:stripped>
evt=<wasm:stripped>

How can I dump the fields of each event so I can understand what events occurred?

For efficiency, how can I get just the events for the current block?

3
  • Are you querying an RPC node or how do you need to access the events? Sep 30, 2022 at 16:43
  • I am querying from an off-chain worker running on the node. ie. no rpc Sep 30, 2022 at 17:02
  • The reason why it displays <wasm:stripped> is because of the node was started using --execution=wasm. If I change it to --execution=Native, it works! Oct 6, 2022 at 19:18

2 Answers 2

4

You can do frame_system::Pallet::<T>::events() to fetch all the events emitted. Example

If you are working with mock runtime then you can directly use System::events() (System being the instantiation of pallet_frame_system that you generated using the construct_runtime!() macro). You can then iterate over all the events and match with the ones that you are concerned about.

In the below example, I'm trying to extract the address of the smart contract I deployed by matching with the Instantiated event from the pallet-contracts.

    let evts = System::events();
    let deployed_address = evts
        .iter()
        .rev()
        .find_map(|rec| {
            if let Event::Contracts(pallet_contracts::Event::Instantiated {
                deployer: _,
                contract,
            }) = &rec.event
            {
                Some(contract)
            } else {
                None
            }
        })
        .expect("unable to find deployed contract");

Hope this answers your question :)

3
  • How do I access System from an offchain worker function inside a pallet? I tried <frame_system::Pallet<T>>::events() but I get error[E0599]: no function or associated item named events found for struct frame_system::Pallet in the current scope. Sep 30, 2022 at 17:21
  • This is for an off-chain worker and not the mock runtime. Sep 30, 2022 at 19:14
  • 1
    The answer is to use: <frame_system::Pallet<T>>::read_events_no_consensus(); Oct 3, 2022 at 12:44
0

You can use the Libuptest crate for Rust to extract the block events from a block. For example: If you know the blocknr or blockhash you can use libuptest to extract all extrinsics from a block in a Vec, code example: https://uptest-sc.github.io/cli/event_sub.html#code-example

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.