Docs
Docs
Home
Getting Started
Agent Tooling
CLI
Supported Chains
Acala
Aptos
Arbitrum
Arc
Asset Hub
Astar
Avalanche
Base
Berachain
Bifrost
Binance Smart Chain
Bittensor
Blast
Boba Network
Bridge Hub
Celo
Centrifuge
Chiliz
Cronos
Enjin
Ethereum
Etherlink
Flow EVM Gateway
Gnosis
Hydration
Hyperliquid
Immutable
Ink
IoTeX
Kusama
Linea
LISK
Manta Atlantic
Manta Pacific
Mantle
MegaETH
Monad
Movement
Neuroweb
opBNB
Optimism
Plasma
Polkadot
Polygon
Pulsechain
Robinhood
Ronin
Scroll
Sonic
Starknet
Taiko
Tempo
Sui
TRON
Unichain
Viction
World Chain
XDC Network
XX Network
Zetachain
zkSync Era
Zora
Supported ChainsPlasmaJSON-RPC APIDebug Methods

debug_traceBlockByHash - Plasma RPC Method

Trace all transactions in a block by hash on Plasma. Investigate specific blocks, analyze execution order, and debug reverts with detailed traces.

Plasma RPC endpoint: endpoint URLs, plans and pricing.

Traces all transactions in a block on Plasma identified by its block hash. Returns detailed execution traces for every transaction, making it ideal for investigating specific blocks when you know the exact hash.

Why Plasma? Build on an EVM Layer 1 for stablecoin payments with PlasmaBFT consensus and Reth execution with 1 second blocks, XPL gas, full EVM JSON-RPC, and debug plus txpool on Dwellir.

Archive Node Required

This method requires an archive node with debug APIs enabled. Standard full nodes prune the historical state needed for transaction tracing. Dwellir provides archive node access for Plasma - ensure your plan includes debug namespace support.

When to Use This Method

debug_traceBlockByHash is essential for payment app developers, wallet teams, and teams shipping Solidity contracts for dollar transfers:

  • Investigating Specific Blocks - When you have a block hash from an event, alert, or on-chain reference, trace every transaction in that exact block on Plasma
  • Analyzing Transaction Execution Order - Understand how transactions within a block interact, including cross-transaction state dependencies
  • Debugging Reverted Transactions - Find the exact opcode where transactions failed across an entire block for stablecoin transfers, payment apps, and wallets that need 1 second confirmation
  • Fork and Reorg Analysis - Use block hashes to trace transactions in specific forks, ensuring you analyze the correct chain branch

Best Practices

  • Use block hash for deterministic results during chain reorganizations
  • Same performance considerations as debug_traceBlockByNumber apply
  • Requires archive node access; not available on standard full nodes
JSON-RPC request
{
  "jsonrpc": "2.0",
  "method": "debug_traceBlockByHash",
  "params": [
    "0xf8e25a8aece71a7a87e8aaefd242832cb0ce838ebbad206c48ca9e9f6b1a7a07",
    {
      "tracer": "callTracer"
    }
  ],
  "id": 1
}

Code Examples

Bash
# Trace with call tracer
curl -X POST https://api-plasma-mainnet.n.dwellir.com/YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "debug_traceBlockByHash",
    "params": [
      "0xf8e25a8aece71a7a87e8aaefd242832cb0ce838ebbad206c48ca9e9f6b1a7a07",
      {"tracer": "callTracer"}
    ],
    "id": 1
  }'

# Trace with prestate tracer
curl -X POST https://api-plasma-mainnet.n.dwellir.com/YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "debug_traceBlockByHash",
    "params": [
      "0xf8e25a8aece71a7a87e8aaefd242832cb0ce838ebbad206c48ca9e9f6b1a7a07",
      {"tracer": "prestateTracer"}
    ],
    "id": 1
  }'

Common Use Cases

1. Find All Reverted Transactions in a Block

Identify and analyze failed transactions on Plasma:

JavaScript
async function findReverts(provider, blockHash) {
  const traces = await provider.send('debug_traceBlockByHash', [
    blockHash,
    { tracer: 'callTracer' }
  ]);

  const reverts = [];

  for (const trace of traces) {
    if (trace.result.error) {
      reverts.push({
        txHash: trace.txHash,
        error: trace.result.error,
        revertReason: trace.result.revertReason || 'N/A',
        from: trace.result.from,
        to: trace.result.to,
        gasUsed: parseInt(trace.result.gasUsed, 16)
      });
    }

    // Also check sub-calls for internal reverts
    const internalReverts = findInternalReverts(trace.result.calls || []);
    if (internalReverts.length > 0) {
      reverts.push({
        txHash: trace.txHash,
        internalReverts,
        topLevelSuccess: !trace.result.error
      });
    }
  }

  console.log(`Found ${reverts.length} reverted transactions out of ${traces.length}`);
  for (const r of reverts) {
    console.log(`  ${r.txHash}: ${r.error || 'internal revert'}`);
  }
  return reverts;
}

function findInternalReverts(calls) {
  const reverts = [];
  for (const call of calls) {
    if (call.error) {
      reverts.push({ type: call.type, to: call.to, error: call.error });
    }
    reverts.push(...findInternalReverts(call.calls || []));
  }
  return reverts;
}

2. Analyze Token Transfer Patterns in a Block

