Deserialize ContractEvent

Hi,
I am trying to work with and understand ContractEvents, but im struggling with the deserialization.

My preference would be to get the subquery to work, i succesfully got the contractEvent hash in the handleTransactionEvent handler from this example:

The event looks like this:
fe040000011101000b9090a0967f57684d0b812c9532c4428d56df1ff7ea0aaf33fbb08fc7de554b

My question is how I can deserialize this in the handler so I can work with the object? I have the schema.bin but I dont know how to proceed.

Trying to understand the process i want back a step to this example from the concordium-rust-sdk

I got the transction details out successfully again which looks like:

AccountTransaction(AccountTransactionDetails { cost: Amount { micro_ccd: 14928115 }, sender: AccountAddress([11, 144, 144, 160, 150, 127, 87, 104, 77, 11, 129, 44, 149, 50, 196, 66, 141, 86, 223, 31, 247, 234, 10, 175, 51, 251, 176, 143, 199, 222, 85, 75]), effects: ContractUpdateIssued { effects: [Updated { data: InstanceUpdatedEvent { contract_version: V1, address: ContractAddress { index: 7418, subindex: 0 }, instigator: Account(AccountAddress([11, 144, 144, 160, 150, 127, 87, 104, 77, 11, 129, 44, 149, 50, 196, 66, 141, 86, 223, 31, 247, 234, 10, 175, 51, 251, 176, 143, 199, 222, 85, 75])), amount: Amount { micro_ccd: 0 }, message: OwnedParameter([1, 0, 11, 144, 144, 160, 150, 127, 87, 104, 77, 11, 129, 44, 149, 50, 196, 66, 141, 86, 223, 31, 247, 234, 10, 175, 51, 251, 176, 143, 199, 222, 85, 75, 1, 4, 0, 0, 1, 17, 1, 25, 0, 0, 0, 104, 116, 116, 112, 115, 58, 47, 47, 105, 112, 102, 115, 46, 105, 111, 47, 105, 112, 102, 115, 47, 81, 109, 90, 50]), receive_name: OwnedReceiveName("ciphers_nft.mint"), events: [ContractEvent { bytes: [254, 4, 0, 0, 1, 17, 1, 0, 11, 144, 144, 160, 150, 127, 87, 104, 77, 11, 129, 44, 149, 50, 196, 66, 141, 86, 223, 31, 247, 234, 10, 175, 51, 251, 176, 143, 199, 222, 85, 75] }, ContractEvent { bytes: [0, 4, 0, 0, 1, 17, 1, 0, 0, 0, 108, 17, 135, 63, 140, 1, 0, 0, 25, 0, 104, 116, 116, 112, 115, 58, 47, 47, 105, 112, 102, 115, 46, 105, 111, 47, 105, 112, 102, 115, 47, 81, 109, 90, 50, 0] }] } }] } })

But im struggling again to get the ContractEvent out and deserialize it into a struct/object. Could someone point me in the right direction?

Many thanks!

Hi.

Since you mention subquery, do you want to use the WebSDK? Or do you want to use Rust?

(The answer depends on which you want to use)

Hello thanks for the quick response,

I prefer to get the subquery to work if thats possible. So to deserialize the event in the “handleTransactionEvent” handler. It uses the “@concordium/node-sdk”.

I just went back to the rust example to try and understand the process, but thats not neccesary if I can get the subquery to work.

I have asked the subquery discord and they gave me this answer:

You can use fromBuffer/fromHexString from ContractEvent | Concordium JS-SDK. If you have a schema you can use the parseMethods

But I cant get those methods in the handler so I dont see that working.

Hi there.

If you have the contract event as hex format and the schema for the event type, you should have the following options:

With @concordium/web-sdk version >7 (recommended)

import { ContractEvent } from '@concordium/web-sdk' // version 7 or higher

const EVENT_SCHEMA: string = ... // base64 representation of the schema for your contract event

const contractEventHex: string = ... // your contract event as hex
const contractEvent = ContractEvent.fromHexString(contractEventHex)
const parsedContractEvent = ContractEvent.parseWithSchemaTypeBase64(contractEvent)

With @concordium/node-sdk (the one used in the example linked)

import { deserializeTypeValue } from '@concordium/node-sdk'

const EVENT_SCHEMA: string = ... // base64 representation of the schema for your contract event

const contractEventHex: string = ... // your contract event as hex
const parsedContractEvent = deserializeTypeValue(Buffer.from(contractEventHex, 'hex'), Buffer.from(EVENT_SCHEMA, 'base64')

Both of these, however, require that you pass just the event portion of the contract schema. If you have access to the contract sourcecode, you can get this by building the module with the --schema-json-out argument:

cargo concordium build --schema-json-out ./out-dir

Hope this helps

2 Likes

Thank you very much soeren, got it to work :grin: .

1 Like

@soerenbz Ive got one more question about the deserialization in the rust-sdk if you dont mind. I am using this example.

I got the event which looks like:

[ContractEvent { bytes: [0, 4, 0, 0, 1, 17, 1, 0, 0, 0, 108, 17, 135, 63, 140, 1, 0, 0, 25, 0, 104, 116, 116, 112, 115, 58, 47, 47, 105, 112, 102, 115, 46, 105, 111, 47, 105, 112, 102, 115, 47, 81, 109, 90, 50, 0] }]

Now how can i deserialize this into my event struct which is:

pub struct MintEvent {
  pub token_id: TokenId,
  pub amount: TokenAmount,
  pub owner: AccountAddress,
}

Ive tried many things but cant get the correct values out.

Thanks!

You should use ContractEvent in concordium_rust_sdk::types::smart_contracts - Rust

So

event.parse::<MintEvent>()

Just make sure that your MintEvent implements concordium_std::Deserial.

1 Like