Skip to main content

Custom Types

Custom types are struct, union, and enum types defined by contracts. They are usable everywhere primitives types can be used: as contract inputs, outputs, or for storage.

info

The custom types example demonstrates how to define your own types.

info

Error enum types are another type contracts can define that have some unique behaviors. See [Errors] for more information. [Errors]: /docs/learn/smart-contract-internals/errors

Structs (with Named Fields)

Structs with named fields are stored on ledger as a map of key-value pairs, where the key is a 32 character string representing the field name, and the value is the value encoded.

Field names must be no more than 32 characters. Fields with names no longer than 9 characters are slightly more efficient at runtime, though the difference should be marginal most of the time.

#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct State {
pub count: u32,
pub last_incr: u32,
}

When converted to XDR, the value becomes an ScVal, containing an ScMap, containing an array of key-value pairs.

{
"map": [
{ "key": { "symbol": "count" }, "val": { "u32": 0 } },
{ "key": { "symbol": "last_incr" }, "val": { "u32": 0 } }
]
}

Structs (with Unnamed Fields)

Structs with unnamed fields are stored on ledger as a vector of values, and are interchangeable with tuples and vectors. The elements are placed in the vector in order that they appear in the field list.

#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct State(pub u32, pub u32);

When converted to XDR, the value becomes an ScVal, containing an ScVec, containing an array of values.

{ "vec": [{ "u32": 0 }, { "u32": 0 }] }

Enum (Unit and Tuple Variants)

Enums containing unit and tuple variants are are stored on ledger as a two element vector, where the first element is the name of the enum variant as a string up to 32 characters in length, and the value is the value if the variant has one.

Only unit variants and tuple variants, like A and B below, are supported.

#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Enum {
A,
B(u32),
}

When a unit variant, such as Enum::A, is converted to XDR, the value becomes an ScVal, containing an ScVec, containing an array with a single value, the symbol containing the variant name.

{ "vec": [{ "symbol": "A" }] }

When a tuple variant, such as Enum::B, is converted to XDR, the value becomes an ScVal, containing an ScVec, containing an array with two values, the symbol containing the variant name and the tuple value.

{ "vec": [{ "symbol": "B" }, { "u32": 0 }] }

When tuple variants containing multiple values are implemented, the values will be included into the vector.

Enum (Integer Variants)

Enums containing integer values are stored on ledger as the u32 value.

#[contracttype]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u32)]
pub enum Enum {
A = 1,
B = 2,
}

When converted to XDR, the value becomes an ScVal, containing a U32.

{ "u32": 1 }