pub enum Opcode {
Show 81 variants ADD(usizeusizeusize), ADDI(usizeusizeu16), AND(usizeusizeusize), ANDI(usizeusizeu16), DIV(usizeusizeusize), DIVI(usizeusizeu16), EQ(usizeusizeusize), EXP(usizeusizeusize), EXPI(usizeusizeu16), GT(usizeusizeusize), LT(usizeusizeusize), MLOG(usizeusizeusize), MROO(usizeusizeusize), MOD(usizeusizeusize), MODI(usizeusizeu16), MOVE(usizeusize), MUL(usizeusizeusize), MULI(usizeusizeu16), NOT(usizeusize), OR(usizeusizeusize), ORI(usizeusizeu16), SLL(usizeusizeusize), SLLI(usizeusizeu16), SRL(usizeusizeusize), SRLI(usizeusizeu16), SUB(usizeusizeusize), SUBI(usizeusizeu16), XOR(usizeusizeusize), XORI(usizeusizeu16), CIMV(usizeusizeusize), CTMV(usizeusize), JI(u32), JNEI(usizeusizeu16), RET(usize), RETD(usizeusize), CFEI(u32), CFSI(u32), LB(usizeusizeu16), LW(usizeusizeu16), ALOC(usize), MCL(usizeusize), MCLI(usizeu32), MCP(usizeusizeusize), MCPI(usizeusizeu16), MEQ(usizeusizeusizeusize), SB(usizeusizeu16), SW(usizeusizeu16), BAL(usizeusizeusize), BHSH(usizeusize), BHEI(usize), BURN(usize), CALL(usizeusizeusizeusize), CCP(usizeusizeusizeusize), CROO(usizeusize), CSIZ(usizeusize), CB(usize), LDC(usizeusizeusize), LOG(usizeusizeusizeusize), LOGD(usizeusizeusizeusize), MINT(usize), RVRT(usize), SLDC(usizeusizeusize), SRW(usizeusize), SRWQ(usizeusize), SWW(usizeusize), SWWQ(usizeusize), TR(usizeusizeusize), TRO(usizeusizeusizeusize), ECR(usizeusizeusize), K256(usizeusizeusize), S256(usizeusizeusize), XIL(usizeusize), XIS(usizeusize), XOL(usizeusize), XOS(usizeusize), XWL(usizeusize), XWS(usizeusize), NOOP, FLAG(usize), GM(usizeu32), Undefined,
}
Expand description

Instruction representation for the interpreter.

Memory Opcodes

All these opcodes advance the program counter $pc by 4 after performing their operation. Every instruction is guaranteed to fit in u32 representation.

Arithmetic/Logic (ALU) Opcodes

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

If the F_UNSAFEMATH flag is unset, an operation that would have set $err to true is instead a panic.

If the F_WRAPPING flag is unset, an operation that would have set $of to a non-zero value is instead a panic. ## Contract Opcodes

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

Cryptographic Opcodes

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

Variants

ADD(usizeusizeusize)

Adds two registers.

| Operation | $rA = $rB + $rC; | | Syntax | add $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
  • $rA is a reserved register.
Execution

$of is assigned the overflow of the operation. $err is cleared.

ADDI(usizeusizeu16)

Adds a register and an immediate value.

| Operation | $rA = $rB + imm; | | Syntax | addi $rA, $rB, immediate | | Encoding | 0x00 rA rB i i |

Panics
  • $rA is a reserved register.
Execution

$of is assigned the overflow of the operation. $err is cleared.

AND(usizeusizeusize)

Bitwise ANDs two registers.

| Operation | $rA = $rB & $rC; | | Syntax | and $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
  • $rA is a reserved register.
Execution

$of and $err are cleared.

ANDI(usizeusizeu16)

Bitwise ANDs a register and an immediate value.

| Operation | $rA = $rB & imm; | | Syntax | andi $rA, $rB, imm | | Encoding | 0x00 rA rB i i |

Panics
  • $rA is a reserved register.
Execution

imm is extended to 64 bits, with the high 52 bits set to 0. $of and $err are cleared.

DIV(usizeusizeusize)

