⌘K

Icon SunFilledIcon MoonStars
Instruction Set

Icon LinkFuelVM Instruction Set

Icon LinkReading Guide

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.

Icon LinkPanics

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:

nametypedescription
typeReceiptTypeReceiptType.Panic
idbyte[32]Contract ID of current context if in an internal context, zero otherwise.
pcuint64Value of register $pc.
isuint64Value of register $is.

then append an additional receipt to the list of receipts, again modifying tx.receiptsRoot:

nametypedescription
typeReceiptTypeReceiptType.ScriptResult
resultuint641
gas_useduint64Gas consumed by the script.

Icon LinkReceipts

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.

Icon LinkEffects

A few instructions are annotated with the effects they produce, the table below explains each effect:

effect namedescription
Storage readInstruction reads from storage slots
Storage writeInstruction writes to storage slots
External callExternal contract call instruction
Balance tree readInstruction reads from the balance tree
Balance tree writeInstruction writes to the balance tree
Output messageInstruction 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.

Icon LinkArithmetic/Logic (ALU) Instructions

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.

Icon LinkADD: Add

DescriptionAdds two registers.
Operation$rA = $rB + $rC;
Syntaxadd $rA, $rB, $rC
Encoding0x00 rA rB rC -
Notes

Panic if:

$of is assigned the overflow of the operation.

$err is cleared.

Icon LinkADDI: Add immediate

DescriptionAdds a register and an immediate value.
Operation$rA = $rB + imm;
Syntaxaddi $rA, $rB, immediate
Encoding0x00 rA rB i i
Notes

Panic if:

$of is assigned the overflow of the operation.

$err is cleared.

Icon LinkAND: AND

DescriptionBitwise ANDs two registers.
Operation$rA = $rB & $rC;
Syntaxand $rA, $rB, $rC
Encoding0x00 rA rB rC -
Notes

Panic if:

$of and $err are cleared.

Icon LinkANDI: AND immediate

DescriptionBitwise ANDs a register and an immediate value.
Operation$rA = $rB & imm;
Syntaxandi $rA, $rB, imm
Encoding0x00 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.

Icon LinkDIV: Divide

DescriptionDivides two registers.
Operation$rA = $rB // $rC;
Syntaxdiv $rA, $rB, $rC
Encoding0x00 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.

Icon LinkDIVI: Divide immediate

DescriptionDivides a register and an immediate value.
Operation$rA = $rB // imm;
Syntaxdivi $rA, $rB, imm
Encoding0x00 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.

Icon LinkEQ: Equals

DescriptionCompares two registers for equality.
Operation$rA = $rB == $rC;
Syntaxeq $rA, $rB, $rC
Encoding0x00 rA rB rC -
Notes

Panic if:

$of and $err are cleared.

Icon LinkEXP: Exponentiate

DescriptionRaises one register to the power of another.
Operation$rA = $rB ** $rC;
Syntaxexp $rA, $rB, $rC
Encoding0x00 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.

Icon LinkEXPI: Exponentiate immediate

DescriptionRaises one register to the power of an immediate value.
Operation$rA = $rB ** imm;
Syntaxexpi $rA, $rB, imm
Encoding0x00 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.

Icon LinkGT: Greater than

DescriptionCompares two registers for greater-than.
Operation$rA = $rB > $rC;
Syntaxgt $rA, $rB, $rC
Encoding0x00 rA rB rC -
Notes

Panic if:

$of and $err are cleared.

Icon LinkLT: Less than

DescriptionCompares two registers for less-than.
Operation$rA = $rB < $rC;
Syntaxlt $rA, $rB, $rC
Encoding0x00 rA rB rC -
Notes

Panic if:

$of and $err are cleared.

Icon LinkMLOG: Math logarithm

DescriptionThe (integer) logarithm base $rC of $rB.
Operation$rA = math.floor(math.log($rB, $rC));
Syntaxmlog $rA, $rB, $rC
Encoding0x00 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.

Icon LinkMOD: Modulus

DescriptionModulo remainder of two registers.
Operation$rA = $rB % $rC;
Syntaxmod $rA, $rB, $rC
Encoding0x00 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.

Icon LinkMODI: Modulus immediate

DescriptionModulo remainder of a register and an immediate value.
Operation$rA = $rB % imm;
Syntaxmodi $rA, $rB, imm
Encoding0x00 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.

Icon LinkMOVE: Move

DescriptionCopy from one register to another.
Operation$rA = $rB;
Syntaxmove $rA, $rB
Encoding0x00 rA rB - -
Notes

Panic if:

$of and $err are cleared.

Icon LinkMOVI: Move immediate

DescriptionCopy an immediate value into a register.
Operation$rA = imm;
Syntaxmovi $rA, imm
Encoding0x00 rA i i i
Notes

Panic if:

$of and $err are cleared.

Icon LinkMROO: Math root

DescriptionThe (integer) $rCth root of $rB.
Operation$rA = math.floor(math.root($rB, $rC));
Syntaxmroo $rA, $rB, $rC
Encoding0x00 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.

Icon LinkMUL: Multiply

DescriptionMultiplies two registers.
Operation$rA = $rB * $rC;
Syntaxmul $rA, $rB, $rC
Encoding0x00 rA rB rC -
Notes

Panic if:

$of is assigned the overflow of the operation.

$err is cleared.

Icon LinkMULI: Multiply immediate

DescriptionMultiplies a register and an immediate value.
Operation$rA = $rB * imm;
Syntaxmul $rA, $rB, imm
Encoding0x00 rA rB i i
Notes

Panic if:

$of is assigned the overflow of the operation.

$err is cleared.

Icon LinkMLDV: Fused multiply-divide

DescriptionMultiplies two registers with arbitrary precision, then divides by a third register.
Operationa = (b * c) / d;
Syntaxmldv $rA, $rB, $rC, $rD
Encoding0x00 rA rB rC rD
NotesDivision 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.

Icon LinkNOOP: No operation

DescriptionPerforms no operation.
Operation
Syntaxnoop
Encoding0x00 - - - -
Notes

$of and $err are cleared.

Icon LinkNOT: Invert

DescriptionBitwise NOT a register.
Operation$rA = ~$rB;
Syntaxnot $rA, $rB
Encoding0x00 rA rB - -
Notes

