How to decode transaction events and determine their types?

I use the UpdateToLatestLedger method of the admission control gRPC interface to retrieve new transactions and their events (via passing fetch_events parameter to the request).

Some examples of the events I receive in the response:

{
    key: "V\342\177\267V\247\3454\257\245Za\362\320\223_\335S\231,]\3725\271\000\304\302tl1\266\334"
    sequence_number: 8
    event_data: "\000\344\013T\002\000\000\000\375\304\004\3562o\201\253\376.\210x\010rl:\250V\320\030t\rP\251\274\2453H\324!\252\316"
}
{
    key: "\320\243~\316\372\261t\324$\330\346ze\333\010\n\214oaR\266\344^\313\215\335w\273\257\254\017\027"
    sequence_number: 4
    event_data: "\000\344\013T\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\nU\014\030"
}

The question is: how can I distinguish the type of the event (ReceivePaymentEvent and SendPaymentEvent) using this data?

1 Like

Unfortunately with our current design, you cannot distinguish the type of the event JUST by looking at this data. However, there are other ways you can get around this by the following steps:
By parsing the event_data, you will be able to get an address that’s either the sender or the receiver of this event. You can then query the StateDB to query for the account state blob that contains the AccountResource of this account. In that Resource, there’s a field called received_events/sent_events, and the key should match the key returned in your response.

That key is guaranteed to be immutable. Thus for each account, it will have two keys for events. Since these are immutable, you can use these keys to distinguish between the two types of event.

The reason for this is a bit complicated and we will make a full document about the Event system in Move. But the TL;DR is we want to design the event system to be generic don’t want to make sent/receive anything special than an arbitrary event emitted by another module.

3 Likes

Thanks for the explanation!

I also found a more quick workaround for the current testnet state (without making an additional request). You can compare the sender_address of the transaction with the address part of the event_data (the last 32 bytes).

1 Like

@runtianz Currently, either sent or received events have the same structure:

pub struct AccountEvent {
    account: AccountAddress,
    amount: u64,
}

In my understanding, the structure of events are determined by the actual Move script. Can there be other structure of events once libra allows arbitrary smart contracts? If so, what do you expect a client to do to understand events?

1 Like

Great question! I think there’s still an ongoing debate about such feature but I would imagine that the Libra node is going to be able to interpret all the system level contract events(like SentEvents/ReceivedEvents), and we will support custom modules to emit their own events, but it would be the client’s job to understand how such data should be parsed.

2 Likes