# trace_call vs debug_traceCall

> The differences between the trace_call method by OpenEthereum and the debug_traceCall method by Geth

> For the complete documentation index, see [llms.txt](/docs/llms.txt).

# Introduction

Geth and OpenEthereum are two popular Ethereum clients. In this article, we'll compare and contrast the [trace\_call](/docs/reference/trace-call) method offered by OpenEthereum with the [debug\_traceCall](/docs/reference/debug-tracecall) method offered by Geth. Both of these methods are used for transaction tracing.

<Info>
  The `trace_call` method was initially supported by the OpenEthereum client but now OpenEthereum has been deprecated and a new client Erigon is supporting the trace methods.

  Going forward, we will only use the name of the Erigon Ethereum client when associating with the trace methods.
</Info>

# Prerequisites

Before reading this article you should know about [Ethereum Clients](https://www.alchemy.com/overviews/execution-layer-and-consensus-layer-node-clients) and [EVM Traces](/docs/reference/what-are-evm-traces).

# The trace\_call method

The [trace\_call](/docs/reference/trace-call) method executes the given call (transaction) and returns a number of possible traces for it. It’s helpful for debugging transactions and analyzing state changes due to a transaction. Under the hood,[trace\_call](/docs/reference/trace-call) is only supported by OpenEthereum or Erigon clients, but if you’re using an Alchemy API key we’ll automatically route the request for you so you don’t have to worry about the node client.

Here are the parameters and response payloads for `trace_call`

## Parameters

1. `Object` - Call options.

   * `from`: `Address` - (optional) - The address the transaction is sent from.
   * `to`: `Address` - (optional when creating a new contract) - The address the transaction is directed to.
   * `gas`: `Quantity` - (optional) Integer formatted as a hex string that represents the gas provided for the transaction execution.
   * `gasPrice`: `Quantity` - (optional) Integer formatted as a hex string that represents the gas price used for each paid gas.
   * `value`: `Quantity` - (optional) Integer formatted as a hex string that represents the value sent with the given transaction.
   * `data`: `Data` - (optional) 4-byte hash of the method signature followed by encoded parameters. This basically represents which function to call in the smart contract along with the function parameters, if it’s just a value transfer then this field can be empty.

2. `Array` - Type of trace, one or more of: `"vmTrace"`, `"trace"`, `"stateDiff"`.

   1. `trace`: Returns the basic trace for the given transaction.
   2. `stateDiff`: Provides information detailing all altered portions of the Ethereum state made due to the execution of the transaction.
   3. `vmTrace`: Provides a full trace of the Ethereum state throughout the execution of the transaction, including for any subcalls.

<Warning>
  `vmTrace` is no longer supported by Alchemy.
</Warning>

3. `Quantity` or `Tag` - (optional) Integer formatted as a hex string that represents a block number, or the string `'earliest'` or `'latest'`. If this parameter is supplied, the transaction is replayed in the context of the given parameter.

   1. `latest`: The latest block that the client has observed.
   2. `earliest`: The lowest number block that the client has available. Intuitively, you can think of this as the first block created.

## Example Request and Response

The `trace_call` method returns an array of traces. The structure of these traces is explained in [Types of Trace Actions and their Structure](/docs/reference/what-are-evm-traces#types-of-trace-actions). Below you can find an example.

### Request

<CodeGroup>
  ```curl cURL
  curl https://eth-mainnet.g.alchemy.com/v2/demo \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"method":"trace_call",
      "params":[{
        "from": "0x6f1FB6EFDf50F34bFA3F2bC0E5576EdD71631638",
        "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
        "value": "0x0",
        "data": "0x70a082310000000000000000000000006E0d01A76C3Cf4288372a29124A26D4353EE51BE"},
        ["trace"]],
      "id":1,
      "jsonrpc":"2.0"}]'
  ```

  ```javascript ethers
  const ethers = require("ethers");

  (async () => {
    const provider = new ethers.providers.JsonRpcProvider(
      "https://eth-mainnet.g.alchemy.com/v2/demo"
    );
    const response = await provider.send("trace_call", [
      {
        from: "0x6f1FB6EFDf50F34bFA3F2bC0E5576EdD71631638",
        to: "0x6b175474e89094c44da98b954eedeac495271d0f",
        data: "0x70a082310000000000000000000000006E0d01A76C3Cf4288372a29124A26D4353EE51BE",
      },
      ["trace"],
      "latest",
    ]);
    console.log(response);
  })();
  ```

  ```python web3py
  from web3 import HTTPProvider

  client = HTTPProvider('https://eth-mainnet.g.alchemy.com/v2/demo')
  result = client.make_request('trace_call', [{
      "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
      "data": "0x70a082310000000000000000000000006E0d01A76C3Cf4288372a29124A26D4353EE51BE"
      },["trace"], "latest"])
  print(result)
  ```
</CodeGroup>

### Response

<CodeGroup>
  ```json trace_call Response
  {
    "output": "0x0000000000000000000000000000000000000000000000000858898f93629000",
    "stateDiff": null,
    "trace": [
      {
        "action": {
          "from": "0x0000000000000000000000000000000000000000",
          "callType": "call",
          "gas": "0x1dcd1148",
          "input": "0x70a082310000000000000000000000006e0d01a76c3cf4288372a29124a26d4353ee51be",
          "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
          "value": "0x0"
        },
        "result": {
          "gasUsed": "0xa2a",
          "output": "0x0000000000000000000000000000000000000000000000000858898f93629000"
        },
        "subtraces": 0,
        "traceAddress": [],
        "type": "call"
      }
    ],
    "vmTrace": null
  }
  ```
</CodeGroup>

# The debug\_traceCall method

The [debug\_traceCall](/docs/reference/debug-tracecall) method executes the given call (transaction) and returns a number of possible traces for it. It’s helpful for debugging transactions and analyzing state changes due to a transaction. Under the hood,[debug\_traceCall](/docs/reference/debug-tracecall) is only supported by OpenEthereum or Erigon clients, but if you’re using an Alchemy API key we’ll automatically route the request for you so you don’t have to worry about the node client.

Here are the parameters and response payloads for `debug_traceCall`

## Parameters

The parameters for the `debug_traceCall` method are:

1. `Object` - Transaction object with the following fields:

   * `from` - string - The address the transaction is sent from.
   * `to` - string, **\[required]** - The address the transaction is directed to.
   * `gasPrice` - string - Integer of the `gasPrice` used for each paid gas.
   * `value` - string - Integer of the value sent with the given transaction.
   * `data` - string - Hash of the method signature and encoded parameters.

2. `String` - One of the following options:

   1. **block hash**

   2. **block number** (in hex)

   3. **block tag** (one of the following):

      * `pending` - A sample next block built by the client on top of the latest and containing the set of transactions usually taken from the local mempool. Intuitively, you can think of these as blocks that have not been mined yet.
      * `latest` - The most recent block observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions.
      * `safe` - The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination. Intuitively, this block is “unlikely” to be re-orged. **Only available on Ethereum Sepolia**.
      * `finalized` - The most recent crypto-economically secure block, that has been accepted by >2/3 of validators. Cannot be re-orged outside of manual intervention driven by community coordination. Intuitively, this block is very unlikely to be re-orged. **Only available on Ethereum Goerli**.
      * `earliest` - The lowest numbered block the client has available. Intuitively, you can think of this as the first block created.

3. Object - tracer

* `tracer` - String to specify the type of tracer. Currently supports `callTracer` and `prestateTracer` (see below for definitions).
* `tracerConfig` - Object to specify configurations for the tracer
  * `onlyTopCall` - boolean - setting this to `true` will only trace the main (top-level) call and none of the sub-calls. This avoids extra processing for each call frame if only the top-level call info is required (useful for getting `revertReason`).

### `callTracer`

The `callTracer` tracks all the call frames executed during a transaction. The result will be a nested list of call frames. They form a tree with the top-level call at the root and sub-calls as children of the higher levels.

It’s similar to the `trace` option of the [trace\_call](/docs/reference/trace-call) method. Each call frame has the following fields:

| field        | type                 | description                          |
| ------------ | -------------------- | ------------------------------------ |
| type         | string               | CALL, CREATE or SUICIDE              |
| from         | string               | address                              |
| to           | string               | address                              |
| value        | string               | hex-encoded amount of value transfer |
| gas          | string               | hex-encoded gas provided for call    |
| gasUsed      | string               | hex-encoded gas used during call     |
| input        | string               | call data                            |
| output       | string               | return data                          |
| error        | string               | error, if any                        |
| revertReason | string               | Solidity revert reason, if any       |
| calls        | array of call frames | list of sub-calls                    |

### `prestateTracer`

The `prestateTracer` replays the transaction and tracks every part of state that is touched during that transaction.

This is similar to the `stateDiff` option of the [trace\_call](/docs/reference/trace-call) method. The result is an object. The keys are addresses of accounts. The value is an object with the following fields:

| field   | type               | description                   |
| ------- | ------------------ | ----------------------------- |
| balance | string             | balance in wei                |
| nonce   | uint64             | nonce                         |
| code    | string             | hex-encoded bytecode          |
| storage | map\[string]string | storage slots of the contract |

As you've seen that the `callTracer` and `prestateTracer` options of [debug\_traceCall](/docs/reference/debug-tracecall) are similar to `trace` and `stateDiff` options of [debug\_traceCall](/docs/reference/debug-tracecall), here's a table depicting this:

| Options of [trace\_call](/docs/reference/trace-call) | Similar options of [debug\_traceCall](/docs/reference/debug-tracecall) |
| ----------------------------------------------- | ----------------------------------------------------------------- |
| trace                                           | callTrace                                                         |
| stateDiff                                       | prestateTracer                                                    |

## Example Request and Response

### Request

<CodeGroup>
  ```curl cURL
  curl  https://eth-mainnet.g.alchemy.com/v2/demo \
    -X POST \
    -H "Content-Type: application/json" \
    --data '{"method":"debug_traceCall","params":[{"from":null,"to":"0x6b175474e89094c44da98b954eedeac495271d0f","data":"0x70a082310000000000000000000000006E0d01A76C3Cf4288372a29124A26D4353EE51BE"}, "latest"],"id":1,"jsonrpc":"2.0"}'
  ```

  ```javascript ethers
  const ethers = require("ethers");
  (async () => {
    const provider = new ethers.providers.JsonRpcProvider(
      "https://eth-mainnet.g.alchemy.com/v2/demo"
    );
    const response = await provider.send("debug_traceCall", [
      {
        from: "0xe5cb067e90d5cd1f8052b83562ae670ba4a211a8",
        to: "0xdc66567a990b7fa10730459537620857c9e03287",
        data: "0xae169a50000000000000000000000000000000000000000000000000000000000000000e",
      },
      "0xF118CE",
      { tracer: "callTracer", tracerConfig: { onlyTopCall: false } },
    ]);
    console.log(response);
  })();
  ```

  ```python web3py
  from web3 import Web3, HTTPProvider
  provider = Web3.HTTPProvider("https://eth-mainnet.g.alchemy.com/v2/demo")
  result = provider.make_request('debug_traceCall', [{
      "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
      "data": "0x70a082310000000000000000000000006E0d01A76C3Cf4288372a29124A26D4353EE51BE"
      }, "latest"])
  print(result)
  ```
</CodeGroup>

### Response

<CodeGroup>
  ```json debug_traceCall Response
  {
    "type": "CALL",
    "from": "0xe5cb067e90d5cd1f8052b83562ae670ba4a211a8",
    "to": "0xdc66567a990b7fa10730459537620857c9e03287",
    "value": "0x0",
    "gas": "0x7fffffffffffad2b",
    "gasUsed": "0x19dd6",
    "input": "0xae169a50000000000000000000000000000000000000000000000000000000000000000e",
    "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
    "calls": [
      {
        "type": "CALL",
        "from": "0xdc66567a990b7fa10730459537620857c9e03287",
        "to": "0xa2b885e7065ea59a3251489715ca80de5ff642f8",
        "gas": "0x7dffffffffff9207",
        "gasUsed": "0x1bb3",
        "input": "0x6352211e000000000000000000000000000000000000000000000000000000000000000e",
        "output": "0x000000000000000000000000e5cb067e90d5cd1f8052b83562ae670ba4a211a8"
      },
      {
        "type": "CALL",
        "from": "0xdc66567a990b7fa10730459537620857c9e03287",
        "to": "0xf418588522d5dd018b425e472991e52ebbeeeeee",
        "gas": "0x7dffffffffff5b32",
        "gasUsed": "0xa4e",
        "input": "0x70a08231000000000000000000000000dc66567a990b7fa10730459537620857c9e03287",
        "output": "0x0000000000000000000000000000000000000000000011b962d6ea64e3500000"
      }
    ]
  }
  ```
</CodeGroup>

# Difference between `trace_call` and `debug_traceCall`

Since [trace\_call](/docs/reference/trace-call) is OpenEthereum's (Now Erigon's) equivalent to Geth's [debug\_traceCall](/docs/reference/debug-tracecall) there are not many differences between them but there are some minor differences which are mentioned below:

* You can choose to trace only the main call (the top-level call) in `debug_traceCall` by setting the `onlyTopCall` option to `true`. This avoids extra processing if only the top-level info is required (like getting the revert reason). However, this is not possible using `trace_call` as you always get back the complete trace.

* You can replay a transaction in a particular block by providing the block hash in `debug_traceCall` but not in `trace_call`. (However, both methods accept the block number in hex format and the tags like `latest` and `earliest`).

* `trace_call` is accessible through Erigon while `debug_traceCall` is accessible through Geth.

* By using `trace_call` you can get the simple trace for a transaction (trace) and the state difference (stateDiff) in just one request by putting an array containing `trace` and `stateDiff` options in trace\_call's second parameter (`["trace", "stateDiff"]`) as mentioned below:

<CodeGroup>
  ```javascript ethers
  // Request using ethers.js in node.js
  const ethers = require("ethers");

  (async () => {
    const provider = new ethers.providers.JsonRpcProvider(
      "https://eth-mainnet.g.alchemy.com/v2/demo"
    );
    const response = await provider.send("trace_call", [
      {
        from: "0xe5cb067e90d5cd1f8052b83562ae670ba4a211a8",
        to: "0xdc66567a990b7fa10730459537620857c9e03287",
        data: "0xae169a50000000000000000000000000000000000000000000000000000000000000000e",
      },
      ["trace", "stateDiff"], // getting both "trace" and "stateDiff" in one request
      "latest",
    ]);
    console.log(response);
  })();
  ```
</CodeGroup>

In response for this request you will get both `trace` and `stateDiff`:

<CodeGroup>
  ```json response
  {
    "output": "0x",
    "stateDiff": { // ---> stateDiff
      "0xe5cb067e90d5cd1f8052b83562ae670ba4a211a8": {
        "balance": {
          "*": {
            "from": "0x43d1b8fda906d05",
            "to": "0x1c0671087043bf963a878705f"
          }
        },
        "code": "=",
        "nonce": {
          "*": {
            "from": "0x21",
            "to": "0x22"
          }
        },
        "storage": {}
      }
    },
    "trace": [ // // ---> trace
      {
        "action": {
          "from": "0xe5cb067e90d5cd1f8052b83562ae670ba4a211a8",
          "callType": "call",
          "gas": "0x1dcd122c",
          "input": "0xae169a50000000000000000000000000000000000000000000000000000000000000000e",
          "to": "0xdc66567a990b7fa10730459537620857c9e03287",
          "value": "0x0"
        },
        "result": {
          "gasUsed": "0x0",
          "output": "0x"
        },
        "subtraces": 0,
        "traceAddress": [],
        "type": "call"
      }
    ],
    "vmTrace": {
      "code": "0x",
      "ops": []
    }
  }
  ```
</CodeGroup>

But by using [debug\_traceCall](/docs/reference/debug-tracecall) you can either get the traces using `callTracer` or the state difference using `prestateTracer` in one request.

# Conclusion

In conclusion, [trace\_call](/docs/reference/trace-call) and [debug\_traceCall](/docs/reference/debug-tracecall) are two important methods for transaction tracing. They are accessible through different Ethereum clients and are slightly different from each other.