Divides two registers.

| Operation | $rA = $rB // $rC; | | Syntax | div $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
  • $rA is a reserved register.
Execution

If $rC == 0, $rA is cleared and $err is set to true. Otherwise, $err is cleared. $of is cleared.

DIVI(usizeusizeu16)

Divides a register and an immediate value.

| Operation | $rA = $rB // imm; | | Syntax | divi $rA, $rB, imm | | Encoding | 0x00 rA rB i i |

Panics
  • $rA is a reserved register.
Execution

If imm == 0, $rA is cleared and $err is set to true. Otherwise, $err is cleared. $of is cleared.

EQ(usizeusizeusize)

Compares two registers for equality.

| Operation | $rA = $rB == $rC; | | Syntax | eq $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
  • $rA is a reserved register,
Execution

$of and $err are cleared.

EXP(usizeusizeusize)

Raises one register to the power of another.

| Operation | $rA = $rB ** $rC; | | Syntax | exp $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
Execution

If the result cannot fit in 8 bytes, $of is set to 1, otherwise $of is cleared. $err is cleared.

EXPI(usizeusizeu16)

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 |

Panics
Execution

If the result cannot fit in 8 bytes, $of is set to 1, otherwise $of is cleared. $err is cleared.

GT(usizeusizeusize)

Compares two registers for greater-than.

| Operation | $rA = $rB > $rC; | | Syntax | gt $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
Execution

$of and $err are cleared.

LT(usizeusizeusize)

Compares two registers for less-than.

| Operation | $rA = $rB < $rC; | | Syntax | lt $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
Execution

$of and $err are cleared.

MLOG(usizeusizeusize)

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 - |

Panics
Execution

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.

MROO(usizeusizeusize)

The (integer) $rCth root of $rB.

| Operation | $rA = math.floor(math.root($rB, $rC)); | | Syntax | mroo $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
Execution

If $rC == 0, both $rA and $of are cleared and $err is set to true.

Otherwise, $of and $err are cleared.

MOD(usizeusizeusize)

Modulo remainder of two registers.

| Operation | $rA = $rB % $rC; | | Syntax | mod $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
Execution

If $rC == 0, both $rA and $of are cleared and $err is set to true.

Otherwise, $of and $err are cleared.

MODI(usizeusizeu16)

Modulo remainder of a register and an immediate value.

| Operation | $rA = $rB % imm; | | Syntax | modi $rA, $rB, imm | | Encoding | 0x00 rA rB i i |

Panics
Execution

If imm == 0, both $rA and $of are cleared and $err is set to true.

Otherwise, $of and $err are cleared.

MOVE(usizeusize)

Copy from one register to another.

| Operation | $rA = $rB; | | Syntax | move $rA, $rB | | Encoding | 0x00 rA rB - - | | Notes | |

Panics
Execution

$of and $err are cleared.

MUL(usizeusizeusize)

Multiplies two registers.

| Operation | $rA = $rB * $rC; | | Syntax | mul $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
Execution

$of is assigned the overflow of the operation.

$err is cleared.

MULI(usizeusizeu16)

Multiplies a register and an immediate value.

| Operation | $rA = $rB * imm; | | Syntax | mul $rA, $rB, imm | | Encoding | 0x00 rA rB i i |

Panics
Execution

$of is assigned the overflow of the operation.

$err is cleared.

NOT(usizeusize)

Bitwise NOT a register.

| Operation | $rA = ~$rB; | | Syntax | not $rA, $rB | | Encoding | 0x00 rA rB - - |

Panics
Execution

$of and $err are cleared.

OR(usizeusizeusize)

Bitwise ORs two registers.

| Operation | $rA = $rB \| $rC; | | Syntax | or $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
Execution

$of and $err are cleared.

ORI(usizeusizeu16)

Bitwise ORs a register and an immediate value.

| Operation | $rA = $rB \| imm; | | Syntax | ori $rA, $rB, imm | | Encoding | 0x00 rA rB i i |

Panics
Execution

imm is extended to 64 bits, with the high 52 bits set to 0.

$of and $err are cleared.

SLL(usizeusizeusize)

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. |

