Skip to main content
The interactive trace viewer provides a rich terminal UI for exploring Stellar smart contract execution traces. Navigate through complex call trees, search for specific events, and inspect contract state with keyboard shortcuts and visual highlighting.

Launching the viewer

Start the interactive trace viewer with the -i flag:
erst debug <transaction-hash> --interactive
# or short form
erst debug <transaction-hash> -i
The viewer launches with:
  • Transaction summary (hash, total steps)
  • Automatic trap detection
  • Full keyboard navigation
  • Real-time terminal resizing

Example session

πŸ” ERST Interactive Trace Viewer
════════════════════════════════════════════════════════════════════
Transaction: abc123def456789
Total Steps: 248

⚠️  Memory Trap Detected!
Type: i32.load out of bounds
Location: token.rs:45
  Use 't' or 'trap' command to see local variables

Stepping through execution

n, next, forward
The viewer respects both event filters and the stdlib toggle, skipping filtered-out steps automatically.
When navigating, the viewer automatically skips Rust core::* traces if the stdlib filter is enabled.

Event type filtering

Cycle through event types with the f command:
f, filter
Filter options cycle through:
  1. All steps (no filter)
  2. Traps only
  3. Contract calls only
  4. Host functions only
  5. Authorization events only
Filter: contract_call (42 matching steps)

Standard library filtering

Toggle visibility of Rust core library traces:
S  # Case-sensitive: capital S
This hides noisy core::* function calls, letting you focus on your contract logic:
πŸ‘οΈ  Rust core::* traces are now hidden

Search functionality

The search engine uses fuzzy matching to find events:
1

Start search

Press / to enter search mode
2

Enter query

Type your search term (contract ID, function name, error message)
3

Navigate results

  • n: Jump to next match
  • N: Jump to previous match
  • ESC: Clear search
Search fields:
  • Contract IDs
  • Function names
  • Error messages
  • Event data
  • Event types
Search is case-insensitive by default and uses fuzzy matching, so β€œtransf” will match β€œtransfer”.

State inspection

Current state display

View the current execution state:
s, show, state
Shows:
  • Step number and timestamp
  • Operation type
  • Contract ID and function
  • Arguments and return values
  • WASM instructions
  • Error messages
  • Source file locations
  • GitHub links (when available)
  • Memory and host state summaries

State reconstruction

Reconstruct the full state at any step:
r, reconstruct
Reconstruction includes:
  • Complete host state
  • Memory contents
  • Storage entries
  • All contract data at that point
πŸ”§ Reconstructed State at Step 125
════════════════════════════════════════════════════════════════════
Step: 125
Time: 15:04:05.342
Operation: InvokeHostFunction

Host State:
  balance: i128(1000000)
  admin: Address(...)
  initialized: Bool(true)

Memory:
  0x1000: [42, 0, 0, 0, ...]
  0x2000: [255, 255, 255, 255, ...]

Trap inspection

When a memory trap is detected, view detailed information:
t, trap
Trap details include:
  • Trap type (out of bounds, division by zero, etc.)
  • Exact instruction that failed
  • Source file and line number
  • Local variable values (with debug symbols)
  • Stack trace
❌ Memory Trap Detected

Type: i32.load offset=8 out of bounds
Step: 145/248

Source Location:
  File: src/token.rs
  Line: 45
  Column: 12

Local Variables:
  amount: i128(1000000)
  recipient: Address("GC...")
  balance_ptr: 0x10008  ← Out of bounds!

Stack Trace:
  token::transfer() at token.rs:45
  token::transfer_from() at token.rs:89
Local variable inspection requires contracts to be compiled with debug symbols. See Source mapping for details.

List and navigation

List steps

Show steps around the current position:
l, list [count]
Default count is 10:
πŸ“‹ Steps 120-130
Filter: trap
════════════════════════════════════════════════════════════════════
     120: InvokeHostFunction (transfer)
     121: HostFunction (require_auth)
  β–Ά  125: ContractCall (check_balance) [trap]
     126: HostFunction (get_contract_data)
     127: ContractCall (update_state)
View detailed navigation state:
i, info
Shows:
  • Total steps and current position
  • Active filters and matching counts
  • Navigation capabilities (can step back/forward)
  • Snapshot count
  • Trap detection status

Split-pane view

View trace and source code side by side:
sp, split
The split pane displays:
  • Left: Current trace node with full details
  • Right: Source code context (if available)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Step: 125               β”‚ token.rs                β”‚
β”‚ Function: transfer      β”‚ 43: fn transfer(        β”‚
β”‚ Contract: CDLZFC...     β”‚ 44:   amount: i128,     β”‚
β”‚                         β”‚ 45:   recipient: Addr   β”‚ ← Error here
β”‚ Error: Out of bounds    β”‚ 46: ) -> Result<()> {   β”‚
β”‚                         β”‚ 47:   check_balance();  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
The split-pane view requires source mapping information. Compile your contracts with --features debug to enable this.

Yanking (copying) raw XDR

Copy raw XDR values to the clipboard:
y, yank a [index]
# Example: yank a 0
Useful for:
  • Inspecting exact XDR encoding
  • Debugging type conversions
  • External XDR analysis tools
✨ Copied raw XDR to clipboard

Keyboard shortcuts reference

View all shortcuts in the viewer:
?, h, help

Complete shortcut list

KeyAction
n, next, forwardStep forward
p, prev, backStep backward
j <step>, jump <step>Jump to specific step
s, show, stateShow current state
SToggle stdlib filter
f, filterCycle event type filter
/Start search
n (in search)Next match
N (in search)Previous match
ESCClear search
r, reconstructReconstruct state
t, trapShow trap info
l <count>, list <count>List steps
i, infoShow navigation info
sp, splitSplit-pane view
e, expandExpand current node
c, collapseCollapse current node
EToggle expand/collapse all
y <a/r>, yank <a/r>Copy raw XDR
?, h, helpShow help
q, quit, exitExit viewer

Advanced features

Cross-contract call tracking

The viewer automatically highlights contract boundaries:
     45: ContractCall (transfer)
     β”Œβ”€ Contract boundary: CDLZFC... β†’ CA3D5K...
     46: ContractCall (mint)
     47: HostFunction (require_auth)

Terminal resizing

The viewer automatically reflows content when you resize your terminal:
  • Long contract IDs wrap intelligently
  • XDR strings adapt to available width
  • Tree structure maintains alignment

Match counter

When searching, see your position in results:
Match 3 of 12

Tips and best practices

1

Start with filters

Use event type filters to focus on relevant steps. Most debugging starts with trap or error events.
2

Hide stdlib noise

Press S to hide Rust core library traces and focus on your contract logic.
3

Search strategically

Search for contract IDs, function names, or error keywords to quickly locate issues.
4

Reconstruct state

Use state reconstruction to see complete memory and storage at failure points.
5

Use split-pane for debugging

When you find an error, use split-pane view to see the exact source code that failed.

Next steps