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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize

Bitwise NOT a register.

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

Panics
Execution

$of and $err are cleared.

OR(usizeusizeusize)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: 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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: 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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: 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)

Tuple Fields

0: 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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: 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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: u32

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: usize
3: usize

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: u16

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize

Get Fuel block height.

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

Panics

BURN(usize)

Tuple Fields

0: 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)

Tuple Fields

0: usize
1: usize
2: usize
3: usize

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)

Tuple Fields

0: usize
1: usize
2: usize
3: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: 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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: usize
3: usize

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)

Tuple Fields

0: usize
1: usize
2: usize
3: usize

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)

Tuple Fields

0: 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)

Tuple Fields

0: 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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: usize
3: usize

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize
2: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize
1: usize

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)

Tuple Fields

0: usize

Set $flag to $rA.

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

GM(usizeu32)

Tuple Fields

0: usize
1: u32

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

Performs the conversion.

Performs the conversion.

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.