A minimal token implementation demonstrating core token functionality: minting, transferring, burning, and balance tracking. This contract is designed to showcase the Soroban Debugger's ability to trace token operations and storage changes.
| Function | Description |
|---|---|
initialize(admin, name, symbol) |
Set up the token with metadata and admin |
mint(to, amount) |
Create new tokens (admin only) |
transfer(from, to, amount) |
Transfer tokens between addresses |
burn(from, amount) |
Destroy tokens from an address |
balance(account) |
Query token balance for an address |
total_supply() |
Query total token supply |
name() |
Get token name |
symbol() |
Get token symbol |
admin() |
Get admin address |
cd examples/contracts/simple-token
cargo build --target wasm32-unknown-unknown --releaseThe WASM output will be at:
target/wasm32-unknown-unknown/release/soroban_simple_token.wasm
soroban-debug inspect \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function initialize \
--args '["GADMIN123", "MyToken", "MTK"]'Expected storage diff:
+ Admin → GADMIN123
+ Name → "MyToken"
+ Symbol → "MTK"
+ TotalSupply → 0
soroban-debug inspect \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function mint \
--args '["GUSER456", 1000000]'Expected storage diff:
+ Balance(GUSER456) → 1000000
~ TotalSupply : 0 → 1000000
soroban-debug inspect \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function transfer \
--args '["GUSER456", "GRECIPIENT789", 250000]'Expected storage diff:
~ Balance(GUSER456) : 1000000 → 750000
+ Balance(GRECIPIENT789) → 250000
soroban-debug inspect \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function burn \
--args '["GUSER456", 100000]'Expected storage diff:
~ Balance(GUSER456) : 750000 → 650000
~ TotalSupply : 1000000 → 900000
soroban-debug inspect \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function balance \
--args '["GUSER456"]'Expected output:
Return value: 650000
Storage diff: (none - read-only)
soroban-debug step \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function transfer \
--args '["GUSER456", "GRECIPIENT789", 50000]' \
--breakpoint transferThis allows you to step through the transfer logic instruction by instruction, watching:
- Authorization checks
- Balance reads
- Balance validation
- Balance updates
- Event emission
soroban-debug interactive \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasmThen run commands interactively:
> call initialize GADMIN123 "MyToken" "MTK"
> call mint GUSER456 1000000
> call balance GUSER456
> call transfer GUSER456 GRECIPIENT789 250000
> storage
> events
soroban-debug list-functions \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasmExpected output:
initialize
mint
transfer
burn
balance
total_supply
name
symbol
admin
soroban-debug profile \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function transfer \
--args '["GUSER456", "GRECIPIENT789", 100000]'This shows CPU instructions, memory usage, and storage operations for the transfer.
First, create traces for two different operations:
soroban-debug run \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function mint \
--args '["GUSER456", 1000]' \
--output-trace mint_trace.json
soroban-debug run \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function transfer \
--args '["GUSER456", "GRECIPIENT789", 500]' \
--output-trace transfer_trace.jsonThen compare them:
soroban-debug compare mint_trace.json transfer_trace.jsonThis highlights differences in execution paths, storage operations, and gas costs.
soroban-debug inspect \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function transfer \
--args '["GUSER456", "GRECIPIENT789", 999999999]'Expected: Error with code InsufficientBalance (1)
soroban-debug inspect \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function mint \
--args '["GUSER456", 0]'Expected: Error with code ZeroAmount (2)
soroban-debug inspect \
--wasm target/wasm32-unknown-unknown/release/soroban_simple_token.wasm \
--function mint \
--args '["GUSER456", 1000]' \
--caller "GNOT_ADMIN"Expected: Error with code Unauthorized (3)
The contract uses the following storage keys:
Balance(Address)— Persistent storage for each account's balanceTotalSupply— Instance storage for total token supplyName— Instance storage for token nameSymbol— Instance storage for token symbolAdmin— Instance storage for admin address
The contract emits the following events:
init— When token is initializedmint— When tokens are mintedtransfer— When tokens are transferredburn— When tokens are burned
cargo testAll tests include comprehensive coverage of:
- Initialization
- Minting (single and multiple)
- Transfers (partial and full)
- Burning (partial and full)
- Error conditions (zero amounts, insufficient balance)
- Multi-user scenarios
This is a simplified token contract for debugging demonstration purposes. A production token contract would include:
- Allowances and
transfer_fromfunctionality - Decimal precision handling
- Access control beyond a single admin
- Pausability
- More sophisticated authorization patterns
- Integration with Soroban's standard token interface (SEP-41)
The simplicity here makes it ideal for learning the debugger's capabilities without getting lost in complex token logic.