Panic if:

$of and $err are cleared.

Icon LinkOR: OR

DescriptionBitwise ORs two registers.
Operation$rA = $rB | $rC;
Syntaxor $rA, $rB, $rC
Encoding0x00 rA rB rC -
Notes

Panic if:

$of and $err are cleared.

Icon LinkORI: OR immediate

DescriptionBitwise ORs a register and an immediate value.
Operation$rA = $rB | imm;
Syntaxori $rA, $rB, imm
Encoding0x00 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.

Icon LinkSLL: Shift left logical

DescriptionLeft shifts a register by a register.
Operation$rA = $rB << $rC;
Syntaxsll $rA, $rB, $rC
Encoding0x00 rA rB rC -
NotesZeroes are shifted in.

Panic if:

$of and $err are cleared.

Icon LinkSLLI: Shift left logical immediate

DescriptionLeft shifts a register by an immediate value.
Operation$rA = $rB << imm;
Syntaxslli $rA, $rB, imm
Encoding0x00 rA rB i i
NotesZeroes are shifted in.

Panic if:

$of and $err are cleared.

Icon LinkSRL: Shift right logical

DescriptionRight shifts a register by a register.
Operation$rA = $rB >> $rC;
Syntaxsrl $rA, $rB, $rC
Encoding0x00 rA rB rC -
NotesZeroes are shifted in.

Panic if:

$of and $err are cleared.

Icon LinkSRLI: Shift right logical immediate

DescriptionRight shifts a register by an immediate value.
Operation$rA = $rB >> imm;
Syntaxsrli $rA, $rB, imm
Encoding0x00 rA rB i i
NotesZeroes are shifted in.

Panic if:

$of and $err are cleared.

Icon LinkSUB: Subtract

DescriptionSubtracts two registers.
Operation$rA = $rB - $rC;
Syntaxsub $rA, $rB, $rC
Encoding0x00 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.

Icon LinkSUBI: Subtract immediate

DescriptionSubtracts a register and an immediate value.
Operation$rA = $rB - imm;
Syntaxsubi $rA, $rB, imm
Encoding0x00 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.

Icon LinkWDCM: 128-bit integer comparison

DescriptionCompare or examine two 128-bit integers using selected mode
Operationb = mem[$rB,16];c = indirect?mem[$rC,16]:$rC;$rA = cmp_op(b,c);
Syntaxwdcm $rA, $rB, $rC, imm
Encoding0x00 rA rB rC i
Notes

The six-bit immediate value is used to select operating mode, as follows:

BitsShort nameDescription
...XXXmodeCompare mode selection
.XX...reservedReserved and must be zero
X.....indirectIs rhs operand ($rC) indirect or not

Then the actual operation that's performed:

modeNameDescription
0eqEquality (==)
1neInequality (!=)
2ltLess than (<)
3gtGreater than (>)
4lteLess than or equals (<=)
5gteGreater than or equals (>=)
6lzcLeading 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

Icon LinkWQCM: 256-bit integer comparison

DescriptionCompare or examine two 256-bit integers using selected mode
Operationb = mem[$rB,32];c = indirect?mem[$rC,32]:$rC;$rA = cmp_op(b,c);
Syntaxwqcm $rA, $rB, $rC, imm
Encoding0x00 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

Icon LinkWDOP: Misc 128-bit integer operations

DescriptionPerform an ALU operation on two 128-bit integers
Operationb = mem[$rB,16];c = indirect?mem[$rC,16]:$rC;mem[$rA,16] = op(b,c);
Syntaxwdop $rA, $rB, $rC, imm
Encoding0x00 rA rB rC i
Notes

The six-bit immediate value is used to select operating mode, as follows:

BitsShort nameDescription
...XXXopOperation selection, see below
.XX...reservedReserved and must be zero
X.....indirectIs rhs operand ($rC) indirect or not

Then the actual operation that's performed:

opNameDescription
0addAdd
1subSubtract
2notInvert bits (discards rhs)
3orBitwise or
4xorBitwise exclusive or
5andBitwise and
6shlShift left (logical)
7shrShift 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

Icon LinkWQOP: Misc 256-bit integer operations

DescriptionPerform an ALU operation on two 256-bit integers
Operationb = mem[$rB,32];c = indirect?mem[$rC,32]:$rC;mem[$rA,32] = op(b,c);
Syntaxwqop $rA, $rB, $rC, imm
Encoding0x00 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

Icon LinkWDML: Multiply 128-bit integers

DescriptionPerform integer multiplication operation on two 128-bit integers.
Operationb=indirect0?mem[$rB,16]:$rB;c=indirect1?mem[$rC,16]:$rC;mem[$rA,16]=b*c;
Syntaxwdml $rA, $rB, $rC, imm
Encoding0x00 rA rB rC i
Notes

The six-bit immediate value is used to select operating mode, as follows:

BitsShort nameDescription
..XXXXreservedReserved and must be zero
.X....indirect0Is lhs operand ($rB) indirect or not
X.....indirect1Is 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

Icon LinkWQML: Multiply 256-bit integers

DescriptionPerform integer multiplication operation on two 256-bit integers.
Operationb=indirect0?mem[$rB,32]:$rB;c=indirect1?mem[$rC,32]:$rC;mem[$rA,32]=b*c;
Syntaxwqml $rA, $rB, $rC, imm
Encoding0x00 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

Icon LinkWDDV: 128-bit integer division

DescriptionDivide a 128-bit integer by another.
Operationb = mem[$rB,16];c = indirect?mem[$rC,16]:$rC;mem[$rA,16] = b / c;
Syntaxwddv $rA, $rB, $rC, imm
Encoding0x00 rA rB rC i
Notes

The six-bit immediate value is used to select operating mode, as follows:

BitsShort nameDescription
.XXXXXreservedReserved and must be zero
X.....indirectIs 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

Icon LinkWQDV: 256-bit integer division

DescriptionDivide a 256-bit integer by another.
Operationb = mem[$rB,32];c = indirect?mem[$rC,32]:$rC;mem[$rA,32] = b / c;
Syntaxwqdv $rA, $rB, $rC, imm
Encoding0x00 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

Icon LinkWDMD: 128-bit integer fused multiply-divide

