This page provides a description of all instructions for the FuelVM. Encoding is read as a sequence of one 8-bit value (the opcode identifier) followed by four 6-bit values (the register identifiers or immediate value). A single i
indicates a 6-bit immediate value, i i
indicates a 12-bit immediate value, i i i
indicates an 18-bit immediate value, and i i i i
indicates a 24-bit immediate value. All immediate values are interpreted as big-endian unsigned integers.
The syntax MEM[x, y]
used in this page means the memory range starting at byte x
, of length y
bytes. The syntax STATE[x, y]
used in this page means the sequence of storage slots starting at key x
and spanning y
bytes.
Some instructions may
panic , i.e. enter an unrecoverable state. Additionally, attempting to execute an instruction not in this list causes a panic and consumes no gas. How a panic is handled depends on
context :
In a predicate context, cease VM execution and return false
. In other contexts, revert (described below).
On a non-predicate panic, append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.Panic
id
byte[32]
Contract ID of current context if in an internal context, zero otherwise. pc
uint64
Value of register $pc
. is
uint64
Value of register $is
.
then append an additional receipt to the list of receipts, again modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.ScriptResult
result
uint64
1
gas_used
uint64
Gas consumed by the script.
The number of receipts is limited to 216, with the last two reserved to panic and script result receipts. Trying to add any other receipts after 216-2 will panic.
A few instructions are annotated with the effects they produce, the table below explains each effect:
effect name description Storage read Instruction reads from storage slots Storage write Instruction writes to storage slots External call External contract call instruction Balance tree read Instruction reads from the balance tree Balance tree write Instruction writes to the balance tree Output message Instruction sends a message to a recipient address
If an instruction is not annotated with an effect, it means it does not produce any of the aforementioned affects.
All these instructions advance the program counter $pc
by 4
after performing their operation.
Normally, if the result of an ALU operation is mathematically undefined (e.g. dividing by zero),
the VM panics. However, if the
F_UNSAFEMATH
flag is set,
$err
is set to
true
and execution continues.
If an operation would overflow, so that the result doesn't fit into the target field, the VM will panic.
Results below zero are also considered overflows. If the
F_WRAPPING
flag is set,
instead
$of
is set to
true
or the overflowing part of the result, depending on the operation.
Description Adds two registers. Operation $rA = $rB + $rC;
Syntax add $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$of
is assigned the overflow of the operation.
$err
is cleared.
Description Adds a register and an immediate value. Operation $rA = $rB + imm;
Syntax addi $rA, $rB, immediate
Encoding 0x00 rA rB i i
Notes
Panic if:
$of
is assigned the overflow of the operation.
$err
is cleared.
Description Bitwise ANDs two registers. Operation $rA = $rB & $rC;
Syntax and $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$of
and $err
are cleared.
Description Bitwise ANDs a register and an immediate value. Operation $rA = $rB & imm;
Syntax andi $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
Panic if:
imm
is extended to 64 bits, with the high 52 bits set to 0
.
$of
and $err
are cleared.
Description Divides two registers. Operation $rA = $rB // $rC;
Syntax div $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
If $rC == 0
, $rA
is cleared and $err
is set to true
.
Otherwise, $err
is cleared.
$of
is cleared.
Description Divides a register and an immediate value. Operation $rA = $rB // imm;
Syntax divi $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
Panic if:
If imm == 0
, $rA
is cleared and $err
is set to true
.
Otherwise, $err
is cleared.
$of
is cleared.
Description Compares two registers for equality. Operation $rA = $rB == $rC;
Syntax eq $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$of
and $err
are cleared.
Description Raises one register to the power of another. Operation $rA = $rB ** $rC;
Syntax exp $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
If the result cannot fit in 8 bytes, $of
is set to 1
and $rA
is instead set to 0
, otherwise $of
is cleared.
$err
is cleared.
Description Raises one register to the power of an immediate value. Operation $rA = $rB ** imm;
Syntax expi $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
Panic if:
If the result cannot fit in 8 bytes, $of
is set to 1
and $rA
is instead set to 0
, otherwise $of
is cleared.
$err
is cleared.
Description Compares two registers for greater-than. Operation $rA = $rB > $rC;
Syntax gt $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$of
and $err
are cleared.
Description Compares two registers for less-than. Operation $rA = $rB < $rC;
Syntax lt $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$of
and $err
are cleared.
Description The (integer) logarithm base $rC
of $rB
. Operation $rA = math.floor(math.log($rB, $rC));
Syntax mlog $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
If $rB == 0
, both $rA
and $of
are cleared and $err
is set to true
.
If $rC <= 1
, both $rA
and $of
are cleared and $err
is set to true
.
Otherwise, $of
and $err
are cleared.
Description Modulo remainder of two registers. Operation $rA = $rB % $rC;
Syntax mod $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
If $rC == 0
, both $rA
and $of
are cleared and $err
is set to true
.
Otherwise, $of
and $err
are cleared.
Description Modulo remainder of a register and an immediate value. Operation $rA = $rB % imm;
Syntax modi $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
Panic if:
If imm == 0
, both $rA
and $of
are cleared and $err
is set to true
.
Otherwise, $of
and $err
are cleared.
Description Copy from one register to another. Operation $rA = $rB;
Syntax move $rA, $rB
Encoding 0x00 rA rB - -
Notes
Panic if:
$of
and $err
are cleared.
Description Copy an immediate value into a register. Operation $rA = imm;
Syntax movi $rA, imm
Encoding 0x00 rA i i i
Notes
Panic if:
$of
and $err
are cleared.
Description The (integer) $rCth
root of $rB
. Operation $rA = math.floor(math.root($rB, $rC));
Syntax mroo $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
If $rC == 0
, both $rA
and $of
are cleared and $err
is set to true
.
Otherwise, $of
and $err
are cleared.
Description Multiplies two registers. Operation $rA = $rB * $rC;
Syntax mul $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$of
is assigned the overflow of the operation.
$err
is cleared.
Description Multiplies a register and an immediate value. Operation $rA = $rB * imm;
Syntax mul $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
Panic if:
$of
is assigned the overflow of the operation.
$err
is cleared.
Description Multiplies two registers with arbitrary precision, then divides by a third register. Operation a = (b * c) / d;
Syntax mldv $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Notes Division by zero is treated as division by 1 << 64
instead.
If the divisor ($rD
) is zero, then instead the value is divided by 1 << 64
. This returns the higher half of the 128-bit multiplication result. This operation never overflows.
If the result of after the division doesn't fit into a register, $of
is assigned the overflow of the operation. Otherwise, $of
is cleared.
$err
is cleared.
Description Performs no operation. Operation Syntax noop
Encoding 0x00 - - - -
Notes
$of
and $err
are cleared.
Description Bitwise NOT a register. Operation $rA = ~$rB;
Syntax not $rA, $rB
Encoding 0x00 rA rB - -
Notes
Panic if:
$of
and $err
are cleared.
Description Bitwise ORs two registers. Operation $rA = $rB | $rC;
Syntax or $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$of
and $err
are cleared.
Description Bitwise ORs a register and an immediate value. Operation $rA = $rB | imm;
Syntax ori $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
Panic if:
imm
is extended to 64 bits, with the high 52 bits set to 0
.
$of
and $err
are cleared.
Description Left shifts a register by a register. Operation $rA = $rB << $rC;
Syntax sll $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes Zeroes are shifted in.
Panic if:
$of
and $err
are cleared.
Description Left shifts a register by an immediate value. Operation $rA = $rB << imm;
Syntax slli $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes Zeroes are shifted in.
Panic if:
$of
and $err
are cleared.
Description Right shifts a register by a register. Operation $rA = $rB >> $rC;
Syntax srl $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes Zeroes are shifted in.
Panic if:
$of
and $err
are cleared.
Description Right shifts a register by an immediate value. Operation $rA = $rB >> imm;
Syntax srli $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes Zeroes are shifted in.
Panic if:
$of
and $err
are cleared.
Description Subtracts two registers. Operation $rA = $rB - $rC;
Syntax sub $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes $of
is assigned the overflow of the operation.
Panic if:
$of
is assigned the underflow of the operation, as though $of
is the high byte of a 128-bit register.
$err
is cleared.
Description Subtracts a register and an immediate value. Operation $rA = $rB - imm;
Syntax subi $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes $of
is assigned the overflow of the operation.
Panic if:
$of
is assigned the underflow of the operation, as though $of
is the high byte of a 128-bit register.
$err
is cleared.
Description Compare or examine two 128-bit integers using selected mode Operation b = mem[$rB,16];
c = indirect?mem[$rC,16]:$rC;
$rA = cmp_op(b,c);
Syntax wdcm $rA, $rB, $rC, imm
Encoding 0x00 rA rB rC i
Notes
The six-bit immediate value is used to select operating mode, as follows:
Bits Short name Description ...XXX
mode
Compare mode selection .XX...
reserved
Reserved and must be zero X.....
indirect
Is rhs operand ($rC
) indirect or not
Then the actual operation that's performed:
mode
Name Description 0 eq
Equality (==
) 1 ne
Inequality (!=
) 2 lt
Less than (<
) 3 gt
Greater than (>
) 4 lte
Less than or equals (<=
) 5 gte
Greater than or equals (>=
) 6 lzc
Leading zero count the lhs argument (lzcnt
). Discards rhs. 7 - Reserved and must not be used
The leading zero count can be used to compute rounded-down log2 of a number using the following formula TOTAL_BITS - 1 - lzc(n)
. Note that log2(0)
is undefined, and will lead to integer overflow with this method.
Clears $of
and $err
.
Panic if:
A reserved compare mode is given $rA
is a reserved register $rB + 16
overflows or > VM_MAX_RAM
indirect == 1
and $rC + 16
overflows or > VM_MAX_RAM
Description Compare or examine two 256-bit integers using selected mode Operation b = mem[$rB,32];
c = indirect?mem[$rC,32]:$rC;
$rA = cmp_op(b,c);
Syntax wqcm $rA, $rB, $rC, imm
Encoding 0x00 rA rB rC i
Notes
The immediate value is interpreted identically to WDCM
.
Clears $of
and $err
.
Panic if:
A reserved compare mode is given $rA
is a reserved register $rB + 32
overflows or > VM_MAX_RAM
indirect == 1
and $rC + 32
overflows or > VM_MAX_RAM
Description Perform an ALU operation on two 128-bit integers Operation b = mem[$rB,16];
c = indirect?mem[$rC,16]:$rC;
mem[$rA,16] = op(b,c);
Syntax wdop $rA, $rB, $rC, imm
Encoding 0x00 rA rB rC i
Notes
The six-bit immediate value is used to select operating mode, as follows:
Bits Short name Description ...XXX
op
Operation selection, see below .XX...
reserved
Reserved and must be zero X.....
indirect
Is rhs operand ($rC
) indirect or not
Then the actual operation that's performed:
op
Name Description 0 add
Add 1 sub
Subtract 2 not
Invert bits (discards rhs) 3 or
Bitwise or 4 xor
Bitwise exclusive or 5 and
Bitwise and 6 shl
Shift left (logical) 7 shr
Shift right (logical)
Operations behave $of
and $err
similarly to their 64-bit counterparts, except that $of
is set to 1
instead of the overflowing part.
Panic if:
Reserved bits of the immediate are set The memory range MEM[$rA, 16]
does not pass ownership check $rB + 16
overflows or > VM_MAX_RAM
indirect == 1
and $rC + 16
overflows or > VM_MAX_RAM
Description Perform an ALU operation on two 256-bit integers Operation b = mem[$rB,32];
c = indirect?mem[$rC,32]:$rC;
mem[$rA,32] = op(b,c);
Syntax wqop $rA, $rB, $rC, imm
Encoding 0x00 rA rB rC i
Notes
The immediate value is interpreted identically to WDOP
.
Operations behave $of
and $err
similarly to their 64-bit counterparts.
Panic if:
Reserved bits of the immediate are set The memory range MEM[$rA, 32]
does not pass ownership check $rB + 32
overflows or > VM_MAX_RAM
indirect == 1
and $rC + 32
overflows or > VM_MAX_RAM
Description Perform integer multiplication operation on two 128-bit integers. Operation b=indirect0?mem[$rB,16]:$rB;
c=indirect1?mem[$rC,16]:$rC;
mem[$rA,16]=b*c;
Syntax wdml $rA, $rB, $rC, imm
Encoding 0x00 rA rB rC i
Notes
The six-bit immediate value is used to select operating mode, as follows:
Bits Short name Description ..XXXX
reserved
Reserved and must be zero .X....
indirect0
Is lhs operand ($rB
) indirect or not X.....
indirect1
Is rhs operand ($rC
) indirect or not
$of
is set to 1
in case of overflow, and cleared otherwise.
$err
is cleared.
Panic if:
Reserved bits of the immediate are set The memory range MEM[$rA, 16]
does not pass ownership check indirect0 == 1
and $rB + 16
overflows or > VM_MAX_RAM
indirect1 == 1
and $rC + 16
overflows or > VM_MAX_RAM
Description Perform integer multiplication operation on two 256-bit integers. Operation b=indirect0?mem[$rB,32]:$rB;
c=indirect1?mem[$rC,32]:$rC;
mem[$rA,32]=b*c;
Syntax wqml $rA, $rB, $rC, imm
Encoding 0x00 rA rB rC i
Notes
The immediate value is interpreted identically to WDML
.
$of
is set to 1
in case of overflow, and cleared otherwise.
$err
is cleared.
Panic if:
Reserved bits of the immediate are set The memory range MEM[$rA, 32]
does not pass ownership check indirect0 == 1
and $rB + 32
overflows or > VM_MAX_RAM
indirect1 == 1
and $rC + 32
overflows or > VM_MAX_RAM
Description Divide a 128-bit integer by another. Operation b = mem[$rB,16];
c = indirect?mem[$rC,16]:$rC;
mem[$rA,16] = b / c;
Syntax wddv $rA, $rB, $rC, imm
Encoding 0x00 rA rB rC i
Notes
The six-bit immediate value is used to select operating mode, as follows:
Bits Short name Description .XXXXX
reserved
Reserved and must be zero X.....
indirect
Is rhs operand ($rC
) indirect or not
$of
is cleared.
If the rhs operand is zero, MEM[$rA, 16]
is cleared and $err
is set to true
. Otherwise, $err
is cleared.
Panic if:
Reserved bits of the immediate are set The memory range MEM[$rA, 16]
does not pass ownership check $rB + 16
overflows or > VM_MAX_RAM
indirect == 1
and $rC + 16
overflows or > VM_MAX_RAM
Description Divide a 256-bit integer by another. Operation b = mem[$rB,32];
c = indirect?mem[$rC,32]:$rC;
mem[$rA,32] = b / c;
Syntax wqdv $rA, $rB, $rC, imm
Encoding 0x00 rA rB rC i
Notes
The immediate value is interpreted identically to WDDV
.
$of
is cleared.
If the rhs operand is zero, MEM[$rA, 32]
is cleared and $err
is set to true
. Otherwise, $err
is cleared.
Panic if:
Reserved bits of the immediate are set The memory range MEM[$rA, 32]
does not pass ownership check $rB + 32
overflows or > VM_MAX_RAM
indirect == 1
and $rC + 32
overflows or > VM_MAX_RAM
Description Combined multiply-divide of 128-bit integers with arbitrary precision. Operation b=mem[$rB,16];
c=mem[$rC,16];
d=mem[$rD,16];
mem[$rA,16]=(b * c) / d;
Syntax wddv $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Notes Division by zero is treated as division by 1 << 128
instead.
If the divisor MEM[$rA, 16]
is zero, then instead the value is divided by 1 << 128
. This returns the higher half of the 256-bit multiplication result.
If the result of after the division is larger than operand size, $of
is set to one. Otherwise, $of
is cleared.
$err
is cleared.
Panic if:
The memory range MEM[$rA, 16]
does not pass ownership check $rB + 16
overflows or > VM_MAX_RAM
$rC + 16
overflows or > VM_MAX_RAM
$rD + 16
overflows or > VM_MAX_RAM
Description Combined multiply-divide of 256-bit integers with arbitrary precision. Operation b=mem[$rB,32];
c=mem[$rC,32];
d=mem[$rD,32];
mem[$rA,32]=(b * c) / d;
Syntax wqdv $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Notes Division by zero is treated as division by 1 << 256
instead.
If the divisor MEM[$rA, 32]
is zero, then instead the value is divided by 1 << 256
. This returns the higher half of the 512-bit multiplication result.
If the result of after the division is larger than operand size, $of
is set to one. Otherwise, $of
is cleared.
$err
is cleared.
Panic if:
The memory range MEM[$rA, 32]
does not pass ownership check $rB + 32
overflows or > VM_MAX_RAM
$rC + 32
overflows or > VM_MAX_RAM
$rD + 32
overflows or > VM_MAX_RAM
Description Add two 128-bit integers and compute modulo remainder with arbitrary precision. Operation b=mem[$rB,16];
c=mem[$rC,16];
d=mem[$rD,16];
mem[$rA,16] = (b+c)%d;
Syntax wdam $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Notes
$of
is cleared.
If the rhs operand is zero, MEM[$rA, 16]
is cleared and $err
is set to true
. Otherwise, $err
is cleared.
Panic if:
The memory range MEM[$rA, 16]
does not pass ownership check $rB + 16
overflows or > VM_MAX_RAM
$rC + 16
overflows or > VM_MAX_RAM
$rD + 16
overflows or > VM_MAX_RAM
Description Add two 256-bit integers and compute modulo remainder with arbitrary precision. Operation b=mem[$rB,32];
c=mem[$rC,32];
d=mem[$rD,32];
mem[$rA,32] = (b+c)%d;
Syntax wdam $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Notes
$of
is cleared.
If the rhs operand is zero, MEM[$rA, 16]
is cleared and $err
is set to true
. Otherwise, $err
is cleared.
Panic if:
The memory range MEM[$rA, 32]
does not pass ownership check $rB + 32
overflows or > VM_MAX_RAM
$rC + 32
overflows or > VM_MAX_RAM
$rD + 32
overflows or > VM_MAX_RAM
Description Multiply two 128-bit integers and compute modulo remainder with arbitrary precision. Operation b=mem[$rB,16];
c=mem[$rC,16];
d=mem[$rD,16];
mem[$rA,16] = (b*c)%d;
Syntax wdmm $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Notes
$of
is cleared.
If the rhs operand is zero, MEM[$rA, 16]
is cleared and $err
is set to true
. Otherwise, $err
is cleared.
Panic if:
The memory range MEM[$rA, 16]
does not pass ownership check $rB + 16
overflows or > VM_MAX_RAM
$rC + 16
overflows or > VM_MAX_RAM
$rD + 16
overflows or > VM_MAX_RAM
Description Multiply two 256-bit integers and compute modulo remainder with arbitrary precision. Operation b=mem[$rB,32];
c=mem[$rC,32];
d=mem[$rD,32];
mem[$rA,32] = (b*c)%d;
Syntax wqmm $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Notes
$of
is cleared.
If the rhs operand is zero, MEM[$rA, 16]
is cleared and $err
is set to true
. Otherwise, $err
is cleared.
Panic if:
The memory range MEM[$rA, 32]
does not pass ownership check $rB + 32
overflows or > VM_MAX_RAM
$rC + 32
overflows or > VM_MAX_RAM
$rD + 32
overflows or > VM_MAX_RAM
Description Bitwise XORs two registers. Operation $rA = $rB ^ $rC;
Syntax xor $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$of
and $err
are cleared.
Description Bitwise XORs a register and an immediate value. Operation $rA = $rB ^ imm;
Syntax xori $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
Panic if:
$of
and $err
are cleared.
Description Jumps to the code instruction offset by a register. Operation $pc = $is + $rA * 4;
Syntax jmp $rA
Encoding 0x00 rA - - -
Notes
Panic if:
$is + $rA * 4 > VM_MAX_RAM - 1
Description Jumps to the code instruction offset by imm
. Operation $pc = $is + imm * 4;
Syntax ji imm
Encoding 0x00 i i i i
Notes
Panic if:
$is + imm * 4 > VM_MAX_RAM - 1
Description Jump to the code instruction offset by a register if $rA
is not equal to $rB
. Operation if $rA != $rB:
$pc = $is + $rC * 4;
else:
$pc += 4;
Syntax jne $rA $rB $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$is + $rC * 4 > VM_MAX_RAM - 1
and the jump would be performed (i.e. $rA != $rB
)
Description Jump to the code instruction offset by imm
if $rA
is not equal to $rB
. Operation if $rA != $rB:
$pc = $is + imm * 4;
else:
$pc += 4;
Syntax jnei $rA $rB imm
Encoding 0x00 rA rB i i
Notes
Panic if:
$is + imm * 4 > VM_MAX_RAM - 1
and the jump would be performed (i.e. $rA != $rB
)
Description Jump to the code instruction offset by imm
if $rA
is not equal to $zero
. Operation if $rA != $zero:
$pc = $is + imm * 4;
else:
$pc += 4;
Syntax jnzi $rA imm
Encoding 0x00 rA i i i
Notes
Panic if:
$is + imm * 4 > VM_MAX_RAM - 1
and the jump would be performed (i.e. $rA != $zero
)
Description Jump $rA + imm
instructions backwards. Operation $pc -= ($rA + imm + 1) * 4;
Syntax jmpb $rA imm
Encoding 0x00 rA i i i
Notes
Panic if:
$pc - ($rA + imm + 1) * 4 < 0
Description Jump $rA + imm
instructions forwards Operation $pc += ($rA + imm + 1) * 4;
Syntax jmpf $rA imm
Encoding 0x00 rA i i i
Notes
Panic if:
$pc + ($rA + imm + 1) * 4 > VM_MAX_RAM - 1
Description Jump $rB + imm
instructions backwards if $rA !=Â $zero
. Operation if $rA != $zero:
$pc -= ($rB + imm + 1) * 4;
else:
$pc += 4;
Syntax jnzb $rA $rB imm
Encoding 0x00 rA rB i i
Notes
Panic if:
$pc - ($rB + imm + 1) * 4 < 0
Description Jump $rB + imm
instructions forwards if $rA !=Â $zero
. Operation if $rA != $zero:
$pc += ($rB + imm + 1) * 4;
else:
$pc += 4;
Syntax jnzf $rA $rB imm
Encoding 0x00 rA rB i i
Notes
Panic if:
$pc + ($rB + imm + 1) * 4 > VM_MAX_RAM - 1
Description Jump $rC + imm
instructions backwards if $rA !=Â $rB
. Operation if $rA != $rB:
$pc -= ($rC + imm + 1) * 4;
else:
$pc += 4;
Syntax jneb $rA $rB $rC imm
Encoding 0x00 rA rB rC i
Notes
Panic if:
$pc - ($rC + imm + 1) * 4 < 0
Description Jump $rC + imm
instructions forwards if $rA !=Â $rB
. Operation if $rA != $rB:
$pc += ($rC + imm + 1) * 4;
else:
$pc += 4;
Syntax jnef $rA $rB $rC imm
Encoding 0x00 rA rB rC i
Notes
Panic if:
$pc + ($rC + imm + 1) * 4 > VM_MAX_RAM - 1
Description Returns from context with value $rA
. Operation return($rA);
Syntax ret $rA
Encoding 0x00 rA - - -
Notes
Append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.Return
id
byte[32]
Contract ID of current context if in an internal context, zero otherwise. val
uint64
Value of register $rA
. pc
uint64
Value of register $pc
. is
uint64
Value of register $is
.
If current context is external, append an additional receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.ScriptResult
result
uint64
0
gas_used
uint64
Gas consumed by the script.
If current context is external, cease VM execution and return $rA
.
Returns from contract call, popping the call frame. Before popping perform the following operations.
Return the unused forwarded gas to the caller:
$cgas = $cgas + $fp->$cgas
(add remaining context gas from previous context to current remaining context gas)
Set the return value:
$ret = $rA
$retl = 0
Then pop the call frame and restore all registers except $ggas
, $cgas
, $ret
, $retl
and $hp
. Afterwards, set the following registers:
$pc = $pc + 4
(advance program counter from where we called)
All these instructions advance the program counter $pc
by 4
after performing their operation.
Description Allocate a number of bytes from the heap. Operation $hp = $hp - $rA;
Syntax aloc $rA
Encoding 0x00 rA - - -
Notes Does not initialize memory.
Panic if:
$hp - $rA
underflows $hp - $rA < $sp
Description Extend the current call frame's stack. Operation $sp = $sp + $rA
Syntax cfei $rA
Encoding 0x00 rA - - -
Notes Does not initialize memory.
Panic if:
$sp + $rA
overflows $sp + $rA > $hp
Description Extend the current call frame's stack by an immediate value. Operation $sp = $sp + imm
Syntax cfei imm
Encoding 0x00 i i i i
Notes Does not initialize memory.
Panic if:
$sp + imm
overflows $sp + imm > $hp
Description Shrink the current call frame's stack. Operation $sp = $sp - $rA
Syntax cfs $rA
Encoding 0x00 $rA - - -
Notes Does not clear memory.
Panic if:
$sp - $rA
underflows $sp - $rA < $ssp
Description Shrink the current call frame's stack by an immediate value. Operation $sp = $sp - imm
Syntax cfsi imm
Encoding 0x00 i i i i
Notes Does not clear memory.
Panic if:
$sp - imm
underflows $sp - imm < $ssp
Description A byte is loaded from the specified address offset by imm
. Operation $rA = MEM[$rB + imm, 1];
Syntax lb $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
Panic if:
Description A word is loaded from the specified address offset by imm
. Operation $rA = MEM[$rB + (imm * 8), 8];
Syntax lw $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
Panic if:
$rA
is a reserved register $rB + (imm * 8) + 8
overflows $rB + (imm * 8) + 8 > VM_MAX_RAM
Description Clear bytes in memory. Operation MEM[$rA, $rB] = 0;
Syntax mcl $rA, $rB
Encoding 0x00 rA rB - -
Notes
Panic if:
$rA + $rB
overflows $rA + $rB > VM_MAX_RAM
The memory range MEM[$rA, $rB]
does not pass ownership check
Description Clear bytes in memory. Operation MEM[$rA, imm] = 0;
Syntax mcli $rA, imm
Encoding 0x00 rA i i i
Notes
Panic if:
$rA + imm
overflows $rA + imm > VM_MAX_RAM
The memory range MEM[$rA, imm]
does not pass ownership check
Description Copy bytes in memory. Operation MEM[$rA, $rC] = MEM[$rB, $rC];
Syntax mcp $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$rA + $rC
overflows $rB + $rC
overflows $rA + $rC > VM_MAX_RAM
$rB + $rC > VM_MAX_RAM
The memory ranges MEM[$rA, $rC]
and MEM[$rB, $rC]
overlap The memory range MEM[$rA, $rC]
does not pass ownership check
Description Copy bytes in memory. Operation MEM[$rA, imm] = MEM[$rB, imm];
Syntax mcpi $rA, $rB, imm
Encoding 0x00 rA rB imm imm
Notes
Panic if:
$rA + imm
overflows $rB + imm
overflows $rA + imm > VM_MAX_RAM
$rB + imm > VM_MAX_RAM
The memory ranges MEM[$rA, imm]
and MEM[$rB, imm]
overlap The memory range MEM[$rA, imm]
does not pass ownership check
Description Compare bytes in memory. Operation $rA = MEM[$rB, $rD] == MEM[$rC, $rD];
Syntax meq $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Notes
Panic if:
$rA
is a reserved register $rB + $rD
overflows $rC + $rD
overflows $rB + $rD > VM_MAX_RAM
$rC + $rD > VM_MAX_RAM
Description Push a set of registers from range 40..64 to the stack in order. Operation tmp=$sp;
$sp+=popcnt(imm)*8;
MEM[tmp,$sp]=registers[40..64].mask(imm)
Syntax pshh imm
Encoding 0x00 i i i i
Notes The immediate value is used as a bitmask for selecting the registers.
Panic if:
$sp + popcnt(imm)*8
overflows $sp + popcnt(imm)*8 > $hp
Description Push a set of registers from range 16..40 to the stack in order. Operation tmp=$sp;
$sp+=popcnt(imm)*8;
MEM[tmp,$sp]=registers[16..40].mask(imm)
Syntax pshl imm
Encoding 0x00 i i i i
Notes The immediate value is used as a bitmask for selecting the registers.
Panic if:
$sp + popcnt(imm)*8
overflows $sp + popcnt(imm)*8 > $hp
Description Pop to a set of registers from range 40..64 from the stack. Operation tmp=$sp-popcnt(imm)*8;
registers[40..64].mask(imm)=MEM[tmp,$sp]
$sp-=tmp;
Syntax poph imm
Encoding 0x00 i i i i
Notes The immediate value is used as a bitmask for selecting the registers.
Panic if:
$sp - popcnt(imm)*8
overflows $sp - popcnt(imm)*8 < $ssp
Description Pop to a set of registers from range 16..40 from the stack. Operation tmp=$sp-popcnt(imm)*8;
registers[16..40].mask(imm)=MEM[tmp,$sp]
$sp-=tmp;
Syntax poph imm
Encoding 0x00 i i i i
Notes The immediate value is used as a bitmask for selecting the registers.
Panic if:
$sp - popcnt(imm)*8
overflows $sp - popcnt(imm)*8 < $ssp
Description The least significant byte of $rB
is stored at the address $rA
offset by imm
. Operation MEM[$rA + imm, 1] = $rB[7, 1];
Syntax sb $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
Panic if:
$rA + imm + 1
overflows $rA + imm + 1 > VM_MAX_RAM
The memory range MEM[$rA + imm, 1]
does not pass ownership check
Description The value of $rB
is stored at the address $rA
offset by imm
. Operation MEM[$rA + (imm * 8), 8] = $rB;
Syntax sw $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
Panic if:
$rA + (imm * 8) + 8
overflows $rA + (imm * 8) + 8 > VM_MAX_RAM
The memory range MEM[$rA + (imm * 8), 8]
does not pass ownership check
All these instructions advance the program counter
$pc
by
4
after performing their operation, except for
CALL ,
RETD
and
RVRT
.
Description Set $rA
to the balance of asset ID at $rB
for contract with ID at $rC
. Operation $rA = balance(MEM[$rB, 32], MEM[$rC, 32]);
Syntax bal $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Effects Balance tree read Notes
Where helper balance(asset_id: byte[32], contract_id: byte[32]) -> uint64
returns the current balance of asset_id
of contract with ID contract_id
.
Panic if:
$rA
is a reserved register $rB + 32
overflows $rB + 32 > VM_MAX_RAM
$rC + 32
overflows $rC + 32 > VM_MAX_RAM
Contract with ID MEM[$rC, 32]
is not in tx.inputs
Description Get Fuel block height. Operation $rA = blockheight();
Syntax bhei $rA
Encoding 0x00 rA - - -
Notes
Panic if:
Description Get block header hash. Operation MEM[$rA, 32] = blockhash($rB);
Syntax bhsh $rA $rB
Encoding 0x00 rA rB - -
Notes
Panic if:
$rA + 32
overflows $rA + 32 > VM_MAX_RAM
The memory range MEM[$rA, 32]
does not pass ownership check
Block header hashes for blocks with height greater than or equal to current block height are zero (0x00**32
).
Description Burn $rA
coins of the $rB
ID from the current contract. Operation burn($rA, $rB);
Syntax burn $rA $rB
Encoding 0x00 rA rB - -
Notes $rB
is a pointer to a 32 byte ID in memory.
The asset ID is constructed using the asset ID construction method.
Panic if:
$rB + 32 > VM_MAX_RAM
Balance of asset ID from constructAssetID(MEM[$fp, 32], MEM[$rB, 32])
of output with contract ID MEM[$fp, 32]
minus $rA
underflows $fp == 0
(in the script context)
For output with contract ID MEM[$fp, 32]
, decrease balance of asset ID constructAssetID(MEM[$fp, 32], MEM[$rB, 32])
by $rA
.
This modifies the balanceRoot
field of the appropriate output.
Append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.Burn
sub_id
byte[32]
Asset sub identifier MEM[$rB, $rB + 32]
. contract_id
byte[32]
Contract ID of the current context. val
uint64
Value of register $rA
. pc
uint64
Value of register $pc
. is
uint64
Value of register $is
.
Description Call contract. Operation Syntax call $rA $rB $rC $rD
Encoding 0x00 rA rB rC rD
Effects External call Notes
There is a balanceOfStart(asset_id: byte[32]) -> uint32
helper that returns the memory address of the remaining free balance of asset_id
. If asset_id
has no free balance remaining, the helper panics.
Panic if:
$rA + 32
overflows $rC + 32
overflows Contract with ID MEM[$rA, 32]
is not in tx.inputs
Reading past MEM[VM_MAX_RAM - 1]
In an external context, if $rB > MEM[balanceOfStart(MEM[$rC, 32]), 8]
In an internal context, if $rB
is greater than the balance of asset ID MEM[$rC, 32]
of output with contract ID MEM[$fp, 32]
Register $rA
is a memory address from which the following fields are set (word-aligned):
bytes type value description 32 byte[32]
to
Contract ID to call. 8 byte[8]
param1
First parameter. 8 byte[8]
param2
Second parameter.
$rB
is the amount of coins to forward. $rC
points to the 32-byte asset ID of the coins to forward. $rD
is the amount of gas to forward. If it is set to an amount greater than the available gas, all available gas is forwarded.
Append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.Call
from
byte[32]
Contract ID of current context if in an internal context, zero otherwise. to
byte[32]
Contract ID of called contract. amount
uint64
Amount of coins to forward, i.e. $rB
. asset_id
byte[32]
Asset ID of coins to forward, i.e. MEM[$rC, 32]
. gas
uint64
Gas to forward, i.e. min($rD, $cgas)
. param1
uint64
First parameter. param2
uint64
Second parameter. pc
uint64
Value of register $pc
. is
uint64
Value of register $is
.
For output with contract ID MEM[$rA, 32]
, increase balance of asset ID MEM[$rC, 32]
by $rB
. In an external context, decrease MEM[balanceOfStart(MEM[$rC, 32]), 8]
by $rB
. In an internal context, decrease asset ID MEM[$rC, 32]
balance of output with contract ID MEM[$fp, 32]
by $rB
.
A
call frame is pushed at
$sp
. In addition to filling in the values of the call frame, the following registers are set:
$fp = $sp
(on top of the previous call frame is the beginning of this call frame) Set $ssp
and $sp
to the start of the writable stack area of the call frame. Set $pc
and $is
to the starting address of the code. $bal = $rB
(forward coins) $cgas = $rD
or all available gas (forward gas)
This modifies the balanceRoot
field of the appropriate output(s).
Description Get the coinbase contract id associated with the block proposer. Operation MEM[$rA, 32] = coinbase();
Syntax cb $rA
Encoding 0x00 rA - - -
Notes
Panic if:
$rA + 32
overflows $rA + 32 > VM_MAX_RAM
The memory range MEM[$rA, 32]
does not pass ownership check
Description Copy $rD
bytes of code starting at $rC
for contract with ID equal to the 32 bytes in memory starting at $rB
into memory starting at $rA
. Operation MEM[$rA, $rD] = code($rB, $rC, $rD);
Syntax ccp $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Notes If $rD
is greater than the code size, zero bytes are filled in.
This is used only for reading and inspecting code of other contracts.
Use
LDC
to load code for executing.
Panic if:
$rA + $rD
overflows $rB + 32
overflows $rA + $rD > VM_MAX_RAM
$rB + 32 > VM_MAX_RAM
The memory range MEM[$rA, $rD]
does not pass ownership check Contract with ID MEM[$rB, 32]
is not in tx.inputs
Description Set the 32 bytes in memory starting at $rA
to the code root for contract with ID equal to the 32 bytes in memory starting at $rB
. Operation MEM[$rA, 32] = coderoot(MEM[$rB, 32]);
Syntax croo $rA, $rB
Encoding 0x00 rA rB - -
Notes
Panic if:
$rA + 32
overflows $rB + 32
overflows $rA + 32 > VM_MAX_RAM
$rB + 32 > VM_MAX_RAM
The memory range MEM[$rA, 32]
does not pass ownership check Contract with ID MEM[$rB, 32]
is not in tx.inputs
Code root computation is defined
here .
Description Set $rA
to the size of the code for contract with ID equal to the 32 bytes in memory starting at $rB
. Operation $rA = codesize(MEM[$rB, 32]);
Syntax csiz $rA, $rB
Encoding 0x00 rA rB - -
Notes
Panic if:
$rA
is a reserved register $rB + 32
overflows $rB + 32 > VM_MAX_RAM
Contract with ID MEM[$rB, 32]
is not in tx.inputs
Description Copy $rC
bytes of code starting at $rB
for contract with ID equal to the 32 bytes in memory starting at $rA
into memory starting at $ssp
. Operation MEM[$ssp, $rC] = code($rA, $rB, $rC);
Syntax ldc $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes If $rC
is greater than the code size, zero bytes are filled in.
Panic if:
$ssp + $rC
overflows $rA + 32
overflows $ssp + $rC > VM_MAX_RAM
$rA + 32 > VM_MAX_RAM
$ssp + $rC >= $hp
$rC > CONTRACT_MAX_SIZE
Contract with ID MEM[$rA, 32]
is not in tx.inputs
Increment $fp->codesize
, $ssp
by $rC
padded to word alignment. Then set $sp
to $ssp
.
This instruction can be used to concatenate the code of multiple contracts together. It can only be used when the stack area of the call frame is unused (i.e. prior to being used).
Description Log an event. This is a no-op. Operation log($rA, $rB, $rC, $rD);
Syntax log $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Notes
Append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.Log
id
byte[32]
Contract ID of current context if in an internal context, zero otherwise. val0
uint64
Value of register $rA
. val1
uint64
Value of register $rB
. val2
uint64
Value of register $rC
. val3
uint64
Value of register $rD
. pc
uint64
Value of register $pc
. is
uint64
Value of register $is
.
Description Log an event. This is a no-op. Operation logd($rA, $rB, $rC, $rD);
Syntax logd $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Notes
Append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.LogData
id
byte[32]
Contract ID of current context if in an internal context, zero otherwise. val0
uint64
Value of register $rA
. val1
uint64
Value of register $rB
. ptr
uint64
Value of register $rC
. len
uint64
Value of register $rD
. digest
byte[32]
Hash of MEM[$rC, $rD]
.pc
uint64
Value of register $pc
. is
uint64
Value of register $is
.
Logs the memory range MEM[$rC, $rD]
.
Panics if:
$rC + $rD
overflows $rA + $rD > VM_MAX_RAM
Description Mint $rA
coins of the $rB
ID from the current contract. Operation mint($rA, $rB);
Syntax mint $rA $rB
Encoding 0x00 rA rB - -
Notes $rB
is a pointer to a 32 byte ID in memory
The asset ID will be constructed using the asset ID construction method.
Panic if:
$rB + 32 > VM_MAX_RAM
Balance of asset ID constructAssetID(MEM[$fp, 32], MEM[$rB])
of output with contract ID MEM[$fp, 32]
plus $rA
overflows $fp == 0
(in the script context)
For output with contract ID MEM[$fp, 32]
, increase balance of asset ID constructAssetID(MEM[$fp, 32], MEM[$rB])
by $rA
.
This modifies the balanceRoot
field of the appropriate output.
Append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.Mint
sub_id
byte[32]
Asset sub identifier MEM[$rB, $rB + 32]
. contract_id
byte[32]
Contract ID of the current context. val
uint64
Value of register $rA
. pc
uint64
Value of register $pc
. is
uint64
Value of register $is
.
Description Returns from context with value MEM[$rA, $rB]
. Operation returndata($rA, $rB);
Syntax retd $rA, $rB
Encoding 0x00 rA rB - -
Notes
Panic if:
$rA + $rB
overflows $rA + $rB > VM_MAX_RAM
Append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.ReturnData
id
byte[32]
Contract ID of current context if in an internal context, zero otherwise. ptr
uint64
Value of register $rA
. len
uint64
Value of register $rB
. digest
byte[32]
Hash of MEM[$rA, $rB]
.pc
uint64
Value of register $pc
. is
uint64
Value of register $is
.
If current context is a script, append an additional receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.ScriptResult
result
uint64
0
gas_used
uint64
Gas consumed by the script.
If current context is external, cease VM execution and return MEM[$rA, $rB]
.
Returns from contract call, popping the call frame. Before popping, perform the following operations.
Return the unused forwarded gas to the caller:
$cgas = $cgas + $fp->$cgas
(add remaining context gas from previous context to current remaining context gas)
Set the return value:
$ret = $rA
$retl = $rB
Then pop the call frame and restore all registers except $ggas
, $cgas
, $ret
, $retl
and $hp
. Afterwards, set the following registers:
$pc = $pc + 4
(advance program counter from where we called)
Description Halt execution, reverting state changes and returning value in $rA
. Operation revert($rA);
Syntax rvrt $rA
Encoding 0x00 rA - - -
Notes
Append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.Revert
id
byte[32]
Contract ID of current context if in an internal context, zero otherwise. val
uint64
Value of register $rA
. pc
uint64
Value of register $pc
. is
uint64
Value of register $is
.
Then append an additional receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.ScriptResult
result
uint64
1
gas_used
uint64
Gas consumed by the script.
Cease VM execution and revert script effects. After a revert:
All OutputContract
outputs will have the same balanceRoot
and stateRoot
as on initialization. All OutputVariable
outputs will have to
, amount
, and asset_id
of zero.
Description Send a message to recipient address MEM[$rA, 32]
from the MEM[$fp, 32]
sender with message data MEM[$rB, $rC]
and the $rD
amount of base asset coins. Operation outputmessage(MEM[$fp, 32], MEM[$rA, 32], MEM[$rB, $rC], $rD);
Syntax smo $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Effects Output message Notes
There is a balanceOfStart(asset_id: byte[32]) -> uint32
helper that returns the memory address of the remaining free balance of asset_id
. If asset_id
has no free balance remaining, the helper panics.
Panic if:
$rA + 32
overflows $rB + $rC
overflows $rA + 32 > VM_MAX_RAM
$rB + $rC > VM_MAX_RAM
$rC > MESSAGE_MAX_DATA_SIZE
In an external context, if $rD > MEM[balanceOfStart(0), 8]
In an internal context, if $rD
is greater than the balance of asset ID 0 of output with contract ID MEM[$fp, 32]
Append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.MessageOut
sender
byte[32]
The address of the message sender: MEM[$fp, 32]
. recipient
byte[32]
The address of the message recipient: MEM[$rA, 32]
. amount
uint64
Amount of base asset coins sent with message: $rD
. nonce
byte[32]
The message nonce as described here . len
uint16
Length of message data, in bytes: $rC
. digest
byte[32]
Hash of MEM[$rB, $rC]
.
In an external context, decrease MEM[balanceOfStart(0), 8]
by $rD
. In an internal context, decrease asset ID 0 balance of output with contract ID MEM[$fp, 32]
by $rD
. This modifies the balanceRoot
field of the appropriate contract that had its' funds deducted.
Description A sequential series of 32 bytes is cleared from the current contract's state. Operation STATE[MEM[$rA, 32], 32 * $rC] = None;
Syntax scwq $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$rA + 32
overflows $rA + 32 > VM_MAX_RAM
$rB
is a reserved register $fp == 0
(in the script context)
Register $rB
will be set to false
if any storage slot in the requested range was already unset (default) and true
if all the slots were set.
Description A word is read from the current contract's state. Operation $rA = STATE[MEM[$rC, 32]][0, 8];
Syntax srw $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Effects Storage read Notes Returns zero if the state element does not exist.
Panic if:
Register $rB
will be set to false
if the requested slot is unset (default) and true
if it's set.
Description A sequential series of 32 bytes is read from the current contract's state. Operation MEM[$rA, 32 * rD] = STATE[MEM[$rC, 32], 32 * rD];
Syntax srwq $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Effects Storage read Notes Returns zero if the state element does not exist.
Panic if:
$rA + 32 * rD
overflows $rA + 32 * rD > VM_MAX_RAM
$rB
is a reserved register $rC + 32 * rD
overflows $rC + 32 * rD > VM_MAX_RAM
The memory range MEM[$rA, 32 * rD]
does not pass ownership check $fp == 0
(in the script context)
Register $rB
will be set to false
if any storage slot in the requested range is unset (default) and true
if all the slots are set.
Description A word is written to the current contract's state. Operation STATE[MEM[$rA, 32]][0, 8] = $rC;
STATE[MEM[$rA, 32]][8, 24] = 0;
Syntax sww $rA $rB $rC
Encoding 0x00 rA rB rC -
Effects Storage write Notes Additional gas is charged when a new storage slot is created.
Panic if:
$rA + 32
overflows $rA + 32 > VM_MAX_RAM
$rB
is a reserved register $fp == 0
(in the script context)
The last 24 bytes of STATE[MEM[$rA, 32]]
are set to 0
. Register $rB
will be set to the number of new slots written, i.e. 1
if the slot was previously unset, and 0
if it already contained a value.
Description A sequential series of 32 bytes is written to the current contract's state. Operation STATE[MEM[$rA, 32], 32 * $rD] = MEM[$rC, 32 * $rD];
Syntax swwq $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Effects Storage write Notes Additional gas is charged when for each new storage slot created.
Panic if:
$rA + 32
overflows $rB
is a reserved register $rC + 32 * $rD
overflows $rA + 32 > VM_MAX_RAM
$rC + 32 * $rD > VM_MAX_RAM
$fp == 0
(in the script context)
Register $rB
will be set to the number of storage slots that were previously unset, and were set by this operation.
Description Get timestamp of block at given height. Operation $rA = time($rB);
Syntax time $rA, $rB
Encoding 0x00 rA rB - -
Notes
Panic if:
Gets the timestamp of the block at height
$rB
. Time is in
TAI64 Icon Link format.
Description Transfer $rB
coins with asset ID at $rC
to contract with ID at $rA
. Operation transfer(MEM[$rA, 32], $rB, MEM[$rC, 32]);
Syntax tr $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Effects Balance tree read, balance tree write Notes
There is a balanceOfStart(asset_id: byte[32]) -> uint32
helper that returns the memory address of the remaining free balance of asset_id
. If asset_id
has no free balance remaining, the helper panics.
Panic if:
$rA + 32
overflows $rC + 32
overflows $rA + 32 > VM_MAX_RAM
$rC + 32 > VM_MAX_RAM
Contract with ID MEM[$rA, 32]
is not in tx.inputs
In an external context, if $rB > MEM[balanceOfStart(MEM[$rC, 32]), 8]
In an internal context, if $rB
is greater than the balance of asset ID MEM[$rC, 32]
of output with contract ID MEM[$fp, 32]
$rB == 0
Append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.Transfer
from
byte[32]
Contract ID of current context if in an internal context, zero otherwise. to
byte[32]
Contract ID of contract to transfer coins to. amount
uint64
Amount of coins transferred. asset_id
byte[32]
asset ID of coins transferred. pc
uint64
Value of register $pc
. is
uint64
Value of register $is
.
For output with contract ID MEM[$rA, 32]
, increase balance of asset ID MEM[$rC, 32]
by $rB
. In an external context, decrease MEM[balanceOfStart(MEM[$rC, 32]), 8]
by $rB
. In an internal context, decrease asset ID MEM[$rC, 32]
balance of output with contract ID MEM[$fp, 32]
by $rB
.
This modifies the balanceRoot
field of the appropriate output(s).
Description Transfer $rC
coins with asset ID at $rD
to address at $rA
, with output $rB
. Operation transferout(MEM[$rA, 32], $rB, $rC, MEM[$rD, 32]);
Syntax tro $rA, $rB, $rC, $rD
Encoding 0x00 rA rB rC rD
Effects Balance tree read, balance tree write Notes
There is a balanceOfStart(asset_id: byte[32]) -> uint32
helper that returns the memory address of the remaining free balance of asset_id
. If asset_id
has no free balance remaining, the helper panics.
Panic if:
$rA + 32
overflows $rD + 32
overflows $rA + 32 > VM_MAX_RAM
$rD + 32 > VM_MAX_RAM
$rB > tx.outputsCount
In an external context, if $rC > MEM[balanceOfStart(MEM[$rD, 32]), 8]
In an internal context, if $rC
is greater than the balance of asset ID MEM[$rD, 32]
of output with contract ID MEM[$fp, 32]
$rC == 0
tx.outputs[$rB].type != OutputType.Variable
tx.outputs[$rB].amount != 0
Append a receipt to the list of receipts, modifying tx.receiptsRoot
:
name type description type
ReceiptType
ReceiptType.TransferOut
from
byte[32]
Contract ID of current context if in an internal context, zero otherwise. to
byte[32]
Address to transfer coins to. amount
uint64
Amount of coins transferred. asset_id
byte[32]
asset ID of coins transferred. pc
uint64
Value of register $pc
. is
uint64
Value of register $is
.
In an external context, decrease MEM[balanceOfStart(MEM[$rD, 32]), 8]
by $rC
. In an internal context, decrease asset ID MEM[$rD, 32]
balance of output with contract ID MEM[$fp, 32]
by $rC
. Then set:
tx.outputs[$rB].to = MEM[$rA, 32]
tx.outputs[$rB].amount = $rC
tx.outputs[$rB].asset_id = MEM[$rD, 32]
This modifies the balanceRoot
field of the appropriate output(s).
All these instructions advance the program counter $pc
by 4
after performing their operation.
Description The 64-byte public key (x, y) recovered from 64-byte signature starting at $rB
on 32-byte message hash starting at $rC
. Operation MEM[$rA, 64] = ecrecover_k1(MEM[$rB, 64], MEM[$rC, 32]);
Syntax eck1 $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$rA + 64
overflows $rB + 64
overflows $rC + 32
overflows $rA + 64 > VM_MAX_RAM
$rB + 64 > VM_MAX_RAM
$rC + 32 > VM_MAX_RAM
The memory range MEM[$rA, 64]
does not pass ownership check
Signatures and signature verification are specified
here .
If the signature cannot be verified, MEM[$rA, 64]
is set to 0
and $err
is set to 1
, otherwise $err
is cleared.
To get the address from the public key, hash the public key with
SHA-2-256 .
Description The 64-byte public key (x, y) recovered from 64-byte signature starting at $rB
on 32-byte message hash starting at $rC
. Operation MEM[$rA, 64] = ecrecover_r1(MEM[$rB, 64], MEM[$rC, 32]);
Syntax ecr1 $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$rA + 64
overflows $rB + 64
overflows $rC + 32
overflows $rA + 64 > VM_MAX_RAM
$rB + 64 > VM_MAX_RAM
$rC + 32 > VM_MAX_RAM
The memory range MEM[$rA, 64]
does not pass ownership check
Signatures and signature verification are specified
here .
If the signature cannot be verified, MEM[$rA, 64]
is set to 0
and $err
is set to 1
, otherwise $err
is cleared.
To get the address from the public key, hash the public key with
SHA-2-256 .
Description Verification recovered from 32-byte public key starting at $rA
and 64-byte signature starting at $rB
on 32-byte message hash starting at $rC
. Operation ed19verify(MEM[$rA, 32], MEM[$rB, 64], MEM[$rC, 32]);
Syntax ed19 $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$rA + 32
overflows $rB + 64
overflows $rC + 32
overflows $rA + 32 > VM_MAX_RAM
$rB + 64 > VM_MAX_RAM
$rC + 32 > VM_MAX_RAM
Verification are specified
here .
If there is an error in verification, $err
is set to 1
, otherwise $err
is cleared.
Description The keccak-256 hash of $rC
bytes starting at $rB
. Operation MEM[$rA, 32] = keccak256(MEM[$rB, $rC]);
Syntax k256 $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$rA + 32
overflows $rB + $rC
overflows $rA + 32 > VM_MAX_RAM
$rB + $rC > VM_MAX_RAM
The memory range MEM[$rA, 32]
does not pass ownership check
Description The SHA-2-256 hash of $rC
bytes starting at $rB
. Operation MEM[$rA, 32] = sha256(MEM[$rB, $rC]);
Syntax s256 $rA, $rB, $rC
Encoding 0x00 rA rB rC -
Notes
Panic if:
$rA + 32
overflows $rB + $rC
overflows $rA + 32 > VM_MAX_RAM
$rB + $rC > VM_MAX_RAM
The memory range MEM[$rA, 32]
does not pass ownership check
All these instructions advance the program counter $pc
by 4
after performing their operation.
Description Call an external function that has full access to the VM state. Operation external(&mut vm, $rA, $rB, $rC, $rD)
Syntax ecal $rA $rB $rC $rD
Encoding 0x00 rA rB rC rD
Notes Does nothing by default, but the VM user can define this to do anything.
This function provides an escape hatch from the VM, similar to ecall
instruction of RISC-V. The suggested convention is to use $rA
for "system call number", i.e. identifying the procedure to call, but all arguments can be used freely. The operation can modify the VM state freely, including writing to registers and memory. Again, the suggested convention is to use $rA
for the return value and $err
for any possible errors. However, these conventions can be ignored when necessary.
Panic if:
The external function panics.
Description Set $flag
to $rA
. Operation $flag = $rA;
Syntax flag $rA
Encoding 0x00 rA - - -
Notes
Panic if:
Any reserved flags are set
Description Get metadata from memory. Operation Varies (see below). Syntax gm $rA, imm
Encoding 0x00 rA imm imm imm
Notes
Read metadata from memory. A convenience instruction to avoid manually extracting metadata.
name value description GM_IS_CALLER_EXTERNAL
0x00001
Get if caller is external. GM_GET_CALLER
0x00002
Get caller's contract ID. GM_GET_VERIFYING_PREDICATE
0x00003
Get index of current predicate. GM_GET_CHAIN_ID
0x00004
Get the value of CHAIN_ID
If imm == GM_IS_CALLER_EXTERNAL
:
Panic if:
$fp == 0
(in an external context)
Set $rA
to true
if parent is an external context, false
otherwise.
If imm == GM_GET_CALLER
:
Panic if:
$fp == 0
(in an external context) $fp->$fp == 0
(if parent context is external)
Set $rA
to $fp->$fp
(i.e. $rA
will point to the previous call frame's contract ID).
If imm == GM_GET_VERIFYING_PREDICATE
:
Panic if:
not in a predicate context
Set $rA
to the index of the currently-verifying predicate.
Description Get transaction fields. Operation Varies (see below). Syntax gtf $rA, $rB, imm
Encoding 0x00 rA rB i i
Notes
name imm
set $rA
to GTF_TYPE
0x001
tx.type
GTF_SCRIPT_GAS_LIMIT
0x002
tx.scriptGasLimit
GTF_SCRIPT_SCRIPT_LENGTH
0x003
tx.scriptLength
GTF_SCRIPT_SCRIPT_DATA_LENGTH
0x004
tx.scriptDataLength
GTF_SCRIPT_INPUTS_COUNT
0x005
tx.inputsCount
GTF_SCRIPT_OUTPUTS_COUNT
0x006
tx.outputsCount
GTF_SCRIPT_WITNESSES_COUNT
0x007
tx.witnessesCount
GTF_SCRIPT_RECEIPTS_ROOT
0x008
Memory address of tx.receiptsRoot
GTF_SCRIPT_SCRIPT
0x009
Memory address of tx.script
GTF_SCRIPT_SCRIPT_DATA
0x00A
Memory address of tx.scriptData
GTF_SCRIPT_INPUT_AT_INDEX
0x00B
Memory address of tx.inputs[$rB]
GTF_SCRIPT_OUTPUT_AT_INDEX
0x00C
Memory address of t.outputs[$rB]
GTF_SCRIPT_WITNESS_AT_INDEX
0x00D
Memory address of tx.witnesses[$rB]
GTF_CREATE_BYTECODE_LENGTH
0x100
tx.bytecodeLength
GTF_CREATE_BYTECODE_WITNESS_INDEX
0x101
tx.bytecodeWitnessIndex
GTF_CREATE_STORAGE_SLOTS_COUNT
0x102
tx.storageSlotsCount
GTF_CREATE_INPUTS_COUNT
0x103
tx.inputsCount
GTF_CREATE_OUTPUTS_COUNT
0x104
tx.outputsCount
GTF_CREATE_WITNESSES_COUNT
0x105
tx.witnessesCount
GTF_CREATE_SALT
0x106
Memory address of tx.salt
GTF_CREATE_STORAGE_SLOT_AT_INDEX
0x107
Memory address of tx.storageSlots[$rB]
GTF_CREATE_INPUT_AT_INDEX
0x108
Memory address of tx.inputs[$rB]
GTF_CREATE_OUTPUT_AT_INDEX
0x109
Memory address of t.outputs[$rB]
GTF_CREATE_WITNESS_AT_INDEX
0x10A
Memory address of tx.witnesses[$rB]
GTF_INPUT_TYPE
0x200
tx.inputs[$rB].type
GTF_INPUT_COIN_TX_ID
0x201
Memory address of tx.inputs[$rB].txID
GTF_INPUT_COIN_OUTPUT_INDEX
0x202
tx.inputs[$rB].outputIndex
GTF_INPUT_COIN_OWNER
0x203
Memory address of tx.inputs[$rB].owner
GTF_INPUT_COIN_AMOUNT
0x204
tx.inputs[$rB].amount
GTF_INPUT_COIN_ASSET_ID
0x205
Memory address of tx.inputs[$rB].asset_id
GTF_INPUT_COIN_TX_POINTER
0x206
Memory address of tx.inputs[$rB].txPointer
GTF_INPUT_COIN_WITNESS_INDEX
0x207
tx.inputs[$rB].witnessIndex
GTF_INPUT_COIN_MATURITY
0x208
tx.inputs[$rB].maturity
GTF_INPUT_COIN_PREDICATE_LENGTH
0x209
tx.inputs[$rB].predicateLength
GTF_INPUT_COIN_PREDICATE_DATA_LENGTH
0x20A
tx.inputs[$rB].predicateDataLength
GTF_INPUT_COIN_PREDICATE
0x20B
Memory address of tx.inputs[$rB].predicate
GTF_INPUT_COIN_PREDICATE_DATA
0x20C
Memory address of tx.inputs[$rB].predicateData
GTF_INPUT_COIN_PREDICATE_GAS_USED
0x20D
tx.inputs[$rB].predicateGasUsed
GTF_INPUT_CONTRACT_TX_ID
0x220
Memory address of tx.inputs[$rB].txID
GTF_INPUT_CONTRACT_OUTPUT_INDEX
0x221
tx.inputs[$rB].outputIndex
GTF_INPUT_CONTRACT_BALANCE_ROOT
0x222
Memory address of tx.inputs[$rB].balanceRoot
GTF_INPUT_CONTRACT_STATE_ROOT
0x223
Memory address of tx.inputs[$rB].stateRoot
GTF_INPUT_CONTRACT_TX_POINTER
0x224
Memory address of tx.inputs[$rB].txPointer
GTF_INPUT_CONTRACT_CONTRACT_ID
0x225
Memory address of tx.inputs[$rB].contractID
GTF_INPUT_MESSAGE_SENDER
0x240
Memory address of tx.inputs[$rB].sender
GTF_INPUT_MESSAGE_RECIPIENT
0x241
Memory address of tx.inputs[$rB].recipient
GTF_INPUT_MESSAGE_AMOUNT
0x242
tx.inputs[$rB].amount
GTF_INPUT_MESSAGE_NONCE
0x243
Memory address of tx.inputs[$rB].nonce
GTF_INPUT_MESSAGE_WITNESS_INDEX
0x244
tx.inputs[$rB].witnessIndex
GTF_INPUT_MESSAGE_DATA_LENGTH
0x245
tx.inputs[$rB].dataLength
GTF_INPUT_MESSAGE_PREDICATE_LENGTH
0x246
tx.inputs[$rB].predicateLength
GTF_INPUT_MESSAGE_PREDICATE_DATA_LENGTH
0x247
tx.inputs[$rB].predicateDataLength
GTF_INPUT_MESSAGE_DATA
0x248
Memory address of tx.inputs[$rB].data
GTF_INPUT_MESSAGE_PREDICATE
0x249
Memory address of tx.inputs[$rB].predicate
GTF_INPUT_MESSAGE_PREDICATE_DATA
0x24A
Memory address of tx.inputs[$rB].predicateData
GTF_INPUT_MESSAGE_PREDICATE_GAS_USED
0x24B
tx.inputs[$rB].predicateGasUsed
GTF_OUTPUT_TYPE
0x300
tx.outputs[$rB].type
GTF_OUTPUT_COIN_TO
0x301
Memory address of tx.outputs[$rB].to
GTF_OUTPUT_COIN_AMOUNT
0x302
tx.outputs[$rB].amount
GTF_OUTPUT_COIN_ASSET_ID
0x303
Memory address of tx.outputs[$rB].asset_id
GTF_OUTPUT_CONTRACT_INPUT_INDEX
0x304
tx.outputs[$rB].inputIndex
GTF_OUTPUT_CONTRACT_BALANCE_ROOT
0x305
Memory address of tx.outputs[$rB].balanceRoot
GTF_OUTPUT_CONTRACT_STATE_ROOT
0x306
Memory address of tx.outputs[$rB].stateRoot
GTF_OUTPUT_CONTRACT_CREATED_CONTRACT_ID
0x307
Memory address of tx.outputs[$rB].contractID
GTF_OUTPUT_CONTRACT_CREATED_STATE_ROOT
0x308
Memory address of tx.outputs[$rB].stateRoot
GTF_WITNESS_DATA_LENGTH
0x400
tx.witnesses[$rB].dataLength
GTF_WITNESS_DATA
0x401
Memory address of tx.witnesses[$rB].data
GTF_POLICY_TYPES
0x500
tx.policies.policyTypes
GTF_POLICY_GAS_PRICE
0x501
tx.policies[0x00].gasPrice
GTF_POLICY_WITNESS_LIMIT
0x502
tx.policies[count_ones(0b11 & tx.policyTypes) - 1].witnessLimit
GTF_POLICY_MATURITY
0x503
tx.policies[count_ones(0b111 & tx.policyTypes) - 1].maturity
GTF_POLICY_MAX_FEE
0x504
tx.policies[count_ones(0b1111 & tx.policyTypes) - 1].maxFee
Panic if:
$rA
is a reserved register imm
is not one of the values listed above The value of $rB
results in an out of bounds access for variable-length fields The input or output type does not match (OutputChange
and OutputVariable
count as OutputCoin
) The requested policy type is not set for this transaction.
For fixed-length fields, the value of $rB
is ignored.