Seaport 批量签名:一次签名最多铺一千六百万张订单,撤单却只认单张 图 1
Seaport 批量签名:一次签名最多铺一千六百万张订单,撤单却只认单张 · 图 1

一晚上挂二十个 NFT,钱包弹二十次签名窗口的痛苦,Seaport 从 v1.2 起用 bulk order creation(批量创建订单)解决:买家或卖家可以把一整批订单装进一个批量签名载荷,一次 ECDSA 签名生成多张订单。官方文档给出的能力参数相当具体:v1.2 起支持从 depth 1(2 张订单)到 depth 24(16,777,216 张订单)的批量载荷;和单张签名一样,批量载荷是带类型的、人类可读的 EIP-712 数据——你在钱包里能读到结构,而不是裸哈希。

批量背后的结构是一棵默克尔树:一次签名锁住的是“这批订单的根”,每张单独订单靠树证明归属。这个结构带来两个直接后果,文档都写得明白。其一,批量生成的订单可以独立履约——一张、几行或全部都能进履约交易,不必打包同卖。其二,履约批量订单有额外的 gas 成本,且随批量规模按对数增长:树高 1 大约多花 4,000 gas,之后每加一层高度约再多 700 gas。文档的建议是直白的:在“一次挂一批的省事”和“给吃单方加的成本”之间权衡——成本最终由履约者支付,定价时市场会把它算进对家的报价里。

批量撤销是这套机制里最需要预先理解的陷阱,文档用专门小节讲它。批量订单的取消有两条路:第一条是 cancel,但它只认单张——一次批量挂出 4 张订单,就要发 4 笔 cancel 交易才能各自作废;第二条是 incrementCounter,把你自己的订单序号推一格,所有以当前序号签出的订单一次性全部失去可履约性,代价是不挑对手——你在别处正常挂着的单也一起阵亡。v1.2 还改了这个函数的行为:counter 不再顺序加一,而是跳到一个由上一个区块哈希派生的准随机值。改动的防线的确具体:如果计数器还是逐格递增,攻击者可以诱你签一份恶意批量载荷,里面的订单在“现在”和“未来若干个序号”下都成立;改成大跳的随机值之后,一次 incrementCounter 就像硬重置,把恶意签名的影响面整个甩开。

把这些规则合成操作手册就是四句话。挂单前:批量载荷是 EIP-712 可读数据,钱包弹窗里认真读订单数量与合约地址,一次签名管住的就是整棵树。挂单中:批量越大对家履约越贵,深批量适合“同一套条款铺量”,别把异构订单硬塞一棵树。撤单时:只撤几张就逐张 cancel 并接受多笔交易费;要彻底清场就 incrementCounter,但记住它会带走你所有在挂订单。日常习惯:文档建议优先创建“短命”订单而不是偶尔挂一茬长命单——频繁重签短单,等于把 counter 这张核按钮留到最后才用。批量优化的是签名次数,不改变每笔订单各自可撤、可履约、可被拒的本质。

再补一个批量签名的实操视角。文档强调批量载荷是带类型的 EIP-712 数据,理论上钱包弹窗应能展示订单结构;现实里多数钱包对深层批量只给出摘要行,用户看到的常是“一份签名、若干物品”的压缩视图。这就产生一个具体的核验动作:在钱包签名前,用市场提供的订单预览或链上只读接口把批量清单展开,核对每个 tokenId 是否都在你想挂的集合里、有没有被夹进陌生合约的单张订单。批量树的结构特性决定了这层人工展开不可省略——一次 ECDSA 签名锁住的是整棵树的根,树里任何一张叶子的错误都会跟着你一起生效。反过来看,这也是批量挂单真正的成本:它把“每单一次人工确认”变成了“一次确认覆盖全部”,省下的弹窗次数,本质是用注意力集中度换回来的。老练的挂单习惯是按集合分组批量、给每批设较短过期时间,让错误签名的暴露窗口天然收敛,比事后 incrementCounter 硬重置体面得多。

本文为机制说明,不构成任何投资建议,也不构成对任何平台、合约或标准实现的背书。文中功能与规则描述以对应版本的官方文档为准,阅读时可能存在版本滞后。

Seaport 批量签名:一次签名最多铺一千六百万张订单,撤单却只认单张 图 2
Seaport 批量签名:一次签名最多铺一千六百万张订单,撤单却只认单张 · 图 2