DescriptionCombined multiply-divide of 128-bit integers with arbitrary precision.
Operationb=mem[$rB,16];c=mem[$rC,16];d=mem[$rD,16];mem[$rA,16]=(b * c) / d;
Syntaxwddv $rA, $rB, $rC, $rD
Encoding0x00 rA rB rC rD
NotesDivision 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

Icon LinkWQMD: 256-bit integer fused multiply-divide

DescriptionCombined multiply-divide of 256-bit integers with arbitrary precision.
Operationb=mem[$rB,32];c=mem[$rC,32];d=mem[$rD,32];mem[$rA,32]=(b * c) / d;
Syntaxwqdv $rA, $rB, $rC, $rD
Encoding0x00 rA rB rC rD
NotesDivision 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

Icon LinkWDAM: Modular 128-bit integer addition

DescriptionAdd two 128-bit integers and compute modulo remainder with arbitrary precision.
Operationb=mem[$rB,16];c=mem[$rC,16];d=mem[$rD,16];mem[$rA,16] = (b+c)%d;
Syntaxwdam $rA, $rB, $rC, $rD
Encoding0x00 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

Icon LinkWQAM: Modular 256-bit integer addition

DescriptionAdd two 256-bit integers and compute modulo remainder with arbitrary precision.
Operationb=mem[$rB,32];c=mem[$rC,32];d=mem[$rD,32];mem[$rA,32] = (b+c)%d;
Syntaxwdam $rA, $rB, $rC, $rD
Encoding0x00 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

Icon LinkWDMM: Modular 128-bit integer multiplication

DescriptionMultiply two 128-bit integers and compute modulo remainder with arbitrary precision.
Operationb=mem[$rB,16];c=mem[$rC,16];d=mem[$rD,16];mem[$rA,16] = (b*c)%d;
Syntaxwdmm $rA, $rB, $rC, $rD
Encoding0x00 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

Icon LinkWQMM: Modular 256-bit integer multiplication

DescriptionMultiply two 256-bit integers and compute modulo remainder with arbitrary precision.
Operationb=mem[$rB,32];c=mem[$rC,32];d=mem[$rD,32];mem[$rA,32] = (b*c)%d;
Syntaxwqmm $rA, $rB, $rC, $rD
Encoding0x00 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

Icon LinkXOR: XOR

DescriptionBitwise XORs two registers.
Operation$rA = $rB ^ $rC;
Syntaxxor $rA, $rB, $rC
Encoding0x00 rA rB rC -
Notes

Panic if:

$of and $err are cleared.

Icon LinkXORI: XOR immediate

DescriptionBitwise XORs a register and an immediate value.
Operation$rA = $rB ^ imm;
Syntaxxori $rA, $rB, imm
Encoding0x00 rA rB i i
Notes

Panic if:

$of and $err are cleared.

Icon LinkControl Flow Instructions

Icon LinkJMP: Jump

DescriptionJumps to the code instruction offset by a register.
Operation$pc = $is + $rA * 4;
Syntaxjmp $rA
Encoding0x00 rA - - -
Notes

Panic if:

  • $is + $rA * 4 > VM_MAX_RAM - 1

Icon LinkJI: Jump immediate

DescriptionJumps to the code instruction offset by imm.
Operation$pc = $is + imm * 4;
Syntaxji imm
Encoding0x00 i i i i
Notes

Panic if:

  • $is + imm * 4 > VM_MAX_RAM - 1

Icon LinkJNE: Jump if not equal

DescriptionJump to the code instruction offset by a register if $rA is not equal to $rB.
Operationif $rA != $rB:$pc = $is + $rC * 4;else:$pc += 4;
Syntaxjne $rA $rB $rC
Encoding0x00 rA rB rC -
Notes

Panic if:

  • $is + $rC * 4 > VM_MAX_RAM - 1 and the jump would be performed (i.e. $rA != $rB)

Icon LinkJNEI: Jump if not equal immediate

DescriptionJump to the code instruction offset by imm if $rA is not equal to $rB.
Operationif $rA != $rB:$pc = $is + imm * 4;else:$pc += 4;
Syntaxjnei $rA $rB imm
Encoding0x00 rA rB i i
Notes

Panic if:

  • $is + imm * 4 > VM_MAX_RAM - 1 and the jump would be performed (i.e. $rA != $rB)

Icon LinkJNZI: Jump if not zero immediate

DescriptionJump to the code instruction offset by imm if $rA is not equal to $zero.
Operationif $rA != $zero:$pc = $is + imm * 4;else:$pc += 4;
Syntaxjnzi $rA imm
Encoding0x00 rA i i i
Notes

Panic if:

  • $is + imm * 4 > VM_MAX_RAM - 1and the jump would be performed (i.e. $rA != $zero)

Icon LinkJMPB: Jump relative backwards

DescriptionJump $rA + imm instructions backwards.
Operation$pc -= ($rA + imm + 1) * 4;
Syntaxjmpb $rA imm
Encoding0x00 rA i i i
Notes

Panic if:

  • $pc - ($rA + imm + 1) * 4 < 0

Icon LinkJMPF: Jump relative forwards

DescriptionJump $rA + imm instructions forwards
Operation$pc += ($rA + imm + 1) * 4;
Syntaxjmpf $rA imm
Encoding0x00 rA i i i
Notes

Panic if:

  • $pc + ($rA + imm + 1) * 4 > VM_MAX_RAM - 1

Icon LinkJNZB: Jump if not zero relative backwards

DescriptionJump $rB + imm instructions backwards if $rA != $zero.
Operationif $rA != $zero:$pc -= ($rB + imm + 1) * 4;else:$pc += 4;
Syntaxjnzb $rA $rB imm
Encoding0x00 rA rB i i
Notes

Panic if:

  • $pc - ($rB + imm + 1) * 4 < 0

Icon LinkJNZF: Jump if not zero relative forwards

DescriptionJump $rB + imm instructions forwards if $rA != $zero.
Operationif $rA != $zero:$pc += ($rB + imm + 1) * 4;else:$pc += 4;
Syntaxjnzf $rA $rB imm
Encoding0x00 rA rB i i
Notes

Panic if:

  • $pc + ($rB + imm + 1) * 4 > VM_MAX_RAM - 1