Panics
Execution

$of is assigned the overflow of the operation.

$err is cleared.

SLLI(usizeusizeu16)

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. |

Panics
Execution

$of is assigned the overflow of the operation.

$err is cleared.

SRL(usizeusizeusize)

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. |

Panics
Execution

$of is assigned the underflow of the operation, as though $of is the high byte of a 128-bit register.

$err is cleared.

SRLI(usizeusizeu16)

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. |

Panics
Execution

$of is assigned the underflow of the operation, as though $of is the high byte of a 128-bit register.

$err is cleared.

SUB(usizeusizeusize)

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. |

Panics
Execution

$of is assigned the underflow of the operation, as though $of is the high byte of a 128-bit register.

$err is cleared.

SUBI(usizeusizeu16)

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. |

Panics
Execution

$of is assigned the underflow of the operation, as though $of is the high byte of a 128-bit register.

$err is cleared.

XOR(usizeusizeusize)

Bitwise XORs two registers.

| Operation | $rA = $rB ^ $rC; | | Syntax | xor $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - | | Notes | |

Panics
Execution

$of and $err are cleared.

XORI(usizeusizeu16)

Bitwise XORs a register and an immediate value.

| Operation | $rA = $rB ^ imm; | | Syntax | xori $rA, $rB, imm | | Encoding | 0x00 rA rB i i | | Notes | |

Panics
Execution

$of and $err are cleared.

CIMV(usizeusizeusize)

Set $rA to true if the $rC <= tx.input[$rB].maturity.

| Operation | $rA = checkinputmaturityverify($rB, $rC); | | Syntax | cimv $rA $rB $rC | | Encoding | 0x00 rA rB rC - |

Panics
Execution

Otherwise, advance the program counter $pc by 4.

See also: BIP-112 and CLTV.

CTMV(usizeusize)

Set $rA to true if $rB <= tx.maturity.

| Operation | $rA = checktransactionmaturityverify($rB); | | Syntax | ctmv $rA $rB | | Encoding | 0x00 rA rB - - |

Panics
Execution

Otherwise, advance the program counter $pc by 4.

See also: BIP-65 and Bitcoin’s Time Locks.

JI(u32)

Jumps to the code instruction offset by imm.

| Operation | $pc = $is + imm * 4; | | Syntax | ji imm | | Encoding | 0x00 i i i i |

Panics
  • $is + imm * 4 > VM_MAX_RAM - 1

JNEI(usizeusizeu16)

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

Panics
  • $is + imm * 4 > VM_MAX_RAM - 1

RET(usize)

Returns from context with value $rA.

| Operation | return($rA); | Syntax | ret $rA | Encoding | 0x00 rA - - -

If current context is external, cease VM execution and return $rA.

Returns from contract call, popping the call frame. Before popping:

  1. Return the unused forwarded gas to the caller:
    • $cgas = $cgas + $fp->$cgas (add remaining context gas from previous context to current remaining context gas)

Then pop the call frame and restoring registers except $ggas and $cgas. Afterwards, set the following registers:

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

RETD(usizeusize)

Return from context with data

| Operation | returndata($rA, $rB); | Syntax | retd $rA, $rB | Encoding | 0x00 rA rB - -

If current context is external, cease VM execution and return MEM[$rA, $rB].

Returns from contract call, popping the call frame. Before popping:

  1. Return the unused forwarded gas to the caller:
    • $cgas = $cgas + $fp->$cgas (add remaining context gas from previous context to current remaining context gas)

Then pop the call frame and restoring registers except $ggas and $cgas. Afterwards, set the following registers:

Set the return value:

  1. $ret = $rA

  2. $retl = $rB

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

CFEI(u32)

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.

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

CFSI(u32)

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.

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

LB(usizeusizeu16)

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

Panics

LW(usizeusizeu16)

A word is loaded from the specified address offset by imm. | Operation | $rA = MEM[$rB + imm, 8]; | Syntax | lw $rA, $rB, imm | Encoding | 0x00 rA rB i i

Panics

ALOC(usize)

Allocate a number of bytes from the heap.

