以太坊共识瘦身:将信标链状态压缩至每验证者6字节

以太坊中文 发布于 2026-07-07 阅读 25

本文探讨以太坊共识链通过“瘦身”升级(单槽最终性、递归STARK抗量子签名聚合)最小化状态需求的方法。

特别感谢 Emile、Potuz 和 Anders Elowsson 提供的初步反馈和审阅。

本文的目标是展示如何在“精简”升级(单槽最终性、基于递归 STARK 的抗量子签名聚合等)背景下,将以太坊共识链设计为能够激进地最小化状态需求,将责任推给验证者,让他们管理自身状态并偶尔使用 ZK 证明其状态。这将消除“epoch 末期处理”(在少数槽最终性中,可能每 16 秒就需要发生一次)的负担,并可能使共识在需要时扩展到数百万验证者。此方案的进阶版本还能“免费”实现验证者匿名性重塑。

“现状”链中的状态核算

信标链状态目前为每个验证者包含以下内容:

字段 大小
公钥 48 字节
提现凭证 32 字节
有效余额 1 字节
是否被罚没? 1 比特
各阶段的 epoch 编号(激活资格、激活、退出、可提现) 8 × 4 字节
活跃余额 8 字节

信标链状态的 变化,每个 epoch 都是一次非常昂贵的操作。几乎所有变化都与验证者参与或未参与导致的活跃余额变动有关。

阶段 1A:省略公钥树

基于 STARK 的聚合的一个主要好处是,我们在签名和聚合方法的内部逻辑方面拥有更大的自由度。我们已经打算将其用于聚合,从而可以实现位域合并聚合。但我们也可以将其用于签名,以从状态中移除验证者公钥。

请注意,当验证者存入时,其公钥存储在存款树中的一个固定位置。此外,没有人需要存储完整的存款树:存款合约只存储 右侧分支,这正是追加下一个值所需的内容:

depositcontract.drawio

我们不在信标链状态中存储验证者的公钥(48 字节),而只存储他们在存款树中的 索引(5 字节)。基础签名算法(leanWOTS)经过调整,使得公钥与通过存款树的 Merkle 证明一起包含在签名中,并且签名验证函数将该索引视为公钥,并取一个最近的(例如,当前天开始时)存款树根作为辅助公共输入。

验证者需要跟踪其存款的更新 Merkle 证明,以便能够继续签名。如果验证者在其存款被包含时拥有右侧分支,并且他们处理链并在此后每次有存款时调整分支,那么这很容易做到。

当验证者存入时,提现凭证就在公钥旁边,因此我们可以使用相同的证明来提现(因此无需在信标链状态中存储提现凭证)。

阶段 1B:ZK 证明余额

我们从信标链状态转换函数中移除所有与奖励和惩罚处理相关的逻辑。见证只需在其有效性检查通过后(使用 STARK)被包含到区块中,并且实时状态下根本不进行任何处理。

在每天结束时,验证者需要生成一个 STARK,该 STARK 遍历自前一天以来的链,提供其索引在每个已上链的见证位域中的 Merkle 分支,利用这些确定他们参与和未参与的次数,并计算其新余额。他们将此 STARK 提交给协议。这更新了验证者的余额,该余额在接下来的一天内保持有效。

chainwalker.drawio

为了实用性,我们需要对上述设计进行一点澄清:时期 [T, T + 1 天] 的有效余额只需要基于截至 T - 0.5 天 的区块来计算。这给验证者半天的时间来提交他们的证明,而不会中断他们的参与能力。它还确保证明的发布可以在半天内分散进行,避免突然的拥堵时期(假设验证者在一定程度上随机化他们分支的发布时间;如果需要,我们可以通过分配错开的最小发布时间来强制实现,例如 T_min(验证者) = global_T_min + (1/4 天) * 验证者.pubkey_hash / 2**256)。

