Custom Types

In certain cases, we create new types that require direct serialization and deserialization when interacting with contracts. For structs and enums, setting up serialization and deserialization is straightforward and requires minimal code.

Custom Structures

Any structure defined in a contract or library can become serializable by adding one or more of the following annotations: TopEncode, TopDecode, NestedEncode, NestedDecode.

Example implementation:

#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode)]
pub struct MyStruct {
    pub int: u16,
    pub seq: Vec<u8>,
    pub another_byte: u8,
    pub uint_32: u32,
    pub uint_64: u64,
}

Top-encoding: All fields are nested-encoded one after the other.

Nested encoding: Similar to top-encoding, where all fields are nested-encoded one after the other.

Example Value

MyStruct {
    int: 0x42,
    seq: vec![0x1, 0x2, 0x3, 0x4, 0x5],
    another_byte: 0x6,
    uint_32: 0x12345,
    uint_64: 0x123456789,
}

This value is encoded (both top-encoding and nested encoding) as: 0x004200000005010203040506000123450000000123456789.

Explanation:

[
/* int */ 0, 0x42,
/* seq length */ 0, 0, 0, 5,
/* seq contents */ 1, 2, 3, 4, 5,
/* another_byte */ 6,
/* uint_32 */ 0x00, 0x01, 0x23, 0x45,
/* uint_64 */ 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89
]

Custom Enums

Any enum defined in a contract or library can be made serializable by adding one or more of the following annotations: TopEncode, TopDecode, NestedEncode, NestedDecode.

A Simple Enum Example:

Example taken from the klever-sc-codec tests.

#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode)]
enum DayOfWeek {
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday,
}

A More Complex Enum Example:

#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode)]
enum EnumWithEverything {
    Default,
    Today(DayOfWeek),
    Write(Vec<u8>, u16),
    Struct {
        int: u16,
        seq: Vec<u8>,
        another_byte: u8,
        uint_32: u32,
        uint_64: u64,
    },
}

Nested Encoding:

  • First, the discriminant is encoded. The discriminant is the index of the variant, starting with 0.
  • Then the fields in that variant (if any) are nested-encoded one after the other.

Top-encoding:

It follows the same rules as nested-encoding, with an additional rule: if the discriminant is 0 (first variant) and there are no fields, nothing is encoded.

Was this page helpful?