| Operation | $hp = $hp - $rA; | | Syntax | aloc $rA | | Encoding | 0x00 rA - - - | | Notes | Does not initialize memory. |

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

MCL(usizeusize)

Clear bytes in memory.

| Operation | MEM[$rA, $rB] = 0; | | Syntax | mcl $rA, $rB | | Encoding | 0x00 rA rB - - |

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

MCLI(usizeu32)

Clear bytes in memory.

| Operation | MEM[$rA, imm] = 0; | | Syntax | mcli $rA, imm | | Encoding | 0x00 rA i i i |

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

MCP(usizeusizeusize)

Copy bytes in memory.

| Operation | MEM[$rA, $rC] = MEM[$rB, $rC]; | | Syntax | mcp $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
  • $rA + $rC overflows
  • $rB + $rC overflows
  • $rA + $rC > VM_MAX_RAM
  • $rB + $rC > VM_MAX_RAM
  • $rC > MEM_MAX_ACCESS_SIZE
  • The memory ranges MEM[$rA, $rC] and MEM[$rB, $rC] overlap
  • The memory range MEM[$rA, $rC] does not pass ownership check

MCPI(usizeusizeu16)

Copy bytes in memory.

| Operation | MEM[$rA, imm] = MEM[$rB, imm]; | | Syntax | mcpi $rA, $rB, imm | | Encoding | 0x00 rA rB i i |

Panics
  • $rA + imm overflows
  • $rB + imm overflows
  • $rA + imm > VM_MAX_RAM
  • $rB + imm > VM_MAX_RAM
  • imm > MEM_MAX_ACCESS_SIZE
  • The memory ranges MEM[$rA, imm] and MEM[$rB, imm] overlap
  • The memory range MEM[$rA, imm] does not pass ownership check

MEQ(usizeusizeusizeusize)

Compare bytes in memory.

| Operation | $rA = MEM[$rB, $rD] == MEM[$rC, $rD]; | | Syntax | meq $rA, $rB, $rC, $rD | | Encoding | 0x00 rA rB rC rD |

Panics
  • $rA is a reserved register
  • $rB + $rD overflows
  • $rC + $rD overflows
  • $rB + $rD > VM_MAX_RAM
  • $rC + $rD > VM_MAX_RAM
  • $rD > MEM_MAX_ACCESS_SIZE

SB(usizeusizeu16)

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 |

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

SW(usizeusizeu16)

The value of $rB is stored at the address $rA offset by imm.

| Operation | MEM[$rA + imm, 8] = $rB; | Syntax | sw $rA, $rB, imm | Encoding | 0x00 rA rB i i

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

BAL(usizeusizeusize)

Set $rA to the balance of color at $rB for contract with ID at $rC. Where helper balance(color: byte[32], contract_id: byte[32]) -> uint64 returns the current balance of color of contract with ID contract_id.

| Operation | $rA = balance(MEM[$rB, 32], MEM[$rC, 32]); | | Syntax | bal $rA, $rB, $rC | | Encoding | 0x00 rA rB rC - |

Panics
  • $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

BHSH(usizeusize)

Get block header hash.

| Operation | MEM[$rA, 32] = blockhash($rB); | | Syntax | bhsh $rA $rB | | Encoding | 0x00 rA rB - - |

Panics
  • $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).

BHEI(usize)

Get Fuel block height.

| Operation | $rA = blockheight(); | | Syntax | bhei $rA | | Encoding | 0x00 rA - - - |

Panics

BURN(usize)

Burn $rA coins of the current contract’s color.

| Operation | burn($rA); | | Syntax | burn $rA | | Encoding | 0x00 rA - - - |

