Block Types¶
XE has eight block types. Every block shares a set of common fields; each type adds its own type-specific fields.
Common fields¶
All blocks carry these fields:
| Field | Type | Description |
|---|---|---|
Type |
string | Block type identifier: send, receive, claim, lease, lease_accept, lease_settle, multisig_open, multisig_update |
Account |
string | Hex-encoded ed25519 public key of the account that owns this block (64 hex chars) |
Previous |
string | Hash of the previous block on this account's chain; "0" for the first block |
Balance |
uint64 | Account balance for this asset after this block |
Timestamp |
int64 | Unix nanoseconds when the block was created |
Asset |
string | Asset identifier: "XE" or "XUSD" |
Representative |
string | Hex public key of this account's voting delegate (empty for no delegation) |
Hash |
string | SHA-256 hash of the canonical binary encoding (64 hex chars) |
Signature |
string | Ed25519 signature over the hash bytes (128 hex chars) |
PoWNonce |
uint64 | Anti-spam proof-of-work nonce (excluded from hash computation) |
Signatures |
array | Multisig signatures array (replaces Signature for multisig accounts) |
Keyset |
object | Multisig keyset for multisig_open and multisig_update blocks |
PoW nonce exclusion
The PoWNonce is computed after signing. It is excluded from Hash computation so the signature remains valid regardless of the nonce value. The PoW is validated separately by checking that blake2b(nonce || hashBytes) >= difficulty.
Send (send)¶
Debits the sender's balance and creates a pending send for the recipient.
Type-specific fields¶
| Field | Type | Description |
|---|---|---|
Destination |
string | Hex public key of the recipient account |
Amount |
uint64 | Number of tokens to send |
Validation rules¶
Amountmust be > 0.- Sender must have sufficient balance:
previousBalance - Amount = Balance. Destinationmust be a valid 32-byte hex-encoded public key.Assetmust be"XE"or"XUSD".
Side effects¶
On successful validation, a PendingSend record is created:
PendingSend{
SendHash: block.Hash,
Source: block.Account,
Destination: block.Destination,
Amount: block.Amount,
Asset: block.Asset,
}
This pending send persists until the recipient creates a matching receive block.
Binary encoding¶
Type byte: 0x01. Tail: destination(32) + amount(8). Total canonical size: 162 bytes (90 header + 40 tail + 32 representative).
Receive (receive)¶
Credits the recipient's balance from a pending send.
Type-specific fields¶
| Field | Type | Description |
|---|---|---|
Source |
string | Hash of the send block being received |
Validation rules¶
Sourcemust reference an existing pending send whereDestinationmatches this block'sAccount.Balancemust equalpreviousBalance + pendingSend.Amount.Assetmust match the pending send's asset.
Side effects¶
The pending send referenced by Source is deleted. The recipient's balance increases by the send amount.
Binary encoding¶
Type byte: 0x02. Tail: source(32). Total canonical size: 154 bytes (90 header + 32 tail + 32 representative).
Claim (claim)¶
Mints 100 XUSD via the testnet faucet.
Type-specific fields¶
None. Claim blocks have no type-specific fields.
Validation rules¶
Balancemust equalpreviousBalance + 100(FaucetClaimAmount).Assetmust be"XUSD"(XE claims are rejected).- Rate limited: one claim per account per 24 hours.
Side effects¶
The account's XUSD balance increases by 100.
Testnet faucet
The faucet is testnet-only and rate limited to one claim per account per 24 hours.
Binary encoding¶
Type byte: 0x03. No tail. Total canonical size: 122 bytes (90 header + 32 representative).
Lease (lease)¶
Debits XUSD from the consumer to request a compute lease. This is the consumer's side of a lease transaction.
Type-specific fields¶
| Field | Type | Description |
|---|---|---|
Destination |
string | Hex public key of the provider account |
Amount |
uint64 | Total XUSD cost of the lease |
VCPUs |
uint64 | Number of virtual CPUs requested |
MemoryMB |
uint64 | Memory in megabytes |
DiskGB |
uint64 | Disk in gigabytes |
Duration |
uint64 | Lease duration in seconds |
Validation rules¶
Assetmust be"XUSD".Amountmust match theLeaseCost()formula (see Cost Model).- Sender must have sufficient XUSD balance:
previousBalance - Amount = Balance. Durationmust be between 60 seconds and 31,536,000 seconds (365 days).VCPUs,MemoryMB, andDiskGBmust each be > 0.
Side effects¶
Creates a pending send (like a regular send) with the XUSD amount directed at the provider. The lease is not active until the provider creates a lease_accept block.
Binary encoding¶
Type byte: 0x04. Tail: destination(32) + amount(8) + vcpus(8) + memory_mb(8) + disk_gb(8) + duration(8) + access_pub_key(32). Total canonical size: 226 bytes (90 header + 104 tail + 32 representative).
Lease Accept (lease_accept)¶
The provider accepts a lease, staking XUSD as collateral. This activates the lease.
Type-specific fields¶
| Field | Type | Description |
|---|---|---|
Source |
string | Hash of the consumer's lease block |
Amount |
uint64 | XUSD stake amount (cost / 5) |
Validation rules¶
Assetmust be"XUSD".Sourcemust reference a valid, unaccepted lease block.Amountmust equalleaseCost / 5(the stake divisor is 5).- Provider must have sufficient XUSD balance:
previousBalance - Amount = Balance. - Requires timekeeper attestations if the state chain has
sys.timekeepersconfigured.
Side effects¶
A Lease record is created tracking the consumer, provider, resources, cost, stake, and start time. The provider's XUSD is locked as stake.
Attestations¶
Lease accept blocks carry Attestations -- signed timestamps from trusted timekeeper nodes. These are not included in the block hash (they are attached after signing). Validation checks that the required number of attestations are present and their signatures are valid.
type TimekeeperAttestation struct {
PublicKey string // hex ed25519 pubkey of timekeeper
Timestamp int64 // unix nanos attested
Signature string // hex ed25519 sig over sha256(leaseHashBytes || timestampBytes)
}
Binary encoding¶
Type byte: 0x05. Tail: source(32) + amount(8). Total canonical size: 162 bytes (90 header + 40 tail + 32 representative).
Lease Settle (lease_settle)¶
Settles an expired lease and emits XE as a reward to the provider.
Type-specific fields¶
| Field | Type | Description |
|---|---|---|
Source |
string | Hash of the original lease block |
Amount |
uint64 | XE emission reward |
Validation rules¶
Assetmust be"XE".Sourcemust reference an active (non-settled) lease.- The lease must have expired (current time > start time + duration).
Amountmust match the emission formula based on the lease cost.- Requires timekeeper attestations if configured.
Side effects¶
- The lease is marked as settled.
- The provider's XUSD stake is returned (added back to their XUSD balance).
- XE is emitted to the provider's account (
Balance = previousXEBalance + Amount).
XE emission
Lease settlement is the mechanism by which new XE enters circulation. Providers earn XE proportional to the compute they deliver, creating a link between real-world utility and token emission.
Binary encoding¶
Type byte: 0x06. Tail: source(32) + amount(8). Total canonical size: 162 bytes (90 header + 40 tail + 32 representative).
Multisig Open (multisig_open)¶
Opens a new multisig account with a hash-derived address.
Type-specific fields¶
| Field | Type | Description |
|---|---|---|
Keyset |
object | {keys: [pubkey1, pubkey2, ...], threshold: N} |
Signatures |
array | [{public_key, signature}, ...] — must have threshold valid signatures |
Validation rules¶
accountmust equalsha256(canonical(keyset))— the address is derived from the keyset.keyset.threshold >= 1and<= len(keys), no duplicate keys.- Block must have
thresholdvalid signatures from keyset members. - Account must not already exist.
- Balance must be 0.
Binary encoding¶
Type byte: 0x08. Tail: canonical_keyset(threshold_u32_be + num_keys_u32_be + sorted_keys_32_each). Canonical size varies with key count.
Multisig Update (multisig_update)¶
Rotates the keyset on an existing multisig account.
Type-specific fields¶
| Field | Type | Description |
|---|---|---|
Keyset |
object | New keyset {keys: [...], threshold: N} |
Signatures |
array | Must have threshold valid signatures from the current (old) keyset |
Validation rules¶
- Account must be an existing multisig account.
- Signed by the current keyset's threshold.
- Balance must be unchanged.
- The account address does NOT change (derived from original keyset).
Binary encoding¶
Type byte: 0x09. Same tail format as multisig_open.
Summary table¶
| Type | Byte | Asset | Debits | Credits | Creates pending | Canonical size |
|---|---|---|---|---|---|---|
send |
0x01 |
XE or XUSD | sender | -- | yes | 162 bytes |
receive |
0x02 |
XE or XUSD | -- | recipient | consumes pending | 154 bytes |
claim |
0x03 |
XUSD | -- | self (+100) | -- | 122 bytes |
lease |
0x04 |
XUSD | consumer | -- | yes | 226 bytes |
lease_accept |
0x05 |
XUSD | provider (stake) | -- | creates Lease record | 162 bytes |
lease_settle |
0x06 |
XE | -- | provider (emission) | settles Lease record | 162 bytes |
multisig_open |
0x08 |
XE or XUSD | -- | -- | registers keyset | varies |
multisig_update |
0x09 |
XE or XUSD | -- | -- | rotates keyset | varies |
Block lifecycle¶
Creator Network Recipient
─────── ─────── ─────────
1. Build block fields
2. MarshalBlockCanonical()
3. SHA-256 → Hash
4. ed25519.Sign(hash) → Signature
5. ComputePoW(hash) → PoWNonce
6. Broadcast via gossip ──────►
7. VerifyBlock (hash + sig)
8. ValidatePoW (nonce)
9. Ledger validation
10. Add to account chain
11. Rebroadcast ─────────────►
12. (for sends) appears as PendingSend
13. (recipient creates receive block)