# トランザクショントレース：debug_traceTransaction と Data API のトレースエンドポイント

> Source: https://docs.blockvectra.com/ja/guides/transaction-traces/

## コールツリーを再構築する 2 つの方法

トランザクショントレースは、実行の再構築されたコールツリーです。どのコントラクトが、どのような入力で呼び出され、どれだけのガスを消費し、どのようなサブ呼び出しを行ったかを示します。BlockVectra はこれを 2 つのインターフェースを通じて公開しています：

* **JSON-RPC `debug_trace` メソッド（`debug_traceTransaction` など）** — JSON-RPC エンドポイントを介してチェーンのノードに対して実行されるため、ノードがまだ保持している最新の状態をトレースできます。
* **Data API トレース** — `GET /{chain}/transactions/{hash}/trace` および `GET /{chain}/blocks/{number}/traces` は、保存およびインデックス化されたコールツリーを REST 経由で返します。

どちらも同じ API key を使用し、メソッドの重み付けに基づいて CU で計測されます（以下の重み付けを参照）。どちらが適しているかは、単一のトランザクションが必要かブロック全体が必要か、対象がどれほど最近のものか、ページネーションなしで完全なブロックを走査したいかによって決まります。

## debug\_trace メソッドに適用される制限

`debug_trace` リクエストは、チェーンのメソッドポリシーが許可しているメソッドおよびトレーサーに対してのみ受け付けられます：

* **許可されるトレーサー**：`tracer` パラメータは組み込みのネイティブトレーサー — `callTracer`、`flatCallTracer`、`prestateTracer`、`4byteTracer`、`noopTracer` のみを受け入れるか、省略してデフォルトの struct logger を使用します。その他の値は JSON-RPC エラー `-32602 tracer not allowed`（課金なし）で拒否されます。
* **トレースのタイムアウト**：`timeout` パラメータは有効な期間指定であり、最大 30 秒である必要があります。そうでない場合、リクエストは `-32602 trace timeout not allowed`（課金なし）で拒否されます。
* **ノード同期ガード**：チェーンのノードが同期されていない間は、`eth_chainId` を除くすべてのメソッド（`debug_trace` メソッドを含む）が `-32010`（課金なし）を返します。
* **状態ウィンドウ**：`debug_traceCall`、`debug_traceBlockByNumber`、`debug_traceTransaction`、および `debug_traceBlockByHash` の対象ブロックは、チェーンの状態ウィンドウ内にある必要があります。ウィンドウより前の対象、または `safe`、`finalized`、`earliest` タグを使用した対象は `-32011`（課金なし）を返します。
* **ハッシュおよびブロックの検索**：不正な形式または未知のハッシュは `-32000 transaction not found` / `block not found` を返します。一時的な障害は `-32603 upstream unavailable`（再試行可能）を返します。課金はされません。
* **チェーンごとのメソッドポリシー**：チェーンがどの `debug_trace` メソッドを許可しているかは、公開の `GET /v1/chains` 応答で公開されます。メソッドリストをハードコードせず、実行時に読み取ってください。チェーンは [対応チェーン](https://docs.blockvectra.com/en/chains/) に一覧表示されており、メソッドリファレンスは [JSON-RPC メソッド](https://docs.blockvectra.com/en/api/json-rpc/methods/) ページにあります。

### callTracer を指定して debug\_traceTransaction をリクエストする

以下の呼び出しは、コールツリーをリクエストするために `tracer` パラメータを追加しています：

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

# 許可されたネイティブトレーサーのいずれかでコールツリーをリクエストするために "tracer" を追加します。
curl -s "https://api.blockvectra.com/v1/robinhood_mainnet" \
  -H 'Content-Type: application/json' \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "debug_traceTransaction",
    "params": [
      "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
      { "tracer": "callTracer" }
    ]
  }'
```


  **TypeScript**

```ts
const RPC_ENDPOINT = "https://api.blockvectra.com/v1/robinhood_mainnet";

const res = await fetch(RPC_ENDPOINT, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": process.env.BLOCKVECTRA_API_KEY!,
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "debug_traceTransaction",
    params: [
      "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
      { tracer: "callTracer" },
    ],
  }),
});

const body = (await res.json()) as {
  result?: unknown;
  error?: { code: number; message: string };
};

if (body.error) {
  throw new Error(`debug_traceTransaction error ${body.error.code}: ${body.error.message}`);
}
console.log(body.result);

// npx tsx example.mts
```


  **Python**

```python
import os
import requests

RPC_ENDPOINT = "https://api.blockvectra.com/v1/robinhood_mainnet"