Icon LinkJNEB: Jump if not equal relative backwards

DescriptionJump $rC + imm instructions backwards if $rA != $rB.
Operationif $rA != $rB:$pc -= ($rC + imm + 1) * 4;else:$pc += 4;
Syntaxjneb $rA $rB $rC imm
Encoding0x00 rA rB rC i
Notes

Panic if:

  • $pc - ($rC + imm + 1) * 4 < 0

Icon LinkJNEF: Jump if not equal relative forwards

DescriptionJump $rC + imm instructions forwards if $rA != $rB.
Operationif $rA != $rB:$pc += ($rC + imm + 1) * 4;else:$pc += 4;
Syntaxjnef $rA $rB $rC imm
Encoding0x00 rA rB rC i
Notes

Panic if:

  • $pc + ($rC + imm + 1) * 4 > VM_MAX_RAM - 1

Icon LinkRET: Return from context

DescriptionReturns from context with value $rA.
Operationreturn($rA);
Syntaxret $rA
Encoding0x00 rA - - -
Notes

Append a receipt to the list of receipts, modifying tx.receiptsRoot:

nametypedescription
typeReceiptTypeReceiptType.Return
idbyte[32]Contract ID of current context if in an internal context, zero otherwise.
valuint64Value of register $rA.
pcuint64Value of register $pc.
isuint64Value of register $is.

If current context is external, append an additional receipt to the list of receipts, modifying tx.receiptsRoot:

nametypedescription
typeReceiptTypeReceiptType.ScriptResult
resultuint640
gas_useduint64Gas 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:

  1. $cgas = $cgas + $fp->$cgas (add remaining context gas from previous context to current remaining context gas)

Set the return value:

  1. $ret = $rA
  2. $retl = 0

Then pop the call frame and restore all registers except $ggas, $cgas, $ret, $retl and $hp. Afterwards, set the following registers:

  1. $pc = $pc + 4 (advance program counter from where we called)

Icon LinkMemory Instructions

All these instructions advance the program counter $pc by 4 after performing their operation.

Icon LinkALOC: Allocate memory

DescriptionAllocate a number of bytes from the heap.
Operation$hp = $hp - $rA;
Syntaxaloc $rA
Encoding0x00 rA - - -
NotesDoes not initialize memory.

Panic if:

  • $hp - $rA underflows
  • $hp - $rA < $sp

Icon LinkCFE: Extend call frame

DescriptionExtend the current call frame's stack.
Operation$sp = $sp + $rA
Syntaxcfei $rA
Encoding0x00 rA - - -
NotesDoes not initialize memory.

Panic if:

  • $sp + $rA overflows
  • $sp + $rA > $hp

Icon LinkCFEI: Extend call frame immediate

DescriptionExtend the current call frame's stack by an immediate value.
Operation$sp = $sp + imm
Syntaxcfei imm
Encoding0x00 i i i i
NotesDoes not initialize memory.

Panic if:

  • $sp + imm overflows
  • $sp + imm > $hp

Icon LinkCFS: Shrink call frame

DescriptionShrink the current call frame's stack.
Operation$sp = $sp - $rA
Syntaxcfs $rA
Encoding0x00 $rA - - -
NotesDoes not clear memory.

Panic if:

  • $sp - $rA underflows
  • $sp - $rA < $ssp

Icon LinkCFSI: Shrink call frame immediate

DescriptionShrink the current call frame's stack by an immediate value.
Operation$sp = $sp - imm
Syntaxcfsi imm
Encoding0x00 i i i i
NotesDoes not clear memory.

Panic if:

  • $sp - imm underflows
  • $sp - imm < $ssp

Icon LinkLB: Load byte

DescriptionA byte is loaded from the specified address offset by imm.
Operation$rA = MEM[$rB + imm, 1];
Syntaxlb $rA, $rB, imm
Encoding0x00 rA rB i i
Notes

Panic if:

Icon LinkLW: Load word

DescriptionA word is loaded from the specified address offset by imm.
Operation$rA = MEM[$rB + (imm * 8), 8];
Syntaxlw $rA, $rB, imm
Encoding0x00 rA rB i i
Notes

Panic if:

  • $rA is a reserved register
  • $rB + (imm * 8) + 8 overflows
  • $rB + (imm * 8) + 8 > VM_MAX_RAM

Icon LinkMCL: Memory clear

DescriptionClear bytes in memory.
OperationMEM[$rA, $rB] = 0;
Syntaxmcl $rA, $rB
Encoding0x00 rA rB - -
Notes

Panic if:

  • $rA + $rB overflows
  • $rA + $rB > VM_MAX_RAM
  • The memory range MEM[$rA, $rB] does not pass ownership check

Icon LinkMCLI: Memory clear immediate

DescriptionClear bytes in memory.
OperationMEM[$rA, imm] = 0;
Syntaxmcli $rA, imm
Encoding0x00 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

Icon LinkMCP: Memory copy

DescriptionCopy bytes in memory.
OperationMEM[$rA, $rC] = MEM[$rB, $rC];
Syntaxmcp $rA, $rB, $rC
Encoding0x00 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

Icon LinkMCPI: Memory copy immediate

DescriptionCopy bytes in memory.
OperationMEM[$rA, imm] = MEM[$rB, imm];
Syntaxmcpi $rA, $rB, imm
Encoding0x00 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

Icon LinkMEQ: Memory equality

DescriptionCompare bytes in memory.
Operation$rA = MEM[$rB, $rD] == MEM[$rC, $rD];
Syntaxmeq $rA, $rB, $rC, $rD
Encoding0x00 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

Icon LinkPSHH: Push a set of high registers to stack

DescriptionPush a set of registers from range 40..64 to the stack in order.
Operationtmp=$sp;$sp+=popcnt(imm)*8;MEM[tmp,$sp]=registers[40..64].mask(imm)
Syntaxpshh imm
Encoding0x00 i i i i
NotesThe immediate value is used as a bitmask for selecting the registers.

Panic if:

  • $sp + popcnt(imm)*8 overflows
  • $sp + popcnt(imm)*8 > $hp

Icon LinkPSHL: Push a set of low registers to stack

