> ## Documentation Index
> Fetch the complete documentation index at: https://docs.intention.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# 索引器

> 已提交的區塊如何變成可查詢的資料：從全節點到 REST 與 WebSocket 介面的串流路徑。

鏈提交的是區塊。而應用問的是**這個帳戶上週成交了什麼**、**訂單簿現在長什麼樣**——這類問題，以區塊為形態的紀錄很難回答。索引器就是把前者轉換成後者的那一層。

在大多數鏈上，索引器是基礎設施中的關鍵一環：鏈發出的是不透明的事件，由第三方從中重建含義，於是你的應用相信什麼，就看它信任哪個索引器。在這裡，重建這一步並不存在。[核心](/zh-Hant/protocol/architecture/kernel)發出的是帶類型、帶歸屬的輸出——每一次狀態變更都已綁定到引起它的那筆交易——因此索引器做的是重塑資料，而不是推斷資料。

這改變了索引器的定位：它是**查詢服務層**，不是事實來源。索引器報出的任何東西都可以對著鏈核驗，一旦分歧，那就是索引器的缺陷，不是懸而未決的問題。

<h2 id="the-path">
  路徑
</h2>

<div className="dg" data-dg="indexer-path">
  <div className="dg-c" style={{aspectRatio:"720 / 318"}}>
    <svg className="dg-w" viewBox="0 0 720 318" aria-hidden="true">
      <path className="dg-wire dg--blue dg-soft" d="M 123.00 102.00 L 155.98 75.97" />

      <path className="dg-head dg--blue" d="M 161.00 72.00 L 158.70 79.42 L 153.25 72.51 Z" />

      <path className="dg-wire dg--blue dg-soft" d="M 123.00 102.00 L 156.23 131.73" />

      <path className="dg-head dg--blue" d="M 161.00 136.00 L 153.30 135.01 L 159.16 128.45 Z" />

      <path className="dg-wire dg--sky dg-soft" d="M 349.00 72.00 L 381.98 98.03" />

      <path className="dg-head dg--sky" d="M 387.00 102.00 L 379.25 101.49 L 384.70 94.58 Z" />

      <path className="dg-wire dg--sky dg-soft" d="M 349.00 136.00 L 382.23 106.27" />

      <path className="dg-head dg--sky" d="M 387.00 102.00 L 385.16 109.55 L 379.30 102.99 Z" />

      <path className="dg-wire dg--green" d="M 536.00 102.00 L 551.60 102.00" />

      <path className="dg-head dg--green" d="M 558.00 102.00 L 551.60 106.40 L 551.60 97.60 Z" />
    </svg>

    <div className="dg-band" style={{left:"20.8333%",top:"8.1761%",width:"29.1667%",height:"47.7987%"}}><span className="dg-cap">按資料新舊分開</span></div>
    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"19.4969%",width:"16.3889%",height:"25.1572%"}}><span className="dg-t">全節點</span><span className="dg-s">已提交區塊，以帶類型記錄串流輸出</span></div>
    <div className="dg-b dg--sky" style={{left:"23.0556%",top:"14.4654%",width:"24.7222%",height:"16.3522%"}}><span className="dg-t">快取</span><span className="dg-s">近期 — 從記憶體提供</span></div>
    <div className="dg-b dg--sky" style={{left:"23.0556%",top:"34.5912%",width:"24.7222%",height:"16.3522%"}}><span className="dg-t">檔案儲存</span><span className="dg-s">歷史 — 持久化</span></div>
    <div className="dg-b dg--sky" style={{left:"54.4444%",top:"19.4969%",width:"19.4444%",height:"25.1572%"}}><span className="dg-t">資料服務</span><span className="dg-s">把兩者呈現為一條流</span></div>
    <div className="dg-b dg--green" style={{left:"78.0556%",top:"19.4969%",width:"21.9444%",height:"25.1572%"}}><span className="dg-t">閘道 → REST · WebSocket</span><span className="dg-s">存取控制、配額、路由</span></div>
    <div className="dg-b dg-dashed dg-left" style={{left:"0.0000%",top:"67.2956%",width:"48.8889%",height:"27.6730%"}}><span className="dg-t">為什麼要拆開</span><span className="dg-s">跟隨鏈頭對延遲敏感、資料量小；歷史查詢對吞吐量敏感、資料量大。共用一條路徑，一次回填就會把即時路徑拖住。</span></div>
    <div className="dg-b dg-dashed dg-left" style={{left:"51.1111%",top:"67.2956%",width:"48.8889%",height:"27.6730%"}}><span className="dg-t">查詢服務層，不是事實來源</span><span className="dg-s">內核發出的是帶類型、帶歸屬的輸出，所以索引器做的是重塑，不是推斷。與鏈分歧，就是索引器的缺陷。</span></div>
  </div>
