Skip to content

Application Binary Interface (ABI)

Type Specifier

NamedTypeRef

::= 0x00 Index:0xnn => NamedTypes(Index)

SimpleTypeSpec

::=

0x01 => u8

| 0x02 => u16

| 0x03 => u32

| 0x04 => u64

| 0x05 => u128

| 0x18 => u256

| 0x06 => i8

| 0x07 => i16

| 0x08 => i32

| 0x09 => i64

| 0x0a => i128

| 0x0b => String

| 0x0c => Boolean

| 0x0d => Address

| 0x13 => Hash

| 0x14 => PublicKey

| 0x15 => Signature

| 0x16 => BlsPublicKey

| 0x17 => BlsSignature

CompositeTypeSpec

::=

0x0e T:TypeSpec => Vec<T>

| 0x0f K:TypeSpec V:TypeSpec => Map<V,K>

| 0x10 T:TypeSpec => Set<T>

| 0x11 L:0xnn => [u8;L]

(0x00 ≤ L ≤ 0x7F; Deprecated)

| 0x12 T:TypeSpec => Option<T>

| 0x19 K:TypeSpec V:TypeSpec => AvlTreeMap<V,K>

| 0x1A T:TypeSpec L:LEB128 => [T;L]

NOTE regarding Map and Set: These cannot be used as RPC arguments since it's not possible for a caller to check equality and sort order of the elements without running the code.

NOTE regarding [u8;L]: This representation is deprecated. Parsers should still be able to parse it, but generators should emit [T;L] representation instead. L must be between 0 and 127 (inclusive). The high bit in length is reserved for later extensions.

NOTE regarding [T;L]: L can be any u32 value.

ABI File binary format

All Identifier names must be valid Java identifiers; other strings are reserved for future extensions.

FileAbi

::= {

Header: 0xnn×6

(The header is always "PBCABI" in ASCII)

VersionBinder: 0xnn×3
VersionClient: 0xnn×3
Contract: ContractAbi

}

ContractAbi

::= {

NamedTypes: List<NamedTypeSpec>
Hooks: List<FnAbi>
StateType: TypeSpec

}

StructTypeSpec

::= {

Name: Identifier
Fields: List<FieldAbi>

}

EnumTypeSpec

::= {

Name: Identifier
Variants: List<EnumVariant>

}

EnumVariant

::= discriminant:0xnn def:NamedTypeRef

FnAbi

::= {

Kind: FnKind
Name: Identifier
Shortname: LEB128
Arguments: List<ArgumentAbi>

SecretArgument: ArgumentAbi

(Only present if Kind is 0x17)

}

FieldAbi

::= {

Name: Identifier
Type: TypeSpec

}

ArgumentAbi

::= {

Name: Identifier
Type: TypeSpec

}

Identifier

::= len:0xnn×4 utf8:0xnn×len

(utf8 must be Rust identifier, len is big-endian)

LEB128

::= A LEB128 encoded unsigned 32 bit integer

(1-5 bytes)

FnKind

::=

0x01 => Init

(Num allowed: 1)

| 0x02 => Action

(0..∞)

| 0x03 => Callback

(0..∞)

| 0x10 => ZkSecretInput

(0..∞)

| 0x11 => ZkVarInputted

(0..∞)

| 0x12 => ZkVarRejected

(0..1)

| 0x13 => ZkComputeComplete

(0..∞)

| 0x14 => ZkVarOpened

(0..1)

| 0x15 => ZkUserVarOpened

(0..1)

| 0x16 => ZkAttestationComplete

(0..1)

| 0x17 => ZkSecretInputWithExplicitType

(0..∞)

| 0x18 => ZkExternalEvent

(0..1)

Note that a ContractAbi is only valid if the Hooks list contains a specific number of hooks of each type, as specified in FnKind.

Also note that if a function has the deprecated kind ZkSecretInput, the default secret argument associated with it is of type i32.

NamedTypes and Hooks order

From version 5.7.0 the NamedTypes and Hooks list in ContractAbi must be ordered for the ABI to be valid.

The types in the ContractAbi can be viewed as one or more directed graphs. The roots for graph traversal are the StateType and each argument type for functions in the sorted Hooks list.

This implicitly means that if StateType is a NamedTypeRef it must have index 0.

For NamedTypes to be considered ordered the following must be true:

  1. For each of the roots, traverse the type graph depth-first starting from the left-most type.
  2. If the type has not been visited before add it to the NamedTypes list.

Hooks must be sorted by their FnKind identifier. If more than one function with the FnKind exists (e.g. Action), sort them by their shortname.

ABI Version changes

  • Version 5.6 to 5.7:
    • The list NamedTypes and Hooks in the ContractAbi must be ordered.
  • Version 5.5 to 5.6:
    • Added new type [T;L]: Fixed-sized arrays with any content type T.
    • Old representation of [u8;L] have been deprecated.
  • Version 5.4 to 5.5:
    • Smart contracts now support \(\text{(0..}\infty\text{)}\) of FnKind: 0x11.
    • Smart contracts now support \(\text{(0..}\infty\text{)}\) of FnKind: 0x13.
    • FnKind 0x11 now requires a Shortname.
    • FnKind 0x13 now requires a Shortname.
  • Version 5.3 to 5.4:
    • Added new FnKind: 0x18 called ZkExternalEvent.
  • Version 5.2 to 5.3:
    • Added new type AvlTreeMap: A map with content that is not serialized to the wasm state format, but instead allows for lazy access to its contents.
  • Version 5.1 to 5.2:
    • Added new FnKind: 0x17 called ZkSecretInputWithExplicitType.
    • Added SecretArgument field to FnAbi to support ZK inputs. Only present when FnKind is ZkSecretInputWithExplicitType.
    • FnKind: 0x10 is now deprecated.
  • Version 5.0 to 5.1:
    • Added additional abi types: U256, Hash, PublicKey, Signature, BlsPublicKey, BlsSignature.
  • Version 4.1 to 5.0:
    • Added support for enum with struct items.
    • Changed StructTypeSpec to NamedTypeSpec which is either an EnumTypeSpec or StructTypeSpec. This means that there is an additional byte when reading the list of NamedTypeSpec in ContractAbi.
  • Version 3.1 to 4.1:
    • Added Kind: FnKind field to FnAbi.
    • Removed Init field from ContractAbi.
    • Added zero-knowledge related FnKinds, for use in Zk contracts.
  • Version 2.0 to 3.1:
    • Shortnames are now encoded as LEB128; ShortnameLength field have been removed.
    • Added explicit, easily extensible return result format.

Partisia All Rights Reserved © 2023