Extract all ERC-20 transfer events from block traces on Plasma:

Python
import requests

def analyze_token_transfers(block_hash):
    response = requests.post('https://api-plasma-mainnet.n.dwellir.com/YOUR_API_KEY', json={
        'jsonrpc': '2.0',
        'method': 'debug_traceBlockByHash',
        'params': [block_hash, {'tracer': 'callTracer'}],
        'id': 1
    })
    traces = response.json()['result']

    # ERC-20 transfer(address,uint256) selector
    TRANSFER_SELECTOR = '0xa9059cbb'
    # ERC-20 transferFrom(address,address,uint256) selector
    TRANSFER_FROM_SELECTOR = '0x23b872dd'

    transfers = []

    for trace in traces:
        calls = flatten_calls(trace['result'])
        for call in calls:
            input_data = call.get('input', '')
            if input_data.startswith(TRANSFER_SELECTOR) or \
               input_data.startswith(TRANSFER_FROM_SELECTOR):
                transfers.append({
                    'tx_hash': trace['txHash'],
                    'token_contract': call['to'],
                    'from': call['from'],
                    'type': call['type'],
                    'gas_used': int(call.get('gasUsed', '0x0'), 16)
                })

    print(f'Found {len(transfers)} token transfers in block')
    # Group by token contract
    by_token = {}
    for t in transfers:
        by_token.setdefault(t['token_contract'], []).append(t)

    for token, txs in by_token.items():
        print(f'  {token}: {len(txs)} transfers')

    return transfers

def flatten_calls(trace):
    calls = [trace]
    for sub in trace.get('calls', []):
        calls.extend(flatten_calls(sub))
    return calls

analyze_token_transfers('0xf8e25a8aece71a7a87e8aaefd242832cb0ce838ebbad206c48ca9e9f6b1a7a07')

3. Block Execution State Diff

Compare account states before and after block execution using the prestate tracer:

JavaScript
async function getBlockStateDiff(provider, blockHash) {
  // Get prestate - accounts state before each transaction
  const prestateTraces = await provider.send('debug_traceBlockByHash', [
    blockHash,
    { tracer: 'prestateTracer', tracerConfig: { diffMode: true } }
  ]);

  const allAddresses = new Set();
  const balanceChanges = {};

  for (const trace of prestateTraces) {
    const pre = trace.result.pre || trace.result;
    const post = trace.result.post || {};

    for (const [addr, state] of Object.entries(pre)) {
      allAddresses.add(addr);
      if (!balanceChanges[addr]) {
        balanceChanges[addr] = {
          preBal: BigInt(state.balance || '0x0'),
          postBal: BigInt((post[addr]?.balance) || state.balance || '0x0')
        };
      }
    }
  }

  console.log(`Block touched ${allAddresses.size} unique addresses`);
  for (const [addr, change] of Object.entries(balanceChanges)) {
    const diff = change.postBal - change.preBal;
    if (diff !== 0n) {
      console.log(`  ${addr}: ${diff > 0n ? '+' : ''}${diff} wei`);
    }
  }

  return balanceChanges;
}

Error Handling

Common errors and solutions:

Error CodeDescriptionSolution
-32000Block not foundVerify the block hash is correct and exists on Plasma
-32000Missing trie nodeNode is not an archive node or state has been pruned - use an archive endpoint
-32601Method not foundDebug namespace is not enabled on the node
-32603Internal errorBlock may be too large to trace - increase timeout or use disableStorage
-32005Rate limit exceededReduce request frequency or upgrade your plan
-32002Resource unavailableNode is syncing or the requested block is not yet available
JavaScript
async function safeTraceBlockByHash(provider, blockHash, options = {}) {
  const defaultOptions = {
    tracer: 'callTracer',
    timeout: '60s',
    ...options
  };

  try {
    return await provider.send('debug_traceBlockByHash', [blockHash, defaultOptions]);
  } catch (error) {
    if (error.code === -32601) {
      throw new Error('debug_traceBlockByHash not available - ensure archive node with debug API');
    }
    if (error.code === -32000 && error.message?.includes('not found')) {
      throw new Error(`Block ${blockHash} not found - verify the hash is correct`);
    }
    if (error.message?.includes('timeout')) {
      console.warn('Trace timed out - retrying with top-level calls only');
      return await provider.send('debug_traceBlockByHash', [
        blockHash,
        { tracer: 'callTracer', tracerConfig: { onlyTopCall: true } }
      ]);
    }
    throw error;
  }
}

Related Methods

  • debug_traceBlock - Trace all transactions using RLP-encoded block data
  • debug_traceBlockByNumber - Trace all transactions in a block by number
  • debug_traceTransaction - Trace a single transaction by hash
  • debug_traceCall - Trace a call without creating a transaction
  • eth_getBlockByHash - Get block details by hash (without traces)

debug_traceBlock

Trace all transactions in a block on Plasma using a serialized block payload. Essential for block-level debugging, gas profiling, and MEV analysis.

debug_traceBlockByNumber

Trace all transactions in a block by number on Plasma. Analyze gas consumption, debug state transitions, and inspect historical block execution.

On this page

When to Use This MethodBest PracticesCode ExamplesCommon Use Cases1. Find All Reverted Transactions in a Block2. Analyze Token Transfer Patterns in a Block3. Block Execution State DiffError HandlingRelated Methods