# Transaction Traces: debug_traceTransaction และ Trace Endpoint บน Data API

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

## สองวิธีในการสร้าง Call Tree ขึ้นใหม่

Transaction trace คือ Call Tree ของการประมวลผลที่ถูกสร้างขึ้นใหม่: สัญญาใดถูกเรียก, ด้วยอินพุตใด, ใช้ gas ไปเท่าใด และมีการเรียกย่อยใดบ้าง BlockVectra ให้บริการข้อมูลนี้ผ่านสองช่องทาง:

* **เมธอด `debug_trace` ของ JSON-RPC** (เช่น `debug_traceTransaction`) — ทำงานกับโหนดของเชนโดยตรงผ่าน JSON-RPC endpoint จึงสามารถติดตามสถานะล่าสุดที่โหนดนั้นยังคงเก็บไว้อยู่ได้
* **Trace บน Data API** — `GET /{chain}/transactions/{hash}/trace` และ `GET /{chain}/blocks/{number}/traces` ส่งคืน Call Tree ที่จัดเก็บและทำดัชนีไว้ผ่าน REST

ทั้งสองช่องทางใช้ API key เดียวกันและวัดปริมาณการใช้งานเป็น CU ตามค่าน้ำหนักของเมธอด (ดูค่าน้ำหนักด้านล่าง) การเลือกวิธีที่เหมาะสมขึ้นอยู่กับว่าคุณต้องการธุรกรรมเดียวหรือทั้งบล็อก เป้าหมายเกิดขึ้นเมื่อเร็วๆ นี้เพียงใด และคุณต้องการอ่านข้อมูลทั้งบล็อกโดยไม่มีการแบ่งหน้าหรือไม่

## ขีดจำกัดที่ใช้กับเมธอด debug\_trace

คำขอ `debug_trace` จะได้รับการยอมรับเฉพาะสำหรับเมธอดและ tracer ที่นโยบายเมธอดของเชนอนุญาตเท่านั้น:

* **Tracer ที่อนุญาต**: พารามิเตอร์ `tracer` ยอมรับเฉพาะ native tracer ภายในตัวเท่านั้น — ได้แก่ `callTracer`, `flatCallTracer`, `prestateTracer`, `4byteTracer`, `noopTracer` หรือการละเว้นพารามิเตอร์นี้เพื่อใช้ struct logger เริ่มต้น ค่าอื่นๆ ทั้งหมดจะถูกปฏิเสธด้วยข้อผิดพลาด JSON-RPC `-32602 tracer not allowed` (ไม่คิดค่าบริการ)
* **ระยะเวลาหมดเวลาของ Trace**: พารามิเตอร์ `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` เพื่อขอ Call Tree:

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