</div>

**全節點**是起點。交易紀錄從全節點流出時就是帶類型的資料，不是還要再作解釋的原始交易。

**快取與檔案儲存**按資料新舊把這條流分開。近期資料從記憶體提供，因為多數消費者要的就是這些，而且延遲很重要。歷史資料寫入持久化的檔案儲存，因為把一切都留在記憶體裡不是一種策略。有人來取舊資料，有人跟著鏈頭走，兩邊由不同的地方服務，而兩邊都感覺不到。

**資料服務**把兩者呈現為一條流。用戶端可以請求從任意位置開始的區間；這個區間由快取提供、由檔案提供，還是兩者共同提供，不是用戶端要操心的事。

**閘道**處理介於服務與公網之間的那些事：存取控制、配額和路由。

**REST 與 WebSocket 介面**才是應用實際使用的東西——行情資料、訂單與成交歷史、部位、帳戶狀態、資金費支付，以及即時訂閱。端點層級的細節參見 [API 參考](https://testnet-openapi.intention.xyz/)。

<h2 id="why-the-split-exists">
  為什麼要拆開
</h2>

同一個服務既要跟隨鏈頭、又要回答歷史查詢，兩件事都做不好。跟隨鏈頭對延遲敏感、資料量小；歷史查詢對吞吐量敏感、資料量大，一次大規模回填就會把即時路徑拖住。

把兩者分開，替新來的消費者回填幾個月前的資料，就不會拖慢正在跟隨鏈頭的造市商；兩者也可以獨立擴充——而且確實需要，因為兩邊的負載特徵毫無共同之處。

<h2 id="what-it-is-safe-to-rely-on">
  什麼可以放心依賴
</h2>

**可以依賴。** 索引器提供的、由已提交區塊派生出來的一切：成交、訂單、部位、資金費支付、轉帳、行情資料。這些都是鏈上輸出的重塑。

**不是一回事。** 任何尚未提交的東西。訂單進了[記憶池](/zh-Hant/protocol/architecture/mempool)（mempool），也還沒有排序，索引器對它無話可說。在索引器裡查不到，意思是「還沒有提交」，不是「被拒絕了」。

**可核驗。** 某個答案若夠重要——一次結算爭議、一次稽核、一次帳務對帳——可以直接對著鏈核驗，不必從索引器裡取。自己跑一個全節點是最徹底的做法；參與者若承擔不起出錯的代價，就該這麼做。參見[運行節點](/zh-Hant/developers/run-a-node)。

<Note>
  兩個消費者讀取同一段已提交區間，應該得到同樣的答案。若不一樣，差異出在服務鏈路上，是應當上報的缺陷，不是「透過索引器讀鏈」這件事的固有屬性。
</Note>

<h2 id="where-to-go-next">
  後續閱讀
</h2>

<CardGroup cols={2}>
  <Card title="狀態模型" href="/zh-Hant/protocol/architecture/state/model">
    索引器讀的是什麼，以及哪一種表示是權威的。
  </Card>

  <Card title="開發者" href="/zh-Hant/developers/overview">
    REST 與 WebSocket 介面、SDK 與工具。
  </Card>

  <Card title="運行節點" href="/zh-Hant/developers/run-a-node">
    自己對著鏈核驗，以及這個集合為什麼是封閉的。
  </Card>

  <Card title="程式服務" href="/zh-Hant/protocol/architecture/programs">
    誰在消費這條流來計算派生的帳戶狀態。
  </Card>
</CardGroup>