Panic
  • Balance of color MEM[$fp, 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 color MEM[$fp, 32] by $rA.

This modifies the balanceRoot field of the appropriate output.

CALL(usizeusizeusizeusize)

Call contract.

| Syntax | call $rA $rB $rC $rD | | Encoding | 0x00 rA rB rC rD |

Panics
  • $rA + 32 overflows
  • $rC + 32 overflows
  • Contract with ID MEM[$rA, 32] is not in tx.inputs
  • Reading past MEM[VM_MAX_RAM - 1]
  • Any output range does not pass ownership check
  • In an external context, if $rB > MEM[balanceOfStart(MEM[$rC, 32]), 8]
  • In an internal context, if $rB is greater than the balance of color MEM[$rC, 32] of output with contract ID MEM[$rA, 32]

Register $rA is a memory address from which the following fields are set (word-aligned).

$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.

For output with contract ID MEM[$rA, 32], increase balance of color MEM[$rC, 32] by $rB. In an external context, decrease MEM[balanceOfStart(MEM[$rC, 32]), 8] by $rB. In an internal context, decrease color 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) 1. Set $ssp and $sp to the start of the writable stack area of the call frame. 1. Set $pc and $is to the starting address of the code. 1. $bal = $rD (forward coins)
  2. $cgas = $rD or all available gas (forward gas)

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

CCP(usizeusizeusizeusize)

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.

Panics
  • $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
  • $rD > MEM_MAX_ACCESS_SIZE
  • Contract with ID MEM[$rB, 32] is not in tx.inputs

CROO(usizeusize)

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 - -

Panics
  • $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 compuration is defined here.

CSIZ(usizeusize)

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 - -

Panics
  • $rA is a reserved register
  • $rB + 32 overflows
  • $rB + 32 > VM_MAX_RAM
  • Contract with ID MEM[$rB, 32] is not in tx.inputs

CB(usize)

Get block proposer address.

| Operation | MEM[$rA, 32] = coinbase(); | | Syntax | cb $rA | | Encoding | 0x00 rA - - - |

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

LDC(usizeusizeusize)

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.

Panics
  • $ssp + $rC overflows
  • $rA + 32 overflows
  • $ssp + $rC > VM_MAX_RAM
  • $rA + 32 > VM_MAX_RAM
  • $ssp != $sp
  • $ssp + $rC > $hp
  • $rC > CONTRACT_MAX_SIZE
  • $rC > MEM_MAX_ACCESS_SIZE
  • Contract with ID MEM[$rA, 32] is not in tx.inputs

Increment $hp->codesize, $ssp, and $sp by $rC padded to word alignment.

This opcode 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).

LOG(usizeusizeusizeusize)

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 |

LOGD(usizeusizeusizeusize)

Logs the memory range MEM[$rC, $rD]. This is a no-op.

| Syntax | logd $rA, $rB, $rC, $rD | | Encoding | 0x00 rA rB rC rD |

MINT(usize)

Mint $rA coins of the current contract’s color.

| Operation | mint($rA); | | Syntax | mint $rA | | Encoding | 0x00 rA - - - |

Panics
  • Balance of color MEM[$fp, 32] 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 color MEM[$fp, 32] by $rA.

This modifies the balanceRoot field of the appropriate output.

RVRT(usize)

Halt execution, reverting state changes and returning value in $rA.

| Operation | revert($rA); | Syntax | rvrt $rA | Encoding | 0x00 rA - - -