# Add "tracer" to request a call tree with one of the allowed native tracers.
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"])
```


## สิ่งที่ Trace Endpoint บน Data API นำเสนอ

Data API ส่งคืน Call Tree ที่จัดเก็บไว้สำหรับสองขอบเขตการทำงาน ซึ่งทั้งสองไม่มีการแบ่งหน้า: โดยไม่มี `next_cursor` ปรากฏเลย

* `GET /{chain}/transactions/{hash}/trace` — Call Frame ของหนึ่งธุรกรรม ค้นหาด้วยแฮชธุรกรรม
* `GET /{chain}/blocks/{number}/traces` — Call Tree หนึ่งรายการต่อหนึ่งธุรกรรมในบล็อก เรียงตามลำดับ `tx_index` โดยบล็อกที่ไม่มีธุรกรรมจะส่งคืน `data: []`

โครงสร้างการตอบกลับคือ:

* `TxTraceEnvelope`: `data` คือ `CallFrame` โดยตรง รวมกับ `meta`
* `BlockTracesEnvelope`: `data` คืออาร์เรย์ของ `BlockTraceItem` ซึ่งแต่ละรายการมี `txHash` และผลลัพธ์ที่เป็น `CallFrame` รวมกับ `meta`

endpoint สำหรับ trace ทั้งสองจะส่งคืนรูปแบบมาตรฐาน `callTracer` ของ Ethereum นี่คือข้อยกเว้นสำหรับการเข้ารหัสเพื่อความปลอดภัยของมูลค่าบน Data API: ในส่วนอื่นๆ ค่าที่อาจเกิน `2^53` จะถูกแปลงเป็นอนุกรมในรูปแบบสตริงฐานสิบ; แต่บนสอง endpoint นี้ `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-byte address
  "to": "0x…",                        // absent for a CREATE/CREATE2 target
  "value": "0x…",                     // 0x-prefixed hex quantity; absent for STATICCALL
  "gas": "0x…",                       // 0x-prefixed hex quantity
  "gasUsed": "0x…",                   // 0x-prefixed hex quantity
  "input": "0x…",
  "output": "0x…",                    // absent when the call returned no data
  "error": "…",                       // absent on success
  "revertReason": "…",                // absent unless the call reverted with Error(string)
  "calls": []                         // nested sub-calls in call order; absent for a leaf frame
}
```

### พารามิเตอร์

* `{chain}` (พารามิเตอร์พาธ, จำเป็น): ตัวระบุเชน ซึ่งเป็นค่า `chain` ของรายการใน `GET /chains` การจับคู่จะตรงกันทุกตัวอักษรและคำนึงถึงตัวพิมพ์ใหญ่-เล็ก; ไม่ยอมรับนามแฝงหรือ chain ID แบบตัวเลข
* `{hash}` (พารามิเตอร์พาธ, จำเป็นสำหรับ transaction trace): แฮชธุรกรรมขนาด 32 ไบต์ คำนำหน้า `0x` เป็นตัวเลือก และยอมรับตัวพิมพ์ใหญ่หรือเล็กก็ได้
* `{number}` (พารามิเตอร์พาธ, จำเป็นสำหรับ block traces): ความสูงของบล็อกที่ไม่เป็นค่าลบ

### ความครอบคลุมและสถานะสิ้นสุด

* ทั้งสอง endpoint อยู่ภายใต้ความสามารถ `traces` เชนที่ไม่มีความสามารถนี้จะส่งคืน `422 no_coverage` เชนที่ให้บริการชุดข้อมูลนี้ขึ้นอยู่กับหน้า [เชนที่รองรับ](https://docs.blockvectra.com/en/chains/) และไดเรกทอรีชุดข้อมูล
* ข้อมูล Trace อาจเริ่มต้นช้ากว่าประวัติที่ทำดัชนีส่วนอื่นๆ ของเชน โดย `GET /chains` จะรายงานขอบเขตเป็น `coverage.traces_from_block`; คำขอที่เกิดขึ้นก่อนหน้านั้น หรืออยู่ในช่วงที่ไม่สามารถทำ trace ได้ จะส่งคืน `422 no_coverage`
* สำหรับ Transaction Trace: หากไม่พบแฮช จะส่งคืน `404 not_found` (สำหรับธุรกรรมที่เพิ่งส่งหรือเพิ่งขุดสำเร็จ ให้ลองใหม่หลังจากผ่านไปสองสามวินาทีก่อนจะถือว่าเป็นข้อผิดพลาดถาวร); หากแฮชระบุไปยังบล็อกที่สูงกว่า `as_of_block` จะส่งคืน `409 not_indexed_yet` แทน
* Endpoint ของ Block Traces รับหมายเลขบล็อก ค่า `{number}` ที่สูงกว่า `as_of_block` จะส่งคืน `409 not_indexed_yet` พร้อมกับ `indexed_through`; ส่วน `{number}` ที่อยู่ที่ระดับหรือต่ำกว่า `as_of_block` จะได้รับข้อมูลทันที
* บล็อกล่าสุดที่มีธุรกรรมแต่ยังไม่มีข้อมูล trace จะส่งคืน `503 unavailable` พร้อมส่วนหัว `Retry-After`

### การขอ Trace จาก Data API

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

# One transaction's call frame.
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/transactions/0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd/trace" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"

# One call tree per transaction in a block.
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/blocks/79900000/traces" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

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

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_ = "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
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`                 | ทำงานกับสถานะปัจจุบันของโหนด; ความพร้อมใช้งานเป็นไปตามนโยบายเมธอดของเชน                                    |
| อ่าน Call Tree ที่จัดเก็บไว้ของธุรกรรมเดียว                 | `GET /{chain}/transactions/{hash}/trace` | ส่งคืน `CallFrame` ของธุรกรรมโดยตรงผ่าน REST; ให้บริการข้อมูลจนถึง `as_of_block`                           |
| อ่าน Call Tree ทุกรายการในหนึ่งบล็อกด้วยคำขอเดียว           | `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
