TEAL Opcodes

Ops have a ‘cost’ of 1 unless otherwise specified.

err

  • Opcode: 0x00
  • Pops: None
  • Pushes: None
  • Error. Panic immediately. This is primarily a fencepost against accidental zero bytes getting compiled into programs.

sha256

  • Opcode: 0x01
  • Pops: … stack, []byte
  • Pushes: []byte
  • SHA256 hash of value, yields [32]byte
  • Cost: 7

keccak256

  • Opcode: 0x02
  • Pops: … stack, []byte
  • Pushes: []byte
  • Keccak256 hash of value, yields [32]byte
  • Cost: 26

sha512_256

  • Opcode: 0x03
  • Pops: … stack, []byte
  • Pushes: []byte
  • SHA512_256 hash of value, yields [32]byte
  • Cost: 9

ed25519verify

  • Opcode: 0x04
  • Pops: … stack, {[]byte A}, {[]byte B}, {[]byte C}
  • Pushes: uint64
  • for (data, signature, pubkey) verify the signature of the data against the pubkey => {0 or 1}
  • Cost: 1900

+

  • Opcode: 0x08
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A plus B. Panic on overflow.

-

  • Opcode: 0x09
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A minus B. Panic if B > A.

/

  • Opcode: 0x0a
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A divided by B. Panic if B == 0.

*

  • Opcode: 0x0b
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A times B. Panic on overflow.

It is worth noting that there are 10,000,000,000,000,000 micro-Algos in the total supply, or a bit less than 2^54. When doing rational math, e.g. (A * (N/D)) as ((A * N) / D) one should limit the numerator to less than 2^10 to be completely sure there won’t be overflow.

<

  • Opcode: 0x0c
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A less than B => {0 or 1}

>

  • Opcode: 0x0d
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A greater than B => {0 or 1}

<=

  • Opcode: 0x0e
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A less than or equal to B => {0 or 1}

>=

  • Opcode: 0x0f
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A greater than or equal to B => {0 or 1}

&&

  • Opcode: 0x10
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A is not zero and B is not zero => {0 or 1}

||

  • Opcode: 0x11
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A is not zero or B is not zero => {0 or 1}

==

  • Opcode: 0x12
  • Pops: … stack, {any A}, {any B}
  • Pushes: uint64
  • A is equal to B => {0 or 1}

!=

  • Opcode: 0x13
  • Pops: … stack, {any A}, {any B}
  • Pushes: uint64
  • A is not equal to B => {0 or 1}

!

  • Opcode: 0x14
  • Pops: … stack, uint64
  • Pushes: uint64
  • X == 0 yields 1; else 0

len

  • Opcode: 0x15
  • Pops: … stack, []byte
  • Pushes: uint64
  • yields length of byte value

itob

  • Opcode: 0x16
  • Pops: … stack, uint64
  • Pushes: []byte
  • converts uint64 to big endian bytes

btoi

  • Opcode: 0x17
  • Pops: … stack, []byte
  • Pushes: uint64
  • converts bytes as big endian to uint64

btoi panics if the input is longer than 8 bytes

%

  • Opcode: 0x18
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A modulo B. Panic if B == 0.

|

  • Opcode: 0x19
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A bitwise-or B

&

  • Opcode: 0x1a
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A bitwise-and B

^

  • Opcode: 0x1b
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64
  • A bitwise-xor B

~

  • Opcode: 0x1c
  • Pops: … stack, uint64
  • Pushes: uint64
  • bitwise invert value

mulw

  • Opcode: 0x1d
  • Pops: … stack, {uint64 A}, {uint64 B}
  • Pushes: uint64, uint64
  • A times B out to 128-bit long result as low (top) and high uint64 values on the stack

intcblock

  • Opcode: 0x20 {varuint length} [{varuint value}, …]
  • Pops: None
  • Pushes: None
  • load block of uint64 constants

intcblock loads following program bytes into an array of integer constants in the evaluator. These integer constants can be referred to by intc and intc_* which will push the value onto the stack.

intc

  • Opcode: 0x21 {uint8 int constant index}
  • Pops: None
  • Pushes: uint64
  • push value from uint64 constants to stack by index into constants

intc_0

  • Opcode: 0x22
  • Pops: None
  • Pushes: uint64
  • push uint64 constant 0 to stack

intc_1

  • Opcode: 0x23
  • Pops: None
  • Pushes: uint64
  • push uint64 constant 1 to stack

intc_2

  • Opcode: 0x24
  • Pops: None
  • Pushes: uint64
  • push uint64 constant 2 to stack

