# JSON-RPC

> Source: https://docs.blockvectra.com/vi/api/json-rpc/

## Tổng quan

Tất cả các yêu cầu được tính bằng **Compute Units (CU)** và được giới hạn tốc độ theo từng key.

* **Điểm cuối**: `POST /v1/{chain}/{api_key}` (key nằm trong đường dẫn) hoặc `POST /v1/{chain}` (key trong header). Đối với Robinhood Chain, `{chain}` là `robinhood_mainnet`: `https://api.blockvectra.com/v1/robinhood_mainnet`. Cùng một [API key](https://docs.blockvectra.com/en/quickstart/#1-get-an-api-key) hoạt động trên mọi chuỗi được hỗ trợ
* **Giao thức**: HTTP `POST`, lệnh gọi đơn lẻ hoặc theo lô (batch)
* **Đo lường**: Tổng chi phí CU của một yêu cầu được tính vào dung lượng burst của key ngay khi yêu cầu đến. Mọi lệnh gọi được chấp nhận và nhận được phản hồi đều bị tính phí theo trọng số CU đã công bố của phương thức; [Tài liệu tham khảo lỗi](https://docs.blockvectra.com/en/errors/) liệt kê các trường hợp không bị tính phí. Phí được quyết toán theo giờ (làm tròn xuống số nguyên, phần dư chuyển sang chu kỳ tiếp theo, thực hiện \~15 phút sau khi kết thúc chu kỳ)
* **Ethereum**: có danh sách phương thức riêng và cửa sổ trạng thái được xác định bởi `state_window_blocks` — xem [Chuỗi được hỗ trợ → Ethereum](https://docs.blockvectra.com/en/chains/#ethereum).

Để xem lược đồ tham số đầy đủ, chữ ký phương thức và thử nghiệm yêu cầu tương tác trên tất cả các phương thức, xem [Tài liệu tham khảo đầy đủ](https://docs.blockvectra.com/en/api/json-rpc/reference/). Về phiên bản đường dẫn, quy tắc tương thích ngược và khuyến nghị SDK, xem [Phiên bản và tính tương thích của API](https://docs.blockvectra.com/en/api/versioning/).

Để tạo API key và gửi yêu cầu đầu tiên, xem [Khởi động nhanh](https://docs.blockvectra.com/en/quickstart/); tài liệu này cũng hướng dẫn cách truyền key và gửi yêu cầu theo lô.

## Các lệnh gọi phổ biến

Ví dụ thực hành cho các lệnh gọi phổ biến.

### Truy vấn log (`eth_getLogs`)

Lọc log của hợp đồng trong phạm vi các khối gần đây — ở đây là sự kiện ERC-20 `Transfer` (topic `0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef`). Xem bảng [Quy tắc đo lường CU](#cu-metering-rules) bên dưới để biết trọng số CU hiện tại của `eth_getLogs`; phạm vi rộng hơn `max_logs_block_range` của chuỗi (từ `GET /v1/chains`) sẽ bị từ chối với mã lỗi `-32602`.

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

curl -X POST "https://api.blockvectra.com/v1/robinhood_mainnet" \
  -H 'Content-Type: application/json' \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_getLogs",
    "params": [{
      "fromBlock": "0x45a2409",
      "toBlock": "0x45a2609",
      "address": "0x1111111111111111111111111111111111111111",
      "topics": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]
    }],
    "id": 1
  }'
```


  **TypeScript**

```ts
// npx tsx example.mts
import { createPublicClient, http } from 'viem'

const apiKey = process.env.BLOCKVECTRA_API_KEY!
const client = createPublicClient({
  transport: http('https://api.blockvectra.com/v1/robinhood_mainnet', { fetchOptions: { headers: { 'x-api-key': apiKey } } }),
})

const TRANSFER_TOPIC = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
const latest = await client.getBlockNumber()

const logs = await client.getLogs({
  address: '0x1111111111111111111111111111111111111111',
  topics: [TRANSFER_TOPIC],
  fromBlock: latest > 100n ? latest - 100n : 0n,
  toBlock: latest,
})
console.log(logs.length)
```


  **Python**

```python
# uv run --with web3 python example.py
import os
from web3 import Web3

api_key = os.environ["BLOCKVECTRA_API_KEY"]
w3 = Web3(
    Web3.HTTPProvider(
        "https://api.blockvectra.com/v1/robinhood_mainnet",
        request_kwargs={"headers": {"Content-Type": "application/json", "x-api-key": api_key}},
    )
)

TRANSFER_TOPIC = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
latest = w3.eth.block_number

logs = w3.eth.get_logs(
    {
        "address": "0x1111111111111111111111111111111111111111",
        "topics": [TRANSFER_TOPIC],
        "fromBlock": max(latest - 100, 0),
        "toBlock": latest,
    }
)
print(len(logs))
```


  **Go**

```go
// go mod init example && go get github.com/ethereum/go-ethereum && go mod tidy && go run .
package main

import (
	"context"
	"fmt"
	"log"
	"math/big"
	"os"

	"github.com/ethereum/go-ethereum"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/ethereum/go-ethereum/rpc"
)

var transferTopic = common.HexToHash(
	"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
)

func main() {
	apiKey := os.Getenv("BLOCKVECTRA_API_KEY")
	ctx := context.Background()

	rpcClient, err := rpc.DialOptions(ctx, "https://api.blockvectra.com/v1/robinhood_mainnet", rpc.WithHeader("x-api-key", apiKey))
	if err != nil {
		log.Fatal(err)
	}
	client := ethclient.NewClient(rpcClient)

	latest, err := client.BlockNumber(ctx)
	if err != nil {
		log.Fatal(err)
	}
	from := uint64(0)
	if latest > 100 {
		from = latest - 100
	}

	address := common.HexToAddress("0x1111111111111111111111111111111111111111")
	logs, err := client.FilterLogs(ctx, ethereum.FilterQuery{
		FromBlock: new(big.Int).SetUint64(from),
		ToBlock:   new(big.Int).SetUint64(latest),
		Addresses: []common.Address{address},
		Topics:    [][]common.Hash{{transferTopic}},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len(logs))
}
```


  **Rust**

Thêm vào `Cargo.toml`:

```toml
[dependencies]
alloy = { version = "1", features = ["provider-http", "rpc-types"] }
tokio = { version = "1", features = ["full"] }
eyre = "0.6"
reqwest = { version = "0.13", default-features = false }
```

```rust
// cargo run
use alloy::primitives::{address, b256};
use alloy::providers::{Provider, ProviderBuilder};
use alloy::rpc::types::Filter;

const TRANSFER_TOPIC: alloy::primitives::B256 =
    b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef");

#[tokio::main]
async fn main() -> eyre::Result<()> {
    let api_key = std::env::var("BLOCKVECTRA_API_KEY").unwrap_or_default();
    let rpc_url: reqwest::Url = "https://api.blockvectra.com/v1/robinhood_mainnet".parse()?;

    let mut headers = reqwest::header::HeaderMap::new();
    headers.insert("x-api-key", api_key.parse()?);
    let http_client = reqwest::Client::builder().default_headers(headers).build()?;

    let provider = ProviderBuilder::new().connect_reqwest(http_client, rpc_url);

    let latest = provider.get_block_number().await?;
    let from = latest.saturating_sub(100);

    let filter = Filter::new()
        .address(address!("1111111111111111111111111111111111111111"))
        .event_signature(TRANSFER_TOPIC)
        .from_block(from)
        .to_block(latest);

    let logs = provider.get_logs(&filter).await?;
    println!("{}", logs.len());

    Ok(())
}
```


### Truy vết giao dịch (`debug_traceTransaction`)

Truy vết các lệnh gọi nội bộ của giao dịch bằng `callTracer`. Xem bảng [Quy tắc đo lường CU](#cu-metering-rules) bên dưới để biết trọng số CU hiện tại của `debug_traceTransaction`. Giống như các phương thức đọc trạng thái khác, yêu cầu sẽ bị từ chối khi khối mục tiêu nằm ngoài cửa sổ trạng thái gần đây của chuỗi (`-32011`). Kích thước cửa sổ là `state_window_blocks` của chuỗi (từ `GET /v1/chains`). Trên các chuỗi cung cấp trace, hãy sử dụng [Data API](https://docs.blockvectra.com/en/api/data/) để truy vấn trace lịch sử.

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

curl -X POST "https://api.blockvectra.com/v1/robinhood_mainnet" \
  -H 'Content-Type: application/json' \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{
    "jsonrpc": "2.0",
    "method": "debug_traceTransaction",
    "params": ["0xYOUR_TRANSACTION_HASH", {"tracer": "callTracer"}],
    "id": 1
  }'
```


  **TypeScript**

```ts
// npx tsx example.mts
import { createPublicClient, http } from 'viem'

const apiKey = process.env.BLOCKVECTRA_API_KEY!
const client = createPublicClient({
  transport: http('https://api.blockvectra.com/v1/robinhood_mainnet', { fetchOptions: { headers: { 'x-api-key': apiKey } } }),
})

const txHash = '0xYOUR_TRANSACTION_HASH'
const trace = await client.request({
  method: 'debug_traceTransaction' as any,
  params: [txHash, { tracer: 'callTracer' }] as any,
})
console.log(trace)
```


  **Python**

```python
# uv run --with web3 python example.py
import os
from web3 import Web3

api_key = os.environ["BLOCKVECTRA_API_KEY"]
w3 = Web3(
    Web3.HTTPProvider(
        "https://api.blockvectra.com/v1/robinhood_mainnet",
        request_kwargs={"headers": {"Content-Type": "application/json", "x-api-key": api_key}},
    )
)

tx_hash = "0xYOUR_TRANSACTION_HASH"
trace = w3.manager.request_blocking(
    "debug_traceTransaction", [tx_hash, {"tracer": "callTracer"}]
)
print(trace)
```


  **Go**

```go
// go mod init example && go get github.com/ethereum/go-ethereum && go mod tidy && go run .
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"os"

	"github.com/ethereum/go-ethereum/rpc"
)

func main() {
	apiKey := os.Getenv("BLOCKVECTRA_API_KEY")
	ctx := context.Background()

	client, err := rpc.DialOptions(ctx, "https://api.blockvectra.com/v1/robinhood_mainnet", rpc.WithHeader("x-api-key", apiKey))
	if err != nil {
		log.Fatal(err)
	}

	txHash := "0xYOUR_TRANSACTION_HASH"
	var trace json.RawMessage
	err = client.CallContext(ctx, &trace, "debug_traceTransaction", txHash, map[string]string{
		"tracer": "callTracer",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(trace))
}
```


  **Rust**

Thêm vào `Cargo.toml`:

```toml
[dependencies]
alloy = { version = "1", features = ["provider-http", "rpc-types"] }
tokio = { version = "1", features = ["full"] }
eyre = "0.6"
reqwest = { version = "0.13", default-features = false }
serde_json = "1"
```

```rust
// cargo run
use alloy::providers::{Provider, ProviderBuilder};
use serde_json::json;

#[tokio::main]
async fn main() -> eyre::Result<()> {
    let api_key = std::env::var("BLOCKVECTRA_API_KEY").unwrap_or_default();
    let rpc_url: reqwest::Url = "https://api.blockvectra.com/v1/robinhood_mainnet".parse()?;

    let mut headers = reqwest::header::HeaderMap::new();
    headers.insert("x-api-key", api_key.parse()?);
    let http_client = reqwest::Client::builder().default_headers(headers).build()?;

    let provider = ProviderBuilder::new().connect_reqwest(http_client, rpc_url);

    let tx_hash = "0xYOUR_TRANSACTION_HASH";
    let trace: serde_json::Value = provider
        .client()
        .request("debug_traceTransaction", (tx_hash, json!({ "tracer": "callTracer" })))
        .await?;
    println!("{trace}");

    Ok(())
}
```


## Quy tắc đo lường CU

Trọng số Compute Unit (CU) cho mỗi phương thức JSON-RPC.

| Phương thức | Trọng số (CU) |
| --- | --- |
| `eth_blockNumber` | 1 |
| `eth_chainId` | 1 |
| `eth_getBlockByNumber` | 5 |
| `eth_blobBaseFee` | 10 |
| `eth_feeHistory` | 10 |
| `eth_gasPrice` | 10 |
| `eth_getBalance` | 10 |
| `eth_getBlockByHash` | 10 |
| `eth_getBlockReceipts` | 10 |
| `eth_getBlockTransactionCountByHash` | 10 |
| `eth_getBlockTransactionCountByNumber` | 10 |
| `eth_getCode` | 10 |
| `eth_getHeaderByHash` | 10 |
| `eth_getHeaderByNumber` | 10 |
| `eth_getProof` | 10 |
| `eth_getRawTransactionByBlockHashAndIndex` | 10 |
| `eth_getRawTransactionByBlockNumberAndIndex` | 10 |
| `eth_getRawTransactionByHash` | 10 |
| `eth_getStorageAt` | 10 |
| `eth_getTransactionByBlockHashAndIndex` | 10 |
| `eth_getTransactionByBlockNumberAndIndex` | 10 |
| `eth_getTransactionByHash` | 10 |
| `eth_getTransactionCount` | 10 |
| `eth_getTransactionReceipt` | 10 |
| `eth_getUncleByBlockHashAndIndex` | 10 |
| `eth_getUncleByBlockNumberAndIndex` | 10 |
| `eth_getUncleCountByBlockHash` | 10 |
| `eth_getUncleCountByBlockNumber` | 10 |
| `eth_maxPriorityFeePerGas` | 10 |
| `eth_syncing` | 10 |
| `net_version` | 10 |
| `web3_clientVersion` | 10 |
| `web3_sha3` | 10 |
| `eth_call` | 15 |
| `eth_createAccessList` | 20 |
| `eth_estimateGas` | 20 |
| `eth_simulateV1` | 20 |
| `eth_getLogs` | 30 |
| `eth_sendRawTransaction` | 30 |
| `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 |

## Chính sách phương thức

Các phương thức khả dụng khác nhau tùy theo chuỗi; danh sách của từng chuỗi được hiển thị bên dưới, và [Chuỗi được hỗ trợ](https://docs.blockvectra.com/en/chains/) trình bày các nội dung còn lại. Chỉ các phương thức khớp với tên hoặc mẫu được phép mới có thể gọi được; bất kỳ phương thức nào khác sẽ trả về `-32601 method not available`.

**Được cho phép trên tất cả các chuỗi dưới đây:**

- `eth_blockNumber`
- `eth_call`
- `eth_chainId`
- `eth_estimateGas`
- `eth_feeHistory`
- `eth_gasPrice`
- `eth_getBalance`
- `eth_getBlockByHash`
- `eth_getBlockByNumber`
- `eth_getBlockReceipts`
- `eth_getBlockTransactionCountByHash`
- `eth_getBlockTransactionCountByNumber`
- `eth_getCode`
- `eth_getLogs`
- `eth_getStorageAt`
- `eth_getTransactionByBlockHashAndIndex`
- `eth_getTransactionByBlockNumberAndIndex`
- `eth_getTransactionByHash`
- `eth_getTransactionCount`
- `eth_getTransactionReceipt`
- `eth_maxPriorityFeePerGas`
- `eth_syncing`
- `net_version`
- `web3_clientVersion`

### Arbitrum One

Phạm vi khối tối đa của eth_getLogs: 1,000 khối; Cửa sổ trạng thái: 6,000 khối

**Được cho phép bổ sung:**

- `debug_traceBlockByHash`
- `debug_traceBlockByNumber`
- `debug_traceCall`
- `debug_traceTransaction`
- `eth_blobBaseFee`
- `eth_createAccessList`
- `eth_getHeaderByHash`
- `eth_getHeaderByNumber`
- `eth_getProof`
- `eth_getRawTransactionByBlockHashAndIndex`
- `eth_getRawTransactionByBlockNumberAndIndex`
- `eth_getRawTransactionByHash`
- `eth_getUncleByBlockHashAndIndex`
- `eth_getUncleByBlockNumberAndIndex`
- `eth_getUncleCountByBlockHash`
- `eth_getUncleCountByBlockNumber`
- `eth_sendRawTransaction`
- `eth_simulateV1`
- `web3_sha3`

### Base

Phạm vi khối tối đa của eth_getLogs: 1,000 khối; Cửa sổ trạng thái: 10,000 khối

**Được cho phép bổ sung:**

- `eth_blobBaseFee`
- `eth_createAccessList`
- `eth_getProof`
- `eth_simulateV1`
- `eth_getRawTransactionByHash`
- `eth_getRawTransactionByBlockHashAndIndex`
- `eth_getRawTransactionByBlockNumberAndIndex`
- `eth_getUncleCountByBlockNumber`
- `eth_getUncleCountByBlockHash`
- `eth_getUncleByBlockNumberAndIndex`
- `eth_getUncleByBlockHashAndIndex`
- `eth_getHeaderByNumber`
- `eth_getHeaderByHash`
- `eth_sendRawTransaction`
- `web3_sha3`

### BNB Smart Chain

Phạm vi khối tối đa của eth_getLogs: 1,000 khối; Cửa sổ trạng thái: 100 khối

**Được cho phép bổ sung:**

- `eth_sendRawTransaction`

### Ethereum

Phạm vi khối tối đa của eth_getLogs: 1,000 khối; Cửa sổ trạng thái: 250,000 khối

**Được cho phép bổ sung:**

- `debug_traceBlockByHash`
- `debug_traceBlockByNumber`
- `debug_traceCall`
- `debug_traceTransaction`
- `eth_blobBaseFee`
- `eth_createAccessList`
- `eth_getProof`
- `eth_sendRawTransaction`
- `trace_block`
- `trace_call`
- `trace_get`
- `trace_replayTransaction`
- `trace_transaction`
- `web3_sha3`

### Ethereum Sepolia

Phạm vi khối tối đa của eth_getLogs: 1,000 khối; Cửa sổ trạng thái: —

**Được cho phép bổ sung:**

- `eth_blobBaseFee`
- `eth_createAccessList`
- `eth_getProof`
- `eth_sendRawTransaction`
- `web3_sha3`

### HyperEVM

Chuỗi này hiện chưa hỗ trợ gửi giao dịch (`eth_sendRawTransaction` trả về `-32601` `method_not_allowed`); các phương thức đọc hoạt động bình thường.

Phạm vi khối tối đa của eth_getLogs: 1,000 khối; Cửa sổ trạng thái: —

### Polygon

Phạm vi khối tối đa của eth_getLogs: 1,000 khối; Cửa sổ trạng thái: 126 khối

**Được cho phép bổ sung:**

- `debug_traceBlockByHash`
- `debug_traceBlockByNumber`
- `debug_traceCall`
- `debug_traceTransaction`
- `eth_blobBaseFee`
- `eth_createAccessList`
- `eth_getHeaderByHash`
- `eth_getHeaderByNumber`
- `eth_getProof`
- `eth_getRawTransactionByBlockHashAndIndex`
- `eth_getRawTransactionByBlockNumberAndIndex`
- `eth_getRawTransactionByHash`
- `eth_getUncleByBlockHashAndIndex`
- `eth_getUncleByBlockNumberAndIndex`
- `eth_getUncleCountByBlockHash`
- `eth_getUncleCountByBlockNumber`
- `eth_sendRawTransaction`
- `eth_simulateV1`
- `web3_sha3`

### Robinhood Chain

Phạm vi khối tối đa của eth_getLogs: 1,000 khối; Cửa sổ trạng thái: 900 khối

**Được cho phép bổ sung:**

- `eth_blobBaseFee`
- `eth_createAccessList`
- `eth_getProof`
- `eth_simulateV1`
- `eth_getRawTransactionByHash`
- `eth_getRawTransactionByBlockHashAndIndex`
- `eth_getRawTransactionByBlockNumberAndIndex`
- `eth_getUncleCountByBlockNumber`
- `eth_getUncleCountByBlockHash`
- `eth_getUncleByBlockNumberAndIndex`
- `eth_getUncleByBlockHashAndIndex`
- `eth_getHeaderByNumber`
- `eth_getHeaderByHash`
- `eth_sendRawTransaction`
- `web3_sha3`
- `debug_traceTransaction`
- `debug_traceCall`
- `debug_traceBlockByNumber`
- `debug_traceBlockByHash`

### Robinhood Chain Testnet

Phạm vi khối tối đa của eth_getLogs: 1,000 khối; Cửa sổ trạng thái: 1,023 khối

**Được cho phép bổ sung:**

- `debug_traceBlockByHash`
- `debug_traceBlockByNumber`
- `debug_traceCall`
- `debug_traceTransaction`
- `eth_blobBaseFee`
- `eth_createAccessList`
- `eth_getHeaderByHash`
- `eth_getHeaderByNumber`
- `eth_getProof`
- `eth_getRawTransactionByBlockHashAndIndex`
- `eth_getRawTransactionByBlockNumberAndIndex`
- `eth_getRawTransactionByHash`
- `eth_getUncleByBlockHashAndIndex`
- `eth_getUncleByBlockNumberAndIndex`
- `eth_getUncleCountByBlockHash`
- `eth_getUncleCountByBlockNumber`
- `eth_sendRawTransaction`
- `eth_simulateV1`
- `web3_sha3`

**Giới hạn**:

* **Theo lô (Batch)**: tối đa 100 lệnh gọi mỗi yêu cầu; cũng bị giới hạn bởi CU burst của key, xem bên dưới.
* **Thân yêu cầu (Request body)**: tối đa 2 MiB
* **CU burst**: mỗi API key có một bucket CU (tốc độ nạp `cu_per_sec`, dung lượng `burst_cu` — mặc định là 400 CU/s và burst 1,600 CU; hiển thị theo từng key trong bảng Keys trên console). Một yêu cầu đơn lẻ — bao gồm toàn bộ lô JSON-RPC — có tổng số CU vượt quá dung lượng burst của key sẽ bị từ chối với mã lỗi `-32022 request_exceeds_burst` (`request cost <N> CU exceeds burst capacity <M> CU`); hãy chia nhỏ thành các lô nhỏ hơn.

## Mã lỗi

Xem [Tài liệu tham khảo lỗi](https://docs.blockvectra.com/en/errors/) để biết mọi mã lỗi, việc lỗi có bị tính phí hay không và cách xử lý.

## Tham khảo OpenAPI đầy đủ

Xem [Tài liệu tham khảo OpenAPI đầy đủ](https://docs.blockvectra.com/en/api/json-rpc/reference/) để xem đặc tả hoàn chỉnh mà máy có thể đọc được cùng tất cả chữ ký phương thức, lược đồ yêu cầu và phản hồi cũng như chi tiết tham số được kết xuất có tính tương tác.
