# ขีดจำกัดอัตรา HyperEVM RPC และการดึงข้อมูล log ย้อนหลัง

> Source: https://docs.blockvectra.com/th/guides/hyperevm-backfill/

## คำตอบโดยตรง

HyperEVM public RPC อย่างเป็นทางการที่เป็นค่าเริ่มต้นอนุญาต 50 บล็อกต่อหนึ่งคิวรี `eth_getLogs` (แหล่งข้อมูล: [เอกสาร JSON-RPC](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc) ทางการของ Hyperliquid) บน BlockVectra คำขอ `eth_getLogs` ที่มีการยืนยันตัวตนครอบคลุมสูงสุด 1,000 บล็อกต่อหนึ่งคิวรี (`hyperevm_mainnet.max_logs_block_range` จาก [GET /v1/chains](https://api.blockvectra.com/v1/chains)) โดยนับรวมจุดสิ้นสุดทั้งสองฝั่ง ช่วงที่กว้างกว่านี้จะส่งกลับ HTTP 200, JSON-RPC `-32602` และ `logs_range_too_large` พร้อม `retryable: false` (ดู [สารบัญข้อผิดพลาด](https://docs.blockvectra.com/en/errors/#logs_range_too_large)); ให้แบ่งเป็น `[from, min(from + max − 1, end)]` บันทึกเคอร์เซอร์ของคุณ และขยับไปยังจุดสิ้นสุดบวกหนึ่งหลังจากสำเร็จเพื่อดำเนินการต่อ ขีดจำกัดอัตราต่อ IP ของ public RPC อย่างเป็นทางการและขีดจำกัดของคีย์ของ BlockVectra ได้รับการอธิบายแยกต่างหากใน [ขีดจำกัดอัตราของ public RPC อย่างเป็นทางการและ 429](#official-public-rpc-rate-limits-and-429) และพารามิเตอร์การให้บริการด้านล่าง

* **ขั้นตอนแรก:** [อ่านบล็อกล่าสุดโดยไม่ต้องใช้ API key](#1-read-the-latest-block-without-an-api-key) โดยใช้คำสั่ง curl ด้านล่าง
* **สำเร็จเมื่อ:** สคริปต์ดึงข้อมูลย้อนหลังแสดงผล `fromBlock`, `toBlock` และอาร์เรย์ `result` สำหรับทุก chunk ในช่วงที่คุณเลือก; อาร์เรย์ว่างหมายถึงไม่มี log ที่ตรงกันใน chunk นั้น

[พารามิเตอร์ของเชนและตัวเลือกการเข้าถึง](https://blockvectra.com/en/chains/hyperevm_mainnet/)

## งานที่คู่มือนี้ช่วยให้คุณทำสำเร็จ

* [ตรวจสอบ HyperEVM RPC](#connect-with-viem-or-ethers) ด้วยการอ่านแบบสาธารณะโดยใช้ viem หรือ ethers ก่อนเลือกเมธอดที่มีการยืนยันตัวตน
* [ดึงข้อมูล log ย้อนหลังในช่วงที่จำกัดขอบเขต](#three-step-task-backfill-a-bounded-hyperevm-log-window) ให้อยู่ภายในขีดจำกัด `eth_getLogs` ของ HyperEVM พร้อมการตัดสินใจลองใหม่ตามข้อผิดพลาดที่ได้รับกลับมา
* [อ่านกิจกรรมของแอดเดรส](#using-data-api-endpoints-instead-of-extensive-getlogs-scanning) ผ่านธุรกรรมและการโอนที่ทำดัชนีไว้ด้วยคีย์ พร้อมตรวจสอบข้อมูลเมทาดาตาความครอบคลุมและความสดใหม่ที่ส่งกลับมา

<span id="bounded-log-backfill-task" />

## งาน 3 ขั้นตอน: ดึงข้อมูล log ของ HyperEVM ย้อนหลังในช่วงที่จำกัดขอบเขต

อ่านบล็อกล่าสุดโดยไม่ต้องใช้คีย์, สร้างคีย์, จากนั้นดึง event log สำหรับสัญญาในช่วงบล็อกที่จำกัด

เลือกสัญญาและช่วงบล็อกที่คุณต้องการ งานนี้ครอบคลุมช่วงที่จำกัดนั้น; ไม่ได้รับประกันประวัติสัญญาที่สมบูรณ์ทั้งหมด

### 1. อ่านบล็อกล่าสุดโดยไม่ต้องใช้ API key

```bash
curl -sS "https://api.blockvectra.com/v1/hyperevm_mainnet/public" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'
```

`result` ของ JSON-RPC คือหมายเลขบล็อกล่าสุดในรูปแบบเลขฐานสิบหก นี่คือ `public.url` ของ HyperEVM ที่เผยแพร่โดย [GET /v1/chains](https://api.blockvectra.com/v1/chains) เมธอด `public.methods` ของ endpoint สาธารณะไม่ได้รวม `eth_getLogs`; ขั้นตอนที่ 3 จำเป็นต้องใช้คีย์

### 2. สร้าง API key

<div data-attribution-ref="docs-hyperevm-task">
  [สร้างคีย์สำหรับการดึงข้อมูลย้อนหลังนี้](https://console.blockvectra.com/login/?next=%2Fkeys%2F) สร้างคีย์และบันทึก secret ที่แสดงในกล่องโต้ตอบไว้สำหรับใช้งานกับ `hyperevm_mainnet`

  สำหรับ AI Agent ที่ใช้ HTTP โดยไม่มีเบราว์เซอร์ ให้ทำตาม <a href="/en/guides/programmatic-signup/">คู่มือการลงทะเบียนแบบโปรแกรม</a> ส่ง `ref` ที่ถูกต้องของ URL คู่มือใน JSON body ของ `POST /auth/siwe/login` แทนที่จะเป็น `docs-signup` ของตัวอย่าง; ละเว้นได้หากไม่มี อย่าขอให้ผู้ใช้แปะคีย์ลงในแชท
</div>

### 3. ดึงข้อมูล log ย้อนหลังด้วยคีย์ของคุณ

เทมเพลตเริ่มต้นฉบับสมบูรณ์: [blockvectra/hyperevm-backfill](https://github.com/blockvectra/hyperevm-backfill)

บันทึกสคริปต์ต่อไปนี้เป็น `hyperevm-task.ts` ซึ่งรันด้วย Node.js 24 ขึ้นไป โดยไม่ต้องมีแพ็กเกจเพิ่มเติม ตั้งค่า `BLOCKVECTRA_API_KEY` เป็นคีย์ที่คุณบันทึกไว้ และ `LOG_ADDRESS` เป็นแอดเดรสของสัญญาที่ส่งเหตุการณ์ที่คุณต้องการตรวจสอบ; เก็บรักษาคีย์ไว้บนเซิร์ฟเวอร์หรือในเทอร์มินัลภายในเครื่องของคุณ

```bash
export BLOCKVECTRA_API_KEY='replace-with-your-key'
export LOG_ADDRESS='replace-with-contract-address'
node hyperevm-task.ts
```

ตามค่าเริ่มต้น สคริปต์จะดึงบล็อกล่าสุดจำนวน `max_logs_block_range` บล็อก หรือน้อยกว่านั้นหากอยู่ใกล้กับบล็อกเริ่มต้น (genesis) สคริปต์จะอ่านขีดจำกัดนั้นจาก `/v1/chains` ขณะรันไทม์ หากต้องการเลือกช่วงที่จำกัดอื่น ให้ตั้งค่าทั้ง `FROM_BLOCK` และ `TO_BLOCK` เป็นหมายเลขบล็อกแบบฐานสิบหรือฐานสิบหกขึ้นต้นด้วย `0x` ก่อนรัน ช่วงที่ใหญ่ขึ้นจะถูกแบ่งออกเป็น chunk ต่อเนื่องกัน โดยแต่ละ chunk จะมีขนาดไม่เกินขีดจำกัดที่ประกาศไว้

```ts
const apiKey = process.env.BLOCKVECTRA_API_KEY;
const address = process.env.LOG_ADDRESS;
if (!apiKey || apiKey === "replace-with-your-key") throw new Error("Set BLOCKVECTRA_API_KEY");
if (!address || !/^0x[0-9a-f]{40}$/i.test(address)) throw new Error("Set LOG_ADDRESS to a contract address");

const fromBlock = process.env.FROM_BLOCK;
const toBlock = process.env.TO_BLOCK;
if ((fromBlock !== undefined || toBlock !== undefined) && (!fromBlock || !toBlock)) {
  throw new Error("Set both FROM_BLOCK and TO_BLOCK");
}

const chainsUrl = "https://api.blockvectra.com/v1/chains";
const rpcUrl = new URL("./hyperevm_mainnet", chainsUrl).href;
async function readJson(url: string) {
  const response = await fetch(url, { signal: AbortSignal.timeout(15_000) });
  if (!response.ok) throw new Error(`Metadata HTTP ${response.status}`);
  return response.json();
}
const catalog = await readJson(chainsUrl);
const chain = catalog.chains.find((item: { chain: string }) => item.chain === "hyperevm_mainnet");
if (!chain || !Number.isSafeInteger(chain.max_logs_block_range) || chain.max_logs_block_range <= 0) {
  throw new Error("Missing or invalid max_logs_block_range");
}
if (!chain.methods.allow.includes("eth_getLogs") || chain.methods.deny.includes("eth_getLogs")) {
  throw new Error("eth_getLogs is unavailable on this chain");
}
const maxRange = BigInt(chain.max_logs_block_range);
const plans = await readJson("https://console-api.blockvectra.com/v1/plans");
function weight(method: string): bigint {
  const row = plans.method_weights.find((item: { method: string }) => item.method === method);
  if (!row || !Number.isSafeInteger(row.cu_weight) || row.cu_weight <= 0) {
    throw new Error(`Missing or invalid CU weight for ${method}`);
  }
  return BigInt(row.cu_weight);
}
const headWeight = weight("eth_blockNumber");
const logsWeight = weight("eth_getLogs");

type RpcBody = {
  result?: unknown;
  error?: { code: number; data?: { retryable?: boolean } };
};
async function rpc(method: string, params: unknown[]): Promise<unknown> {
  for (let attempt = 0; attempt < 4; attempt++) {
    const response = await fetch(rpcUrl, {
      method: "POST",
      redirect: "error",
      headers: { "Content-Type": "application/json", "x-api-key": apiKey! },
      body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
      signal: AbortSignal.timeout(15_000),
    });
    const body = await response.json() as RpcBody;
    if (response.ok && !body.error && body.result !== undefined) return body.result;
    if (body.error?.data?.retryable !== true || attempt === 3) {
      throw new Error(`RPC failed: HTTP ${response.status}, code ${body.error?.code ?? "unknown"}`);
    }
    const retryAfter = response.headers.get("Retry-After");
    const delay = retryAfter === null ? 0 : /^\d+$/.test(retryAfter)
      ? Number(retryAfter) * 1000 : Date.parse(retryAfter) - Date.now();
    if (delay > 30_000) throw new Error("Retry-After exceeds 30 seconds; rerun later");
    const backoff = 1000 * 2 ** attempt + Math.random() * 250;
    await new Promise((resolve) => setTimeout(resolve, Math.max(backoff, Number.isFinite(delay) ? delay : 0)));
  }
  throw new Error("Retry limit reached");
}
function block(value: string): bigint {
  if (!/^(0x[0-9a-f]+|[0-9]+)$/i.test(value)) throw new Error("Invalid block number");
  return BigInt(value);
}
const head = await rpc("eth_blockNumber", []);
if (typeof head !== "string" || !/^0x[0-9a-f]+$/i.test(head)) throw new Error("Invalid chain head");
const latest = block(head);
const end = toBlock ? block(toBlock) : latest;
const start = fromBlock ? block(fromBlock)
  : end >= maxRange - 1n ? end - maxRange + 1n : 0n;
if (start > end || end > latest) throw new Error("Require 0 <= FROM_BLOCK <= TO_BLOCK <= latest");
const chunks = (end - start + maxRange) / maxRange;
console.error(`Window ${start}..${end}; chunks=${chunks}; estimated CU=${headWeight + chunks * logsWeight}`);

const hex = (value: bigint) => `0x${value.toString(16)}`;
for (let from = start; from <= end; from += maxRange) {
  const to = from + maxRange - 1n < end ? from + maxRange - 1n : end;
  const result = await rpc("eth_getLogs", [{ address, fromBlock: hex(from), toBlock: hex(to) }]);
  if (!Array.isArray(result)) throw new Error("Expected eth_getLogs result array");
  console.log(JSON.stringify({ fromBlock: hex(from), toBlock: hex(to), result }));
}
```

คำขอจะทำงานตามลำดับ ข้อผิดพลาด JSON-RPC จะได้รับการลองใหม่ก็ต่อเมื่อ `error.data.retryable` เป็น `true` โดยลองใหม่ได้สูงสุดสี่ครั้งต่อหนึ่งคำขอ พร้อม exponential backoff และ jitter รวมถึงรองรับ `Retry-After` ในรูปแบบวินาทีหรือวันที่ HTTP การรอที่นานกว่า 30 วินาทีจะหยุดการทำงานของสคริปต์เพื่อให้คุณสามารถรันใหม่ในภายหลัง ความล้มเหลวของเครือข่าย, การหมดเวลา, การตอบกลับที่ผิดรูปแบบ และข้อผิดพลาดที่ไม่สามารถลองใหม่ได้จะหยุดทำงานทันที; สคริปต์จะออกจากการทำงานแบบไม่สำเร็จแทนที่จะรายงานว่าการดึงข้อมูลย้อนหลังเสร็จสมบูรณ์

แต่ละบรรทัดที่แสดงผลบน standard output ประกอบด้วย `fromBlock`, `toBlock` และอาร์เรย์ `result` ของแต่ละ chunk โดยที่ `result: []` หมายถึงไม่มี log ที่ตรงกันใน chunk นั้น ให้อ่านฟิลด์เหล่านี้ในแต่ละ log:

| ฟิลด์                                             | ความหมาย                                                                                                 |
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `address`                                         | สัญญาที่ส่งเหตุการณ์ออกมา                                                                                |
| `blockNumber`, `blockHash`                        | บล็อกที่มี log; หมายเลขอยู่ในรูปแบบเลขฐานสิบหก                                                           |
| `transactionHash`, `transactionIndex`, `logIndex` | ตำแหน่งธุรกรรมและ log; ดัชนีอยู่ในรูปแบบเลขฐานสิบหก                                                      |
| `topics`, `data`                                  | อาร์กิวเมนต์เหตุการณ์ที่ทำดัชนีและอาร์กิวเมนต์ที่ไม่ทำดัชนีซึ่งเข้ารหัสตาม ABI; ถอดรหัสด้วย ABI ของสัญญา |
| `removed`                                         | ระบุว่า log ถูกลบออกเนื่องจากการจัดระเบียบเชนใหม่ (chain reorganization) หรือไม่                         |

บล็อกล่าสุดไม่ใช่เครื่องหมายบอกความเป็นที่สิ้นสุด (finality) หากคุณต้องการช่วงประวัติที่เสถียร ให้เลือก `TO_BLOCK` ที่ได้รับการยืนยันแล้วของแอปพลิเคชันของคุณ และจัดการกับการจัดระเบียบเชนใหม่ (reorg)

สำหรับช่วงที่มีขนาด `B = TO_BLOCK − FROM_BLOCK + 1` บล็อกและขีดจำกัดที่ประกาศไว้ `L` จำนวน chunk จะเป็น `N = ceil(B / L)` ให้อ่าน `method_weights[].cu_weight` สำหรับ `eth_getLogs` และ `eth_blockNumber` จาก [GET /v1/plans](https://console-api.blockvectra.com/v1/plans) สคริปต์จะพิมพ์ค่าประมาณการไปยัง standard error: `N × weight(eth_getLogs) + weight(eth_blockNumber)` รวมถึงการค้นหา head ที่ใช้คีย์ด้วย ซึ่งไม่รวมการเรียกเพิ่มเติมและการลองใหม่ที่คิดค่าบริการ; โปรดดู [กฎการเรียกเก็บเงิน](https://docs.blockvectra.com/en/guides/billing-rules/) สำหรับการชำระบัญชี CU ขึ้นอยู่กับจำนวนการเรียก ไม่ใช่จำนวน log ที่ส่งกลับมา

**การส่งมอบเหตุการณ์:** ใช้การโพลล์ HTTP แบบแบ่งส่วนด้านล่าง หรือส่งเหตุการณ์ของแอดเดรสที่ติดตามไปยังตัวรับ HTTPS ด้วย [webhook push](https://docs.blockvectra.com/en/guides/webhook-push/) โดย **GET /v1/push/chains จะแสดงรายการเชนที่รองรับ** และการตั้งค่าการยืนยัน; ยืนยันตัวตนด้วย `x-api-key` ลายเซ็น webhook, การขจัดข้อมูลซ้ำ และการเล่นซ้ำมีอธิบายอยู่ในคู่มือนั้น ทั้งนี้ Webhook push จะแยกต่างหากจากการสมัครสมาชิก WebSocket (`ws` และ `subscriptions` ใน `/v1/chains`)

## เชื่อมต่อด้วย viem หรือ ethers

| พารามิเตอร์ / เอนด์พอยต์ | ค่า / เทมเพลต | การยืนยันตัวตน |
|---|---|---|
| Chain ID (EIP-155) | `999` | — |
| JSON-RPC (คีย์ในพาธ) | `POST https://api.blockvectra.com/v1/hyperevm_mainnet/{api_key}` | API key ในพาธ URL |
| JSON-RPC (คีย์ในส่วนหัว) | `POST https://api.blockvectra.com/v1/hyperevm_mainnet` | ส่วนหัว x-api-key: {api_key} |
| ที่อยู่หลัก Data API | `GET https://api.blockvectra.com/v1/data/hyperevm_mainnet/…` | ส่วนหัว x-api-key: {api_key} |
| สถานะสาธารณะ | `GET https://api.blockvectra.com/v1/status` | ไม่ต้องยืนยันตัวตน (สาธารณะ) |

นักพัฒนาและ AI Agent สามารถใช้การตั้งค่าฝั่งเซิร์ฟเวอร์เดียวกันได้ ใช้ Node.js 24 ขึ้นไป, viem 2 หรือ ethers 6 และเริ่มต้นด้วยการอ่านแบบสาธารณะ ตั้งค่า `BLOCKVECTRA_API_KEY` อย่างปลอดภัยในสภาพแวดล้อมสำหรับเมธอดที่ใช้คีย์ เก็บรักษาคีย์และ RPC URL ที่มีคีย์ให้พ้นจากโค้ดของเบราว์เซอร์, ล็อก และการควบคุมเวอร์ชัน

บันทึกไฟล์นี้เป็น `network.mjs` ซึ่งจะอ่าน `chain_id` และนโยบายเมธอดจาก [GET /v1/chains](https://api.blockvectra.com/v1/chains) สำหรับการอ่านแบบไม่ใช้คีย์ ให้ใช้ `public.url` ของสารบบและเฉพาะเมธอดที่ระบุไว้ใน `public.methods`; ความพร้อมใช้งานของ HTTP สาธารณะไม่ได้หมายความว่าสามารถเข้าถึง WebSocket ได้

```js
const chainSlug = process.env.BLOCKVECTRA_CHAIN ?? 'hyperevm_mainnet';
const key = process.env.BLOCKVECTRA_API_KEY;
const catalogUrl = 'https://api.blockvectra.com/v1/chains';
const response = await fetch(catalogUrl, { signal: AbortSignal.timeout(15_000) });
if (!response.ok) throw new Error(`Chains HTTP ${response.status}`);
const catalog = await response.json();
export const chainInfo = catalog.chains.find(item => item.chain === chainSlug);
if (!chainInfo || !Number.isSafeInteger(chainInfo.chain_id) || chainInfo.chain_id <= 0) {
  throw new Error('Missing chain or chain_id');
}
export function allows(method) {
  const matches = pattern => pattern.endsWith('*')
    ? method.startsWith(pattern.slice(0, -1)) : pattern === method;
  if (!key) return (chainInfo.public?.methods ?? []).some(matches);
  return (chainInfo.methods?.allow ?? []).some(matches)
    && !(chainInfo.methods?.deny ?? []).some(matches);
}
if (!allows('eth_chainId')) throw new Error('eth_chainId is unavailable');
export const rpcUrl = key
  ? new URL(`./${chainSlug}/${encodeURIComponent(key)}`, catalogUrl).href
  : chainInfo.public?.url;
if (!rpcUrl) throw new Error('Public RPC is unavailable; set BLOCKVECTRA_API_KEY');
```

บันทึกเป็น `viem-client.mjs`, ติดตั้งด้วย `npm install viem@2` แล้วรัน `node viem-client.mjs`

```js
import { createPublicClient, defineChain, http } from 'viem';
import { chainInfo, rpcUrl } from './network.mjs';

export const chain = defineChain({
  id: chainInfo.chain_id,
  name: chainInfo.name,
  nativeCurrency: { name: 'HYPE', symbol: 'HYPE', decimals: 18 },
  rpcUrls: { default: { http: [rpcUrl] } },
});
export const client = createPublicClient({ chain, transport: http(rpcUrl) });
if (await client.getChainId() !== chain.id) throw new Error('RPC chain ID mismatch');
console.error(await client.getBlockNumber());
```

สำหรับ ethers ให้บันทึกเป็น `ethers-client.mjs`, ติดตั้งด้วย `npm install ethers@6` แล้วรัน `node ethers-client.mjs`

```js
import { JsonRpcProvider } from 'ethers';
import { chainInfo, rpcUrl } from './network.mjs';

const provider = new JsonRpcProvider(rpcUrl, chainInfo.chain_id, { batchMaxCount: 1 });
const network = await provider.getNetwork();
if (network.chainId !== BigInt(chainInfo.chain_id)) throw new Error('RPC chain ID mismatch');
console.log(await provider.getBlockNumber());
provider.destroy();
```

## ดีพลอยด้วย Foundry หรือ Hardhat

สารบบ `hyperevm_mainnet` ปัจจุบันมี `ws=false` และไม่มี `eth_sendRawTransaction` ใน `methods.allow` ใช้ BlockVectra สำหรับการอ่าน; การดีพลอยจำเป็นต้องใช้ RPC ที่รองรับการบรอดแคสต์ ตั้งค่า `DEPLOY_RPC_URL` เป็น URL HTTP ที่ผ่านการยืนยันตัวตนของผู้ให้บริการรายนั้น อย่าสันนิษฐานว่าผู้ให้บริการรายอื่นจะมีขีดจำกัดเมธอดหรือช่วงของ log เหมือนกับ BlockVectra โปรดตรวจสอบ chain ID ที่เลือกก่อนลงนาม

```bash
: "${DEPLOY_RPC_URL:?Set a broadcasting RPC URL}"
export RPC_URL="$DEPLOY_RPC_URL"
export CHAIN_ID="$(node --input-type=module -e "import { chainInfo } from './network.mjs'; console.log(chainInfo.chain_id)")"
```

ดำเนินการต่อด้วย [บทเรียนการดีพลอยด้วย Foundry หรือ Hardhat](https://docs.blockvectra.com/en/guides/deploy-contract/) ที่ใช้ร่วมกัน เติม EVM HYPE ให้กับผู้ดีพลอยและตรวจสอบข้อกำหนด dual-block ด้านล่างก่อนทำการดีพลอยขนาดใหญ่

## HYPE, บล็อกขนาดเล็ก และการดีพลอยขนาดใหญ่

[คู่มือเครือข่ายอย่างเป็นทางการของ HyperEVM](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm) ระบุว่า HYPE เป็น gas โดยมีทศนิยม 18 ตำแหน่ง (เข้าถึงเมื่อ: 2026-10-07) ตรวจสอบให้แน่ใจว่าผู้ดีพลอยถือครอง HYPE บน HyperEVM; ยอดคงเหลือบน HyperCore เพียงอย่างเดียวไม่ใช่ยอด gas ของ EVM โปรดทำตามคำแนะนำการโอนแบบ native ตามลิงก์เมื่อย้ายเงินทุน

[คู่มือ dual-block](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/dual-block-architecture) อธิบายถึงบล็อกขนาดเล็กที่รวดเร็วและบล็อกขนาดใหญ่ที่ช้ากว่าสำหรับธุรกรรมขนาดใหญ่ (เข้าถึงเมื่อ: 2026-10-07) ให้ประเมิน gas สำหรับการดีพลอยก่อน สำหรับการดีพลอยที่เกินงบประมาณบล็อกขนาดเล็ก ผู้ดีพลอยจะต้องเป็นผู้ใช้ HyperCore อยู่แล้ว และลงนามใน Core action `{"type":"evmUserModify","usingBigBlocks":true}`; การตั้งค่า gas limit ของธุรกรรมให้ใหญ่ขึ้นเพียงอย่างเดียวไม่ได้เป็นการเลือกบล็อกขนาดใหญ่ ให้กู้คืน `usingBigBlocks=false` ในภายหลังเพื่อกลับสู่บล็อกขนาดเล็ก

บนผู้ให้บริการที่รองรับ ให้ใช้ `eth_usingBigBlocks` เพื่อตรวจสอบโหมดแอดเดรส และใช้ `eth_bigBlockGasPrice` สำหรับ base fee ของบล็อกขนาดใหญ่ [เอกสารอ้างอิง JSON-RPC อย่างเป็นทางการ](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc) มีเอกสารอธิบายเมธอดเหล่านี้ (เข้าถึงเมื่อ: 2026-10-07) ตรวจสอบเมธอดของผู้ให้บริการที่เลือก; ใช้ `/v1/chains` สำหรับ BlockVectra การดีพลอยขั้นต่ำด้านบนกำหนดเป้าหมายไปยังสัญญาขนาดเล็กและไม่ได้เปลี่ยนโหมดบัญชี Core

## ข้อมูล HyperCore และ HyperEVM

EVM RPC ให้บริการสัญญา, ใบเสร็จ (receipt) และ log ส่วนข้อมูลการเทรดและการดำเนินการของ HyperCore จะใช้ Core API สัญญาอัจฉริยะสามารถอ่านสถานะ Core ผ่าน precompile และส่งการดำเนินการผ่าน CoreWriter; ใช้ [คู่มือการโต้ตอบอย่างเป็นทางการ](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/interacting-with-hypercore) เมื่อผสานรวมเส้นทางเหล่านี้ (เข้าถึงเมื่อ: 2026-10-07) ทั้งนี้ EVM log ไม่สามารถแทนที่การคิวรี order book หรือโพซิชันของ Core ได้

ธุรกรรมระบบ (system transaction) ของ HyperEVM (เช่น การโอนจาก HyperCore ไปยัง HyperEVM) จะไม่รวมอยู่ในการตอบกลับ `eth_getBlockByNumber` มาตรฐาน และให้บริการแยกต่างหากโดย RPC อย่างเป็นทางการผ่าน `eth_getSystemTxsByBlockNumber` และ `eth_getSystemTxsByBlockHash` (ดู [เอกสาร JSON-RPC อย่างเป็นทางการ](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc), เข้าถึงเมื่อ: 2026-10-07) ในปัจจุบัน ข้อมูลบล็อก, ธุรกรรม และ Data API ของ HyperEVM บน BlockVectra ยังไม่รวมธุรกรรมระบบ; ให้ใช้สองเมธอด RPC ทางการนี้โดยตรงเมื่อต้องการข้อมูลธุรกรรมระบบ

## การจัดการข้อผิดพลาดทางการ 10055

[คู่มือ HyperEVM อย่างเป็นทางการ](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm) กำหนดว่า `10055` เป็นข้อผิดพลาดบริเวณรอยต่อ Core/EVM รวมถึงความล้มเหลวเกี่ยวกับ nonce, เงินทุนไม่เพียงพอ, แฮชซ้ำ และค่าธรรมเนียมการแทนที่ต่ำเกินไป (underpriced-replacement) (เข้าถึงเมื่อ: 2026-10-07) ตรวจสอบข้อความจาก RPC ที่บรอดแคสต์ก่อนตัดสินใจว่าจะกู้คืนอย่างไร:

* **Nonce:** เปรียบเทียบ `eth_getTransactionCount` กับธุรกรรมที่รอดำเนินการของคุณ; จัดลำดับการส่งจากผู้ดีพลอยรายเดียวและกระทบยอด nonce ถัดไป
* **Funds:** ตรวจสอบยอดคงเหลือ EVM HYPE ของผู้ดีพลอยเทียบกับมูลค่ารวมกับค่า gas
* **Duplicate hash:** ค้นหาธุรกรรมและใบเสร็จที่มีอยู่ก่อนส่งธุรกรรมอื่น
* **Replacement fee:** ตรวจสอบ nonce และค่าธรรมเนียมที่มีอยู่ จากนั้นใช้นโยบายการแทนที่ของผู้บรอดแคสต์; การส่งไบต์เดิมซ้ำไม่ได้เป็นการเพิ่มค่าธรรมเนียม

`10055` เพียงอย่างเดียวไม่เพียงพอที่จะสุ่มลองใหม่โดยไม่ตรวจสอบ โปรดอ่านข้อผิดพลาดและคำแนะนำในการกู้คืนแยกต่างหากใน [ข้อมูลอ้างอิงข้อผิดพลาด BlockVectra](https://docs.blockvectra.com/en/errors/)

## ขีดจำกัดอัตราของ public RPC อย่างเป็นทางการและ 429

[เอกสารการจำกัดอัตราอย่างเป็นทางการ](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/rate-limits-and-user-limits) ของ Hyperliquid ระบุไว้สูงสุด 100 คำขอ EVM JSON-RPC ต่อนาทีต่อ IP สำหรับ `rpc.hyperliquid.xyz/evm` ส่วน [เอกสาร JSON-RPC](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc) ยังจำกัด `eth_getLogs` ไว้ที่ 50 บล็อกต่อหนึ่งคิวรีและไม่เกิน 4 topics เข้าถึงเมื่อ: 2026-10-07

เมื่อพบ HTTP 429 ให้หยุดส่งคำขอชั่วคราวและปฏิบัติตาม `Retry-After` ก่อนเป็นอันดับแรก (หน่วยเป็นวินาทีหรือวันที่ HTTP) หากไม่มี ให้ใช้ exponential backoff ร่วมกับ jitter และจำกัดจำนวนครั้งในการลองใหม่ โดยลองใหม่กับ chunk เดิมที่ยังไม่เสร็จสมบูรณ์ ลดการทำงานพร้อมกันและความถี่ในการโพลล์ และแบ่งการคิวรี log ออกเป็น chunk ให้อยู่ภายในขีดจำกัดของ endpoint การแบ่ง chunk เพียงอย่างเดียวไม่ได้ขจัดขีดจำกัดอัตราออกไป; ไคลเอนต์ที่ใช้ IP ร่วมกันจำเป็นต้องประสานอัตราคำขอของตน

สำหรับ endpoint ที่ใช้คีย์ของ BlockVectra ให้อ่าน `max_logs_block_range`, `methods.allow` และ `methods.deny` ของ `hyperevm_mainnet` จาก [GET /v1/chains](https://api.blockvectra.com/v1/chains) แทนที่จะนำช่วงบล็อกหรือขีดจำกัดคำขอต่อนาทีของ public RPC ทางการมาใช้ อัตราคำขอจะขึ้นอยู่กับ `cu_per_sec`, `burst_cu` ของคีย์ และขีดจำกัดการเรียกของแผนบริการฟรีแยกต่างหาก (ดูหัวข้อถัดไป) เมื่อพบ 429 ให้ตรวจสอบ `error.data.reason` และ `retryable`; `request_exceeds_burst` จำเป็นต้องส่งคำขอที่มีขนาดเล็กลงแทนที่จะลองใหม่แบบไม่เปลี่ยนแปลงค่าพร้อม backoff

## พารามิเตอร์และกฎการให้บริการของ BlockVectra

BlockVectra ให้บริการ HyperEVM mainnet ผ่าน endpoints แบบ JSON-RPC และ REST Data API:

1. **พารามิเตอร์ของเชนและขีดจำกัดของ log**:
   จาก `GET /v1/chains` สำหรับ `hyperevm_mainnet`:
   * **ตัวระบุเชน (Slug)**: `hyperevm_mainnet`, Chain ID `999`
   * **`max_logs_block_range`**: กำกับดูแลโดยฟิลด์ `max_logs_block_range` จาก `GET /v1/chains` คำขอ `eth_getLogs` รายการเดียวสามารถครอบคลุมบล็อกได้สูงสุดไม่เกินจำนวนนี้ (`toBlock − fromBlock + 1`) การส่งคำขอเกินกว่าช่วงนี้จะส่งกลับ HTTP 200 พร้อมรหัสข้อผิดพลาด JSON-RPC `-32602` (`eth_getLogs block range too large: max <N> blocks`) ซึ่งไม่คิดค่าบริการ
   * **`state_window_blocks`**: กำกับดูแลโดยฟิลด์ `state_window_blocks` จาก `GET /v1/chains` การเรียกที่อ่านสถานะ (เช่น `eth_call` และ `eth_getBalance`) จะอยู่ภายใต้กรอบเวลาการเก็บรักษาที่ระบุไว้ในฟิลด์นี้ (เมื่อเป็น `null` สถานะเต็มจะถูกเก็บรักษาไว้โดยไม่มีขีดจำกัดแบบ rolling window)
   * **นโยบายเมธอด**: กำกับดูแลโดย `methods.allow` และ `methods.deny` เมธอด EVM มาตรฐาน (`eth_blockNumber`, `eth_getLogs`, `eth_call`, `eth_getBalance`, `eth_getBlockByNumber`, `eth_getTransactionReceipt` ฯลฯ) ได้รับอนุญาต; ส่วนเมธอดตัวกรองและการสมัครสมาชิก (`eth_subscribe`, `eth_unsubscribe`, `eth_newFilter`, `eth_newBlockFilter`) จะถูกปฏิเสธ โดยส่งกลับ `-32601` (ไม่คิดค่าบริการ)
2. **ขีดจำกัดอัตราของระดับฟรีและการอัปเกรด**:
   จาก `GET /v1/plans`:
   * **`free.max_calls_per_sec`**: สูงสุด 25 คำขอต่อวินาที แชร์ร่วมกันระหว่างทุกคีย์ในบัญชี ทุกเชน และ Data API
   * **ขีดจำกัดเริ่มต้นของคีย์**: แต่ละ API key มี bucket ของ CU (อัตราเติม `cu_per_sec`, ความจุ `burst_cu` — ค่าเริ่มต้นคือ 400 CU/s และ burst 1,600 CU) เมธอดต่างๆ จะถูกวัดปริมาณตามค่าน้ำหนัก Compute Unit (CU)
   * **การอัปเกรดขีดจำกัด**: หลังจากการเติมเงิน ขีดจำกัดคำขอต่อวินาทีของทั้งบัญชีจะถูกยกเลิก; แต่ละคีย์ยังคงอยู่ภายใต้อัตราและขีดจำกัด burst ของ Compute Unit (CU) สำหรับอัตราและหน่วยการเรียกเก็บเงินปัจจุบัน โปรดดู [หน้าราคา](https://blockvectra.com/en/pricing/)

## การดึงข้อมูล log ย้อนหลัง: eth\_getLogs แบบแบ่งส่วนและตรรกะการลองใหม่

เมื่อทำการคิวรี log ย้อนหลัง ช่วงเวลาที่กว้างจะต้องถูกแบ่งออกเป็น chunk ต่อเนื่องกันซึ่งถูกจำกัดโดย `max_logs_block_range` ของเชนเป้าหมาย กลยุทธ์การลองใหม่ของไคลเอนต์ควรตรวจสอบฟิลด์ `retryable` ภายในการตอบกลับข้อผิดพลาด

### การประเมิน retryable ในการตอบกลับข้อผิดพลาด

บน BlockVectra อ็อบเจกต์ข้อผิดพลาด JSON-RPC จะมีเพย์โหลด `error.data` ซึ่งประกอบด้วย `reason`, `docs_url` และ `retryable` (บูลีน):

* **`retryable: true`**: สภาวะชั่วคราว รวมถึงบริการโอเวอร์โหลด (`overloaded`), ขีดจำกัดคำขอต่อวินาทีของแผนบริการฟรี (`free_plan_call_limit`), การซิงก์โหนด (`node_syncing`) หรืออัปสตรีมไม่พร้อมใช้งาน (`upstream_unavailable`) ไคลเอนต์ควรปฏิบัติตามส่วนหัว `Retry-After` เมื่อปรากฏ หรือใช้ exponential backoff ร่วมกับ jitter
* **`retryable: false`**: ข้อผิดพลาดที่ไม่ใช่สภาวะชั่วคราว เช่น ช่วงบล็อกเกินขีดจำกัด (`-32602` / `logs_range_too_large`), พารามิเตอร์ไม่ถูกต้อง (`invalid_params`), API key ขาดหายไป (`missing_api_key`) หรือคำขอเกินความจุ burst (`-32022` / `request_exceeds_burst`) การลองใหม่โดยไม่ปรับพารามิเตอร์จะไม่ประสบความสำเร็จ

ด้านล่างนี้คือการตอบกลับที่ได้รับเมื่อไม่ได้ระบุ API key:

```json
{
  "jsonrpc": "2.0",
  "id": null,
  "error": {
    "code": -32024,
    "message": "missing API key: send it in the request path (/v1/{chain}/<api_key>) or in the x-api-key header",
    "data": {
      "reason": "missing_api_key",
      "docs_url": "https://docs.blockvectra.com/en/errors/#missing_api_key",
      "retryable": false
    }
  }
}
```

## การใช้ Data API endpoints แทนการสแกน getLogs ปริมาณมาก

เมื่อแอปพลิเคชันติดตามประวัติธุรกรรมหรือการเคลื่อนไหวของโทเค็นสำหรับแอดเดรสที่ระบุ การสแกนผ่าน `eth_getLogs` จะต้องส่งคำขอแบบแบ่งส่วนตามลำดับซึ่งถูกจำกัดโดย `max_logs_block_range` และต้องแยกวิเคราะห์ raw Transfer event logs

BlockVectra Data API มี REST endpoints ที่ทำดัชนีไว้ล่วงหน้าสำหรับ `hyperevm_mainnet` ซึ่งรองรับช่วงสูงสุดถึง 100,000 บล็อกพร้อมการแบ่งหน้าด้วยเคอร์เซอร์:

1. **ธุรกรรมของแอดเดรส**: `GET /v1/data/hyperevm_mainnet/addresses/{address}/transactions`
   * พารามิเตอร์: `from_block` (จำเป็น), `to_block` (จำเป็น), `direction` (ไม่บังคับ: `from`, `to`, `any`, ค่าเริ่มต้น `any`), `clamp` (สตริงบูลีนไม่บังคับ, ค่าเริ่มต้น `false`; เมื่อตั้งค่าเป็น `true` ช่วงที่เกิน 100,000 บล็อกหรือสูงกว่า `as_of_block` จะถูกตัดทอนแทนที่จะส่งกลับ 409), `limit` (ไม่บังคับ, สูงสุด 500), `cursor` (โทเค็นการแบ่งหน้า)
2. **การโอนโทเค็นของแอดเดรส**: `GET /v1/data/hyperevm_mainnet/addresses/{address}/transfers`
   * พารามิเตอร์: `standard` (จำเป็น: `erc20` หรือ `erc721`; `erc1155` ไม่สามารถคิวรีตามแอดเดรสได้และจะส่งกลับ `422 no_coverage`), `token` (ตัวกรองสัญญาโทเค็นไม่บังคับ), `from_block` (จำเป็น), `to_block` (จำเป็น), `direction` (ไม่บังคับ: `in`, `out`, `any`), `clamp` (ไม่บังคับ), `limit`, `cursor`

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

การตอบกลับใช้ schema มาตรฐาน:

* `data`: อาร์เรย์ของระเบียน ธุรกรรมประกอบด้วย `hash`, `block_number`, `block_timestamp`, `from`, `to`, `value`, `tx_index`, `gas_limit`, `gas_used` และ `status` การโอนประกอบด้วย `token`, `standard`, `from`, `to`, `block_number`, `block_timestamp`, `tx_hash`, `tx_index` และ `log_index` (`amount` สำหรับ ERC-20, `token_id` สำหรับ ERC-721)
* `next_cursor`: โทเค็นการแบ่งหน้าแบบทึบแสง (opaque) ที่ส่งกลับมาเมื่อมีระเบียนถัดไป (ไม่มีในหน้าสุดท้าย ไม่ใช่ `null`)
* `meta`: ข้อมูลเมทาดาตาประกอบด้วย `chain`, `chain_slug`, `chain_external_id`, `as_of_block`, `safe_block`, `finalized_block`, `coverage` (`full` หรือ `partial`) และ `refreshed_at`

### ตัวอย่างโค้ด: การคิวรี Data API

**cURL**

```bash
export BLOCKVECTRA_API_KEY="rgw_your_api_key"

# 1. Query address transaction history (clamp=true prevents 409 errors)
curl -s "https://api.blockvectra.com/v1/data/hyperevm_mainnet/addresses/0x2222222222222222222222222222222222222222/transactions?from_block=0&to_block=50000&clamp=true" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"

# 2. Query address ERC-20 token transfers
curl -s "https://api.blockvectra.com/v1/data/hyperevm_mainnet/addresses/0x2222222222222222222222222222222222222222/transfers?standard=erc20&from_block=0&to_block=50000&clamp=true" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

```ts
const apiKey = process.env.BLOCKVECTRA_API_KEY!;
const targetAddress = "0x2222222222222222222222222222222222222222";

let cursor: string | undefined;

do {
  const url = new URL(
    `https://api.blockvectra.com/v1/data/hyperevm_mainnet/addresses/${targetAddress}/transfers`,
  );
  url.searchParams.set("standard", "erc20");
  url.searchParams.set("from_block", "0");
  url.searchParams.set("to_block", "50000");
  url.searchParams.set("clamp", "true");
  if (cursor) {
    url.searchParams.set("cursor", cursor);
  }

  const res = await fetch(url, {
    headers: { "x-api-key": apiKey },
  });

  if (!res.ok) {
    throw new Error(`Data API HTTP ${res.status}`);
  }

  const body = (await res.json()) as {
    data: unknown[];
    next_cursor?: string;
  };

  console.log(`Fetched ${body.data.length} transfers`);
  cursor = body.next_cursor; // Loop terminates when cursor is absent
} while (cursor);
```


## การติดตามแบบเรียลไทม์: การโพลล์บล็อกใหม่

สำหรับการรับส่งข้อมูลแบบ HTTP ให้ติดตามบล็อกด้วยการโพลล์และดึง event log ใน chunk ที่ต่อเนื่องกันภายใน `max_logs_block_range` เลือก WebSocket เฉพาะเมื่อ `/v1/chains` รายงาน `ws=true` และมีรายการ `subscriptions` ที่ต้องการ สำหรับการส่งข้อมูลไปยังตัวรับ HTTPS ให้ใช้ [webhook push](https://docs.blockvectra.com/en/guides/webhook-push/)

หากต้องการทดสอบสัญญา `Hello` ที่ดีพลอยแล้ว ให้ตั้งค่า `LOG_ADDRESS` เป็นแอดเดรสของสัญญา ส่ง `ping()` ผ่าน RPC ที่บรอดแคสต์ จากนั้นดึงข้อมูลบล็อกของใบเสร็จย้อนหลังด้วยสคริปต์การดึงข้อมูลย้อนหลังในหน้านี้ ดำเนินการต่อจาก chunk ล่าสุดที่เสร็จสมบูรณ์สำหรับเหตุการณ์ใหม่

```bash
cast send "$CONTRACT_ADDRESS" "ping()" --rpc-url "$DEPLOY_RPC_URL" \
  --private-key "$DEPLOYER_PRIVATE_KEY"
```

### โฟลว์การโพลล์

1. ส่งคำขอแบบ lightweight ไปยัง `eth_blockNumber` เป็นระยะเพื่อตรวจสอบ block head ล่าสุดของเชน
2. เปรียบเทียบหมายเลขบล็อกที่ส่งกลับมากับ `lastSeenBlock` ที่ประมวลผลก่อนหน้านี้
3. หาก `currentBlock > lastSeenBlock` ให้แบ่ง `[lastSeenBlock + 1, currentBlock]` ออกเป็น chunk ที่มีขนาดไม่เกิน `max_logs_block_range` บันทึกค่า `lastSeenBlock` แบบถาวรหลังจากประมวลผลแต่ละ chunk สำเร็จแล้วเท่านั้น; หากล้มเหลว ให้ลองใหม่กับ chunk ที่ยังไม่เสร็จสมบูรณ์ กำจัดข้อมูลซ้ำซ้อนด้วย `(blockHash, transactionHash, logIndex)` และเล่นซ้ำช่วงที่ทับซ้อนกันหลังจากเชื่อมต่อใหม่เพื่อจัดการกับการจัดระเบียบเชนใหม่ (reorg)
4. ฟังก์ชัน `watchBlockNumber` หรือ `watchBlocks` ของ viem ใช้วิธีการโพลล์ HTTP ภายใต้ transport แบบ HTTP โดยตรง ซึ่งช่วยให้สามารถปรับแต่งผ่านพารามิเตอร์ `pollingInterval` ได้ (เช่น 1,000 ms)

### โพลล์ event logs ใน chunk ที่จำกัดขอบเขต

บันทึกเป็น `poll-logs.mjs` ไว้ข้าง `network.mjs` และ `viem-client.mjs` ตั้งค่า `BLOCKVECTRA_API_KEY`, `LOG_ADDRESS` และ `FROM_BLOCK` จากนั้นรัน `node poll-logs.mjs` ตัวอย่างจำกัดนี้จะสุ่มตรวจตัวอย่าง head 12 ครั้ง ห่างกันครั้งละห้าวินาที และคิวรีทุกช่วงใหม่ใน chunk ตามลำดับ หากเกิดข้อผิดพลาดจะหยุดการทำงานของสคริปต์ก่อนที่จะขยับผ่าน chunk ที่ล้มเหลว

```js
import { isAddress } from 'viem';
import { client } from './viem-client.mjs';
import { chainInfo, allows } from './network.mjs';

const address = process.env.LOG_ADDRESS;
const start = process.env.FROM_BLOCK;
if (!address || !isAddress(address)) throw new Error('Set LOG_ADDRESS');
if (!/^(0x[0-9a-f]+|[0-9]+)$/i.test(start ?? '')) throw new Error('Set FROM_BLOCK');
if (!allows('eth_getLogs')) throw new Error('eth_getLogs requires an available keyed endpoint');
if (!Number.isSafeInteger(chainInfo.max_logs_block_range) || chainInfo.max_logs_block_range <= 0) {
  throw new Error('Invalid max_logs_block_range');
}
const max = BigInt(chainInfo.max_logs_block_range);
let from = BigInt(start);
for (let poll = 0; poll < 12; poll++) {
  const head = await client.getBlockNumber();
  while (from <= head) {
    const to = from + max - 1n < head ? from + max - 1n : head;
    const logs = await client.getLogs({ address, fromBlock: from, toBlock: to });
    console.log(JSON.stringify({ from: from.toString(), to: to.toString(), logs },
      (_, value) => typeof value === 'bigint' ? value.toString() : value));
    from = to + 1n;
  }
  if (poll < 11) await new Promise(resolve => setTimeout(resolve, 5_000));
}
```

ผลลัพธ์แต่ละรายการจะบันทึก chunk ที่เสร็จสมบูรณ์ หากต้องการดำเนินการต่อ ให้ตั้งค่า `FROM_BLOCK` เป็น `to + 1` ของ chunk นั้น; consumer ที่ทนทานจะต้องบันทึกเหตุการณ์และเคอร์เซอร์ไว้ด้วยกัน, กำจัดข้อมูลซ้ำ และกระทบยอดการจัดระเบียบเชนใหม่ตามที่อธิบายไว้ข้างต้น สำหรับ 429 หรือความล้มเหลวอื่นๆ ที่สามารถลองใหม่ได้ ให้ใช้คำแนะนำ bounded-backoff กับ chunk เดิมที่ยังไม่เสร็จสมบูรณ์

## คู่มือที่เกี่ยวข้อง

* ค้นหา public RPC URL, เมธอดที่รองรับ และขีดจำกัดปัจจุบันได้ใน [หน้าเชน HyperEVM](https://blockvectra.com/en/chains/hyperevm_mainnet/)
* สำหรับกฎทั้งหมดเกี่ยวกับช่วงของ `eth_getLogs` และอัลกอริทึมการแบ่ง chunk โปรดดู [ขีดจำกัดช่วงบล็อกของ eth\_getLogs และการคิวรีแบบแบ่งส่วน](https://docs.blockvectra.com/en/guides/getlogs-block-range/)
* สำหรับการเปรียบเทียบ `eth_getLogs` กับการโอนของ Data API, การทำความเข้าใจขอบเขต `as_of_block` และมาร์กเกอร์ `safe_block` / `finalized_block` โปรดดู [eth\_getLogs และการโอนที่ทำดัชนี: ความครอบคลุมและความเป็นที่สิ้นสุด](https://docs.blockvectra.com/en/guides/logs-vs-transfers/)
* สำหรับรายละเอียดเกี่ยวกับการวัดปริมาณ CU, ข้อผิดพลาดที่ไม่คิดค่าบริการ และการลองใหม่ โปรดดู [สิ่งที่ไม่คิดค่าบริการ: รหัสข้อผิดพลาดและกฎการเรียกเก็บเงิน](https://docs.blockvectra.com/en/guides/billing-rules/)

## ขั้นตอนถัดไป

* [เลือกดูสารบบชุดข้อมูล](https://blockvectra.com/en/data/) เพื่อดูทุกชุดข้อมูลที่ BlockVectra ทำดัชนี
* [ดูแผนบริการฟรีและราคา](https://blockvectra.com/en/pricing/#free) เพื่อตรวจสอบสิ่งที่บัญชีของคุณได้รับ
* [เข้าสู่ระบบคอนโซล](https://console.blockvectra.com/login/?next=%2Fkeys%2F) เพื่อสร้าง API key