res = requests.post(
    RPC_ENDPOINT,
    headers={
        "Content-Type": "application/json",
        "x-api-key": os.environ["BLOCKVECTRA_API_KEY"],
    },
    json={
        "jsonrpc": "2.0",
        "id": 1,
        "method": "debug_traceTransaction",
        "params": [
            "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
            {"tracer": "callTracer"},
        ],
    },
)
res.raise_for_status()
body = res.json()

if "error" in body:
    err = body["error"]
    raise RuntimeError(f"debug_traceTransaction error {err.get('code')}: {err.get('message')}")
print(body["result"])
```


## Data API トレースエンドポイントが提供するもの

Data API は、2 つのスコープに対して保存されたコールツリーを返します。どちらもページネーションされておらず、`next_cursor` は決して存在しません。

* `GET /{chain}/transactions/{hash}/trace` — トランザクションハッシュによって検索された、1 つのトランザクションのコールフレーム。
* `GET /{chain}/blocks/{number}/traces` — ブロック内のトランザクションごとに 1 つのコールツリー（`tx_index` 順）。トランザクションのないブロックは `data: []` を返します。

レスポンスエンベロープは次のとおりです：

* `TxTraceEnvelope`：`data` は直接 `CallFrame` であり、それに加えて `meta` が含まれます。
* `BlockTracesEnvelope`：`data` は `BlockTraceItem` の配列で、各項目に `txHash` と `result`（`CallFrame`）が含まれ、それに加えて `meta` が含まれます。

どちらのトレースエンドポイントも、標準的な Ethereum の `callTracer` 形式を返します。これは Data API の金額安全性エンコーディングの例外です。他のエンドポイントでは、`2^53` を超える可能性のある値は 10 進文字列としてシリアライズされますが、これら 2 つのエンドポイントでは、`value`、`gas`、および `gasUsed` は 10 進文字列ではなく `0x` プレフィックス付きの 16 進数値になります。すべての `CallFrame` は `type`、`from`、`gas`、`gasUsed`、および `input` を保持します。`type` は `CALL`、`DELEGATECALL`、`STATICCALL`、`CREATE`、`CREATE2`、または `SELFDESTRUCT` のいずれかです。`CREATE`/`CREATE2` フレームのターゲットでは `to` は存在せず、`STATICCALL` フレームでは `value` は存在しません。オプションのメンバーは、`output`（呼び出しがデータを返さなかった場合は非存在）、`error`（成功時は非存在）、`revertReason`（`Error(string)` でリバートした場合のみ存在）、および `calls`（呼び出し順にネストされたサブ呼び出し）です。フレームの追加メンバーは保持されます。

構造を具体的に把握できるよう、以下に `CallFrame` フィールドの骨格を示します：

```jsonc
{
  "type": "CALL | DELEGATECALL | STATICCALL | CREATE | CREATE2 | SELFDESTRUCT",
  "from": "0x…",                      // 20 バイトのアドレス
  "to": "0x…",                        // CREATE/CREATE2 のターゲットでは非存在
  "value": "0x…",                     // 0x プレフィックス付き 16 進数値。STATICCALL では非存在
  "gas": "0x…",                       // 0x プレフィックス付き 16 進数値
  "gasUsed": "0x…",                   // 0x プレフィックス付き 16 進数値
  "input": "0x…",
  "output": "0x…",                    // 呼び出しがデータを返さなかった場合は非存在
  "error": "…",                       // 成功時は非存在
  "revertReason": "…",                // 呼び出しが Error(string) でリバートした場合のみ存在
  "calls": []                         // 呼び出し順のネストされたサブ呼び出し。リーフフレームでは非存在
}
```

### パラメータ

* `{chain}`（パスパラメータ、必須）：チェーン識別子。`GET /chains` のエントリの `chain` の値。完全一致かつ大文字小文字を区別します。エイリアスや数値の Chain ID は受け付けられません。
* `{hash}`（パスパラメータ、トランザクションのトレースで必須）：32 バイトのトランザクションハッシュ。`0x` プレフィックスは任意、大文字小文字の区別なし。
* `{number}`（パスパラメータ、ブロックトレースで必須）：非負のブロック高。

### カバレッジとファイナリティ

* 両方のエンドポイントは `traces` 機能に属します。この機能を持たないチェーンは `422 no_coverage` を返します。このデータセットを提供するチェーンは [対応チェーン](https://docs.blockvectra.com/en/chains/) ページおよびデータセットディレクトリに準拠します。
* トレースデータは、チェーンの残りのインデックス化された履歴よりも遅れて開始される場合があります。`GET /chains` はこの境界を `coverage.traces_from_block` として報告します。それより前のリクエスト、またはトレースできなかった範囲内のリクエストは `422 no_coverage` を返します。
* トランザクションのトレースの場合：ハッシュが見つからない場合は `404 not_found` を返します（送信直後または採掘直後のトランザクションの場合、恒久的なものとして扱う前に数秒後に再試行してください）。ハッシュが `as_of_block` より高いブロックに解決される場合は、代わりに `409 not_indexed_yet` を返します。
* ブロックトレースエンドポイントはブロック番号を受け取ります。`as_of_block` より上の `{number}` は `indexed_through` を伴って `409 not_indexed_yet` を返します。`as_of_block` 以下の `{number}` は即座に提供されます。
* トランザクションが存在するものの、トレースデータがまだ存在しない最近のブロックは、`Retry-After` ヘッダー付きで `503 unavailable` を返します。

### Data API からトレースをリクエストする

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

# 1 つのトランザクションのコールフレーム。
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/transactions/0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd/trace" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"

# ブロック内のトランザクションごとに 1 つのコールツリー。
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/blocks/79900000/traces" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

```ts
const hash = "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd";

