Skip to main content
Simultaneously replay a transaction against a local WASM file and the on-chain contract, then display a side-by-side diff.

Usage

erst compare <transaction-hash> [flags]

Description

The compare command is the primary tool for “What broke when I updated my contract?” debugging. It works by:
  1. Fetching the transaction envelope and ledger state from the network
  2. Running two simulation passes in parallel:
    • Pass A: Uses your local WASM file (--wasm)
    • Pass B: Uses the on-chain WASM (normal replay)
  3. Displaying a color-coded side-by-side diff of the results
This command is essential for testing contract changes before deployment and understanding behavioral differences.

Examples

erst compare abc123...def --wasm ./my_contract.wasm

Arguments

transaction-hash
string
required
Stellar transaction hash to replay and compare

Flags

Required

--wasm
string
required
Path to local WASM file for comparisonThis is the contract version you want to test against the on-chain version.

Network configuration

--network
string
default:"mainnet"
Stellar network to useOptions: testnet, mainnet, futurenetAlias: -n
--rpc-url
string
Custom Soroban RPC URLCan specify multiple URLs separated by commas for fallback.
--rpc-token
string
RPC authentication tokenCan also use ERST_RPC_TOKEN environment variable.

Optimization

--optimize
boolean
default:"false"
Run dead-code elimination on local WASM before simulationUseful for comparing optimized vs unoptimized builds.
--args
string[]
Mock arguments to pass to the local WASM executionCan be specified multiple times: --args arg1 --args arg2

Output options

--verbose
boolean
default:"false"
Print full simulation JSON for both passesAlias: -v
--theme
string
Color theme for diff outputOptions: default, deuteranopia, protanopia, tritanopia, high-contrast

Advanced options

--protocol-version
uint32
Override protocol version for both simulation passesExamples: 20, 21, 22
--sim-path
string
Path to erst-sim binaryOverrides auto-discovery.

Output

The compare command displays:
📊  Compare Replay
Transaction : abc123...def
Network     : mainnet
Local WASM  : ./my_contract.wasm
If --optimize is used, shows optimization report:
Optimization:
  Original size: 245.3 KB
  Optimized size: 189.7 KB
  Reduction: 55.6 KB (22.7%)

Side-by-side diff

Displays differences in:
  • Events: Contract events emitted during execution
  • Diagnostic output: Debug logs and traces
  • Budget usage: CPU instructions, memory bytes, operations
  • Call paths: Function call trees showing divergence points
  • Return values: Different results or error codes
Events:
- Local:    transfer(from=G123..., to=G456..., amount=1000)
+ On-chain: transfer(from=G123..., to=G456..., amount=500)

Use cases

Pre-deployment testing

Test contract changes before deploying:
# Build new version
cargo build --target wasm32-unknown-unknown --release

# Compare with production transaction
erst compare <prod-tx-hash> \
  --wasm ./target/wasm32-unknown-unknown/release/contract.wasm

Debugging behavior changes

Understand why a transaction behaves differently:
# Compare local fix with failing transaction
erst compare <failing-tx-hash> \
  --wasm ./target/debug/contract.wasm \
  --verbose

Optimization validation

Verify optimizations don’t change behavior:
# Compare unoptimized vs optimized
erst compare <tx-hash> \
  --wasm ./contract_optimized.wasm \
  --optimize

Protocol upgrade testing

Test contract behavior on new protocol versions:
# Test on protocol 22
erst compare <tx-hash> \
  --wasm ./contract.wasm \
  --protocol-version 22

Parallel execution

Both simulation passes run in parallel for performance:
  • Faster total execution time
  • Identical ledger state for both passes
  • Consistent timestamp and protocol version
The parallel execution ensures a fair comparison by using exactly the same network conditions for both passes.

Verbose mode

With --verbose, shows full JSON output for each pass:
──── VERBOSE: LOCAL WASM ────
  Status : Success
  Events : 3
  DiagEvt: 5
    • transfer(from=..., to=..., amount=1000)
    • approval(owner=..., spender=...)
    • balance_updated(account=..., balance=5000)
  Budget : CPU=1250000  Mem=524288  Ops=45

──── VERBOSE: ON-CHAIN WASM ────
  Status : Success
  Events : 3
  DiagEvt: 5
    • transfer(from=..., to=..., amount=1000)
    • approval(owner=..., spender=...)
    • balance_updated(account=..., balance=5000)
  Budget : CPU=1180000  Mem=491520  Ops=42

Error handling

Common errors and solutions:

WASM file not found

Error: WASM file not found: ./contract.wasm
Solution: Check the path and ensure the file exists:
ls -lh ./target/wasm32-unknown-unknown/release/*.wasm

Invalid transaction hash

Error: invalid transaction hash: abc123
Solution: Provide a valid 64-character hex hash:
erst compare 5c0a1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab --wasm ./contract.wasm

Simulation failed

Error: local WASM simulation failed: invalid contract
Solution: Ensure WASM is valid and compatible:
# Check WASM file
wasm-opt --validate ./contract.wasm

# Try with optimization
erst compare <tx-hash> --wasm ./contract.wasm --optimize
  • debug - Debug individual transactions
  • trace - Explore execution traces interactively
  • profile - Analyze gas consumption differences