Skip to main content
This page provides complete, annotated smart contract examples demonstrating various patterns and techniques.

Simple Counter

A basic counter that increments a storage value on each call.
counter.asm
; Simple counter contract
; Increments a storage value by 1 on each call
.entry main

.const STORAGE_COUNTER 0

main:
    LOADI R0, STORAGE_COUNTER   ; Load storage slot address
    SLOAD R1, R0                ; Load current counter value
    LOADI R2, 1                 ; Load increment value
    ADD R1, R1, R2              ; Increment: R1 = R1 + 1
    SSTORE R0, R1               ; Store new value
    LOG R1                      ; Emit new counter value
    HALT                        ; Exit successfully

Owner-Only Access

A contract that restricts execution to its deployer.
owner.asm
; Owner-only contract
; Only the deployer can call this contract
.entry main

.const STORAGE_OWNER 0
.const STORAGE_INITIALIZED 1
.const STORAGE_VALUE 2

main:
    ; Check if initialized
    LOADI R0, STORAGE_INITIALIZED
    SLOAD R1, R0
    LOADI R2, 1
    EQ R3, R1, R2               ; Is initialized?
    LOADI R4, check_owner
    JUMPI R3, R4                ; Jump if initialized

    ; First call - store deployer as owner
    CALLER R5
    LOADI R6, STORAGE_OWNER
    SSTORE R6, R5               ; Store owner address
    SSTORE R0, R2               ; Mark as initialized
    HALT

check_owner:
    ; Verify caller is owner
    CALLER R7
    LOADI R8, STORAGE_OWNER
    SLOAD R9, R8                ; Load owner address
    EQ R10, R7, R9              ; Is caller == owner?
    LOADI R11, authorized
    JUMPI R10, R11              ; Jump if authorized
    REVERT                      ; Revert if not owner

authorized:
    ; Owner-only logic here
    LOADI R12, STORAGE_VALUE
    SLOAD R13, R12
    LOADI R14, 1
    ADD R13, R13, R14           ; Increment value
    SSTORE R12, R13
    LOG R13
    HALT

Simple Token Balance

A minimal token contract tracking balances.
token.asm
; Minimal token contract
; Each address has a balance in storage
.entry main

.const STORAGE_TOTAL_SUPPLY 0
.const INITIAL_SUPPLY 1000000

main:
    ; Check if initialized
    LOADI R0, STORAGE_TOTAL_SUPPLY
    SLOAD R1, R0
    LOADI R2, 0
    EQ R3, R1, R2               ; Is total supply 0?
    LOADI R4, mint_initial
    JUMPI R3, R4                ; Initialize if needed
    
    ; Normal execution - just show caller balance
    CALLER R5
    SLOAD R6, R5                ; Load balance using address as key
    LOG R6                      ; Emit balance
    HALT

mint_initial:
    ; Mint initial supply to deployer
    CALLER R7
    LOADI R8, INITIAL_SUPPLY
    SSTORE R7, R8               ; Store balance
    SSTORE R0, R8               ; Store total supply
    LOG R8                      ; Emit minted amount
    HALT

Conditional Update

A contract that only updates storage under certain conditions.
conditional.asm
; Conditional storage update
; Only allows updating if value is below threshold
.entry main

.const STORAGE_VALUE 0
.const THRESHOLD 100
.const INCREMENT 10

main:
    ; Load current value
    LOADI R0, STORAGE_VALUE
    SLOAD R1, R0                ; R1 = current value
    LOG R1                      ; Log current value
    
    ; Check if below threshold
    LOADI R2, THRESHOLD
    LT R3, R1, R2               ; R3 = (value < 100)
    LOADI R4, can_update
    JUMPI R3, R4                ; Jump if can update
    
    ; Value too high - revert
    REVERT

can_update:
    ; Increment value
    LOADI R5, INCREMENT
    ADD R1, R1, R5              ; R1 += 10
    SSTORE R0, R1               ; Store new value
    LOG R1                      ; Log new value
    HALT

Loop Example

Demonstrates implementing a loop in assembly.
loop.asm
; Loop example - sum numbers 1 to 10
.entry main

.const MAX_ITERATIONS 10

main:
    LOADI R0, 0                 ; Counter (i = 0)
    LOADI R1, 0                 ; Sum (sum = 0)
    LOADI R2, MAX_ITERATIONS    ; Max value

loop:
    ; Add counter to sum
    ADD R1, R1, R0              ; sum += i
    
    ; Increment counter
    LOADI R3, 1
    ADD R0, R0, R3              ; i++
    
    ; Check if done
    LE R4, R0, R2               ; i <= 10?
    LOADI R5, loop
    JUMPI R4, R5                ; Continue if i <= 10
    
    ; Done - emit result
    LOG R1                      ; Log sum (should be 55)
    HALT

Payment Contract

Accepts payments and tracks the total received.
payment.asm
; Payment contract - accepts and tracks payments
.entry main

.const STORAGE_TOTAL_RECEIVED 0
.const MIN_PAYMENT 100

main:
    ; Get payment amount
    CALLVALUE R0                ; R0 = sent value
    LOG R0                      ; Log payment
    
    ; Check minimum payment
    LOADI R1, MIN_PAYMENT
    LT R2, R0, R1               ; payment < 100?
    LOADI R3, too_small
    JUMPI R2, R3                ; Jump if too small
    
    ; Accept payment - add to total
    LOADI R4, STORAGE_TOTAL_RECEIVED
    SLOAD R5, R4                ; Load total
    ADD R5, R5, R0              ; Add payment
    SSTORE R4, R5               ; Store new total
    LOG R5                      ; Log new total
    HALT

too_small:
    ; Payment too small - revert
    REVERT

Next Steps

Assembly Reference

Complete assembly language reference

Deploy Contracts

Learn how to deploy your contracts

VM Instructions

Full instruction set reference

Gas Optimization

Optimize your contracts for gas efficiency

Build docs developers (and LLMs) love