DescriptionPush a set of registers from range 16..40 to the stack in order.
Operationtmp=$sp;$sp+=popcnt(imm)*8;MEM[tmp,$sp]=registers[16..40].mask(imm)
Syntaxpshl imm
Encoding0x00 i i i i
NotesThe immediate value is used as a bitmask for selecting the registers.

Panic if:

  • $sp + popcnt(imm)*8 overflows
  • $sp + popcnt(imm)*8 > $hp

Icon LinkPOPH: Pop a set of high registers from stack

DescriptionPop to a set of registers from range 40..64 from the stack.
Operationtmp=$sp-popcnt(imm)*8;registers[40..64].mask(imm)=MEM[tmp,$sp]$sp-=tmp;
Syntaxpoph imm
Encoding0x00 i i i i
NotesThe immediate value is used as a bitmask for selecting the registers.

Panic if:

  • $sp - popcnt(imm)*8 overflows
  • $sp - popcnt(imm)*8 < $ssp

Icon LinkPOPL: Pop a set of low registers from stack

DescriptionPop to a set of registers from range 16..40 from the stack.
Operationtmp=$sp-popcnt(imm)*8;registers[16..40].mask(imm)=MEM[tmp,$sp]$sp-=tmp;
Syntaxpoph imm
Encoding0x00 i i i i
NotesThe immediate value is used as a bitmask for selecting the registers.

Panic if:

  • $sp - popcnt(imm)*8 overflows
  • $sp - popcnt(imm)*8 < $ssp

Icon LinkSB: Store byte

DescriptionThe least significant byte of $rB is stored at the address $rA offset by imm.
OperationMEM[$rA + imm, 1] = $rB[7, 1];
Syntaxsb $rA, $rB, imm
Encoding0x00 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

Icon LinkSW: Store word

DescriptionThe value of $rB is stored at the address $rA offset by imm.
OperationMEM[$rA + (imm * 8), 8] = $rB;
Syntaxsw $rA, $rB, imm
Encoding0x00 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

Icon LinkContract Instructions

All these instructions advance the program counter $pc by 4 after performing their operation, except for CALL , RETD and RVRT .

Icon LinkBAL: Balance of contract ID

DescriptionSet $rA to the balance of asset ID at $rB for contract with ID at $rC.
Operation$rA = balance(MEM[$rB, 32], MEM[$rC, 32]);
Syntaxbal $rA, $rB, $rC
Encoding0x00 rA rB rC -
EffectsBalance 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

Icon LinkBHEI: Block height

DescriptionGet Fuel block height.
Operation$rA = blockheight();
Syntaxbhei $rA
Encoding0x00 rA - - -
Notes

Panic if:

Icon LinkBHSH: Block hash

DescriptionGet block header hash.
OperationMEM[$rA, 32] = blockhash($rB);
Syntaxbhsh $rA $rB
Encoding0x00 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).

Icon LinkBURN: Burn existing coins

DescriptionBurn $rA coins of the $rB ID from the current contract.
Operationburn($rA, $rB);
Syntaxburn $rA $rB
Encoding0x00 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:

nametypedescription
typeReceiptTypeReceiptType.Burn
sub_idbyte[32]Asset sub identifier MEM[$rB, $rB + 32].
contract_idbyte[32]Contract ID of the current context.
valuint64Value of register $rA.
pcuint64Value of register $pc.
isuint64Value of register $is.

Icon LinkCALL: Call contract

DescriptionCall contract.
Operation
Syntaxcall $rA $rB $rC $rD
Encoding0x00 rA rB rC rD
EffectsExternal 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):

bytestypevaluedescription
32byte[32]toContract ID to call.
8byte[8]param1First parameter.
8byte[8]param2Second 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:

nametypedescription
typeReceiptTypeReceiptType.Call
frombyte[32]Contract ID of current context if in an internal context, zero otherwise.
tobyte[32]Contract ID of called contract.
amountuint64Amount of coins to forward, i.e. $rB.
asset_idbyte[32]Asset ID of coins to forward, i.e. MEM[$rC, 32].
gasuint64Gas to forward, i.e. min($rD, $cgas).
param1uint64First parameter.
param2uint64Second parameter.
pcuint64Value of register $pc.
isuint64Value 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:

  1. $fp = $sp (on top of the previous call frame is the beginning of this call frame)
  2. Set $ssp and $sp to the start of the writable stack area of the call frame.
  3. Set $pc and $is to the starting address of the code.
  4. $bal = $rB (forward coins)
  5. $cgas = $rD or all available gas (forward gas)

This modifies the balanceRoot field of the appropriate output(s).

Icon LinkCB: Coinbase contract id

DescriptionGet the coinbase contract id associated with the block proposer.
OperationMEM[$rA, 32] = coinbase();
Syntaxcb $rA
Encoding0x00 rA - - -
Notes

Panic if:

  • $rA + 32 overflows
  • $rA + 32 > VM_MAX_RAM
  • The memory range MEM[$rA, 32] does not pass ownership check

Icon LinkCCP: Code copy

DescriptionCopy $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.
OperationMEM[$rA, $rD] = code($rB, $rC, $rD);
Syntaxccp $rA, $rB, $rC, $rD
Encoding0x00 rA rB rC rD
NotesIf $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

Icon LinkCROO: Code Merkle root

DescriptionSet 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.
OperationMEM[$rA, 32] = coderoot(MEM[$rB, 32]);
Syntaxcroo $rA, $rB
Encoding0x00 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 .

Icon LinkCSIZ: Code size

DescriptionSet $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]);
Syntaxcsiz $rA, $rB
Encoding0x00 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

Icon LinkLDC: Load code from an external contract

DescriptionCopy $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.
OperationMEM[$ssp, $rC] = code($rA, $rB, $rC);
Syntaxldc $rA, $rB, $rC
Encoding0x00 rA rB rC -
NotesIf $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).

Icon LinkLOG: Log event

DescriptionLog an event. This is a no-op.
Operationlog($rA, $rB, $rC, $rD);
Syntaxlog $rA, $rB, $rC, $rD
Encoding0x00 rA rB rC rD
Notes

Append a receipt to the list of receipts, modifying tx.receiptsRoot:

nametypedescription
typeReceiptTypeReceiptType.Log
idbyte[32]Contract ID of current context if in an internal context, zero otherwise.
val0uint64Value of register $rA.
val1uint64Value of register $rB.
val2uint64Value of register $rC.
val3uint64Value of register $rD.
pcuint64Value of register $pc.
isuint64Value of register $is.

