Skip to content
This new developer portal is under construction. For complete documentation, please refer to the old developer portal.

Control Flow

Algorand Python Control Flow

Control flow in Algorand Python is similar to standard Python control flow, with support for if statements, while loops, for loops, and match statements.

If statements

If statements work the same as Python. The conditions must be an expression that evaluates to bool, which can include a String or Uint64 among others.

1
if condition:
2
# block of code to execute if condition is True
3
elif condition2:
4
# block of code to execute if condition is False and condition2 is True
5
else:
6
# block of code to execute if condition and condition2 are both False

See full example.

Ternary conditions

Ternary conditions work the same as Python. The condition must be an expression that evaluates to bool, which can include a String or Uint64 among others.

1
value1 = UInt64(5)
2
value2 = String(">6") if value1 > 6 else String("<=6")

While loops

While loops work the same as Python. The condition must be an expression that evaluates to bool, which can include a String or Uint64 among others.

You can use break and continue.

1
while condition:
2
# block of code to execute if condition is True

Note: we don’t currently have support for while-else statements.

See full example.

For Loops

For loops are used to iterate over sequences, ranges and ARC-4 arrays. They work the same as Python.

Algorand Python provides functions like uenumerate and urange to facilitate creating sequences and ranges; in-built Python reversed method works with these.

  • uenumerate is similar to Python’s built-in enumerate function, but for UInt64 numbers; it allows you to loop over a sequence and have an automatic counter.
  • urange is a function that generates a sequence of Uint64 numbers, which you can iterate over.
  • reversed returns a reversed iterator of a sequence.

Here is an example of how you can use these functions in a contract:

1
test_array = arc4.StaticArray(arc4.UInt8(), arc4.UInt8(), arc4.UInt8(), arc4.UInt8())
2
3
# urange: reversed items, forward index
4
5
for index, item in uenumerate(reversed(urange(4))):
6
test_array[index] = arc4.UInt8(item)
7
8
assert test_array.bytes == Bytes.from_hex("03020100")

Note: we don’t currently have support for for-else statements.

See full examples.

Match Statements

Match statements work the same as Python and work for […]

1
match value:
2
case pattern1:
3
# block of code to execute if pattern1 matches
4
case pattern2:
5
# block of code to execute if pattern2 matches
6
case _:
7
# Fallback

Note: Captures and patterns are not supported. Currently, there is only support for basic case/switch functionality; pattern matching and guard clauses are not currently supported.

See full example.

TEAL Flow Control Opcode

Algorand Python and TypeScript are high-level smart contract languages that allow developers to express control flows in more accessible languages. However, the Algorand Virtual Machine (AVM) executes the Transaction Execution Approval Language (TEAL) flow control opcodes after compilation. TEAL is a low-level assembly language that the AVM understands directly. While developers will write smart contracts in higher-level languages, understanding the underlying TEAL opcodes can be beneficial to comprehend what’s happening line by line. The following chart contains all of the control flow opcodes available in TEAL.

OpcodeDescription
errFail immediately.
bnz targetbranch to TARGET if value A is not zero
bz targetbranch to TARGET if value A is zero
b targetbranch unconditionally to TARGET
returnuse A as success value; end
popdiscard A
popn nremove N values from the top of the stack
dupduplicate A
dup2duplicate A and B
dupn nduplicate A, N times
dig nNth value from the top of the stack. dig 0 is equivalent to dup
bury nreplace the Nth value from the top of the stack with A. bury 0 fails.
cover nremove top of stack, and place it deeper in the stack such that N elements are above it. Fails if stack depth <= N.
uncover nremove the value at depth N in the stack and shift above items down so the Nth deep value is on top of the stack. Fails if stack depth <= N.
frame_dig iNth (signed) value from the frame pointer.
frame_bury ireplace the Nth (signed) value from the frame pointer in the stack with A
swapswaps A and B on stack
selectselects one of two values based on top-of-stack: B if C != 0, else A
assertimmediately fail unless A is a non-zero number
callsub targetbranch unconditionally to TARGET, saving the next instruction on the call stack
proto a rPrepare top call frame for a retsub that will assume A args and R return values.
retsubpop the top instruction from the call stack and branch to it
switch target …branch to the Ath label. Continue at following instruction if index A exceeds the number of labels.
match target …given match cases from A[1] to A[N], branch to the Ith label where A[I] = B. Continue to the following instruction if no matches are found.