状态膨胀是个特别容易被忽视的问题。一条链跑两三年,全节点数据悄悄从几十GB涨到几百GB,你再不去管它,过一两年就是TB级。对中小型验证者、独立开发者和普通用户来说,这是实打实的参与门槛——光同步一次全量数据就要花掉一整天甚至更久,硬件成本摆在那,链的去中心化程度会慢慢被稀释。
Polkadot生态里讨论度越来越高的Bulletin Chain,核心思路就很直接:不是所有链上数据都需要永久保存。它引入了一个叫"临时存储"的设计,让数据在有效期内得到链级保证,过了有效期就从活跃状态中释放掉,从根上缓解状态膨胀。这篇文章我会把它的设计动机、运作机制、和相关方案的对比一次性讲透,也会聊聊我判断哪些场景真正适用、哪些场景别硬蹭。
1. 状态膨胀的根源:从"全节点=全历史"这个惯性说起
1.1 状态(State)和历史(History)是两码事
很多人容易混淆一个概念:区块链节点到底在存什么?其实可以拆成两层。
第一层是历史(History),也就是从创世区块到最新区块的完整区块数据,包括每一笔交易、每一个签名、每一段原始输入。这一层更像账本档案,主要用来追溯和审计。
第二层是状态(State),它是当前区块高度的世界快照。比如某地址当前余额是多少、某个合约当前的存储变量是什么、某个账户的nonce是多少。这一层不需要重放历史就能直接回答"现在谁拥有什么"。
问题就出在状态这一层。历史数据是线性增长的,每个区块固定那么多字节,增长速度是可预估的。但状态不一样——很多应用的数据结构是累积的。用户地址越来越多,合约存储的账目越积越深,历史上一笔早已无人问津的转账记录对应的账户状态,照样永远挂在状态树里。
因为节点回答查询请求时,需要从状态树里读取数据。如果数据不在状态里,就不能算"账本当前认可的事实"。所以几乎所有公链的节点都被迫保留完整的当前状态,哪怕某一个账户从2018年之后再没动过。
提示:状态膨胀和区块膨胀是两种不同的问题。区块膨胀可以靠轻节点和分布式存储缓解,状态膨胀则直接影响验证节点和出块节点的性能,因为它内嵌在共识和执行流程里。
1.2 状态膨胀的连锁反应:从单点成本到全生态门槛
状态膨胀带来的第一个直接后果,是存储成本上升。但这个上升不是线性的,而是叠加的——状态越大,执行交易时访问状态树的计算开销就越大,数据库的读写IO也随之增加,内存缓存命中率下降,最终出块时间都被拖慢。
第二个后果更隐蔽:同步时间变长。新节点从创世区块开始同步,需要不断下载历史区块、重放交易、重建状态树。状态越大的链,重建时间越长。很多链后来引入了快照同步,但快照同步意味着你要信任对方提供的状态,这里面又碰到了信任假设的问题。
第三个后果是验证者中心化倾向。当存储需求从几百GB涨到几个TB时,运行节点的硬件门槛变高,普通家用机器就带不动了。能够负担得起高性能服务器的机构自然更有优势。小节点要么退出去,要么依赖云服务商,节点分布集中化是必然趋势。
1.3 状态膨胀最后会出现什么局面
理论上,如果没有机制干预,状态会无限增长。实际中,每条链都在有意无意地做"隐式控制"——比如限制每个区块的Gas上限来限制状态增长速率,或者对存储操作收取更高费用。但这些只是减速,不是刹车。
真正要解决状态膨胀,只有两条路:要么让状态变小,要么让部分数据"不被当作状态"。第一条路大家都在做,比如压缩数据格式、清理无用账户。第二条路,也就是Bulletin Chain正在探索的方向,之前反而很少有人把它做成一个通用机制。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Bulletin Chain的定位:它要解决的是"状态"问题,不是"历史"问题
2.1 从公告板说起:有些信息天然就该"过期"
"Bulletin Chain"这个名字,直译就是"公告链"。公告板这个东西大家都见过——学校走廊、小区门口、公司茶水间,贴满了各种通知。每一张公告在它贴出来的那一刻是有时效价值的:明天要停电、周末有活动、谁丢了钥匙。但三个月后还挂在墙上,不仅没人看,还占地方,最后被新公告覆盖掉。
区块链当前的默认范式和公告板相反:所有数据一旦上链,就默认永久存在于状态中。它不区分这笔数据是一个DeFi协议的清算价,还是某次抽奖活动的随机数种子。两者都被寄望于"永远可查"。但实际上,很多数据的有效价值窗口只有几天甚至几小时。
Bulletin Chain的核心思路,就是为"时效性数据"提供一种新的存储语义。数据可以上链,可以享受链级的共识确认和安全保证,但它只会在活状态里保留一段可配置的期限。期限一到,就自动从活跃状态中释放。历史证明依然存在,但不再作为全节点必须维护的当前状态存在。
2.2 定义"临时数据":凭什么说某些数据不需要永久保存
为明确边界,可以给"临时数据"下几个定义特征:
- 价值与时间强相关:数据的价值集中在发布后的短时间内,过后不再需要被频繁读取或验证。例如投票结果、价格信息、事件通知。
- 可重建性:如果数据丢失,可以从链上历史或其他数据集重新推导出来。它不是唯一的事实来源。
- 低查询频率:数据在活跃期内会有人读,但过了活跃期几乎没有链上应用或用户再去查询它。
- 非资产类:不涉及所有权变更、余额记录、资产归属,这类数据一旦丢失会造成确权问题,不适合临时存储。
符合这些特征的数据,放到永久状态里维护是资源浪费。用临时存储,既保留了上链的可验证性和透明度,又把状态维护成本控制在可管理的范围内。
2.3 Bulletin Chain在Polkadot生态中的位置
Polkadot的中继链设计本身就有"不存一切"的哲学。中继链不执行也不存储平行链内部交易的完整状态,它只保存每个平行链的头部和状态根。平行链的交易细节、业务逻辑、执行环境都留在各自的平行链上,中继链只负责最终性和跨链消息路由。
Bulletin Chain如果作为平行链接入Polkadot生态,它可以扮演一个"轻量级公告层"的角色。其他平行链或者外部应用,可以把需要临时公告的数据发送到Bulletin Chain,由它负责在有效期内提供数据可用性和可验证性。有效期结束,数据进入归档层,活跃状态自行收缩。
这个位置很有意思,因为它和Polkadot的跨链消息传递(XCM)天然契合。跨链消息通知、预言机价格更新、事件订阅记录这类数据,确实不需要永久留存在状态里。Bulletin Chain可以成为这些数据的天然承接方。
3. 临时存储的机制拆解:见证、证明、生命周期
3.1 数据上链但不入状态:这到底怎么实现
传统区块链的数据存储流程很简单:交易被打包进区块,节点执行交易后把结果写入本地状态数据库,状态根随之更新。所有全节点都保存这份状态。
Bulletin Chain的关键区别在于:交易执行后,数据不会写入全节点必存的状态数据库。它进入的是一个特殊的临时存储区。这个临时存储区的数据,虽然也被当前区块的验证者见证和签名,但它不在状态根中占据永久位置。
有人会问:既然不写入状态数据库,那怎么保证数据在这段时间内可用?答案是验证者见证。数据在被提交的那一刻,当前区块的验证者集合会对其进行签名见证。这个见证本身就是一种公证——证明"在某个区块高度上,这些数据被提交了,内容是这样的"。验证者的签名聚合后形成一个可验证的证据,在数据有效期内,任何人都可以通过这个证据来验证数据的存在性和完整性。
3.2 生命周期管理:从诞生到归档的完整流转
临时存储的数据需要一套明确的生命周期状态机来管理。我基于常见实践,把这个生命周期梳理成四个阶段。
第一阶段是提交。数据通过普通交易提交到Bulletin Chain,提交者可以附带一个预期的存活时间(TTL)。这个TTL不是随便填的,协议层会规定一个最小值和最大值区间,防止有人恶意提交超长存活期的数据,变相在临时存储里塞了永久数据。
第二阶段是活跃。在这个阶段,数据可以被查询、被引用、被其他应用读取。验证者节点会维护这份数据的索引,供外界访问。这是数据价值的黄金期。
第三阶段是过期。TTL到达后,数据从活跃状态中标记为过期。它不再被常规查询接口直接返回,也不再占用节点的活跃存储空间。
第四阶段是归档。过期的数据进入归档流程。归档数据不会从链上彻底消失——它的原始内容和验证者签名证明可以保存在分布式存储网络或专门的历史节点里。需要审计时可以从归档层恢复,但它不再是全节点必须同步和存储的部分。
3.3 查询路径和证明机制:数据过期后怎么还被信任
这里有一个很有意思的博弈问题:数据从活跃状态释放后,如果还有人想验证它曾经存在过,怎么办?
Bulletin Chain的答案是区块头+签名聚合证明。每个包含临时数据的区块,其区块头和验证者签名集合本身就是完整的历史档案。任何人拿到了这个区块头,就可以验证里面包含的数据是否被当时出块的验证者集合承认过。这不需要其他全节点保留完整状态副本,只需要信任当时验证者集合的诚实多数。
所以,"临时存储"并不意味着"数据不安全"。它的安全性来自共识层的签名见证,而不是来自每个节点都存一份副本。从安全模型上说,这其实更接近轻客户端的信任模型——你不需要验证全部历史,只需要验证那一条签名链路。
3.4 和Substrate/FRAME的关系:从技术栈看实现路径
从技术实现角度看,Polkadot生态的Substrate框架天然适合构建Bulletin Chain。Substrate的Runtime模块化设计可以让开发者自行定义存储项,但Substrate默认的存储是"写入即永久"的StorageMap和StorageValue。
实现临时存储,需要在FRAME层做一次封装:定义一个新的存储类型,比如TransientStorage,它内部带有一个过期时间戳字段。链在每次处理区块前,先清理所有已过期的临时存储项,再执行本区块的交易。这个清理动作本身会消耗少量计算资源,但因为过期数据是分批清理的,均摊成本可以控制得很低。
注意:在实际实现中,清理策略有个性能权衡——是每次出块都扫描一遍全表找过期项,还是用队列按时间排序只在队首项到期时才执行清理。按我的工程经验,队列方案更优,扫描方案的复杂度会随数据量线性上涨,很快就会成为瓶颈。
4. 与主流"减负"方案横向对比:谁付出了什么成本
4.1 存储租金模式:用经济手段逼用户自我清理
存储租金是最早被提出的状态膨胀治理方案之一。核心逻辑是:状态不是免费的,你要占用链上存储,就得持续付费。租金断了,数据就被回收或标记为不可访问。
这个方案解决了一定问题,但用户体验很糟糕——用户已经为提交交易付了手续费,还要为一笔历史数据持续交租金,而且租金的目标对象经常是那些"早就忘了"的链上资产。更麻烦的是,如果租金清算逻辑处理不当,用户会在不知情的情况下失去对自己资产状态的访问权。
Bulletin Chain的临时存储不要求用户为数据持续付费。它只在提交时一次性支付包含存储费用的交易费,到期后数据自然过期。对用户来说,没有持续的"持有成本焦虑"。
4.2 状态剪枝:只减历史负担,不减状态负担
状态剪枝是目前很多链实际在用的方案。以太坊2.0讨论过状态过期,很多基于Tendermint的链也会定期做状态同步快照,让新节点不用重放全部历史。
但剪枝有个前提:剪掉的是"不再被需要的状态",这个判断通常由协议层根据访问频率、时间阈值等硬性条件来定,缺乏灵活性。更关键的是,剪枝后的数据没有办法做简洁的密码学证明——如果你需要向第三方证明某个旧数据在某个时间点存在,剪枝后的全节点帮不了你。
Bulletin Chain的签名聚合见证从设计之初就保留了可验证性,这是它与剪枝一个很本质的区别。剪枝是为了省空间而砍掉数据,Bulletin Chain是把数据从"状态"降级为"可验证的事件"。
| 方案 | 是否释放活跃状态 | 过期后是否可验证 | 用户持续成本 | 实现复杂度 |
|---|---|---|---|---|
| 存储租金 | 是 | 弱 | 高 | 中 |
| 状态剪枝 | 部分 | 弱 | 无 | 中 |
| 链下存储 | 是 | 弱 | 因方案而异 | 低 |
| Bulletin Chain | 是 | 强 | 无 | 高 |
4.3 链下存储方案:牺牲了链级保证
数据放在IPFS、Arweave这类链下存储网络上,确实是解决状态膨胀的常见思路。它能承载大量数据,成本也低。但链下存储面临一个老问题:链下数据与链上共识是断裂的。
链上合约引用了一个IPFS哈希,这个哈希指向的内容在发布时可能是有效的。但如果发布者后来撤回了文件,IPFS的节点不再缓存它,链上引用就变成了一个"永久死链"。虽然可以通过固定服务来缓解,但固定服务的中心化倾向又是另一种代价。
Bulletin Chain的验证者见证机制,保证了数据在有效期内是"链上共识锚定的",而不是依赖某个外部存储节点的持续在线。这是它在可信度上的一个重要加分项。
4.4 数据可用性层:换赛道但没直接解决状态问题
Celestia这类模块化区块链的数据可用性层,解决的是"区块数据可被重建和验证"的问题。它用纠删码和抽样验证来确保数据可被轻节点低成本验证。但数据可用性层本身依然要保存数据,只是把这个负担从单一链分摊到分布式网络。
它和Bulletin Chain并不冲突,甚至可以是互补关系。Bulletin Chain可以把归档数据放在数据可用性层上,这样既保证了过期数据可恢复,又不需要全节点在活跃状态里维护它。两者结合,效果可能比单独用任何一个都好。
5. 哪些场景真的适合Bulletin Chain:应用视角冷静评估
5.1 预言机价格数据流:时效性强,历史语义淡
预言机推送的价格数据是一个典型场景。价格数据每几秒钟或几分钟更新一次,链上应用读取的永远是"最新价格"。几个月前的ETH/USD价格数据,除了做历史回测的分析师,几乎没人会去链上查询。
这类数据上链的意义在于:当时的价格被链上验证者确认过,可以用来做清算、结算、借贷等关键操作的依据。它不需要永久在状态里,因为一旦新价格进入,旧价格就只是历史记录。用Bulletin Chain的临时存储来承载价格数据流,既保证了查询时的数据可用性,又不会让历史价格无限堆叠。
5.2 可验证随机数结果:验证完毕即生命周期结束
链上抽奖、盲盒、随机分配等场景经常使用可验证随机函数(VRF)生成随机数。随机数结果公布后,参与者需要验证这个结果是否公平、是否被操纵。验证逻辑执行完毕后,这个随机数本身就没有长期状态价值了。
用临时存储保存随机数种子和结果,刚好覆盖了"公布—验证—争议期"全过程。争议期结束后,数据自然过期。这在产品设计上还有一个隐形好处:用户不会拿着几个月前的随机数结果跑来问客服"为什么当时我没中奖"——因为数据已经过期,产品可以引导用户去归档层查询,而不是在链上吵。
5.3 跨链消息通知:XCM场景的天然搭档
Polkadot生态中,跨链消息传递(XCM)是基础能力。跨链转账通知、平行链间的事件通知、智能合约间的一跳消息,这些数据本质上都是过程性信息。它们存在的意义是让接收方知道"发生了某件事",而不是让所有节点永久记录"某件事发生过"。
把通知类数据放进Bulletin Chain的临时存储,接收方在有效期内读取并处理消息,过期后消息就从活跃状态释放。这大幅降低了跨链消息的存储成本,让平行链之间传递消息变得更轻量。
5.4 活动凭证和时间戳证明:短期验证,长期归档
数字凭证、活动参与记录、时间戳存证这类数据,也并非都需要永久状态。比如一个开发大赛的提交记录,需要一个验证窗口期来确认"这个作品确实在截止时间前提交了"。窗口期结束后,记录只需要保留在归档层,不需要每个全节点都维护。
这里要注意一个边界:如果这个凭证代表一种长期的权益(比如NFT门票、身份证明),那它就需要永久状态,不能进临时存储。判断标准还是回到那四条定义特征——是否与时间强相关、是否可重建、查询频率、是否资产类。
5.5 不适合的场景:别把临时存储当万能药
加密货币资产余额、DeFi清算状态、DEX流动性池、NFT所有权记录这些,都属于永久状态型数据。它们必须时刻在状态中可查询,不能有任何"过期"的可能。如果把这类数据放进临时存储,等于在资产安全上埋了一颗定时炸弹。
另外,某些数据本身是小型的,比如一个合约的管理员地址、一个协议的参数配置,这类数据虽然变化频率低,但它需要被持续读取,放在永久状态里没有任何问题,没必要为了用临时存储而用临时存储。
6. 关于未来落地路径的一点观察
6.1 从原型到平行链:工程上要解决的核心问题
Bulletin Chain作为一个概念模型,要走通产业化路径,需要先解决几个工程问题。第一个是存储清理效率。我在前面提到,用队列按时间排序存储过期数据,可以做到O(1)的过期检查。但区块链出块是离散的,每次出块前可能有一批数据同时过期,清理操作必须在区块执行时间预算内完成。这需要做批量删除优化,最好能配合数据库层的批量删除接口,而不是逐条删除。
第二个问题是查询接口的兼容性。开发者已经习惯了读取永久状态,如果API返回的结果会因为数据过期而变得不确定,上层应用需要一套新的容错逻辑。这要求Bulletin Chain提供清晰的查询接口分层:活跃数据走快速查询通道,过期数据走归档查询通道,两者之间要有明确的错误码和响应头。
第三个问题是验证者激励。临时存储不占用长期状态,验证者节点的存储压力确实变小了,但存储压力变小也意味着验证者的"工作量证明"变轻了。出块奖励需要在"处理多少交易"和"维护多大状态"之间重新校准。如果一个链的临时数据量过大而永久状态很小,验证者实际承担的资源成本其实并不低,激励模型不能按传统链的状态增长逻辑来设计。
6.2 生态整合路径:与Polkadot已有能力的协同
Bulletin Chain如果作为Polkadot平行链上线,有几个协同点可以重点利用。
一个是与轻客户端的配合。Polkadot轻客户端可以通过验证中继链头来间接验证平行链的状态。Bulletin Chain的临时数据持有者可以发布精简的Merkle证明,让轻客户端在不运行全节点的前提下验证数据有效性。这和临时存储的签名聚合证明是天然互补的。
另一个是跨链消息路由。其他平行链可以通过XCM把临时数据转发给Bulletin Chain,由后者统一做数据发布和过期管理。这让开发者不必在自己的链上重复实现一套临时存储逻辑,直接用XCM消息调用Bulletin Chain的接口注册一个临时数据就可以了。
6.3 个人对这项技术方向的一点判断
我在区块链基础设施领域观察了几年,一个越来越强烈的感受是:链上存储需要"分层",但不能搞成物理隔离。过去大家习惯把存储问题拆成链上/链下两个选项,链上贵但可靠,链下便宜但可信度弱。Bulletin Chain想证明的是,中间还有一条路——数据在某个时间段内是链上的一等公民,过了这个时间段就理智地退居二线,让位于新数据。
这个思路的好处在短期看不太明显,但如果你把时间维度拉长到十年、二十年,状态膨胀问题几乎必然成为每一条成功公链的核心瓶颈。提前设计好"数据如何优雅地退出状态",和设计好"数据如何优雅地进入状态"同样重要。
6.4 小规模试水建议
如果你是个开发者,想亲身体验Bulletin Chain理念,不一定要等它主网上线。完全可以用Substrate在本地起一条测试链,在FRAME层写一个带TTL的临时存储pallet,逻辑其实不复杂——存储项加一个expires_at字段,每次出块前执行一次过期清理即可。然后部署一个简单的投票合约或者公告栏应用,让数据在几天后自动过期,体会一下"状态可收缩"和"全节点头重脚轻"之间的体验差异。
提示:在小规模验证时,我建议把清理逻辑的日志输出打开,观察每次区块执行时清理掉的数据量和耗时。如果清理操作耗时超过区块时间的5%,就需要优化批量删除策略了。这个阈值在真上线时会成为决定性能基准的关键地方。
这个方向目前的公开讨论和工程实现还在早期,但它踩中的痛点非常实在。如果你也在为链上状态增长过快而头疼,不妨关注一下Bulletin Chain的后续进展,或者直接动手实现一个最小原型。真正的价值,往往在你亲手写下一个"能过期的存储"之后才开始显现。
