极致精简链:权益证明

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

本文探讨了如何通过“精益”升级(单槽最终性、基于递归STARK的抗量子签名聚合等)来激进地最小化以太坊共识链的状态需求,将验证者状态从当前的多字段压缩至仅6字节(有效余额1字节+公钥索引5字节)。

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

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

“现状”链中的状态记账

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

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

信标链状态的 变化(每个周期)是一个代价非常高的操作。几乎所有的变化都与验证者参与或不参与导致的活跃余额变动有关。

阶段 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),使其在不同余额下大致具有相同的损失性。我们重载此值,将 被罚没 表示为 0 有效余额(我们单独跟踪 总余额,并且 从总余额中减去被罚没的余额)。
  • 不活跃泄漏中的最大每日损失大致与有效余额的粒度级别相同,因此不活跃泄漏机制不会因此受到大的退化。此外,如果我们重新设计有效余额,我们不妨加上 滞后现象

新的记账方式

每个验证者的状态为:

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

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

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

状态更新为:

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

证明的成本

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

使用以天为单位的时间段和 16 秒的周期,这意味着大约 5400 个 Merkle 分支。使用 STARK(证明成本远低于 SNARK),即使在较弱的硬件上,这也完全可以在一个小时内完成。在分叉的情况下,分叉一侧的证明只会被包含在该侧,因此每个验证者只需证明他们参与的分叉侧的分支;保持更新其他分叉侧的证明的成本要低得多。

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

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

在链上,该机制假设每个验证者每天一个 STARK。对于 1 百万验证者,这将是每个槽超过 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 条评论