deposited transaction 是什么?OP Stack 跨层交易为什么不需要签名 图 1
deposited transaction 是什么?OP Stack 跨层交易为什么不需要签名 · 图 1

大多数交易靠签名证明自己,但 OP Stack 链上有一类交易从诞生起就不带签名:deposited transaction(存款交易)。它们是规范里专门定义的一种交易类型,由 L1 上的事件触发、在推导过程中自动生成、必须在 L2 上被执行。理解它为什么不需要签名,比记住它叫什么更重要,因为这关系到跨链转入资产时”谁授权了这笔钱动”的根本问题。

为什么签名可以省掉

OP Stack 规范给出的存款交易与 EIP-1559 交易有三点显著差异:它由 L1 区块推导而来、协议规定必须包含;它不做签名验证;它在 L1 上购买 L2 的 gas,因此这部分 gas 不退还。省略签名不是漏洞,而是授权模型的替换:正常交易的授权来自私钥签名,存款交易的授权来自”L1 日志已经发生”这个事实本身。规范明确写了授权由链推导过程处理——只要推导正确执行,from 地址必然与 L1 存款合约日志所声明的地址一致。也就是说,伪造一笔别人名下的存款交易,等于要伪造 L1 上已确认的合约事件,这在假设层级上等价于改写 L1 历史。

交易类型与字段构成

机制示意(图片由 Agnes 生成,非产品界面或链上数据图)

规范用 EIP-2718 兼容的方式新增了一个交易类型,前缀字节为 0x7E。字段按顺序包括:标识来源的 32 字节 sourceHash、发送方地址 from、接收方 to(合约创建时为空)、要在 L2 上铸造的 mint 金额、转账的 value、L2 gas 上限、isSystemTx 标志(自 Regolith 升级起被强制为 false)以及 calldata。它没有 nonce 字段,唯一性完全靠 sourceHash 保证——规范解释过原因:用 nonce 去重需要在推导区块时额外读取一次 L2 EVM 状态,代价太高。API 返回里为了兼容仍然带签名字段,但 vrs 是零值。

sourceHash 怎么算、三种来源

sourceHash 按来源分域计算。用户存款是 对 l1BlockHashl1LogIndex 连续做两次 keccak 哈希,即对 L1 区块哈希与该条日志在区块全部日志中的序号做双层哈希;L1 属性存款是域前缀 1 配合 l1BlockHash 与 L2 纪元内序号;升级存款是域前缀 2 配合一个标识升级意图的 UTF-8 字符串。外层哈希把标识信息与域前缀绑在一起,防止不同来源类型之间撞号。如果没有 sourceHash,两笔内容相同但来源不同的存款会算出完全一样的交易哈希——这正是这个字段存在的理由。

区块里的位置和 gas 的购买方式

每个 L2 区块的第一笔交易必须是 L1 属性存款交易,用于把 L1 区块信息写进 L2 的 L1Block 预部署合约;其后才是零或多笔用户存款交易,且用户存款只出现在每个 L2 纪元的第一个区块里。执行顺序上先把 mint 金额无条件加到 from 余额(即使后续执行失败也不撤销),再像 type-2 交易一样执行,但不校验费用字段和 nonce。L2 的 gas 在 L1 侧通过燃烧 L1 gas 的方式购买,规范特别强调这笔支出不可退还,因为它可能根本不是用 ETH 直接支付的。

实操核对与常见误解

链上核对时,存款交易在区块浏览器里能通过 sourceHash 与 L1 日志对得上号:同一事件在任何节点上推导出的哈希完全一致,这也是”跨链转入是否被遗漏”可判定性的来源。常见误解有两个:一是把存款交易当作可替换交易——它没有 nonce,也不靠签名,替换或取消都无从谈起,唯一的路径是等推导;二是把 mint 加余额这一步当成”转账成功”——规范规定这一步无条件执行,即便存款交易后续执行失败,铸出的余额也不回滚,失败体现在执行结果而非到账动作上。另外注意升级存款的存在:规范允许用域前缀 2 配合一个标识升级意图的字符串生成系统级存款,用于升级时执行预定的链上动作,它们和用户充值混在同一套交易类型里,靠 from 与数据特征区分。以上是协议规范层面的机制描述,具体合约地址与参数以各链官方文档为准。本文只做机制解释,不构成任何投资建议。