# 状态和存储 *阅读其它语言版本: [English](../state.md), [Korean](state_KR.md), [日本語](state_JP.md).* ## Grin 的状态 ### 结构 一条 Grin 链的完整状态包含以下所有数据: 1. 完整的未花费输出(UTXO)集。 1. 每个输出的范围证明。 1. 所有交易内核。 1. 针对上述每一项的 MMR(除了输出 MMR 以外包括其它所有输出的哈希,不仅仅是未花费的哈希)。 此外,链中的所有头都必须使用有效的工作证明来锚定上述状态(该状态对应于工作量最大的链)。 我们注意到,一旦验证了每个范围证明并计算了所有内核承诺的总和,就不再严格要求范围证明和内核对节点起作用。 ### 验证方式 对于一个完整状态的 Grin,我们可以验证以下内容: 1. 内核签名针对其承诺(公钥)有效。 这证明内核是有效的。 1. 所有内核承诺的总和等于所有 UTXO 承诺的总和减去总供应量。这证明内核和输出承诺均有效,并且没有创建任何预期之外的代币。 1. 所有 UTXO,范围证明和内核哈希都存在于它们各自的 MMR 中,并且那些 MMR 哈希到有效根。 1. 在给定的时间点上一个已知的工作量最多的块头包括 3 个 MMR 的根。这验证了 MMR,并证明整个状态是由工作量最多的链产生的。 ### MMR 与修剪 用于为每个 MMR 中的叶节点生成的哈希数据(除其位置以外,还包括以下内容: * 输出 MMR 哈希的特征字段和自创世以来所有输出的承诺。 * 范围证明 MMR,对整个范围证明数据进行哈希处理。 * 内核 MMR 哈希了内核的所有字段:功能(feature),费用(fee),锁高度(lock height),超额承诺(excess commitment)和超额签名(excess signature)。 请注意,所有输出,范围证明和内核均以它们在每个块中出现的顺序添加到其各自的 MMR 中(还有一点需要注意,需要对块数据进行排序)。 随着输出被花费掉,其承诺和范围证明数据都可以被删除掉。此外,相应的输出和范围验证 MMR 可以被修剪。 ## 状态存储 Grin 中的输出,范围证明和内核的数据存储很简单:一个 append-only 的文件,通过内存映射来访问数据。 随着输出被花费,删除日志将维护可以删除的职位。这些位置与 MMR 节点位置完全匹配,因为它们均以相同顺序插入。 当删除日志变大时,可以偶尔通过重写相应文件来压缩这些文件,而无需删除它们(同样也是 append-only),并且可以清空删除日志。 对于 MMR,我们需要增加一些复杂性。