Icon LinkLOGD: Log data event

DescriptionLog an event. This is a no-op.
Operationlogd($rA, $rB, $rC, $rD);
Syntaxlogd $rA, $rB, $rC, $rD
Encoding0x00 rA rB rC rD
Notes

Append a receipt to the list of receipts, modifying tx.receiptsRoot:

nametypedescription
typeReceiptTypeReceiptType.LogData
idbyte[32]Contract ID of current context if in an internal context, zero otherwise.
val0uint64Value of register $rA.
val1uint64Value of register $rB.
ptruint64Value of register $rC.
lenuint64Value of register $rD.
digestbyte[32]Hash of MEM[$rC, $rD].
pcuint64Value of register $pc.
isuint64Value of register $is.

Logs the memory range MEM[$rC, $rD].

Panics if:

  • $rC + $rD overflows
  • $rA + $rD > VM_MAX_RAM

Icon LinkMINT: Mint new coins

DescriptionMint $rA coins of the $rB ID from the current contract.
Operationmint($rA, $rB);
Syntaxmint $rA $rB
Encoding0x00 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:

nametypedescription
typeReceiptTypeReceiptType.Mint
sub_idbyte[32]Asset sub identifier MEM[$rB, $rB + 32].
contract_idbyte[32]Contract ID of the current context.
valuint64Value of register $rA.
pcuint64Value of register $pc.
isuint64Value of register $is.

Icon LinkRETD: Return from context with data

DescriptionReturns from context with value MEM[$rA, $rB].
Operationreturndata($rA, $rB);
Syntaxretd $rA, $rB
Encoding0x00 rA rB - -
Notes

Panic if:

  • $rA + $rB overflows
  • $rA + $rB > VM_MAX_RAM

Append a receipt to the list of receipts, modifying tx.receiptsRoot:

nametypedescription
typeReceiptTypeReceiptType.ReturnData
idbyte[32]Contract ID of current context if in an internal context, zero otherwise.
ptruint64Value of register $rA.
lenuint64Value of register $rB.
digestbyte[32]Hash of MEM[$rA, $rB].
pcuint64Value of register $pc.
isuint64Value of register $is.

If current context is a script, append an additional receipt to the list of receipts, modifying tx.receiptsRoot:

nametypedescription
typeReceiptTypeReceiptType.ScriptResult
resultuint640
gas_useduint64Gas 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:

  1. $cgas = $cgas + $fp->$cgas (add remaining context gas from previous context to current remaining context gas)

Set the return value:

  1. $ret = $rA
  2. $retl = $rB

Then pop the call frame and restore all registers except $ggas, $cgas, $ret, $retl and $hp. Afterwards, set the following registers:

  1. $pc = $pc + 4 (advance program counter from where we called)

Icon LinkRVRT: Revert

DescriptionHalt execution, reverting state changes and returning value in $rA.
Operationrevert($rA);
Syntaxrvrt $rA
Encoding0x00 rA - - -
Notes

Append a receipt to the list of receipts, modifying tx.receiptsRoot:

nametypedescription
typeReceiptTypeReceiptType.Revert
idbyte[32]Contract ID of current context if in an internal context, zero otherwise.
valuint64Value of register $rA.
pcuint64Value of register $pc.
isuint64Value of register $is.

Then append an additional receipt to the list of receipts, modifying tx.receiptsRoot:

nametypedescription
typeReceiptTypeReceiptType.ScriptResult
resultuint641
gas_useduint64Gas consumed by the script.

Cease VM execution and revert script effects. After a revert:

  1. All OutputContract outputs will have the same balanceRoot and stateRoot as on initialization.
  2. All OutputVariable outputs will have to, amount, and asset_id of zero.

Icon LinkSMO: Send message out

DescriptionSend 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.
Operationoutputmessage(MEM[$fp, 32], MEM[$rA, 32], MEM[$rB, $rC], $rD);
Syntaxsmo $rA, $rB, $rC, $rD
Encoding0x00 rA rB rC rD
EffectsOutput 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:

nametypedescription
typeReceiptTypeReceiptType.MessageOut
senderbyte[32]The address of the message sender: MEM[$fp, 32].
recipientbyte[32]The address of the message recipient: MEM[$rA, 32].
amountuint64Amount of base asset coins sent with message: $rD.
noncebyte[32]The message nonce as described here .
lenuint16Length of message data, in bytes: $rC.
digestbyte[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.

Icon LinkSCWQ: State clear sequential 32 byte slots

DescriptionA sequential series of 32 bytes is cleared from the current contract's state.
OperationSTATE[MEM[$rA, 32], 32 * $rC] = None;
Syntaxscwq $rA, $rB, $rC
Encoding0x00 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.

Icon LinkSRW: State read word

DescriptionA word is read from the current contract's state.
Operation$rA = STATE[MEM[$rC, 32]][0, 8];
Syntaxsrw $rA, $rB, $rC
Encoding0x00 rA rB rC -
EffectsStorage read
NotesReturns 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.

Icon LinkSRWQ: State read sequential 32 byte slots

DescriptionA sequential series of 32 bytes is read from the current contract's state.
OperationMEM[$rA, 32 * rD] = STATE[MEM[$rC, 32], 32 * rD];
Syntaxsrwq $rA, $rB, $rC, $rD
Encoding0x00 rA rB rC rD
EffectsStorage read
NotesReturns 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.

Icon LinkSWW: State write word

DescriptionA word is written to the current contract's state.
OperationSTATE[MEM[$rA, 32]][0, 8] = $rC;STATE[MEM[$rA, 32]][8, 24] = 0;
Syntaxsww $rA $rB $rC
Encoding0x00 rA rB rC -
EffectsStorage write
NotesAdditional 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.

Icon LinkSWWQ: State write sequential 32 byte slots

DescriptionA sequential series of 32 bytes is written to the current contract's state.
OperationSTATE[MEM[$rA, 32], 32 * $rD] = MEM[$rC, 32 * $rD];
Syntaxswwq $rA, $rB, $rC, $rD
Encoding0x00 rA rB rC rD
EffectsStorage write
NotesAdditional 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.

Icon LinkTIME: Timestamp at height

DescriptionGet timestamp of block at given height.
Operation$rA = time($rB);
Syntaxtime $rA, $rB
Encoding0x00 rA rB - -
Notes

Panic if:

Gets the timestamp of the block at height $rB. Time is in TAI64 Icon Link format.

Icon LinkTR: Transfer coins to contract

DescriptionTransfer $rB coins with asset ID at $rC to contract with ID at $rA.
Operationtransfer(MEM[$rA, 32], $rB, MEM[$rC, 32]);
Syntaxtr $rA, $rB, $rC
Encoding0x00 rA rB rC -
EffectsBalance 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:

nametypedescription
typeReceiptTypeReceiptType.Transfer
frombyte[32]Contract ID of current context if in an internal context, zero otherwise.
tobyte[32]Contract ID of contract to transfer coins to.
amountuint64Amount of coins transferred.
asset_idbyte[32]asset ID of coins transferred.
pcuint64Value of register $pc.
isuint64Value 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).

