State Management
algorand-python-testing
provides tools to test state-related abstractions in Algorand smart contracts. This guide covers global state, local state, boxes, and scratch space management.
import algopyfrom algopy_testing import algopy_testing_context
# Create the context manager for snippets belowctx_manager = algopy_testing_context()
# Enter the contextcontext = ctx_manager.__enter__()
Global State
Global state is represented as instance attributes on algopy.Contract
and algopy.ARC4Contract
classes.
class MyContract(algopy.ARC4Contract): def __init__(self): self.state_a = algopy.GlobalState(algopy.UInt64, key="global_uint64") self.state_b = algopy.UInt64(1)
# In your testcontract = MyContract()contract.state_a.value = algopy.UInt64(10)contract.state_b.value = algopy.UInt64(20)
Local State
Local state is defined similarly to global state, but accessed using account addresses as keys.
class MyContract(algopy.ARC4Contract): def __init__(self): self.local_state_a = algopy.LocalState(algopy.UInt64, key="state_a")
# In your testcontract = MyContract()account = context.any.account()contract.local_state_a[account] = algopy.UInt64(10)
Boxes
The framework supports various Box abstractions available in algorand-python
.
class MyContract(algopy.ARC4Contract): def __init__(self): self.box_map = algopy.BoxMap(algopy.Bytes, algopy.UInt64)
@algopy.arc4.abimethod() def some_method(self, key_a: algopy.Bytes, key_b: algopy.Bytes, key_c: algopy.Bytes) -> None: self.box = algopy.Box(algopy.UInt64, key=key_a) self.box.value = algopy.UInt64(1) self.box_map[key_b] = algopy.UInt64(1) self.box_map[key_c] = algopy.UInt64(2)
# In your testcontract = MyContract()key_a = b"key_a"key_b = b"key_b"key_c = b"key_c"
contract.some_method(algopy.Bytes(key_a), algopy.Bytes(key_b), algopy.Bytes(key_c))
# Access boxesbox_content = context.ledger.get_box(contract, key_a)assert context.ledger.box_exists(contract, key_a)
# Set box content manuallywith context.txn.create_group(): context.ledger.set_box(contract, key_a, algopy.op.itob(algopy.UInt64(1)))
Scratch Space
Scratch space is represented as a list of 256 slots for each transaction.
class MyContract(algopy.Contract, scratch_slots=(1, 2, algopy.urange(3, 20))): def approval_program(self): algopy.op.Scratch.store(1, algopy.UInt64(5)) assert algopy.op.Scratch.load_uint64(1) == algopy.UInt64(5) return True
# In your testcontract = MyContract()result = contract.approval_program()
assert resultscratch_space = context.txn.last_group.get_scratch_space()assert scratch_space[1] == algopy.UInt64(5)
For more detailed information, explore the example contracts in the examples/
directory, the coverage page, and the API documentation.
ctx_manager.__exit__(None, None, None)