一张订单也能拆着成交:Wyvern 协议的部分成交与谓词订单 图 1
一张订单也能拆着成交:Wyvern 协议的部分成交与谓词订单 · 图 1

从零阶到一阶:订单语言的代际差

Wyvern 官方文档把自己的定位说得很学术:一个”一阶”(first-order)去中心化交易所协议。作为对照,它点名 0x、Etherdelta 这类协议是”零阶”的——每一张订单只描述一次离散资产的兑换,通常是一对代币按固定比例成交。Wyvern 的订单不是描述”换什么”,而是描述一组”在什么条件下成交才算数”的谓词:一张订单是对maker 的调用、对手方的调用和订单元数据这三个输入的函数,输出是真或假。换句话说,订单声明的是可接受状态迁移的集合,而不是一条具体报价。

这个差别在 NFT 场景里立刻显出价值。ERC-721 代币不可分割,“卖一枚特定 NFT”在零阶语言里只能写成一次性兑换;而”我愿意以不低于某价出售这个系列里任意一枚""允许拆分成交”这类偏好,只有谓词语言才表达得出来。后来 NFT 市场普遍支持的批量收单、按属性收单,谱系上都能追溯到这种订单表达力。

部分成交:只对”最多卖多少”签名

文档里最能落地到日常体验的是部分成交订单(Partial Fill Orders)的设计:订单签名覆盖的是一个最大成交量,静态调用返回撮合后的剩余成交值,订单的当前已成交量也可以由合约所有者手动设置。翻译一下:卖家签一张”最多卖 10 份”的 ERC-1155 订单,买家 A 买走 3 份、买家 B 买走 4 份,订单仍然有效、剩余 3 份额度继续挂在市场上;不需要每个买家付一次签名、也不需要重签。对纯 721 市场这条看起来用不上,但它正是”一次签名、多人分批吃单”的最早工程答案,也是后来 ERC-721A 批量铸造、批量挂单讨论绕不开的前置实验。

文档还提到对部分成交订单的签名校验结果会被缓存,避免重复的签名检查——这是把 Gas 账算进协议层的细节。

谓词订单的代价

表达能力从来不是免费的。零阶订单的检查逻辑一眼能看完:代币对不对、价格够不够、签名真不真。谓词订单则要执行一段合约代码去评估条件,评估本身消耗 Gas,写错的谓词还可能留下意外的攻击面——一段可以替卖家执行任意调用的条件逻辑,既是功能也是风险敞口。这也是后来主流市场在 Seaport 这类协议里把表达能力收回”结构化字段”(集合地址、编号、属性条件、起止价)而不是任意函数的原因之一:表达力减一档,可审计性高一档。理解这条权衡,比记住 Wyvern 这个名字更有用——你今天在每个市场看到的”按属性收单""批量买”,都是这条钟摆摆到中间位置的产物。

代理账户与授权链

Wyvern 的订单必须由 maker 授权,而实际执行调用的是 maker 的代理合约(proxy)。授权方式有两种:用 EIP-712 类型的链下签名逐单授权,或者一次性授权一个哈希表。这解释了老用户在区块浏览器里看到的一个常见疑惑:为什么 NFT 市场里的操作大多不是”你的钱包直接调市场合约”,而是”市场调你的代理合约,代理再调代币合约”。这个代理结构后来被大量市场继承,成为 NFT 交易免预授权挂单的通用底座。

今天还值得读它的理由

Wyvern 本体早已淡出一线,但它定义的问题一个没消失:订单到底是对价格的承诺还是对条件的承诺、签名应该覆盖意图的哪一部分、一部分成交之后残量归谁。任何一个在 NFT 市场挂过批量收单的人,其实都在使用这场实验的后代。理解订单”只对上限签名”的边界,也能帮你在签名弹窗前多一分警觉:一张订单被签掉时,你让渡的不是一笔交易,而是一类交易的可能性。本文只整理协议文档内容,不涉及任何平台推荐或投资建议。