Icon LinkTRO: Transfer coins to output

DescriptionTransfer $rC coins with asset ID at $rD to address at $rA, with output $rB.
Operationtransferout(MEM[$rA, 32], $rB, $rC, MEM[$rD, 32]);
Syntaxtro $rA, $rB, $rC, $rD
Encoding0x00 rA rB rC rD
EffectsBalance 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:

nametypedescription
typeReceiptTypeReceiptType.TransferOut
frombyte[32]Contract ID of current context if in an internal context, zero otherwise.
tobyte[32]Address to transfer coins to.
amountuint64Amount of coins transferred.
asset_idbyte[32]asset ID of coins transferred.
pcuint64Value of register $pc.
isuint64Value 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).

Icon LinkCryptographic Instructions

All these instructions advance the program counter $pc by 4 after performing their operation.

Icon LinkECK1: Secp256k1 signature recovery

DescriptionThe 64-byte public key (x, y) recovered from 64-byte signature starting at $rB on 32-byte message hash starting at $rC.
OperationMEM[$rA, 64] = ecrecover_k1(MEM[$rB, 64], MEM[$rC, 32]);
Syntaxeck1 $rA, $rB, $rC
Encoding0x00 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 .

Icon LinkECR1: Secp256r1 signature recovery

DescriptionThe 64-byte public key (x, y) recovered from 64-byte signature starting at $rB on 32-byte message hash starting at $rC.
OperationMEM[$rA, 64] = ecrecover_r1(MEM[$rB, 64], MEM[$rC, 32]);
Syntaxecr1 $rA, $rB, $rC
Encoding0x00 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 .

Icon LinkED19: EdDSA curve25519 verification

DescriptionVerification recovered from 32-byte public key starting at $rA and 64-byte signature starting at $rB on 32-byte message hash starting at $rC.
Operationed19verify(MEM[$rA, 32], MEM[$rB, 64], MEM[$rC, 32]);
Syntaxed19 $rA, $rB, $rC
Encoding0x00 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.

Icon LinkK256: keccak-256

DescriptionThe keccak-256 hash of $rC bytes starting at $rB.
OperationMEM[$rA, 32] = keccak256(MEM[$rB, $rC]);
Syntaxk256 $rA, $rB, $rC
Encoding0x00 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

Icon LinkS256: SHA-2-256

DescriptionThe SHA-2-256 hash of $rC bytes starting at $rB.
OperationMEM[$rA, 32] = sha256(MEM[$rB, $rC]);
Syntaxs256 $rA, $rB, $rC
Encoding0x00 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

Icon LinkOther Instructions

All these instructions advance the program counter $pc by 4 after performing their operation.

Icon LinkECAL: Call external function

DescriptionCall an external function that has full access to the VM state.
Operationexternal(&mut vm, $rA, $rB, $rC, $rD)
Syntaxecal $rA $rB $rC $rD
Encoding0x00 rA rB rC rD
NotesDoes 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.

Icon LinkFLAG: Set flags

DescriptionSet $flag to $rA.
Operation$flag = $rA;
Syntaxflag $rA
Encoding0x00 rA - - -
Notes

Panic if:

  • Any reserved flags are set

Icon LinkGM: Get metadata

DescriptionGet metadata from memory.
OperationVaries (see below).
Syntaxgm $rA, imm
Encoding0x00 rA imm imm imm
Notes

Read metadata from memory. A convenience instruction to avoid manually extracting metadata.

namevaluedescription
GM_IS_CALLER_EXTERNAL0x00001Get if caller is external.
GM_GET_CALLER0x00002Get caller's contract ID.
GM_GET_VERIFYING_PREDICATE0x00003Get index of current predicate.
GM_GET_CHAIN_ID0x00004Get 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.

Icon LinkGTF: Get transaction fields

DescriptionGet transaction fields.
OperationVaries (see below).
Syntaxgtf $rA, $rB, imm
Encoding0x00 rA rB i i
Notes

Get fields from the transaction .