备注

  • 如果验证者延迟提交其余额更新证明,他们不会被罚没或踢出。相反,他们仍然可以随时提交。验证者唯一的损失是,在提交余额更新证明之前,他们无法进行见证。
  • 只需证明参与的 Merkle 分支,无需证明未参与的。
  • 目前,罚没发生在此 STARK 机制之外,以使其能够立即生效。
  • 我们还调整了退出方式。退出是通过提交一个“我想要退出”的 STARK 来代替你下一天的余额更新 STARK。部分提现是通过在下一天的余额更新 STARK 中添加一条“我想要部分提现”的消息。
  • 我们要求每个见证(位域)要么指向同一个区块的前一个见证,要么指向区块本身,并将其包含在其 STARK 合并中。因此,每个见证的位域是其应用对象的最新位域,它将任何先前的见证和新的见证进行 OR 合并。
  • 提议者必须证明其包含的见证中任何对象的“总有效余额”,以便区块能够在需要时被证明、公证、最终化等。
  • 我们还可以稍微调整有效余额的计算方式以进行优化。使用无符号位的 fp8 格式(例如,3 位指数,5 位尾数,最低值 16 覆盖 16…4032 ETH),使其在不同余额下大致具有相同的精度损失。我们重载此值,将 slashed 表示为有效余额为 0(我们单独跟踪 总余额,并且 从中减去被罚没的余额)。
  • 不活跃泄漏中的最大每日损失大致相当于有效余额的粒度级别,因此不活跃泄漏机制不会因此严重退化。此外,如果我们重新设计有效余额,我们也可以加入迟滞

新的核算

每个验证者的状态为:

字段 大小
有效余额 1 字节
公钥索引 5 字节

其他所有内容都不需要存储。每个余额更新证明都连接到 验证者上一个链上余额更新证明,因此其余额的低位数字会通过证明传递,而不进入有效余额。我们不需要跟踪存款 epoch、退出 epoch 等,因为这种跟踪被包含在余额更新证明机制中。

请注意,验证者的第 N-1 个余额更新证明是其(i)第 N-2 个余额更新证明和(ii)此后链上数据的确定函数。这意味着从固定备份种子进行恢复仍然是可行的。

状态更新包括:

  • 每次罚没一次写入
  • 每个验证者每天一次写入

证明成本

为了生成余额更新证明,验证者需要证明自前一天以来每个对象(该对象的最新见证)最多一个 Merkle 分支。这里的“对象”指的是区块;在最终性槽中几乎总是最多只有一个区块。

以天为周期和 16 秒的 epoch 计算,这意味着大约 5400 个 Merkle 分支。使用 STARK(证明成本远低于 SNARK),即使在较弱的硬件上,也可以在一小时内轻松完成。如果发生分叉,只有分叉一侧的见证会被包含在该侧,因此每个验证者只需要为他们参与的分叉一侧证明分支;更新其他分叉侧的证明成本将低得多。

证明总有效余额的成本更高,因为它需要遍历整个位域和整个有效余额集合(注意:为了优化,公钥索引和有效余额应存储在独立的树中,这样证明只需要遍历后者,每个验证者一字节)。

其中非哈希部分“只是”一个子集和,因此成本将主要由位域的 Merkle 树化(每百万验证者 128 kB)和有效余额树的 Merkle 树化(每百万验证者 1 MB)决定。如今,高端笔记本电脑可以每秒证明超过 50 万次哈希(即每秒证明 16 MB 的 Merkle 树化),因此这不是问题;即使是低端笔记本电脑也应该能够处理。

在链上,此机制假设每个验证者每天一个 STARK。对于 100 万验证者,每个槽将有超过 100 个 STARK,这太多了。因此,这些证明也需要像签名那样被聚合。

这已经是一个非常高效和优化的设计。下一步我们将加入隐私保护。

阶段 2:隐私保护

我们对信标链设计进行了几项重大调整。

首先,“活跃验证者注册表”变成每个天独立的注册表。没有长期验证者索引的概念。从系统角度看,验证者每天重新出现,声明并证明其有效余额,并且他们都是活跃的。特别需要注意的是,任何委员会分配都必须来自当天的公钥。

