State Management
algorand-typescript-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 * as algots from '@algorandfoundation/algorand-typescript';import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing';
// Create the context manager for snippets belowconst ctx = new TestExecutionContext();
Global State
Global state is represented as instance attributes on algots.Contract
and algots.arc4.Contract
classes.
class MyContract extends algots.arc4.Contract { stateA = algots.GlobalState<algots.uint64>({ key: 'globalStateA' }); stateB = algots.GlobalState({ initialValue: algots.Uint64(1), key: 'globalStateB' });}
// In your testconst contract = ctx.contract.create(MyContract);contract.stateA.value = algots.Uint64(10);contract.stateB.value = algots.Uint64(20);
Local State
Local state is defined similarly to global state, but accessed using account addresses as keys.
class MyContract extends algots.arc4.Contract { localStateA = algots.LocalState<algots.uint64>({ key: 'localStateA' });}
// In your testconst contract = ctx.contract.create(MyContract);const account = ctx.any.account();contract.localStateA(account).value = algots.Uint64(10);
Boxes
The framework supports various Box abstractions available in algorand-typescript
.
class MyContract extends algots.arc4.Contract { box: algots.Box<algots.uint64> | undefined; boxMap = algots.BoxMap<algots.bytes, algots.uint64>({ keyPrefix: 'boxMap' });
@algots.arc4.abimethod() someMethod(keyA: algots.bytes, keyB: algots.bytes, keyC: algots.bytes) { this.box = algots.Box<algots.uint64>({ key: keyA }); this.box.value = algots.Uint64(1); this.boxMap.set(keyB, algots.Uint64(1)); this.boxMap.set(keyC, algots.Uint64(2)); }}
// In your testconst contract = ctx.contract.create(MyContract);const keyA = algots.Bytes('keyA');const keyB = algots.Bytes('keyB');const keyC = algots.Bytes('keyC');
contract.someMethod(keyA, keyB, keyC);
// Access boxesconst boxContent = ctx.ledger.getBox(contract, keyA);expect(ctx.ledger.boxExists(contract, keyA)).toBe(true);
// Set box content manuallyctx.ledger.setBox(contract, keyA, algots.op.itob(algots.Uint64(1)));
Scratch Space
Scratch space is represented as a list of 256 slots for each transaction.
@algots.contract({ scratchSlots: [1, 2, { from: 3, to: 20 }] })class MyContract extends algots.Contract { approvalProgram(): boolean { algots.op.Scratch.store(1, algots.Uint64(5)); algots.assert(algots.op.Scratch.loadUint64(1) === algots.Uint64(5)); return true; }}
// In your testconst contract = ctx.contract.create(MyContract);const result = contract.approvalProgram();
expect(result).toBe(true);const scratchSpace = ctx.txn.lastGroup.getScratchSpace();expect(scratchSpace[1]).toEqual(5);
For more detailed information, explore the example contracts in the examples/
directory, the coverage page, and the API documentation.
// test cleanupctx.reset();