nameimmset $rA to
GTF_TYPE0x001tx.type
GTF_SCRIPT_GAS_LIMIT0x002tx.scriptGasLimit
GTF_SCRIPT_SCRIPT_LENGTH0x003tx.scriptLength
GTF_SCRIPT_SCRIPT_DATA_LENGTH0x004tx.scriptDataLength
GTF_SCRIPT_INPUTS_COUNT0x005tx.inputsCount
GTF_SCRIPT_OUTPUTS_COUNT0x006tx.outputsCount
GTF_SCRIPT_WITNESSES_COUNT0x007tx.witnessesCount
GTF_SCRIPT_RECEIPTS_ROOT0x008Memory address of tx.receiptsRoot
GTF_SCRIPT_SCRIPT0x009Memory address of tx.script
GTF_SCRIPT_SCRIPT_DATA0x00AMemory address of tx.scriptData
GTF_SCRIPT_INPUT_AT_INDEX0x00BMemory address of tx.inputs[$rB]
GTF_SCRIPT_OUTPUT_AT_INDEX0x00CMemory address of t.outputs[$rB]
GTF_SCRIPT_WITNESS_AT_INDEX0x00DMemory address of tx.witnesses[$rB]
GTF_CREATE_BYTECODE_LENGTH0x100tx.bytecodeLength
GTF_CREATE_BYTECODE_WITNESS_INDEX0x101tx.bytecodeWitnessIndex
GTF_CREATE_STORAGE_SLOTS_COUNT0x102tx.storageSlotsCount
GTF_CREATE_INPUTS_COUNT0x103tx.inputsCount
GTF_CREATE_OUTPUTS_COUNT0x104tx.outputsCount
GTF_CREATE_WITNESSES_COUNT0x105tx.witnessesCount
GTF_CREATE_SALT0x106Memory address of tx.salt
GTF_CREATE_STORAGE_SLOT_AT_INDEX0x107Memory address of tx.storageSlots[$rB]
GTF_CREATE_INPUT_AT_INDEX0x108Memory address of tx.inputs[$rB]
GTF_CREATE_OUTPUT_AT_INDEX0x109Memory address of t.outputs[$rB]
GTF_CREATE_WITNESS_AT_INDEX0x10AMemory address of tx.witnesses[$rB]
GTF_INPUT_TYPE0x200tx.inputs[$rB].type
GTF_INPUT_COIN_TX_ID0x201Memory address of tx.inputs[$rB].txID
GTF_INPUT_COIN_OUTPUT_INDEX0x202tx.inputs[$rB].outputIndex
GTF_INPUT_COIN_OWNER0x203Memory address of tx.inputs[$rB].owner
GTF_INPUT_COIN_AMOUNT0x204tx.inputs[$rB].amount
GTF_INPUT_COIN_ASSET_ID0x205Memory address of tx.inputs[$rB].asset_id
GTF_INPUT_COIN_TX_POINTER0x206Memory address of tx.inputs[$rB].txPointer
GTF_INPUT_COIN_WITNESS_INDEX0x207tx.inputs[$rB].witnessIndex
GTF_INPUT_COIN_MATURITY0x208tx.inputs[$rB].maturity
GTF_INPUT_COIN_PREDICATE_LENGTH0x209tx.inputs[$rB].predicateLength
GTF_INPUT_COIN_PREDICATE_DATA_LENGTH0x20Atx.inputs[$rB].predicateDataLength
GTF_INPUT_COIN_PREDICATE0x20BMemory address of tx.inputs[$rB].predicate
GTF_INPUT_COIN_PREDICATE_DATA0x20CMemory address of tx.inputs[$rB].predicateData
GTF_INPUT_COIN_PREDICATE_GAS_USED0x20Dtx.inputs[$rB].predicateGasUsed
GTF_INPUT_CONTRACT_TX_ID0x220Memory address of tx.inputs[$rB].txID
GTF_INPUT_CONTRACT_OUTPUT_INDEX0x221tx.inputs[$rB].outputIndex
GTF_INPUT_CONTRACT_BALANCE_ROOT0x222Memory address of tx.inputs[$rB].balanceRoot
GTF_INPUT_CONTRACT_STATE_ROOT0x223Memory address of tx.inputs[$rB].stateRoot
GTF_INPUT_CONTRACT_TX_POINTER0x224Memory address of tx.inputs[$rB].txPointer
GTF_INPUT_CONTRACT_CONTRACT_ID0x225Memory address of tx.inputs[$rB].contractID
GTF_INPUT_MESSAGE_SENDER0x240Memory address of tx.inputs[$rB].sender
GTF_INPUT_MESSAGE_RECIPIENT0x241Memory address of tx.inputs[$rB].recipient
GTF_INPUT_MESSAGE_AMOUNT0x242tx.inputs[$rB].amount
GTF_INPUT_MESSAGE_NONCE0x243Memory address of tx.inputs[$rB].nonce
GTF_INPUT_MESSAGE_WITNESS_INDEX0x244tx.inputs[$rB].witnessIndex
GTF_INPUT_MESSAGE_DATA_LENGTH0x245tx.inputs[$rB].dataLength
GTF_INPUT_MESSAGE_PREDICATE_LENGTH0x246tx.inputs[$rB].predicateLength
GTF_INPUT_MESSAGE_PREDICATE_DATA_LENGTH0x247tx.inputs[$rB].predicateDataLength
GTF_INPUT_MESSAGE_DATA0x248Memory address of tx.inputs[$rB].data
GTF_INPUT_MESSAGE_PREDICATE0x249Memory address of tx.inputs[$rB].predicate
GTF_INPUT_MESSAGE_PREDICATE_DATA0x24AMemory address of tx.inputs[$rB].predicateData
GTF_INPUT_MESSAGE_PREDICATE_GAS_USED0x24Btx.inputs[$rB].predicateGasUsed
GTF_OUTPUT_TYPE0x300tx.outputs[$rB].type
GTF_OUTPUT_COIN_TO0x301Memory address of tx.outputs[$rB].to
GTF_OUTPUT_COIN_AMOUNT0x302tx.outputs[$rB].amount
GTF_OUTPUT_COIN_ASSET_ID0x303Memory address of tx.outputs[$rB].asset_id
GTF_OUTPUT_CONTRACT_INPUT_INDEX0x304tx.outputs[$rB].inputIndex
GTF_OUTPUT_CONTRACT_BALANCE_ROOT0x305Memory address of tx.outputs[$rB].balanceRoot
GTF_OUTPUT_CONTRACT_STATE_ROOT0x306Memory address of tx.outputs[$rB].stateRoot
GTF_OUTPUT_CONTRACT_CREATED_CONTRACT_ID0x307Memory address of tx.outputs[$rB].contractID
GTF_OUTPUT_CONTRACT_CREATED_STATE_ROOT0x308Memory address of tx.outputs[$rB].stateRoot
GTF_WITNESS_DATA_LENGTH0x400tx.witnesses[$rB].dataLength
GTF_WITNESS_DATA0x401Memory address of tx.witnesses[$rB].data
GTF_POLICY_TYPES0x500tx.policies.policyTypes
GTF_POLICY_GAS_PRICE0x501tx.policies[0x00].gasPrice
GTF_POLICY_WITNESS_LIMIT0x502tx.policies[count_ones(0b11 & tx.policyTypes) - 1].witnessLimit
GTF_POLICY_MATURITY0x503tx.policies[count_ones(0b111 & tx.policyTypes) - 1].maturity
GTF_POLICY_MAX_FEE0x504tx.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.