Binary Encoding

Binary Encoding

The XE network uses a deterministic binary encoding format for blocks and votes. This encoding is critical for hashing, signing, and network serialization -- all implementations must produce byte-identical output for the same logical data.

[!IMPORTANT] Version 2 is current The encoding format described here is version 2 (0x02). Older formats are not supported.

Block canonical encoding

The canonical encoding is used for computing block hashes and signatures. It excludes the PoW nonce -- only the content that the account holder signs is included.

Field layout

Offset  Size  Field
──────  ────  ─────
0       1     Version byte (0x02)
1       1     Type byte
2       8     Asset (left-aligned UTF-8, zero-padded to 8 bytes)
10      32    Account (hex-decoded to raw 32 bytes)
42      32    Previous (hex-decoded; genesis blocks use 32 zero bytes)
74      8     Balance (big-endian uint64)
82      8     Timestamp (big-endian int64)
90+     var   Type-specific tail (see below)
last    32    Representative (appended after type tail; 32 zero bytes if empty)

Type bytes

Type

Byte

Description

Send

0x01

Transfer funds to another account

Receive

0x02

Accept a pending send

Claim

0x03

Faucet claim (100 XUSD)

Lease

0x04

Request a compute lease

LeaseAccept

0x05

Provider accepts a lease

LeaseSettle

0x06

Settle a completed lease

MultisigOpen

0x08

Open a multisig account

MultisigUpdate

0x09

Rotate a multisig keyset

Type-specific tails

Each block type appends additional fields after the common header:

Send

Offset

Size

Field

90

32

Destination (hex-decoded)

122

8

Amount (big-endian uint64)

Total canonical size: 162 bytes (130 + 32 representative)

Receive

Offset

Size

Field

90

32

Source hash (hex-decoded)

Total canonical size: 154 bytes (122 + 32 representative)

Claim

No additional fields.

Total canonical size: 122 bytes (90 + 32 representative)

Lease

Offset

Size

Field

90

32

Destination / provider (hex-decoded)

122

8

Amount (big-endian uint64)

130

8

vCPUs (big-endian uint64)

138

8

Memory MB (big-endian uint64)

146

8

Disk GB (big-endian uint64)

154

8

Duration seconds (big-endian uint64)

162

32

AccessPubKey (hex-decoded ed25519 public key; empty → 32 zero bytes)

Total canonical size: 226 bytes (90 base + 104 tail + 32 representative)

LeaseAccept

Offset

Size

Field

90

32

Source / lease hash (hex-decoded)

122

8

Amount (big-endian uint64)

Total canonical size: 162 bytes (130 + 32 representative)

LeaseSettle

Offset

Size

Field

90

32

Source / lease hash (hex-decoded)

122

8

Amount (big-endian uint64)

Total canonical size: 162 bytes (130 + 32 representative)

MultisigOpen / MultisigUpdate

Offset

Size

Field

90

4

Threshold (big-endian uint32)

94

4

Number of keys (big-endian uint32)

98

32×N

Keys (sorted, hex-decoded, 32 bytes each)

Total canonical size: 130 + 32N bytes (90 header + 8 + 32N keyset + 32 representative)

Keys are sorted lexicographically before encoding. This ensures the same keyset always produces the same canonical encoding and thus the same derived address.

Full block encoding

The full block encoding appends the PoW nonce after the canonical bytes:

[ canonical bytes ] [ 8 bytes PoW nonce (little-endian uint64) ]

This is the format used for storage and network transmission. The MarshalBlock function produces this format, and UnmarshalBlock parses it.

Field encoding rules

Field

Encoding

Hex strings (account, previous, hashes)

Decoded to raw bytes (32 bytes each)

Asset

Left-aligned UTF-8, zero-padded to exactly 8 bytes

Previous = "0" (genesis)

32 zero bytes

Balance, Amount

Big-endian uint64

Timestamp

Big-endian int64

PoW Nonce

Little-endian uint64

Representative (empty)

32 zero bytes

[!WARNING] Endianness The PoW nonce uses little-endian encoding while all other numeric fields use big-endian. This is intentional and must be preserved across implementations.

Vote encoding

Votes are serialized for signing and network transmission:

Offset  Size  Field
──────  ────  ─────
0       1     Version byte (0x01)
1       32    Representative public key (hex-decoded)
33      32    Block hash (hex-decoded)
65      32    Conflict account (hex-decoded)
97      32    Conflict previous (hex-decoded; "0" → 32 zero bytes)
129     8     Timestamp (big-endian int64)
137     2     Signature length (big-endian uint16)
139     N     Signature bytes

Fixed portion: 139 bytes + variable signature length.

Functions

The encoding package exposes the following functions:

Function

Description

MarshalBlockCanonical(block)

Encode a block for hashing/signing (no PoW nonce)

MarshalBlock(block)

Full encoding including PoW nonce trailer

UnmarshalBlock(data)

Decode a full block from bytes

EncodeVote(vote)

Serialize a vote for signing/transmission

DecodeVote(data)

Deserialize a vote from bytes

See also