tl;dr
可信的预配置协议要求提议者在签署区块之前验证其承诺是否得到履行。一种简单的方法是检查完整的区块体,但这会泄露构建者的区块,这是行不通的。中继机制可以弥补这一缺陷,但在 ePBS 之后不再需要。无需信任的解决方案是让构建者在其出价中提交约束满足证明。缺点是,证明生成会增加关键路径的延迟,尤其是在约束演变为超出简单交易包含范围时。
EIP-7928 BAL提供了一种结构化的替代方案。BAL 完整记录了块中每次状态写入的情况,这些状态写入是执行过程的副产品,并被写入The Block。由于每个BAL条目都具有相同的结构,因此任何预配置类型都可以简化为对同一对象的真/假查询。单一的验证语言可以涵盖任何预配置类型(包含、执行、排序、排除ETC),并且单个验证器函数无需重新部署即可处理所有类型。新的预配置类型会转化为新的公式,这些公式可以使用相同的基础架构进行验证。这在严格意义上改进了 Merkle 证明所能提供的保证,同时降低了延迟和复杂性。
背景
预配置允许提议者在区块构建之前承诺,其下一个区块将包含某些属性。例如,用户可能会收到预配置,保证其交易将被包含在区块中,某个值将被写入特定的存储槽位,或者超过特定Threshold的支付将被包含在The Block中。
提议者做出的承诺限制了The Block的构建方式。目前,如果没有这些限制,构建者可以自由地向提议者提交任何区块。例如,如果引入包含性预配置,构建者就必须提交包含指定交易的区块。
在提交区块之前,提议者需要一种方法来验证The Block是否满足所有约束,以确保他们的承诺能够得到履行。需要注意的是,承诺是面向用户的,而约束是面向构建者的。
验证问题
最直接的方法是让提议者直接检查整个区块。如果The Block满足约束条件,提议者就签字。但这行不通,因为这会让提议者无需向建造者支付任何费用就能窃取The Block。
目前,中继机制已经解决了公平交换的问题。悲观中继机制中,中继会在将区块头分享给提议者签名之前,完整执行The Block,并且可以将其扩展到验证预配置约束,作为一项可信服务。另一种方案是乐观中继机制,中继在不完整执行The Block的情况下转发区块头,而是依赖于追溯性故障归因:如果构建者的区块之后被发现无效或违反约束,则会受到惩罚。这两种模式目前都在生产环境中存在。然而,ePBS(增强型区块验证系统)将中继从关键路径中完全移除,因此这两种模式都将不复存在。
另一种无需信任的替代方案是,构建者在提交报价的同时生成约束满足证明。最简单的形式是针对The Block块头中承诺的 trie 树根的 Merkle 包含证明。构建者可以证明某个特定交易已被包含,或者某个特定存储槽在区块末尾的值已设定,而无需披露完整的区块体。
其中一个问题是延迟。证明生成发生在The Block完全构建之后。随着预配置约束数量的增加,证明生成成为区块构建和投标提交之间关键路径上一个不容忽视的步骤。每一毫秒都会损失宝贵的构建时间,从而损害提议者的收益。
另一个问题是表达能力。默克尔证明是区块级别的:它们可以证明某个交易被包含在区块中,或者某个状态槽持有特定值,但它们无法证明交易级别的状态差异。没有默克尔证明可以证明某个特定交易导致了某个特定状态的改变。验证有状态的预配置需要完全重新执行或零知识证明,但出于隐私或延迟方面的考虑,这两种方法都不可行。
阻止访问列表的作用
EIP-7928将区块级访问列表 (BAL) 定义为区块执行期间访问的所有账户和存储位置的完整记录。每个BAL通过block_access_list_hash与特定的出价/区块绑定,通过重放BAL,任何人都可以重新计算区块的最终状态,而无需执行实际的交易。
在 preconfs 环境中,这样做主要有两个原因:
1. 区块访问日志(BAL)是执行的直接副产品,无需单独的证明生成步骤。构建者在构建The Block时就已经拥有BAL记录了The Block期间发生的每一次状态写入:存储槽值、余额变化、随机数递增和代码更新,每项都带有block_access_index标签,用于捕获全局写入顺序。这足以让提议者直接验证状态结果的任何属性:存储槽的值被写入了什么、账户余额是否超过了Threshold、随机数是否递增、两次写入是否按特定顺序发生,或者合约是否被修改过。所有这些检查都不需要交易检查。
2. BAL可以在不泄露区块内容的情况下进行验证。重建区块需要实际的已签名交易及其输入,而BAL省略了这些信息。仅检查BAL 的提议者无法获得任何信息,使其能够在不向区块创建者支付费用的情况下重建并重新提交The Block。然而,如果所有交易都来自公共内存池,那么有决心的提议者原则上可以仅凭公开信息重建区块(但那样的话,他们完全可以在没有区块创建者BAL的情况下自行构建相同的区块)。具有私有订单流的区块无法重建。
从交易承诺到结果预会议
当前的预配置方法对特定的已签名交易做出承诺。结果预配置则不再关注交易,而只关注状态承诺。
在当今的意图机制中,你预先设定一个结果,例如“用X至少交换Y ”,求解器竞相寻找自定义解决方案,然后智能合约最终验证意图是否得到满足。结果预配置在提议者层应用了相同的模型。当提议者承诺“对槽位S首次写入值为V ”时,他们承诺的是一个状态结果,而不是一个执行路径。构建者可以通过任何有效的交易序列来满足此约束,因为该约束并未说明是哪个交易执行了写入、由谁发送的、消耗了多少 gas等等。
简而言之,提议者表达其区块的期望结果,建造者竞争寻找任何能够实现这些结果的有效执行路径,提议者在提交The Block之前(并且不会泄露The Block内容)验证结果是否已实现(通过BAL )。
统一约束语言
BAL是一个单一的结构,任何结果预配置类型都可基于此进行验证。这与当前预配置的工作方式截然不同,在当前情况下,每种类型都是一个独立的设计问题:包含预配置需要一种证明格式,排序约束需要另一种,执行预配置又需要另一种。每增加一种新类型,都需要为提议者提供新的验证逻辑,并需要新的链上惩罚机制。添加新的预配置类型意味着需要对整个技术栈的每一层进行协调升级。
由于每个BAL条目都共享相同的四个字段(地址、字段类型、写入的值和排序索引),因此验证任何结果的 preconf 都简化为相同的真/假问题:是否存在具有这些属性的写入?此地址是否存在?写入A是否发生在写入B之前?
一阶逻辑 (FOL) 是一种形式语言,专门用于对一组固定的对象进行真/假判断。它易于理解,并且已知在有限结构上是完备的:任何可以用纯英语表达的关于固定模式BAL的布尔属性都可以用一阶逻辑公式表示。
实际结果是只需要一个验证器。它以一阶逻辑公式和BAL作为输入,并返回真或假。验证器函数只需构建一次(在正常竞价流程中位于提议方的边车函数中,在争议解决时位于惩罚合约中),之后无需更改。新的预配置类型意味着需要编写一个新的一阶逻辑公式,而无需部署新的基础设施。
该语言包含两类基本运算。比较运算是叶子节点:字段相等性、不等性以及顺序检查( == 、 >= 、 <ETC),应用于匹配条目中的值。逻辑连接词构成结构:“存在一个满足……的条目”、“两个条件都成立”以及“此条件不成立”。这与使用单一门类型构建任何逻辑电路的原理相同,只需最少的基本运算即可获得无限的表达能力。
去中心化应用(DApp)需要代表用户计算公式。这包括确定哪些存储位置会受到用户交易的影响,以及哪些存储位置需要检查余额(BAL)。对于算术约束(例如“余额增加Y ”、“价格在5%以内”、“nonce 递增”),DApp 会直接向公式提供这些提示,这意味着 DApp 语言本身无需支持算术运算。具体来说,如果 Alice 的 nonce 为5 , USDC余额为500 ,并且她希望至少收到2000 USDC,那么 DApp 会读取初始状态,计算出 nonce 为6且余额为2500 ,并构建一个公式,该公式只需检查nonce == 6且balance >= 2500 。
会前模式和一级用户体验结果
以下每个模式都是BAL 的一个公式。所有模式均由同一验证器处理。请注意,这些模式仅供参考,可能并不完整。在以下公式中, (A, Nonce)和(A, Balance)分别指账户A的 nonce 和ETH余额字段; (C, S)指合约C中的存储槽S ; V是预期值。这些字段类型与BAL条目中的字段类型直接对应。
保证包含。Alice希望她向 Bob 转账的ETH被包含在下一个区块中。Alice 的 nonce 递增确认了她的交易已执行,而 Bob 的余额增加确认了付款已到账。这两个写入操作必须共享相同的block_access_index ,以确认它们来自同一笔交易。dapp 在构建公式之前,会从父状态根计算绝对的 post-state 值。
there exists a write to ( Alice, Nonce ) with value == n+ 1 [call this e1] AND there exists a write to ( Bob, Balance ) with value > = bob_pre_balance + amount AND index == e1.index区块顶部。用户的交易应该是The Block中的第一个用户交易。block_access_index 是按交易分配的block_access_index其中索引0保留给执行前系统合约写入(例如 EIP-4788 信标根更新),用户交易的索引从1开始。这是目前最强的排序保证,因此定价也应相应较高。
there exists a write to (Alice, Nonce) with value == n+ 1 AND index == 1 AND there exists a write to (C, S) with value == V AND index == 1合约优先访问权。用户希望成为第一个与特定合约交互的人,但不想支付区块顶币的费用。一个经典的例子是铸造 NFT:第一个调用铸造函数的人优先,其他一切都无关紧要。检查范围完全限定于合约C的条目,这使得构建者可以完全自由地决定其他所有内容的顺序。
there exists a write to (C, S) with value == VAND its index is less than or equal to every other write to C同槽位意图结算。用户签署一个意图,“将我的X ETH兑换成至少Y USDC”,但未指定如何实现。构建器会同时包含用户的意图交易和求解器的执行交易。公式中的顺序约束确保意图执行在求解器支付之前完成。至关重要的是,健康的构建器竞争对于提升用户收益至关重要。
there exists a write to ( A, Nonce ) with value == n+ 1 [call this e1] AND there exists a write to ( A, ETH_Balance ) with value < = eth_pre_balance - X AND index == e1. indexAND there exists a write to ( A, USDC_Balance ) with value > = Y [call this e2]AND e1.index < e2.index执行结果预配置。以往,保证特定的执行后状态需要对 EVM 执行进行零知识证明。而使用 BAL,随机数递增即可确认用户事务已运行;存储槽检查即可确认预期的状态变更。两次写入必须共享同一个索引,以确认它们来自同一事务。无需重新执行。
there exists a write to ( A, Nonce ) with value == n+ 1 [call this e1] AND there exists a write to ( C, S ) with value == V AND index == e1.index上述模式可以自由组合。通过在 nonce 检查中添加index == 1 ,可以将块顶保证叠加到同槽意图结算之上。执行结果可以与排序约束结合使用。上述任何组合都是有效的公式,并且使用相同的验证函数进行验证。
使用 ePBS 进行会前结果评估
由于结果预配置的范围限定于结果而非特定交易,因此满足这些预配置就形成了一个市场。多个搜索者可以独立竞争来满足任何给定的预配置。构建者选择最佳组合。任何一方都不需要了解其他方的执行策略。以下流程图展示了这如何融入 ePBS 后的竞价流程。
请注意,构建者签署的约束承诺并不参与链上流程。它的作用在于协议之外:如果构建者签署了约束,然后提交了违反这些约束的BAL ,那么它就生成了自身过错的加密证明,外部惩罚或信誉系统可以据此采取行动。
约束验证步骤在提议者的边车程序中运行,边车程序是链下实现的,其验证逻辑与惩罚合约中部署的验证逻辑相同。两者在构造上是等价的,因此提议者确认的检查与惩罚合约在争议发生时运行的检查相同。
另请注意,在 ePBS 规范中,构建者的出价包含的是block_hash承诺,而不是头部本身。因此,提议者需要建立从BAL → block_access_list_hash → 头部 → block_hash → 出价的信任链。
局限性
BAL并不能证明底层交易具有有效的签名。构建者可以构造一个满足所有结果预配置检查的BAL ,但该 BAL 对应的却是无效或伪造的交易。当有效载荷被揭露时,它将无法通过验证,提议者也将失去其席位。幸运的是,在 ePBS 之后,提议者仍然可以无条件地获得竞标金额。
如果没有协议外惩罚机制来抑制这种构建者行为,结果预配置可能会进一步刺激构建者行使他们的自由选择权,因为违反预配置承诺可以获利。让构建者甚至多个参与方承诺遵守约束条件,是朝着建立这种机制迈出的一步。
BAL作为争议证据
如果预协商争议进入链上裁决阶段,则每个约束均可独立提出异议。提出异议的一方需提供被违反的约束、提议者在该约束上的签名、构建者的签名承诺、 BAL(区块访问列表)以及The Block块头。惩罚合约会使用block_access_list_hash对BAL进行身份验证,并运行与提议者边车在正常验证期间运行的相同的验证器。如果验证器返回 false,则证明存在违规行为。
一阶逻辑公式结构非常适合零知识证明。对固定模式BAL 的查询进行证明的成本远低于对任意 EVM 执行的证明成本,因此针对已提交的BAL根进行零知识证明是一个可行的未来优化方向。
通往圣殿之路
本文所述设计完全违反协议。提案者和构建者的承诺通过经济激励和违反协议的惩罚机制来强制执行。即使区块违反了预配置结果,从网络的角度来看,它仍然是一个有效的区块。
实现协议内承诺是可行的。PEPC 指出了协议强制提案人承诺的必要性,但承诺的表示形式仍未确定,例如是否使用 EVM 执行、SNARK 或其他结构。此外, PEPC还指出了一个数据可用性问题:第三方如何以验证者可验证的方式提供承诺证明?BAL 有望解决这两个问题,因为它本身就是The Block块头中承诺的一等对象,无需单独的证明交付机制。FOL 约束语言简洁且定义明确,验证器是一个可在共识层部署的单一函数。协议无需验证者重新执行承诺代码,而是可以直接使用经过认证的BAL来验证 FOL 公式。
要使之符合协议规定,还需要几个其他部分协同工作:
具有约束力的承诺广播。提案方的约束条件需要在竞价过程开始前以不可更改且可追溯的方式发布。这类似于提案承诺广播(PTC),但针对的是约束条件。
投标文件中包含BAL和标头。为了使提案方在签署前能够核实约束条件,建设方必须在投标文件中包含BAL和标头,而这些文件目前并非 ePBS 规范的一部分。
无效的BAL将对建筑商处以处罚。如果投标时提交的BAL与最终公布的The Block不符,或者公布的区块无法验证,则应处罚建筑商。在ePBS实施后,建筑商已被要求提供抵押品,因此大部分繁重的工作已经完成。
概括
ePBS 不需要中继,因此重新引入中继作为可信的预配置验证器并不理想。默克尔证明提供了一种无需信任的替代方案,但会增加关键路径的延迟,并且无法表达有状态或排除约束。BAL 解决了这两个问题:它们作为区块执行的副产品生成,不会增加延迟;并且通过将承诺从事务级转移到意图级,任何预配置类型都可以简化为基于相同BAL结构的公式。这种可表达性不需要在关键路径上使用零知识证明,并且添加新的预配置类型不需要对验证器或惩罚基础设施进行任何更改。






