traceState — evmstate
Skip to content

traceState

Analyzes storage access patterns during transaction execution, identifying which contract slots are read and modified, and providing human-readable labels.

Signature

import type { Abi, ContractFunctionName } from "tevm";
import type { TraceStateOptions, TraceStateResult } from "@polareth/evmstate";
 
// @ts-expect-error - Function implementation is missing
function traceState<
  TAbi extends Abi | readonly unknown[] = Abi,
  TFunctionName extends ContractFunctionName<TAbi> = ContractFunctionName<TAbi>,
>(options: TraceStateOptions<TAbi, TFunctionName>): Promise<TraceStateResult>;

Parameters

The function accepts a single options object with these properties:

Connection options

PropertyTypeDescription
rpcUrlstringEthereum RPC URL (needs debug_traceTransaction)
clientMemoryClientOptional Tevm client instance
explorersRecord<string, Explorer>Optional (recommended) configuration for contract explorers

Transaction options

Three ways to specify the transaction to trace:

1. Raw transaction data

PropertyTypeDescription
fromAddressSender address
toAddress | undefinedRecipient address or omit for deploy
dataHexTransaction calldata
valuebigint | undefinedOptional ETH amount to send

2. Contract ABI call

PropertyTypeDescription
fromAddressSender address
toAddressContract address
abiTAbiContract ABI
functionNameTFunctionNameFunction name to call
argsunknown[]Function arguments
valuebigint | undefinedOptional ETH amount to send

3. Existing transaction

PropertyTypeDescription
txHashHexTransaction hash to trace

Return value

Returns a promise that resolves to a record mapping account addresses to their state changes:

import type { TraceStateResult } from "@polareth/evmstate";
 
type ReturnType = TraceStateResult;

See the output format reference for details on the structure.

Examples

Simulating a transaction

import { traceState } from "@polareth/evmstate";
 
const trace = await traceState({
  rpcUrl: "https://1.rpc.thirdweb.com",
  from: "0xSenderAddress",
  to: "0xContractAddress",
  data: "0xEncodedCalldata",
  value: 0n,
});
 
const state = trace.get("0xTokenAddress");
console.log(state?.storage);

Using a contract ABI

example.ts
import { traceState } from "@polareth/evmstate";
 
const trace = await traceState({
  rpcUrl: "https://1.rpc.thirdweb.com",
  from: "0xSenderAddress",
  to: "0xTokenAddress",
  abi: erc20Abi,
  functionName: "transfer",
  args: ["0xRecipient", 1000000000000000000n],
});

Tracing an existing transaction

import { traceState } from "@polareth/evmstate";
 
const trace = await traceState({
  rpcUrl: "https://1.rpc.thirdweb.com",
  txHash: "0xTransactionHash",
});

Using a custom Tevm client

import { createMemoryClient, http } from "tevm";
import { mainnet } from "tevm/common";
import { traceState } from "@polareth/evmstate";
 
const client = createMemoryClient({
  common: mainnet,
  fork: {
    transport: http("https://1.rpc.thirdweb.com"),
    blockTag: "latest",
  },
});
 
const trace = await traceState({
  client,
  from: "0xSenderAddress",
  to: "0xContractAddress",
  data: "0xEncodedCalldata",
});