Smart Batching 是一种新的以太坊批量编码标准,允许每个参数在执行时动态解析(通过 literal、staticcall 或余额查询),并支持内联约束(断言)作为批处理的一等公民。
智能批量处理(Smart Batching)是一种批量编码标准,其中每个参数都声明了在执行时如何获取其值以及该值必须满足哪些条件。参数可以是字面量、实时的 staticcall 结果或余额查询——每个参数在链上独立解析,并在组装成调用之前根据内联约束进行验证。
关键在于,一个批次不再仅仅是步骤序列——它可以包含内联断言:对链上状态的条件,这些条件必须满足才能继续执行。用户不仅仅说“先做A,再做B”;他们说“做A,断言结果是可以接受的,然后做B”。步骤和断言在同一个批次编码中是平等的,将盲目的交易列表转变为具有内置安全保障的可验证程序。
这消除了静态批量处理(ERC-4337、EIP-5792)的根本限制:每个参数在签名时被冻结,对执行时的链上状态视而不见。如果一笔兑换返回的代币少于预期、Gas 成本发生变化,或者跨链桥交付时产生意外的滑点——批次将回滚。目前唯一的解决办法是针对每个多步骤流程部署自定义智能合约,或依赖于并非每个目标合约都暴露的协议级滑点参数。
拉取请求: 添加 ERC:由 oxshaman 提出的智能批量处理 · 拉取请求 #1638 · ethereum/ERCs · GitHub
完整规范: ERCs/ERCS/erc-xxxx.md at smart-batching · oxshaman/ERCs · GitHub
现实世界中的 DeFi 流程会产生动态且不可预测的输出。一次兑换会产生可变的代币数量。从借贷金库中提取会产生可变的份额到资产转换比率。一笔跨链桥交易会在不可预测的延迟后交付代币,并伴随可变费用。静态批量处理让用户面临两种糟糕的选择:硬编码乐观的金额(冒着回滚的风险)或保守地低估(导致资金搁浅)。
智能批量处理在执行时解析参数。用户不是预先编码一个静态的 calldata 块,而是签署一个批次,其中每个参数指定了如何获取其值——作为字面量、一次 staticcall 或一次余额查询。执行逻辑在交易期间解析每个参数,并从头构建 calldata。
但仅靠动态解析只完成了故事的一半。另一半是断言——批次声明在执行过程中任何时刻必须为真的条件的能力。今天的批次是扁平的动作列表:“调用A,调用B,调用C。”如果调用A的结果不理想,你只能在整个批次回滚后(或者更糟,成功执行但结果不佳)才能发现。通过智能批量处理,断言作为一级条目位于步骤之间,让用户表达:“调用A,验证输出至少为X,然后调用B。”批次变成了一个嵌入了安全检查的程序,而不是一个抱有希望的脚本。
静态批量处理(当前模型)
第1步:swap(100 USDC) → OK
第2步:supply(0.05 WETH) → 回滚(实际输出是0.0495)
问题:"0.05" 是签名时的猜测。
无法表达"只有当输出 ≥ 阈值时才继续。"
智能批量处理(本标准)
第1步:swap(100 USDC) → OK,返回0.0495
断言:BALANCE(WETH, account) ≥ 0.04 ✓(用户定义的安全下限)
第2步:supply(amount) → amount = BALANCE(WETH, account) = 0.0495 ✓
参数在链上解析。断言守卫每一步转换。
智能批量处理不是预先编码带有已知偏移量处的哨兵字节并进行修补,而是从头构建 calldata——每个 InputParam 都是自包含的,包含其获取器类型、路由目标和约束。不需要偏移量计算,也不需要了解目标函数的 ABI 布局。
本标准定义了编码方案和接口——而不是一个具体的模块。相同的 ComposableExecution[] 编码可以作为:
一种网络格式。一个接口(IComposableExecution)。薄适配器处理安装和权限;核心逻辑是共享的。
在每一个现有的批量处理标准中,一个批量条目意味着“执行此调用”。智能批量处理引入了第二种条目:断言——一个对链上状态的条件,必须成立才能继续执行批次。断言不是附加功能;它们使用与动作条目相同的 InputParam 解析和约束机制,只是没有调用目标。
这之所以重要,有三个原因:
无需自定义合约即可实现安全性。 今天,如果你想强制执行“只有当我的兑换输出超过阈值时才向 Aave 提供资金”,你需要一个特制的合约(或一个恰好暴露了 minAmountOut 参数的协议)。通过断言,安全检查是批次本身的一部分——任何用户都可以表达对任何解析值、针对任何协议的任意条件,无需部署任何东西。
防御 MEV 和状态操纵。 断言让用户防范三明治攻击、预言机操纵和不利的执行条件。一个批次可以断言价格源在预期范围内、某个池子的储备没有被扭曲,或者余额满足最低要求——所有这些都在同一笔交易中原子性地进行评估。如果任何一个断言失败,整个批次在价值损失之前就会回滚。
可组合的意图表达。 断言将批次从命令式脚本(“做X,做Y”)转变为声明式程序(“做X,要求 P,做Y”)。用户表达他们认为可接受的结果,而不仅仅是采取什么行动。这是一个根本不同的模型——批次编码了意图,而 EVM 强制执行它。
每个解析后的值可以携带内联约束(GTE、LTE、EQ、IN)。一个没有调用目标(address(0))的条目变成了一个关于链上状态的纯布尔门——一个谓词条目。不需要独立的谓词机制。
这免费产生了跨链编排:中继器通过 eth_call 模拟批次,当谓词满足时提交。多链流程作为一个单一签名的程序执行,每一步由可验证的链上谓词门控——与互操作性层无关(原生桥、ERC-7683、ERC-7786、任何消息协议)。
const batch = smartBatch([
swap({ from: WETH, to: USDC, amount: fullBalance() }),
assert({ balance: gte(USDC, account, 2500e6) }), // 如果兑换输出过低则中止
supply({ protocol: "aave", token: USDC, amount: fullBalance() }),
assert({ balance: gte(aUSDC, account, 2400e6) }), // 验证供应已被贷记
stake({ token: aUSDC, amount: fullBalance() }),
]);
步骤和断言自由交错。开发者在 TypeScript 中编写多步骤、多链的程序——动作和安全条件并列——编译为标准链上编码,签名一次,完全由 EVM 执行。无需部署合约。新流程无需审计周期。
输入参数——每个指定了两个正交关注点:
TARGET、VALUE、CALL_DATA)RAW_BYTES、STATIC_CALL、BALANCE)输出参数——捕获返回值到外部存储合约,供后续条目使用(EXEC_RESULT、STATIC_CALL)。
约束——对解析后的值的内联谓词(EQ、GTE、LTE、IN)。如果任何约束失败,整个批次回滚。
存储合约——带有按账户、按调用者隔离的命名空间键值存储。支持临时存储(EIP-1153)以提高 Gas 效率。
完全向后兼容。该编码是自包含且增量的——没有现有的智能账户需要迁移。与现有的 executeBatch 操作兼容,并与 EIP-8141 框架交易向前兼容。
参考实现包括:
IComposableExecution.sol —— 标准接口ComposableExecutionLib.sol —— 包含完整解析算法的共享库Storage.sol —— 外部命名空间存储合约ComposableExecutionModule.sol —— ERC-7579 适配器ComposableExecutionBase.sol —— 原生账户集成基础参考实现已经过审计,所有发现的问题均已修复。
作者: Mislav Javor ( @oxshaman)、Filip Dujmušić ( @fichiokaku)、Filipp Makarov ( @filmakarov)、Venkatesh Rajendran ( @vr16x)
我们欢迎对规范的反馈,尤其是在以下方面:
约束机制以及四种约束类型(EQ、GTE、LTE、IN)是否足够
存储合约设计与临时存储的权衡
用于跨链编排的谓词条目模式
不同账户标准(ERC-7579、ERC-6900、ERC-7702)的集成考量
- 原文链接: ethereum-magicians.org/t...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!
作者暂未设置收款二维码