This document provides the specification for the Fuel Virtual Machine (FuelVM). The specification covers the types, instruction set, and execution semantics.
FuelVM instructions are exactly 32 bits (4 bytes) wide and comprise of a combination of:
Opcode: 8 bits
Register/special register (see below) identifier: 6 bits
Immediate value: 12, 18, or 24 bits, depending on operation
Of the 64 registers (6-bit register address space), the first 16 are reserved:
value
register
name
description
0x00
$zero
zero
Contains zero (0), for convenience.
0x01
$one
one
Contains one (1), for convenience.
0x02
$of
overflow
Contains overflow/underflow of addition, subtraction, and multiplication.
0x03
$pc
program counter
The program counter. Memory address of the current instruction.
0x04
$ssp
stack start pointer
Memory address of bottom of current writable stack area.
0x05
$sp
stack pointer
Memory address on top of current writable stack area (points to free memory).
0x06
$fp
frame pointer
Memory address of beginning of current call frame.
0x07
$hp
heap pointer
Memory address below the current bottom of the heap (points to used/OOB memory).
0x08
$err
error
Error codes for particular operations.
0x09
$ggas
global gas
Remaining gas globally.
0x0A
$cgas
context gas
Remaining gas in the context.
0x0B
$bal
balance
Received balance for this context.
0x0C
$is
instructions start
Pointer to the start of the currently-executing code.
0x0D
$ret
return value
Return value or pointer.
0x0E
$retl
return length
Return value length in bytes.
0x0F
$flag
flags
Flags register.
Integers are represented in big-endian Icon Link format, and all operations are unsigned. Boolean false is 0 and Boolean true is 1.
Registers are 64 bits (8 bytes) wide. Words are the same width as registers.
Persistent state (i.e. storage) is a key-value store with 32-byte keys and 32-byte values. Each contract has its own persistent state that is independent of other contracts. This is committed to in a Sparse Binary Merkle Tree.
Every time the VM runs, a single monolithic memory of size VM_MAX_RAM bytes is allocated, indexed by individual byte. A stack and heap memory model is used, allowing for dynamic memory allocation in higher-level languages. The stack begins at 0 and grows upward. The heap begins at VM_MAX_RAM and grows downward.
To initialize the VM, the following is pushed on the stack sequentially:
Transaction hash (byte[32], word-aligned), computed as defined here .
MAX_INPUTS pairs of (asset_id: byte[32], balance: uint64), of:
For script execution , the free balance for each asset ID seen in the transaction's inputs, ordered in ascending order. If there are fewer than MAX_INPUTS asset IDs, the pair has a value of zero.
Transaction length, in bytes (uint64, word-aligned).
In addition, during predicate mode if $pc is set to a value greater than the end of predicate bytecode (this would allow bytecode outside the actual predicate), predicate estimation halts returning Boolean false.
A predicate that halts without returning Boolean true would not pass verification, making the entire transaction invalid. Note that predicate validity is monotonic with respect to time (i.e. if a predicate evaluates to true then it will always evaluate to true in the future).
After successful execution, predicateGasUsed is set to MAX_GAS_PER_PREDICATE - $ggas.
For each such input in the transaction, the VM is initialized , then:
$pc and $is are set to the start of the input's predicate field.
$ggas and $cgas are set to predicateGasUsed.
Predicate verification will fail if gas is exhausted during execution.
During predicate mode, hitting any contract instruction causes predicate verification to halt, returning Boolean false.
In addition, during predicate mode if $pc is set to a value greater than the end of predicate bytecode (this would allow bytecode outside the actual predicate), predicate verification halts returning Boolean false.
A predicate that halts without returning Boolean true does not pass verification, making the entire transaction invalid. Note that predicate validity is monotonic with respect to time (i.e. if a predicate evaluates to true then it will always evaluate to true in the future).
After execution, if $ggas is non-zero, predicate verification fails.
$pc and $is are set to the start of the transaction's script bytecode.
$ggas and $cgas are set to tx.scriptGasLimit.
Following initialization, execution begins.
For each instruction, its gas cost gc is first computed. If gc > $cgas, deduct $cgas from $ggas and $cgas (i.e. spend all of $cgas and no more), then revert immediately without actually executing the instruction. Otherwise, deduct gc from $ggas and $cgas.
Cross-contract calls push a call frame onto the stack, similar to a stack frame used in regular languages for function calls (which may be used by a high-level language that targets the FuelVM). The distinction is as follows:
Stack frames: store metadata across trusted internal (i.e. intra-contract) function calls. Not supported natively by the FuelVM, but may be used as an abstraction at a higher layer.
Call frames: store metadata across untrusted external (i.e. inter-contract) calls. Supported natively by the FuelVM.
Call frames are needed to ensure that the called contract cannot mutate the running state of the current executing contract. They segment access rights for memory: the currently-executing contracts may only write to their own call frame and their own heap.
A call frame consists of the following, word-aligned:
bytes
type
value
description
Unwritable area begins.
32
byte[32]
to
Contract ID for this call.
32
byte[32]
asset_id
asset ID of forwarded coins.
8*64
byte[8][64]
regs
Saved registers from previous context.
8
uint64
codesize
Code size in bytes.
8
byte[8]
param1
First parameter.
8
byte[8]
param2
Second parameter.
1*
byte[]
code
Zero-padded to 8-byte alignment, but individual instructions are not aligned.
Memory is only executable in range [$is, $ssp). Attempting to execute instructions outside these boundaries will panic. This area never overlaps with writable registers, essentially providing W^X Icon Link protection.