Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions docs/debug-and-trace-apis.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,7 @@ To enable debug and trace APIs on your Polygon node, you must have a [paid plan]

#### Dedicated Nodes

To enable debug and trace APIs on your dedicated Polygon node, you must have a [paid plan](https://chainstack.com/pricing/). Dedicated Nodes can be deployed either as the Bor or Erigon client implementation for the full and archive modes respectively, however, they slightly differ from each other:

* With a node running on Bor, only `debug_*`namespace is exposed.
* With a node running on Erigon, both `debug_*` and `trace_*`namespaces are exposed.

For the full list of the available debug and trace API methods, see: [Erigon: RPC implementation status](https://github.com/ledgerwatch/erigon/blob/stable/cmd/rpcdaemon/README.md#rpc-implementation-status)
To enable debug and trace APIs on your dedicated Polygon node, you must have a [paid plan](https://chainstack.com/pricing/). Dedicated Polygon nodes run the Bor client, which exposes the `debug_*` namespace. Bor does not implement the Erigon-only Parity `trace_*` namespace — see [Polygon methods](/docs/polygon-methods) for the `trace_*` → `debug_*` migration.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Say “debug APIs,” not “debug and trace APIs.”

The paragraph says Bor exposes only debug_* and does not implement trace_*, so the opening currently implies unsupported trace APIs are available on dedicated Polygon nodes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/debug-and-trace-apis.mdx` at line 46, Update the opening sentence in the
dedicated Polygon node documentation to say “debug APIs” instead of “debug and
trace APIs.” Keep the remaining Bor and trace_* migration explanation unchanged.


### BNB Smart Chain

Expand Down
4 changes: 4 additions & 0 deletions reference/polygon-debug-trace-rpc-methods.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ This tracer looks for function signatures that are 4 bytes long during contract

This tracer extracts information about all internal calls made by a transaction, providing visibility into how contracts interact with each other.

### `flatCallTracer`

This tracer returns the same call data as `callTracer` but as a flat array in the Parity-style trace format, where each entry's `traceAddress` marks its position in the call tree. It is the drop-in replacement for the Erigon `trace_*` methods, which Bor does not implement.

### `prestateTracer`

This tracer returns sufficient information about an account to create a local execution of the transaction. This procedure runs the given transaction again and monitors every aspect of the state that is modified or accessed during execution.
Expand Down
2 changes: 1 addition & 1 deletion reference/polygon-getblockreceipts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ openapi: /openapi/polygon_node_api/transaction_info/eth_getBlockReceipts.json PO
description: "Polygon API method that retrieves all transaction receipts for a given block. Reference for eth_getBlockReceipts on Polygon via Chainstack."
---

Polygon API method that retrieves all transaction receipts for a given block. Transaction receipts contain information about the execution status of a transaction and can be useful for monitoring the status of transfers or contract execution on the blockchain. This method is available on Erigon only.
Polygon API method that retrieves all transaction receipts for a given block. Transaction receipts contain information about the execution status of a transaction and can be useful for monitoring the status of transfers or contract execution on the blockchain.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | grep -F 'reference/polygon-getblockreceipts.mdx' || true

echo "== file excerpt =="
if [ -f reference/polygon-getblockreceipts.mdx ]; then
  nl -ba reference/polygon-getblockreceipts.mdx | sed -n '1,120p'
fi

echo "== search for getblockreceipt-related wording =="
rg -n "getblockreceipt|block receipt|transaction receipt|transfer|monitoring" reference -g '*.mdx' -g '*.md' | head -200

echo "== external docs check =="
python3 - <<'PY'
# Read-only semantic check against local file and common Ethereum RPC docs via web if needed.
from pathlib import Path
p = Path('reference/polygon-getblockreceipts.mdx')
text = p.read_text() if p.exists() else ''
print("mentions_transfer_on_same_sentence_as_receipt_or_monitoring:", any(s in text for s in ["receipts for a given block", "monitoring the status of transfers", "contract execution", "transaction receipts"]))
PY

Repository: chainstack/dev-portal

Length of output: 275


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file excerpt =="
if [ -f reference/polygon-getblockreceipts.mdx ]; then
  awk '{printf "%6d\t%s\n", NR, $0}' reference/polygon-getblockreceipts.mdx | sed -n '1,140p'
fi

echo "== search for getblockreceipt-related wording =="
rg -n "getblockreceipt|block receipt|transaction receipt|transfer|monitoring" reference -g '*.mdx' -g '*.md' | head -200 || true

Repository: chainstack/dev-portal

Length of output: 46661


Distinguish receipt status from transfer verification.

status reports whether the transaction executed successfully; transfer details come from the to/value fields for native transfers or from emitted logs for contract transfers. Reword this as monitoring the transaction outcome or use receipt logs for transfer/event monitoring.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/polygon-getblockreceipts.mdx` at line 7, Revise the Polygon API
method description to distinguish transaction receipt status from transfer
verification: describe status as indicating transaction execution outcome, and
refer to receipt logs or the to/value fields when discussing transfer or event
monitoring.

Source: MCP tools


<Visibility for="humans">
<Check>
Expand Down
17 changes: 14 additions & 3 deletions reference/polygon-traceblockbyhash.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ You can sign up with your GitHub, X, Google, or Microsoft account.
+ `4byteTracer` — tracer that captures the function signatures and call data sizes for all functions executed during a transaction, creating a map that links each selector and size combination to the number of times it occurred. This provides valuable information about the frequency and usage of each function within the transaction.
+ `callTracer` — tracer that captures information on all call frames executed during a transaction. The resulting nested list of call frames is organized into a tree structure that reflects the way the Ethereum Virtual Machine works and can be used for debugging and analysis purposes.
+ `prestateTracer` — tracer with two modes: `prestate` and `diff`, where the former returns the accounts needed to execute a transaction, and the latter returns the differences between the pre and post-states of the transaction. The tracer operates by re-executing the transaction and tracking every state change made, resulting in an object with the account addresses as keys and the corresponding trie leaves as values.
+ `flatCallTracer` — tracer that returns the transaction's calls as a flat array in the Parity-style trace format, with each entry's position given by its `traceAddress`. This is the drop-in replacement for the Erigon `trace_*` methods, which Bor does not implement.

## Response types

Expand All @@ -49,6 +50,16 @@ You can sign up with your GitHub, X, Google, or Microsoft account.
+ `revertReason` — the reason why the transaction was reverted, returned by the smart contract if any.
+ `calls` — a list of sub-calls made by the contract during the call, each represented as a nested call frame object.

### `flatCallTracer` response

* `array` — the block's calls as a flat list in the Parity trace format, one object per call:
+ `action` — the call details: `from`, `to`, `value`, `gas`, `input`, and `callType` (for example, `call`, `delegatecall`, or `staticcall`). Contract creations and self-destructs carry the corresponding Parity `create` and `suicide` fields instead.
+ `result` — the call outcome: `gasUsed` and `output`. Contract creations return the new contract `address` and its `code`.
+ `subtraces` — the number of child calls made directly by this call.
+ `traceAddress` — the position of this call in the call tree, as an array of child indices.
+ `type` — the call type: `call`, `create`, or `suicide`.
+ `error` — present only when the call failed, with the failure reason.

Comment on lines +53 to +62

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Repository files matching trace MDX:"
git ls-files 'reference/*trace*.mdx' | sed -n '1,120p'

echo
echo "Relevant reference sections:"
for f in reference/polygon-traceblockbyhash.mdx reference/polygon-traceblockbynumber.mdx reference/polygon-tracecall.mdx reference/polygon-tracetransaction.mdx; do
  if [ -f "$f" ]; then
    echo "--- $f"
    wc -l "$f"
    sed -n '1,110p' "$f" | nl -ba
  else
    echo "MISSING $f"
  fi
done

echo
echo "Search for flatCallTracer/tracer terminology:"
rg -n "flatCallTracer|tracer|txHash|result" reference -g '*.mdx' | sed -n '1,200p'

echo
echo "Changed files/stat (if available):"
git diff --stat HEAD~1..HEAD 2>/dev/null || git diff --stat 2>/dev/null || true

Repository: chainstack/dev-portal

Length of output: 5161


🏁 Script executed:

#!/bin/bash
set - eu

for f in reference/polygon-traceblockbyhash.mdx reference/polygon-traceblockbynumber.mdx reference/polygon-tracecall.mdx reference/polygon-tracetransaction.mdx; do
  if [ -f "$f" ]; then
    echo "--- $f"
    wc -l "$f"
    cat -n "$f" | sed -n '1,130p'
  else
    echo "MISSING $f"
  fi
done

echo
echo "Search relevant docs terms:"
rg -n "flatCallTracer|tracer|txHash|result|three built-in|built-in tracers" reference -g '*.mdx' | sed -n '1,240p'

echo
echo "Changed files/stat:"
git diff --stat 2>/dev/null || true

Repository: chainstack/dev-portal

Length of output: 50379


🌐 Web query:

Bor debug_traceBlockByHash flatCallTracer response envelope txHash result

💡 Result:

When using the debug_traceBlockByHash RPC method on a Bor (Polygon) or Ethereum node with the flatCallTracer option, the response is typically an array of transaction trace objects [1][2]. Each object within this array represents a transaction from the block and contains a txHash field identifying the transaction, followed by a result field that provides the flattened execution trace [1][2]. The result field for flatCallTracer consists of an array of call frame objects [1][2]. Unlike the standard callTracer, which returns a hierarchical, tree-like structure of nested calls, the flatCallTracer provides a flattened list of these execution frames [2][3]. Each call frame within the result array typically includes the following fields [1][2]: - action: An object containing details about the call, such as: - callType: The type of operation (e.g., 'call', 'delegatecall', 'staticcall') [1][2]. - from: The address initiating the call [1][2]. - to: The recipient address [1][2]. - gas: The gas provided for the call [1][2]. - input: The input data (hexadecimal) [1][2]. - value: The amount of value transferred (hexadecimal) [1][2]. - result: An object containing execution results: - gasUsed: The gas consumed by this specific call [1][2]. - output: The return data from the call [1][2]. - type: The type of call [1][2]. - traceAddress: An array representing the position of the call in the overall trace (e.g., empty for top-level, or indices for nested calls) [1][2]. - subtraces: An integer indicating the number of internal sub-calls [1][2]. - blockHash and blockNumber: Metadata about the block [1][2]. - transactionHash and transactionPosition: Metadata identifying the specific transaction and its order in the block [1][2]. Because flatCallTracer is designed to provide a simplified, non-nested view, it is particularly useful for performance-sensitive analysis where the tree structure of a standard callTracer is not required [2][3].

Citations:


🌐 Web query:

Erigon flatCallTracer traceBlockByHash response txHash result structure

💡 Result:

When using the flatCallTracer with Erigon's debug_traceBlockByHash RPC method, the response structure differs significantly from the tree-based callTracer [1][2]. Instead of a nested structure, it returns a flattened list of call frames in a format compatible with OpenEthereum/Parity-style traces [3][2]. For a block trace, the top-level response is typically a JSON-RPC result object containing an array [4]. Each element in this array corresponds to a transaction within the block, often keyed by txHash [4]. The result for each transaction is an array of flat call frame objects [4]. Each flat call frame object typically includes the following fields [5]: - action: An object containing details such as callType, from, to, input, value, and gas [6][4]. - result: An object containing execution results such as gasUsed and output [6][4]. - subtraces: An integer representing the count of sub-calls [3][6]. - traceAddress: An array of integers representing the position of the call within the execution tree [6][5]. - type: A string indicating the type of call (e.g., call, delegatecall, staticcall, create) [6][4]. Unlike the Geth-style output where traces are often nested under a result field, the flatCallTracer organizes all call frames from the execution into a single, linear list [3][2]. Note that Erigon may return these results within a JSON-RPC envelope [4], and users should be aware that discrepancies may exist between Erigon and Geth output formats, such as the inclusion of specific result keys or handling of errors [7][8]. For example, if a method handler crashes or an error occurs during tracing, the response structure might be incomplete or contain error-specific fields [7][5].

Citations:


🌐 Web query:

"flatCallTracer" "debug_traceBlockByHash" "txHash" "result"

💡 Result:

The flatCallTracer is a native tracer available in Geth and other Ethereum clients that provides a flattened, Parity-style list of call frames, rather than the nested tree structure produced by the default callTracer [1][2][3]. When using flatCallTracer with the debug_traceBlockByHash method, you provide it within the tracer configuration object [4][5][6]. Below is an example of the request structure: curl -X POST <RPC_URL> \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "debug_traceBlockByHash", "params": [ "<BLOCK_HASH>", { "tracer": "flatCallTracer" } ], "id": 1 }' Key characteristics and notes for flatCallTracer: 1. Output Format: It outputs call traces as a flattened list of frames [2][3]. 2. Compatibility: It was implemented in Geth to provide compatibility with Parity/OpenEthereum-style tracing [1]. 3. Implementation Differences: While it mimics Parity-style output, there are known differences, such as how Geth handles errors, gas usage (Geth includes intrinsic gas and refunds, while Parity did not), and how it handles whole-block tracing (Geth typically nests transaction results within a result field) [1]. 4. Block Tracing: When tracing an entire block, the RPC response returns a list of results for all transactions contained within that block [7][1]. 5. Versioning/Bugs: Users should be aware that implementation details may vary between client versions, and specific bugs (such as incorrect hash returns or timeout handling) have been documented in various client implementations [8][9]. Because the debug_traceBlockByHash method expects a block hash as the first parameter and a configuration object (which can include the tracer type) as the second, the txHash is not a direct parameter of this specific RPC call [4][5][6]. If you need a trace for a specific transaction, you should use the debug_traceTransaction method instead [4].

Citations:


🌐 Web query:

Bor flatCallTracer block trace result txHash source

💡 Result:

The flatCallTracer is a transaction tracing tool designed to provide a flattened, Parity-style list of call frames, rather than the nested tree structure produced by the standard callTracer [1][2][3]. This format is primarily used for compatibility with tooling built for the OpenEthereum/Parity trace format [1][3]. On networks like Polygon (Bor), tracing support—including the availability of specific tracers—can vary based on the node configuration and the specific implementation of the trace API [4][5]. Key Technical Details: - Format: It returns a flattened list of call frames [2][6][3]. - Purpose: It offers a simplified output for complex transactions [7][8][9] and ensures compatibility with legacy OpenEthereum/Parity tooling [1][3]. - Implementation: In go-ethereum (which Bor is based on), the flatCallTracer is implemented as a wrapper that uses the standard callTracer to collect callstack information and then reformats the output into the flat structure [1]. - Bor/Polygon Context: Bor has integrated support for various tracing methods, often backported or adapted from go-ethereum and OpenEthereum implementations [4]. If you are experiencing issues tracing transactions (e.g., state-sync transactions failing) [10][11], it is often due to how the node handles specific transaction types, such as system transactions with zero gas or intrinsic gas issues [10]. Enabling specific flags like borTraceEnabled in the tracer configuration is sometimes required for successful tracing on Bor [5]. If you are attempting to locate a transaction by its hash in a trace result, the flatCallTracer output includes the transactionHash field for each entry [7]. When tracing blocks, the structure typically returns a result containing transaction results, which may vary slightly between implementations regarding how errors are nested [1].

Citations:


🌐 Web query:

site:geth.ethereum.org/docs/interacting-with-geth/rpc/ns-debug traceBlockByHash txHash result flatCallTracer

💡 Result:

The flatCallTracer is a native tracer available in Geth (go-ethereum) designed to provide Parity-style transaction tracing output [1]. It functions as a proxy that utilizes the callTracer to collect call stack information, which is then formatted to align with compatibility requirements for users transitioning from or integrating with systems that expect Parity-style traces [1]. You can use the flatCallTracer with Geth's debug RPC methods, such as debug_traceBlockByHash or debug_traceBlockByNumber, by specifying it in the tracer configuration [2][3]. Example RPC request: { "method": "debug_traceBlockByHash", "params": [ "0xYourBlockHash", { "tracer": "flatCallTracer", "tracerConfig": { "includePrecompiles": false, "convertParityErrors": false } } ], "id": 1, "jsonrpc": "2.0" } Key characteristics and compatibility notes include: 1. Compatibility Options: You can enable includePrecompiles: true to report precompile calls, which are excluded by default [1]. If you require Parity-style error messages, you can set convertParityErrors: true [1]. 2. Output Differences: Unlike Parity, Geth's implementation accounts for intrinsic gas and refunds in the gasUsed field, and it nests transaction results within a result field when tracing an entire block [1]. 3. Maintenance: It is an actively maintained native tracer within the Geth codebase, with bug fixes and updates (such as blob base fee support) integrated to ensure reliability and performance [4][5].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

echo "OpenAPI response schemas for Polygon debug_traceBlock methods:"
fd -a 'debug_traceBlock.*\.(yaml|json|yml|md)' . | sed -n '1,40p'

for f in $(fd 'debug_traceBlock.*\.(json|yaml|yml)$' .); do
  echo "--- $f"
  # Print lines that mention flatCallTracer/response schema if present
  rg -n "flatCallTracer|result|array|object|properties|type" "$f" | sed -n '1,220p'
done

Repository: chainstack/dev-portal

Length of output: 19171


🏁 Script executed:

#!/bin/bash
set -eu

python3 - <<'PY'
import json
from pathlib import Path
for name in ["debug_traceBlockByHash", "debug_traceBlockByNumber"]:
    path = Path("openapi/polygon_node_api/debug_and_trace") / f"{name}.json"
    data = json.loads(path.read_text())
    result = None
    schema = data.get("content", {}).get("application/json", {}).get("schema", {})
    def walk(cur):
        nonlocal result
        if isinstance(cur, dict):
            if cur.get("type") == "object" and cur.get("properties"):
                if "result" in cur["properties"]:
                    result = cur["properties"]["result"]
            for v in cur.values():
                walk(v)
    schema.get("properties", {}).get("result", {}).get("items", {})
    walk(schema)
    print(f"--- {name}")
    print(json.dumps(result, indent=2, sort_keys=True, ensure_ascii=False)[:2000])
PY

Repository: chainstack/dev-portal

Length of output: 236


🏁 Script executed:

#!/bin/bash
set -eu

python3 - <<'PY'
import json
from pathlib import Path

for name in ["debug_traceBlockByHash", "debug_traceBlockByNumber"]:
    path = Path("openapi/polygon_node_api/debug_and_trace") / f"{name}.json"
    data = json.loads(path.read_text())

    def find_result_schema(node, depth=0):
        if not isinstance(node, dict):
            return None
        if node.get("type") == "object" and node.get("properties") and "result" in node["properties"]:
            return node["properties"]["result"]
        for v in node.values():
            r = find_result_schema(v, depth + 1)
            if r is not None:
                return r
        return None

    result = find_result_schema(data)
    print(f"--- {name}: type={result.get('type')}, title={result.get('title')}, description={result.get('description')}")
    print(json.dumps(result, indent=2)[:2400])
PY

echo
echo "Top-level API docs around flatCallTracer:"
for f in reference/polygon-debug-trace-rpc-methods.mdx; do
  [ -f "$f" ] && cat -n "$f" | sed -n '1,260p'
done

Repository: chainstack/dev-portal

Length of output: 3638


Document the flatCallTracer transaction wrapper for both block methods.

debug_traceBlockByHash/debug_traceBlockByNumber return per-transaction trace objects for each transaction in the block, so the flat entries should be documented under result in a transaction/result/response envelope that includes txHash, rather than listing the flat call fields as the top-level response.

  • reference/polygon-traceblockbyhash.mdx#L53-L62
  • reference/polygon-traceblockbynumber.mdx#L63-L72
📍 Affects 2 files
  • reference/polygon-traceblockbyhash.mdx#L53-L62 (this comment)
  • reference/polygon-traceblockbynumber.mdx#L63-L72
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/polygon-traceblockbyhash.mdx` around lines 53 - 62, The
flatCallTracer documentation is missing the per-transaction wrapper returned by
both block trace methods. In reference/polygon-traceblockbyhash.mdx lines 53-62
and reference/polygon-traceblockbynumber.mdx lines 63-72, document the flat
entries under a transaction/result/response envelope containing txHash, rather
than presenting the call fields as the top-level response.

Source: MCP tools

### `prestateTracer` response

* `object` — the `prestateTracer` traces object:
Expand All @@ -68,7 +79,7 @@ const provider = new ethers.JsonRpcProvider(NODE_URL);

const traceBlockByHash = async (blockHash) => {

// Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer
// Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer
const tracer = { tracer: '4byteTracer' };
const traces = await provider.send("debug_traceBlockByHash", [blockHash, tracer]);
console.log(traces);
Expand All @@ -84,7 +95,7 @@ web3 = Web3.HTTPProvider(node_url)

block_hash = "0x22507441629262af0d44bfadebe086470df5936827bc482300b5183b4b8ac8bd"

# Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer
# Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer
tracer = { "tracer": '4byteTracer' }
block_traces = web3.provider.make_request('debug_traceBlockByHash', [block_hash, tracer])
print(block_traces)
Expand All @@ -107,7 +118,7 @@ const provider = new ethers.JsonRpcProvider(NODE_URL);

async function traceTransferFunction(blockHash) {
try {
// Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer
// Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer
const tracer = { tracer: '4byteTracer' };
const response = await provider.send("debug_traceBlockByHash", [blockHash, tracer]);

Expand Down
15 changes: 13 additions & 2 deletions reference/polygon-traceblockbynumber.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ See the [default block parameter](https://ethereum.org/en/developers/docs/apis/j
+ `4byteTracer` — tracer that captures the function signatures and call data sizes for all functions executed during a transaction, creating a map that links each selector and size combination to the number of times it occurred. This provides valuable information about the frequency and usage of each function within the transaction.
+ `callTracer` — tracer that captures information on all call frames executed during a transaction. The resulting nested list of call frames is organized into a tree structure that reflects the way the Ethereum Virtual Machine works and can be used for debugging and analysis purposes.
+ `prestateTracer` — tracer with two modes: `prestate` and `diff`, where the former returns the accounts needed to execute a transaction, and the latter returns the differences between the pre and post-states of the transaction. The tracer operates by re-executing the transaction and tracking every state change made, resulting in an object with the account addresses as keys and the corresponding trie leaves as values.
+ `flatCallTracer` — tracer that returns the transaction's calls as a flat array in the Parity-style trace format, with each entry's position given by its `traceAddress`. This is the drop-in replacement for the Erigon `trace_*` methods, which Bor does not implement.

## Response types

Expand All @@ -59,6 +60,16 @@ See the [default block parameter](https://ethereum.org/en/developers/docs/apis/j
+ `revertReason` — the reason why the transaction was reverted, returned by the smart contract if any.
+ `calls` — a list of sub-calls made by the contract during the call, each represented as a nested call frame object.

### `flatCallTracer` response

* `array` — the block's calls as a flat list in the Parity trace format, one object per call:
+ `action` — the call details: `from`, `to`, `value`, `gas`, `input`, and `callType` (for example, `call`, `delegatecall`, or `staticcall`). Contract creations and self-destructs carry the corresponding Parity `create` and `suicide` fields instead.
+ `result` — the call outcome: `gasUsed` and `output`. Contract creations return the new contract `address` and its `code`.
+ `subtraces` — the number of child calls made directly by this call.
+ `traceAddress` — the position of this call in the call tree, as an array of child indices.
+ `type` — the call type: `call`, `create`, or `suicide`.
+ `error` — present only when the call failed, with the failure reason.

### `prestateTracer` response

* `object` — the `prestateTracer` traces object:
Expand All @@ -78,7 +89,7 @@ const provider = new ethers.JsonRpcProvider(NODE_URL);

const traceBlockByNumber = async (block) => {

// Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer
// Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer
const tracer = { tracer: 'callTracer' };
const traces = await provider.send("debug_traceBlockByNumber", [block, tracer]);
console.log(traces);
Expand All @@ -94,7 +105,7 @@ web3 = Web3.HTTPProvider(node_url)

block = "latest"

# Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer
# Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer
tracer = { "tracer": 'callTracer' }
block_traces = web3.provider.make_request('debug_traceBlockByNumber', [block, tracer])
print(block_traces)
Expand Down
17 changes: 14 additions & 3 deletions reference/polygon-tracecall.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ See the [default block parameter](https://ethereum.org/en/developers/docs/apis/j
+ `4byteTracer` — tracer that captures the function signatures and call data sizes for all functions executed during a transaction, creating a map that links each selector and size combination to the number of times it occurred. This provides valuable information about the frequency and usage of each function within the transaction.
+ `callTracer` — tracer that captures information on all call frames executed during a transaction. The resulting nested list of call frames is organized into a tree structure that reflects the way the Ethereum Virtual Machine works and can be used for debugging and analysis purposes.
+ `prestateTracer` — tracer with two modes: `prestate` and `diff`, where the former returns the accounts needed to execute a transaction, and the latter returns the differences between the pre and post-states of the transaction. The tracer operates by re-executing the transaction and tracking every state change made, resulting in an object with the account addresses as keys and the corresponding trie leaves as values.
+ `flatCallTracer` — tracer that returns the call's execution as a flat array in the Parity-style trace format, with each entry's position given by its `traceAddress`. This is the drop-in replacement for the Erigon `trace_*` methods, which Bor does not implement.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove the stale tracer count.

Adding flatCallTracer creates a fourth documented built-in tracer, but both pages still refer to “one of the three built-in tracers.”

  • reference/polygon-tracecall.mdx#L49-L49: update the later built-in-tracer note to avoid the stale count.
  • reference/polygon-tracetransaction.mdx#L31-L31: update the matching note to avoid the stale count.
📍 Affects 2 files
  • reference/polygon-tracecall.mdx#L49-L49 (this comment)
  • reference/polygon-tracetransaction.mdx#L31-L31
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@reference/polygon-tracecall.mdx` at line 49, Update the built-in-tracer note
in reference/polygon-tracecall.mdx (line 49) and
reference/polygon-tracetransaction.mdx (line 31) to remove the stale reference
to “one of the three built-in tracers,” reflecting that flatCallTracer is now
included as a fourth documented tracer.


<Note>
Find a complete [list of available built-in tracers](/reference/polygon-debug-trace-rpc-methods#pre-built-native-tracers) in the debug and trace overview.
Expand Down Expand Up @@ -97,6 +98,16 @@ When no built-in tracer is selected, the response defaults to the [Struct/opcode
+ `revertReason` — the reason why the transaction was reverted, returned by the smart contract, if any.
+ `calls` — a list of sub-calls made by the contract during the call, each represented as a nested call frame object.

### `flatCallTracer` response

* `array` — the call's execution as a flat list in the Parity trace format, one object per call:
+ `action` — the call details: `from`, `to`, `value`, `gas`, `input`, and `callType` (for example, `call`, `delegatecall`, or `staticcall`). Contract creations and self-destructs carry the corresponding Parity `create` and `suicide` fields instead.
+ `result` — the call outcome: `gasUsed` and `output`. Contract creations return the new contract `address` and its `code`.
+ `subtraces` — the number of child calls made directly by this call.
+ `traceAddress` — the position of this call in the call tree, as an array of child indices.
+ `type` — the call type: `call`, `create`, or `suicide`.
+ `error` — present only when the call failed, with the failure reason.

### `prestateTracer` response

* `object` — the `prestateTracer` traces object:
Expand Down Expand Up @@ -137,7 +148,7 @@ const traceCall = async () => {

const block = 'latest'

// Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer. Leave empty {} for Struct/opcode logger.
// Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer. Leave empty {} for Struct/opcode logger.
const tracer = {};
const traces = await provider.send("debug_traceCall", [call, block, tracer]);
console.log(traces);
Expand All @@ -161,7 +172,7 @@ call = {

block = 'latest'

# Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer. Leave empty {} for Struct/opcode logger.
# Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer. Leave empty {} for Struct/opcode logger.
tracer = { "tracer": 'prestateTracer' }
tx_traces = web3.provider.make_request('debug_traceCall', [call, block, tracer])
print(tx_traces)
Expand All @@ -187,7 +198,7 @@ const provider = new ethers.JsonRpcProvider(NODE_URL);

async function traceCall(call, block) {
try {
// Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer.
// Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer.
// Leave empty {} for Struct/opcode logger.
const tracer = { tracer: 'callTracer' };

Expand Down
15 changes: 13 additions & 2 deletions reference/polygon-tracetransaction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ You can sign up with your GitHub, X, Google, or Microsoft account.
+ `4byteTracer` — tracer that captures the function signatures and call data sizes for all functions executed during a transaction, creating a map that links each selector and size combination to the number of times it occurred. This provides valuable information about the frequency and usage of each function within the transaction.
+ `callTracer` — tracer that captures information on all call frames executed during a transaction. The resulting nested list of call frames is organized into a tree structure that reflects the way the Ethereum Virtual Machine works and can be used for debugging and analysis purposes.
+ `prestateTracer` — tracer with two modes: `prestate` and `diff`, where the former returns the accounts needed to execute a transaction, and the latter returns the differences between the pre and post-states of the transaction. The tracer operates by re-executing the transaction and tracking every state change made, resulting in an object with the account addresses as keys and the corresponding trie leaves as values.
+ `flatCallTracer` — tracer that returns the transaction's calls as a flat array in the Parity-style trace format, with each entry's position given by its `traceAddress`. This is the drop-in replacement for the Erigon `trace_*` methods, which Bor does not implement.

<Note>
Find a complete [list of available built-in tracers](/reference/polygon-debug-trace-rpc-methods#pre-built-native-tracers) in the debug and trace overview.
Expand Down Expand Up @@ -79,6 +80,16 @@ When no built-in tracer is selected, the response defaults to the [Struct/opcode
+ `revertReason` — the reason why the transaction was reverted, returned by the smart contract if any.
+ `calls` — a list of sub-calls made by the contract during the call, each represented as a nested call frame object.

### `flatCallTracer` response

* `array` — the transaction's calls as a flat list in the Parity trace format, one object per call:
+ `action` — the call details: `from`, `to`, `value`, `gas`, `input`, and `callType` (for example, `call`, `delegatecall`, or `staticcall`). Contract creations and self-destructs carry the corresponding Parity `create` and `suicide` fields instead.
+ `result` — the call outcome: `gasUsed` and `output`. Contract creations return the new contract `address` and its `code`.
+ `subtraces` — the number of child calls made directly by this call.
+ `traceAddress` — the position of this call in the call tree, as an array of child indices.
+ `type` — the call type: `call`, `create`, or `suicide`.
+ `error` — present only when the call failed, with the failure reason.

### `prestateTracer` response

* `object` — the `prestateTracer` traces object:
Expand Down Expand Up @@ -109,7 +120,7 @@ const provider = new ethers.JsonRpcProvider(NODE_URL);

const traceTransaction = async (txhash) => {

// Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer. Leave empty {} for Struct/opcode logger.
// Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer. Leave empty {} for Struct/opcode logger.
const tracer = {};
const traces = await provider.send("debug_traceTransaction", [txhash, tracer]);
console.log(traces);
Expand All @@ -125,7 +136,7 @@ web3 = Web3.HTTPProvider(node_url)

tx_hash = "0x6be573c85c46d02cd2d47b997d2f153583fbc959541400bc41b9f140d1216772"

# Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer. Leave empty {} for Struct/opcode logger.
# Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer. Leave empty {} for Struct/opcode logger.
tracer = { "tracer": '4byteTracer' }
tx_traces = web3.provider.make_request('debug_traceTransaction', [tx_hash, tracer])
print(tx_traces)
Expand Down