# Трейси транзакцій: debug_traceTransaction та ендпоінти трейсів Data API

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

## Два способи реконструкції дерева викликів

Трейс транзакції — це реконструйоване дерево викликів виконання: який контракт було викликано, з якими вхідними даними, скільки газу він спожив і які підклики здійснив. BlockVectra надає доступ до нього через дві поверхні:

* **Методи 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`, або його можна опустити для використання реєстратора структур за замовчуванням. Будь-яке інше значення відхиляється з помилкою JSON-RPC `-32602 tracer not allowed` (не тарифікується).
* **Таймаут трейсу**: параметр `timeout` має бути дійсним значенням тривалості та не перевищувати 30s; інакше запит відхиляється з помилкою `-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/).

### Запит debug\_traceTransaction за допомогою callTracer

Наведений нижче виклик додає параметр `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 повертає збережені дерева викликів для двох рівнів. Жоден із них не має пагінації: поле `next_cursor` ніколи не повертається.

* `GET /{chain}/transactions/{hash}/trace` — фрейм виклику однієї транзакції, знайденої за хешем транзакції.
* `GET /{chain}/blocks/{number}/traces` — одне дерево викликів на транзакцію в блоці, у порядку `tx_index`. Блок без транзакцій повертає `data: []`.

Обгортками відповідей є:

* `TxTraceEnvelope`: `data` є безпосередньо об'єктом `CallFrame`, плюс `meta`.
* `BlockTracesEnvelope`: `data` є масивом `BlockTraceItem`, кожен із яких містить `txHash` та `result` `CallFrame`, плюс `meta`.

Обидва ендпоінти трейсів повертають стандартний формат Ethereum `callTracer`. Це виняток із кодування безпеки грошових сум Data API: в інших місцях значення, які можуть перевищувати `2^53`, серіалізуються як десяткові рядки; на цих двох ендпоінтах `value`, `gas` та `gasUsed` є шістнадцятковими величинами з префіксом `0x`, а не десятковими рядками. Кожен `CallFrame` містить `type`, `from`, `gas`, `gasUsed` та `input`; `type` набуває одного зі значень: `CALL`, `DELEGATECALL`, `STATICCALL`, `CREATE`, `CREATE2` або `SELFDESTRUCT`. Поле `to` відсутнє для цілі фрейму `CREATE`/`CREATE2`, а `value` відсутнє для фрейму `STATICCALL`. Необов'язкові поля: `output` (відсутнє, коли виклик не повернув даних), `error` (відсутнє в разі успіху), `revertReason` (присутнє лише для revert типу `Error(string)`) та `calls` (вкладені підклики в порядку виклику). Додаткові члени фрейму зберігаються.

Для наочності наведено структуру полів `CallFrame`:

```jsonc
{
  "type": "CALL | DELEGATECALL | STATICCALL | CREATE | CREATE2 | SELFDESTRUCT",
  "from": "0x…",                      // 20-байтна адреса
  "to": "0x…",                        // відсутнє для цілі CREATE/CREATE2
  "value": "0x…",                     // шістнадцяткова величина з префіксом 0x; відсутнє для STATICCALL
  "gas": "0x…",                       // шістнадцяткова величина з префіксом 0x
  "gasUsed": "0x…",                   // шістнадцяткова величина з префіксом 0x
  "input": "0x…",
  "output": "0x…",                    // відсутнє, коли виклик не повернув даних
  "error": "…",                       // відсутнє в разі успіху
  "revertReason": "…",                // відсутнє, якщо виклик не завершився revert з Error(string)
  "calls": []                         // вкладені підклики в порядку виклику; відсутнє для листового фрейму
}
```

### Параметри

* `{chain}` (параметр шляху, обов'язковий): ідентифікатор мережі, значення `chain` запису в `GET /chains`. Зіставлення точне та чутливе до регістру; псевдоніми та числові 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`.
* Ендпоінт трейсів блоку приймає номер блоку. `{number}`, вищий за `as_of_block`, повертає `409 not_indexed_yet` із `indexed_through`; `{number}` на рівні або нижче `as_of_block` обслуговується негайно.
* Нещодавній блок із транзакціями, для якого дані трейсів ще недоступні, повертає `503 unavailable` із заголовком `Retry-After`.

### Запит трейсу з Data API

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

# Фрейм виклику однієї транзакції.
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/transactions/0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd/trace" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"

# Одне дерево викликів на кожну транзакцію в блоці.
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` | Повертає `CallFrame` транзакції безпосередньо через REST; обслуговується до `as_of_block`.                |
| Зчитування всіх дерев викликів в одному блоці за один запит        | `GET /{chain}/blocks/{number}/traces`    | Повертає весь блок без пагінації, у порядку `tx_index`; обслуговується до `as_of_block`.                  |
| Трасування стану, який вузол ще має, але набір даних ще не зберіг  | Методи `debug_trace`                     | Data API обслуговує збережені дані до `as_of_block`; вузол може відповідати за блоки, які ще не записані. |

## CU за виклик

Кожен метод тарифікується за його вагою в CU. Ваги нижче зчитуються з 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.