intc_3

  • Opcode: 0x25
  • Pops: None
  • Pushes: uint64
  • push uint64 constant 3 to stack

bytecblock

  • Opcode: 0x26 {varuint length} [({varuint value length} bytes), …]
  • Pops: None
  • Pushes: None
  • load block of byte-array constants

bytecblock loads the following program bytes into an array of byte string constants in the evaluator. These constants can be referred to by bytec and bytec_* which will push the value onto the stack.

bytec

  • Opcode: 0x27 {uint8 byte constant index}
  • Pops: None
  • Pushes: []byte
  • push bytes constant to stack by index into constants

bytec_0

  • Opcode: 0x28
  • Pops: None
  • Pushes: []byte
  • push bytes constant 0 to stack

bytec_1

  • Opcode: 0x29
  • Pops: None
  • Pushes: []byte
  • push bytes constant 1 to stack

bytec_2

  • Opcode: 0x2a
  • Pops: None
  • Pushes: []byte
  • push bytes constant 2 to stack

bytec_3

  • Opcode: 0x2b
  • Pops: None
  • Pushes: []byte
  • push bytes constant 3 to stack

arg

  • Opcode: 0x2c {uint8 arg index N}
  • Pops: None
  • Pushes: []byte
  • push LogicSig.Args[N] value to stack by index

arg_0

  • Opcode: 0x2d
  • Pops: None
  • Pushes: []byte
  • push LogicSig.Args[0] to stack

arg_1

  • Opcode: 0x2e
  • Pops: None
  • Pushes: []byte
  • push LogicSig.Args[1] to stack

arg_2

  • Opcode: 0x2f
  • Pops: None
  • Pushes: []byte
  • push LogicSig.Args[2] to stack

arg_3

  • Opcode: 0x30
  • Pops: None
  • Pushes: []byte
  • push LogicSig.Args[3] to stack

txn

  • Opcode: 0x31 {uint8 transaction field index}
  • Pops: None
  • Pushes: any
  • push field from current transaction to stack

Most fields are a simple copy of a uint64 or byte string value. XferAsset is the concatenation of the AssetID Creator Address (32 bytes) and the big-endian bytes of the uint64 AssetID Index for a total of 40 bytes. SenderBalance is the uin64 balance of the sender, with rewards factored in, at the time of execution.

txn Fields:

Index Name Type
0 Sender []byte
1 Fee uint64
2 FirstValid uint64
3 FirstValidTime uint64
4 LastValid uint64
5 Note []byte
6 Lease []byte
7 Receiver []byte
8 Amount uint64
9 CloseRemainderTo []byte
10 VotePK []byte
11 SelectionPK []byte
12 VoteFirst uint64
13 VoteLast uint64
14 VoteKeyDilution uint64
15 Type []byte
16 TypeEnum uint64
17 XferAsset []byte
18 AssetAmount uint64
19 AssetSender []byte
20 AssetReceiver []byte
21 AssetCloseTo []byte
22 GroupIndex uint64
23 TxID []byte

TypeEnum mapping:

Index Name
0 unknown
1 pay
2 keyreg
3 acfg
4 axfer
5 afrz

global

  • Opcode: 0x32 {uint8 global field index}
  • Pops: None
  • Pushes: any
  • push value from globals to stack

global Fields:

Index Name Type
0 MinTxnFee uint64
1 MinBalance uint64
2 MaxTxnLife uint64
3 ZeroAddress []byte
4 GroupSize uint64

gtxn

  • Opcode: 0x33 {uint8 transaction group index}{uint8 transaction field index}
  • Pops: None
  • Pushes: any
  • push field to the stack from a transaction in the current transaction group

for notes on transaction fields available, see txn

load

  • Opcode: 0x34 {uint8 position in scratch space to load from}
  • Pops: None
  • Pushes: any
  • copy a value from scratch space to the stack

store

  • Opcode: 0x35 {uint8 position in scratch space to store to}
  • Pops: … stack, any
  • Pushes: None
  • pop a value from the stack and store to scratch space

bnz

  • Opcode: 0x40 {0..0x7fff forward branch offset, big endian}
  • Pops: … stack, uint64
  • Pushes: None
  • branch if value is not zero

For a bnz instruction at pc, if the last element of the stack is not zero then branch to instruction at pc + 3 + N, else proceed to next instruction at pc + 3. Branch targets must be well aligned instructions. (e.g. Branching to the second byte of a 2 byte op will be rejected.)

pop

  • Opcode: 0x48
  • Pops: … stack, any
  • Pushes: None
  • discard value from stack

dup

  • Opcode: 0x49
  • Pops: … stack, any
  • Pushes: any, any
  • duplicate last value on stack