> ## 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/protocol/architecture/kernel)在区块之间拿着的东西：市场元数据、账户、仓位、订单簿、合约状态、清算所状态。它是工作表示——按撮合与清算实际的访问模式来布局，不按存储来布局。

**区块工作集**只在一个区块执行期间存在：区块开始时固定的标记价格、哪些账户和订单被动过、产生了哪些成交、正在组装的输出。它是这个区块里发生了什么的一份流水账。

**链上状态**是已提交的结果：带版本的键值条目，由 Merkle 结构认证，持久、可重放。节点同步的是它，证明针对的是它，[索引器](/zh/protocol/architecture/indexer)读的也是它。

**链上状态是权威。** 区块工作集是用来构建确定性输出的流水账，不是事实来源。引擎状态则是链上状态为执行而优化出来的一份重建：它必须能从已提交的记录里推导出来，反过来绝不可以。

把这个关系搞反，会引出一种特定而且认得出来的失效：引擎的内存视图已经和已提交内容漂开了，它却照样一个接一个地给答案，而每一个答案都是错的——错在哪里，要等到结算才暴露。

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

链上状态按键编址。交易状态归进具名、且显式带版本的命名空间——手续费配置、永续合约索引、杠杆档位表、管理角色列表，都是例子。

版本后缀不是装饰。一份配置的结构一变，它就迁到该键的新版本，旧键留着，好让迁移期间仍能读到按旧模式写入的状态。读取方如果把某个版本写死、而且从不重新检查，迁移之后就会悄无声息地读到过期配置；每次去解析当前键的读取方则不会。

<Note>
  这就是为什么配置应当从链上读，不要写死在客户端代码里。[费率档位服务](/zh/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/protocol/architecture/state/storage">
    已提交状态如何在物理上存储、认证与裁剪。
  </Card>

  <Card title="状态同步" href="/zh/protocol/architecture/state/sync">
    一个从未见过这条链的节点如何追上它。
  </Card>

  <Card title="IntentionKernel" href="/zh/protocol/architecture/kernel">
    引擎状态与区块工作集所在之处。
  </Card>

  <Card title="索引器" href="/zh/protocol/architecture/indexer">
    把已提交状态变成可查询的东西。
  </Card>
</CardGroup>