其次,我们将公钥注册移到余额证明步骤中。每个验证者每天提供一个新的公钥。这也意味着可以移除公钥索引的概念,因为索引只是该验证者在当天树中的位置。

第三,我们采用一种 BFT 共识形式,其中 验证者每轮发送一条消息。不存在“双重罚没”

我们还调整了余额更新证明中所声明的证明内容。验证者证明的是:从之前的 N 个链上注册记录,追溯到存款或超过[弱主观期]天的注册记录。

  • 其之前的链上注册记录(可能是一个存款)
  • 此后所有链上发生的见证
  • 此后所有链上发生的罚没

我们要求区块中的罚没按公钥顺序排列,以支持 Merkle 分支大小的证明,因此扫描罚没的开销至多与扫描见证的开销相同(通常区块中没有罚没)。

此外,请确保所使用的 STARK 是 ZK-STARK

我们还将部分提现作为一个单独的 ZK-STARK,以避免将确切的超额余额(部分提现不可避免地会泄露这一点,但有效余额由于粒度粗不会泄露)关联到下一天的密钥,从而避免下一天的密钥与前一天的关键联。

我们还需要执行以下操作之一,以支持罚没 之前的 公钥:

  • 要求公钥由存款时确定的种子确定性生成;这允许证明从之前的[弱主观期]天生成公钥,并检查其中所有的罚没。
  • 要求证明遍历链上最多[弱主观期]天前的罚没记录。

前者更简单、成本更低。后者更密集、更复杂,但有两个优势:

  • 它无需通过提现再存款循环即可实现密钥轮换
  • 它允许验证者删除超过[弱主观期]天前的密钥(提现凭证除外),在设备被攻破的特殊情况下提高隐私性,不过请注意,这样做会增加备份过程的复杂性。

对当前活跃公钥的罚没立即生效(通过将有效余额设置为零),对之前公钥的罚没仅在延迟一天后生效。

这为我们提供了相当强的验证者匿名性:每个验证者身份每天完全重新随机化,只有验证者自己知道其当前和过去身份之间的联系,并仅在证明此联系时透露两项信息:(i)自上次证明以来的余额变化,(ii)他们是否被罚没。

最后,确保存款不会公开提现地址;而是做出一个 隐藏承诺 hash(提现地址, 秘密)。只有知道提现地址和秘密的人才能进行提现。因此,每日证明还必须证明尚未发生提现(这要求状态有一个每日提现事件累加器)。这确实暴露了提现地址(这是不可避免的,因为它是执行层一侧的明文 ETH 转账),但这在公共层面不会泄露任何超出“此地址现已收到 X ETH”的信息——提现地址永远不会与存款或任何链上活动公开关联。

SSLE

本文介绍的机制在某种意义上几乎“免费”提供了单一秘密领导者选举 (SSLE)。公开跟踪的永久验证者集合的概念不复存在,因此选择提议者的唯一场所是重新匿名化的每日验证者集合。实际上,如果验证者在提议之前不进行见证,这已经满足了 SSLE 的核心属性。该设计可以扩展为即使在验证者在提议之前进行了见证,也能提供 SSLE 属性。

周期长度的选择

生成证明的大部分成本是摊销的——即从上一个检查点到当前检查点的“遍历链”,因此在一个非常低的阈值之上,无论周期长度如何,成本都差不多。

主要的 链上 成本是,一个余额更新证明需要在链上包含一个 32 字节的承诺。这比一次见证(1 比特)贵 256 倍。因此,如果我们希望成本不超过两倍,那么最小余额更新周期是 256 个最终性周期。如果一个最终性周期是 16 秒,这意味着余额更新周期为 4096 秒(约 1.1 小时)。如此激进的参数还需要更新在整个周期内错开,而不仅仅是像上述文章建议的 1/4 长度范围内,这会在一定程度上增加更新的延迟。

因此,1 小时是下限,1 天是保守选择。

更长的周期会降低验证者匿名性的有效性。

  • 原文链接: ethresear.ch/t/the-extre...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~

相关文章

0 条评论