> ## 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.

# 狀態模型

> 什麼構成鏈上狀態、如何編址與版本化，以及三種狀態表示裡哪一種才是權威。

交易引擎裡有三樣不同的東西都叫「狀態」，混為一談，系統給出的答案就會變成看你問誰而定。本頁把三者區分開，並說明哪一種才是權威。

<h2 id="three-representations">
  三種表示
</h2>

<div className="dg" data-dg="state-model">
  <div className="dg-c" style={{aspectRatio:"720 / 288"}}>
    <svg className="dg-w" viewBox="0 0 720 288" aria-hidden="true">
      <path className="dg-wire dg--blue" d="M 215.00 90.00 L 243.60 90.00" />

      <path className="dg-head dg--blue" d="M 250.00 90.00 L 243.60 94.40 L 243.60 85.60 Z" />

      <path className="dg-wire dg--green" d="M 470.00 90.00 L 498.60 90.00" />

      <path className="dg-head dg--green" d="M 505.00 90.00 L 498.60 94.40 L 498.60 85.60 Z" />

      <path className="dg-wire dg--green dg-dash" d="M 615.00 145.00 L 615.00 176.00 L 105.00 176.00 L 105.00 151.40" />

      <path className="dg-head dg--green" d="M 105.00 145.00 L 109.40 151.40 L 100.60 151.40 Z" />
    </svg>

    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"13.8889%",width:"29.1667%",height:"34.7222%"}}><span className="dg-t">引擎狀態</span><span className="dg-s">市場 · 帳戶 · 部位 · 訂單簿 · 清算所</span><span className="dg-n">跨區塊存續 · 一份重建</span></div>
    <div className="dg-b dg--yellow dg-dashed" style={{left:"35.4167%",top:"13.8889%",width:"29.1667%",height:"34.7222%"}}><span className="dg-t">區塊工作集</span><span className="dg-s">標記價格 · 被觸及帳戶 · 成交 · 暫存輸出</span><span className="dg-n">只存續一個區塊 · 一本流水帳</span></div>
    <div className="dg-b dg--green" style={{left:"70.8333%",top:"13.8889%",width:"29.1667%",height:"34.7222%"}}><span className="dg-t">鏈上狀態</span><span className="dg-s">帶版本的鍵值，由 Merkle 認證</span><span className="dg-n">權威</span></div>
    <div className="dg-b dg--orange dg-left" style={{left:"0.0000%",top:"72.9167%",width:"100.0000%",height:"23.6111%"}}><span className="dg-t">這防住的是哪種失效</span><span className="dg-s">引擎的記憶體視圖一旦與已提交內容漂移，還是會照常給出答案，而每一個答案都是錯的，並且要到結算時才暴露出來。</span></div>
    <div className="dg-lbl" style={{left:"50.0000%",top:"61.1111%",width:"45.8333%",whiteSpace:"normal"}}>引擎狀態必須能從已提交的紀錄推導出來，反過來絕對不行</div>
  </div>
</div>

**引擎狀態**是[內核](/zh-Hant/protocol/architecture/kernel)在區塊之間持有的東西：市場中繼資料、帳戶、部位、訂單簿、商品狀態、清算所狀態。這是工作表示——照撮合與清算實際的存取模式佈局，不照儲存佈局。

**區塊工作集**只在一個區塊執行期間存在：區塊開始時固定的標記價格、哪些帳戶和訂單被觸及、產生了哪些成交、正在組裝的輸出。這是本區塊內發生了什麼的一份流水帳。

**鏈上狀態**是已提交的結果：帶版本的鍵值條目，由 Merkle 結構做認證，持久且可重放。節點同步的是這一份，證明針對的是這一份，[索引器](/zh-Hant/protocol/architecture/indexer)讀的也是這一份。

**鏈上狀態是權威。** 區塊工作集是用來建構確定性輸出的流水帳，不是事實來源。引擎狀態則是鏈上狀態為執行而最佳化的一份重建，必須能從已提交的紀錄推導出來；反過來絕對不行。

把這個關係搞反，會導致一種特定而且認得出來的失效：引擎的記憶體視圖一旦與已提交內容漂移，還是會照常給出答案，而每一個答案都是錯的，並且要到結算時才暴露出來。

<h2 id="keys">
  鍵
</h2>

鏈上狀態按鍵編址。交易狀態歸入具名、而且顯式版本化的命名空間，例如手續費配置、永續合約索引、槓桿級距表、管理角色清單。

版本後綴不是裝飾。一份配置的結構若有變化，就遷到該鍵的新版本，舊鍵保留下來，遷移期間仍讀得到以舊結構寫入的狀態。讀取方若把某個版本寫死、又從不重新檢查，遷移之後就會悄無聲息地讀到過期配置；讀取方若每次解析當前鍵，就不會。

<Note>
  這就是為什麼配置應當從鏈上讀，不要在用戶端程式碼裡寫死。[費率級距服務](/zh-Hant/protocol/architecture/programs)每個週期都讀鏈上即時的手續費配置，正是出於這個原因——級距表一旦寫死在用戶端裡，終究會和網路實際套用的那一張對不上。
</Note>

<h2 id="versions">
  版本
</h2>

每一個已提交的區塊都會推進一個版本。狀態值按寫入時所處的版本儲存，這意味著這個儲存區不只是「當前狀態」，而是「任意版本上的狀態」。

這一性質一口氣讓好幾件事成為可能：

* **證明**可以針對某個特定版本產生，而不只是針對當下。
* **重放**可以從任意版本開始，而不只是從創世開始。
* **讀取**可以是歷史性的——索引器重建某個部位的歷史，是在請求舊版本，不是在掃描日誌。
* **修剪**變成一項政策決定——往回保留多久——不是結構性限制。

<h2 id="what-ends-up-committed">
  最終被提交的是什麼
</h2>

內核執行每個區塊產生兩樣東西。每筆交易攜帶自己的寫入與事件，並與該交易綁定。不屬於任何單筆使用者交易的影響——資金費收付、保險基金變動、區塊級計數器——進入一個專門的系統通道。

兩者合起來，沒有任何東西會丟失：內核內部的任何一種執行影響，不是落在某筆交易的輸出裡，就是落在系統通道裡。正因為這份完整性，已提交的紀錄才能當作完整的事實，而不是一份摘要；也正因為如此，撮合就算是成批運行，事件仍然追得回導致它的那筆交易。

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

<CardGroup cols={2}>
  <Card title="儲存與證明" href="/zh-Hant/protocol/architecture/state/storage">
    已提交狀態如何在實體上儲存、認證與修剪。
  </Card>

  <Card title="狀態同步" href="/zh-Hant/protocol/architecture/state/sync">
    節點從沒見過這條鏈，要怎麼追上。
  </Card>

  <Card title="IntentionKernel" href="/zh-Hant/protocol/architecture/kernel">
    引擎狀態與區塊工作集待在哪裡。
  </Card>

  <Card title="索引器" href="/zh-Hant/protocol/architecture/indexer">
    把已提交狀態變成可查詢的東西。
  </Card>
</CardGroup>