After a revert:

  1. All OutputContract outputs will have the same amount and stateRoot as on initialization. 1. All OutputVariable (../protocol/tx_format.md outputs#outputvariable) outputs will have to and amount of zero.
  2. All OutputContractConditional (../protocol/tx_format.md# outputcontractconditional) outputs will have contractID, amount, and stateRoot of zero.

SLDC(usizeusizeusize)

Copy $rC bytes of code starting at $rB for contract with static index $rA into memory starting at $ssp.

| Operation | MEM[$ssp, $rC] = scode($rA, $rB, $rC); | Syntax | sloadcode $rA, $rB, $rC | Encoding | 0x00 rA rB rC - | Notes | If $rC is greater than the code size, zero bytes are filled in. |

Panics
  • $ssp + $rC overflows
  • $ssp + $rC > VM_MAX_RAM
  • $rA >= MAX_STATIC_CONTRACTS
  • $rA is greater than or equal to staticContractsCount for the contract with ID MEM[$fp, 32]
  • $ssp != $sp
  • $ssp + $rC > $hp
  • $rC > CONTRACT_MAX_SIZE
  • $rC > MEM_MAX_ACCESS_SIZE
  • $fp == 0 (in the script context)

Increment $hp->codesize, $ssp, and $sp by $rC padded to word alignment.

This opcode 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).

SRW(usizeusize)

A word is read from the current contract’s state.

| Operation | $rA = STATE[MEM[$rB, 32]][0, 8]; | | Syntax | srw $rA, $rB | | Encoding | 0x00 rA rB - - | | Notes | Returns zero if the state element does not exist. |

Panics
  • $rA is a reserved register
  • $rB + 32 overflows
  • $rB + 32 > VM_MAX_RAM
  • $fp == 0 (in the script context)

SRWQ(usizeusize)

32 bytes is read from the current contract’s state.

| Operation | MEM[$rA, 32] = STATE[MEM[$rB, 32]]; | | Syntax | srwx $rA, $rB | | Encoding | 0x00 rA rB - - | | Notes | Returns zero if the state element does not exist. |

Panics
  • $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
  • $fp == 0 (in the script context)

SWW(usizeusize)

A word is written to the current contract’s state.

| Operation | STATE[MEM[$rA, 32]][0, 8] = $rB; | | Syntax | sww $rA $rB | | Encoding | 0x00 rA rB - - |

Panics
  • $rA + 32 overflows
  • $rA + 32 > VM_MAX_RAM
  • $fp == 0 (in the script context)

SWWQ(usizeusize)

32 bytes is written to the current contract’s state.

| Operation | STATE[MEM[$rA, 32]] = MEM[$rB, 32]; | | Syntax | swwx $rA, $rB | | Encoding | 0x00 rA rB - - |

Panics
  • $rA + 32 overflows
  • $rB + 32 overflows
  • $rA + 32 > VM_MAX_RAM
  • $rB + 32 > VM_MAX_RAM
  • $fp == 0 (in the script context)

TR(usizeusizeusize)

Transfer $rB coins with color 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 -

Given helper balanceOfStart(color: byte[32]) -> uint32 which returns the memory address of color balance, or 0 if color has no balance.

Panics
  • $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[balanceOf(MEM[$rC, 32]), 8]
  • In an internal context, if $rB is greater than the balance of color MEM[$rC, 32] of output with contract ID MEM[$fp, 32]
  • $rB == 0

For output with contract ID MEM[$rA, 32], increase balance of color MEM[$rC, 32] by $rB. In an external context, decrease MEM[balanceOfStart(MEM[$rC, 32]), 8] by $rB. In an internal context, decrease color MEM[$rC, 32] balance of output with contract ID MEM[$fp, 32] by $rB.

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

TRO(usizeusizeusizeusize)

Transfer $rC coins with color 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

Given helper balanceOfStart(color: byte[32]) -> uint32 which returns the memory address of color balance, or 0 if color has no balance.

Panics
  • $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[balanceOf(MEM[$rD, 32]), 8]
  • In an internal context, if $rC is greater than the balance of color MEM[$rD, 32] of output with contract ID MEM[$fp, 32]
  • $rC == 0
  • tx.outputs[$rB].type != OutputType.Variable
  • tx.outputs[$rB].amount != 0

In an external context, decrease MEM[balanceOfStart(MEM[$rD, 32]), 8] by $rC. In an internal context, decrease color 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].color = MEM[$rD, 32]

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

ECR(usizeusizeusize)

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(MEM[$rB, 64], MEM[$rC, 32]); | Syntax | ecr $rA, $rB, $rC | Encoding | 0x00 rA rB rC -

Panics
  • $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

To get the address, hash the public key with SHA-2-256.

K256(usizeusizeusize)

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 -

Panics
  • $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
  • $rC > MEM_MAX_ACCESS_SIZE

S256(usizeusizeusize)

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 - |

Panics
  • $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
  • $rC > MEM_MAX_ACCESS_SIZE

XIL(usizeusize)

Set $rA to the length in bytes of the $rBth input.

| Operation | $rA = xil($rB); | | Syntax | xil $rA, $rB | | Encoding | 0x00 rA rB - - |

Panics
  • $rB >= tx.inputsCount

XIS(usizeusize)

Set $rA to the memory addess of the start of the $rBth input.

