Skip to content

Specification

View as Markdown

Use this page when you need the model behind ABI YAML before you start debugging layout behavior or designing advanced dynamic types.

Deterministic

ABI layouts are byte-for-byte reproducible so every backend sees the same structure.

Zero-Copy Friendly

The format is designed so generated code can access buffers directly instead of copying data out first.

Cross-Language

The same ABI definition can drive C, Rust, TypeScript, and reflection tooling.

RuleWhat to keep in mind
EndiannessMulti-byte values are little-endian.
Primitive typesThe core type system includes signed and unsigned integers, floating-point types, and char.
Struct layoutPacked structs have no padding. Aligned structs insert padding based on natural alignment.
ArraysArrays can be fixed-size or runtime-sized through field references.
Flexible Array MembersOnce the first runtime-sized field appears, offsets for later fields become runtime-dependent.
Enums and unionsVariant layout and discriminator rules must still yield deterministic validation behavior.
Dynamic parametersRuntime-sized fields, tags, and payload sizes are tracked explicitly so validators, reflection, and codegen can agree on the same layout math.

At a high level, an ABI file contains:

  • package metadata such as package name and version
  • optional imports
  • named type definitions

The type system supports:

  • primitive fields
  • structs
  • unions
  • enums
  • fixed-size arrays
  • variable-size arrays whose size is driven by earlier fields
  • references to imported or previously defined types

The ABI toolchain supports multiple import sources:

  • local path imports
  • git imports
  • HTTP imports
  • on-chain imports

That flexibility is useful, but it changes the safe publishing workflow:

  • local imports are fine while you are writing and testing
  • on-chain publishing requires those local imports to be inlined or otherwise normalized first

The important authoring rule is that remote files cannot depend on local filesystem paths. Use Authoring Guide for how to structure imports and Publishing and Iteration for the publish-safe workflow.

The hardest ABI cases are the ones with runtime-sized fields. Common examples:

  • a name_len field followed by a byte array of that size
  • nested field references such as box.first
  • arrays whose element counts depend on earlier fields
  • expressions over nested array elements such as state proof bitsets

Those layouts are valid, but they are also where mistakes tend to surface first. Prefer to validate them with:

  • Put the field that drives a variable-length array before the variable field itself.
  • Expect fully flattened or publish-ready artifacts to differ from your authoring-time source if you use local imports.
  • Treat analyze --print-ir as the fastest way to inspect what the toolchain thinks the layout really is.