Calldata Encoding#

Calldata is a format used within GenVM to exchange data between contracts and VMs. It is designed to be safe to load, dynamically typed and JSON-like, binary and compact, and supports blockchain specific types.

Types#

Calldata is one of:

  1. Arbitrary big integer

  2. Raw bytes

  3. UTF-8 string

  4. Array of Calldata

  5. Mapping from strings to Calldata

  6. Address (20 bytes)

Format#

ULEB128 Encoding#

“Unsigned little endian base 128” is a variable-length code compression used to store arbitrarily large integers.

Encoding: Split number into groups of 7 bits, little-endian, zero extend the biggest one. For each except the biggest one (rightmost), set 8th bit to one and concatenate.

Examples:

  • 0 ↔ 0x00

  • 1 ↔ 0x01

  • 128 ↔ 0x80 0x01

Calldata Encoding#

Each calldata value starts with a ULEB128 number, which is treated as follows:

least significant 3 bits

interpreted as type

number shifted by this 3 bits

followed by

0

atom

0 ⇒ null

1 ⇒ false

2 ⇒ true

3 ⇒ followed by address

_ ⇒ reserved for future use

nothing

nothing

nothing

20 bytes of address

reserved for future use

1

positive int or 0

value

nothing

2

negative int

abs(value) - 1

nothing

3

bytes

length

bytes[length]

4

string

length

bytes[length] of utf8 encoded string

5

array

length

calldata[length]

6

map

length

Pair(FastString, calldata)[length]

sorted by keys

7

reserved for future use

FastString is encoded as ULEB128 length followed by UTF-8 encoded bytes (difference is that it does not have a type).