| Operation | $rA = xis($rB); | | Syntax | xis $rA, $rB | | Encoding | 0x00 rA rB - - |

Panics
  • $rB >= tx.inputsCount

XOL(usizeusize)

Set $rA to the length in bytes of the $rBth output.

| Operation | $rA = xol($rB); | | Syntax | xol $rA, $rB | | Encoding | 0x00 rA rB - - |

Panics
  • $rB >= tx.outputsCount

XOS(usizeusize)

Set $rA to the memory addess of the start of the $rBth output.

| Operation | $rA = xos($rB); | | Syntax | xos $rA, $rB | | Encoding | 0x00 rA rB - - |

Panics
  • $rB >= tx.outputsCount

XWL(usizeusize)

Set $rA to the length in bytes of the $rBth witness.

| Operation | $rA = xwl($rB); | | Syntax | xwl $rA, $rB | | Encoding | 0x00 rA rB - - |

Panics
  • $rB >= tx.witnessesCount

Note that the returned length includes the entire witness, not just of the witness’s data field.

XWS(usizeusize)

Set $rA to the memory addess of the start of the $rBth witness.

| Operation | $rA = xws($rB); | | Syntax | xws $rA, $rB | | Encoding | 0x00 rA rB - - |

Panics
  • $rB >= tx.witnessesCount

Note that the returned memory address includes the entire witness, not just of the witness’s data field.

NOOP

Performs no operation.

| Operation | | | Syntax | noop | | Encoding | 0x00 - - - - |

$of and $err are cleared.

FLAG(usize)

Set $flag to $rA.

| Operation | $flag = $rA; | | Syntax | flag $rA | | Encoding | 0x00 rA - - - |

GM(usizeu32)

Get metadata from memory

| Operation | Selected by imm | | Syntax | gm $rA, imm | | Encoding | 0x00 rA imm imm imm |

Undefined

Undefined opcode, potentially from inconsistent serialization

Implementations

Size of the struct when serialized into bytes

Create a new Opcode given the internal attributes

Create a Opcode from a slice of bytes

Safety

Reflects the requirements of bytes::from_slice_unchecked

Convert the opcode to bytes representation

Transform the Opcode into an optional array of 4 register identifiers

Return the underlying immediate value, if present

Create a Opcode from a slice of bytes

This function will fail if the length of the bytes is smaller than Opcode::LEN.

Create a set of Opcode from an iterator of bytes

If not padded to Self::LEN, will consume the unaligned bytes but won’t try to parse an opcode from them.

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Feeds this value into the given Hasher. Read more

Feeds a slice of this type into the given Hasher. Read more

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

Pull some bytes from this source into the specified buffer, returning how many bytes were read. Read more

Like read, except that it reads into a slice of buffers. Read more

🔬 This is a nightly-only experimental API. (can_vector)

Determines if this Reader has an efficient read_vectored implementation. Read more

Read all bytes until EOF in this source, placing them into buf. Read more

Read all bytes until EOF in this source, appending them to buf. Read more

Read the exact number of bytes required to fill buf. Read more

🔬 This is a nightly-only experimental API. (read_buf)

Pull some bytes from this source into the specified buffer. Read more

🔬 This is a nightly-only experimental API. (read_buf)

Read the exact number of bytes required to fill buf. Read more

Creates a “by reference” adaptor for this instance of Read. Read more

Transforms this Read instance to an Iterator over its bytes. Read more

Creates an adapter which will chain this stream with another. Read more

Creates an adapter which will read at most limit bytes from it. Read more

Write a buffer into this writer, returning how many bytes were written. Read more

Flush this output stream, ensuring that all intermediately buffered contents reach their destination. Read more

Like write, except that it writes from a slice of buffers. Read more

🔬 This is a nightly-only experimental API. (can_vector)

Determines if this Writer has an efficient write_vectored implementation. Read more

Attempts to write an entire buffer into this writer. Read more

🔬 This is a nightly-only experimental API. (write_all_vectored)

Attempts to write multiple buffers into this writer. Read more

Writes a formatted string into this writer, returning any error encountered. Read more

Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Should always be Self

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.