Skip to main content

trace_call Developer Guide

This guide covers testing and development workflows for Forest's trace_call implementation. For API documentation and user-facing usage, see the trace_call API guide.

Tracer Contract​

The Tracer.sol contract provides various functions to test different tracing scenarios.

Storage Layout​

SlotVariableDescription
0xInitialized to 42
1balancesMapping base slot
2storageTestAStarts empty (for add tests)
3storageTestBStarts empty
4storageTestCStarts empty
5dynamicArrayArray length slot

Function Reference​

Basic Operations​

FunctionSelectorDescription
setX(uint256)0x4018d9aaWrite to slot 0
deposit()0xd0e30db0Receive ETH, update mapping
withdraw(uint256)0x2e1a7d4dSend ETH from contract
doRevert()0xafc874d2Always reverts

Call Tracing​

FunctionSelectorDescription
callSelf(uint256)0xa1a88595Single nested CALL
delegateSelf(uint256)0x8f5e07b8DELEGATECALL trace
complexTrace()0x6659ab96Multiple nested calls
deepTrace(uint256)0x0f3a17b8Recursive N-level deep

Storage Diff Testing​

FunctionSelectorDescription
storageAdd(uint256)0x55cb64b4Add to empty slot 2
storageChange(uint256)0x7c8f6e57Modify existing slot
storageDelete()0xd92846a3Set slot to zero
storageMultiple(uint256,uint256,uint256)0x310af204Change slots 2,3,4

Generating Function Selectors​

Use cast from Foundry to generate function selectors:

# Get selector for a function
cast sig "setX(uint256)"
# Output: 0x4018d9aa

# Encode full calldata
cast calldata "setX(uint256)" 123
# Output: 0x4018d9aa000000000000000000000000000000000000000000000000000000000000007b

Deployed Contracts​

Pre-deployed Tracer contracts for quick testing:

NetworkContract Address
Calibnet0x1112da864d5b3a9e23bbdb543699351a694f814d
Mainnet0x9BB686Ba6a50D1CF670a98f522a59555d4977fb2

Comparison Testing with Anvil​

Anvil uses Geth style tracing (debug_traceCall with prestateTracer), while Forest uses Parity style tracing (trace_call with stateDiff). This makes Anvil useful for comparison testing — verifying that Forest produces semantically equivalent results in a different format.

Prerequisites​

What is Anvil?​

Anvil is a local Ethereum development node included with Foundry. It provides:

  • Instant block mining
  • Pre-funded test accounts (10 accounts with 10,000 ETH each)
  • Support for debug_traceCall with various tracers
  • No real tokens required

Starting Anvil​

# Start Anvil with tracer to allow debug_traceCall API's
anvil --tracing

Anvil RPC endpoint: http://localhost:8545

Deploying Contract on Anvil​

forge create src/tool/subcommands/api_cmd/contracts/tracer/Tracer.sol:Tracer \
--rpc-url http://localhost:8545 \
--broadcast \
--private-key <ANVIL_OUTPUT_PRIVATE_KEY>

# Output:
# Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
# Deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
# Transaction hash: 0x...

Comparing Forest vs Anvil Responses​

The same contract call can be tested against both nodes. The request data payloads are identical; only the method name and parameter ordering differ.

Forest (Parity-style trace_call):

curl -s -X POST "http://localhost:2345/rpc/v1" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "trace_call",
"params": [
{"from": "0x...", "to": "0x...", "data": "0x4018d9aa..."},
["stateDiff"],
"latest"
]
}'

Anvil (Geth style debug_traceCall):

curl -s -X POST "http://localhost:8545" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "debug_traceCall",
"params": [
{"from": "0x...", "to": "0x...", "data": "0x4018d9aa..."},
"latest",
{"tracer": "prestateTracer", "tracerConfig": {"diffMode": true}}
]
}'

Integration Test Script​

An automated test script is available to compare Forest's trace_call with Anvil's debug_traceCall:

# Run the test (requires Forest and Anvil running)
./scripts/tests/trace_call_integration_test.sh

or

# Deploy contract on Anvil first, forest and anvil node should already be running
./scripts/tests/trace_call_integration_test.sh --deploy

Test Categories​

  1. Trace Tests: Call hierarchy, subcalls, reverts, deep traces
  2. Balance Diff Tests: ETH transfers, deposits
  3. Storage Diff Tests: Single slot, multiple slots, value comparison

Official Resources​