const txRes = await fetch(
  `https://api.blockvectra.com/v1/data/robinhood_mainnet/transactions/${hash}/trace`,
  { headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! } },
);
const txBody = await txRes.json();
console.log(txBody.data, txBody.meta);

const blockRes = await fetch("https://api.blockvectra.com/v1/data/robinhood_mainnet/blocks/79900000/traces", {
  headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! },
});
const blockBody = await blockRes.json();
console.log(blockBody.data.map((item: { txHash: string }) => item.txHash));

// npx tsx example.mts
```


  **Python**

```python
import os
import requests

hash_ = "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
headers = {"x-api-key": os.environ["BLOCKVECTRA_API_KEY"]}

tx = requests.get(
    f"https://api.blockvectra.com/v1/data/robinhood_mainnet/transactions/{hash_}/trace",
    headers=headers,
)
tx.raise_for_status()
tx_body = tx.json()
print(tx_body["data"], tx_body["meta"])

block = requests.get(
    "https://api.blockvectra.com/v1/data/robinhood_mainnet/blocks/79900000/traces",
    headers=headers,
)
block.raise_for_status()
block_body = block.json()
print([item["txHash"] for item in block_body["data"]])
```


## どちらを使用すべきか

| 典型的なタスク                                   | より適した選択肢                                 | 理由                                                                        |
| ----------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------- |
| トランザクションが取り込まれた直後に単一のトランザクションを再構築する       | `debug_traceTransaction`                 | ノードの現在の状態に対して実行されます。利用可能性はチェーンのメソッドポリシーに従います。                             |
| 単一トランザクションの保存済みコールツリーを読み取る                | `GET /{chain}/transactions/{hash}/trace` | REST 経由でトランザクションの `CallFrame` を直接返します。`as_of_block` までのデータを提供します。         |
| 1 回のリクエストで 1 ブロック内のすべてのコールツリーを読み取る        | `GET /{chain}/blocks/{number}/traces`    | ページネーションなしでブロック全体を `tx_index` 順に返します。`as_of_block` までのデータを提供します。          |
| ノードはまだ保持しているが、データセットにはまだ保存されていない状態をトレースする | `debug_trace` メソッド                       | Data API は `as_of_block` まで保存されたデータを提供します。ノードはまだ書き込まれていないブロックに対しても応答できます。 |

## 呼び出しあたりの CU

すべてのメソッドはその CU 重み付けに基づいて課金されます。以下の重み付けはプラットフォームの plans API から読み取られます：

**呼び出しあたりの CU 重み付け**

| メソッド | 呼び出しあたりの CU |
| --- | --- |
| `debug_traceBlockByHash` | 100 |
| `debug_traceBlockByNumber` | 100 |
| `debug_traceCall` | 100 |
| `debug_traceTransaction` | 100 |
| `trace_block` | 100 |
| `trace_call` | 100 |
| `trace_get` | 100 |
| `trace_replayTransaction` | 100 |
| `trace_transaction` | 100 |
| `data.block_traces` | 200 |
| `data.transaction_trace` | 200 |

拒否されたリクエストは課金されません。完全な課金ルールについては、[課金されないリクエスト：エラーコードと課金ルール](https://docs.blockvectra.com/en/guides/billing-rules/) を参照してください。

## 次のステップ

* [無料プランと料金](https://blockvectra.com/en/pricing/#free) で、アカウントに含まれる内容を確認できます。
* [コンソールにログイン](https://console.blockvectra.com/login/?next=%2Fkeys%2F) して、API key を作成してください。
