Wyvern 订单匹配协议

本文讨论 OpenSea 中使用的 Wyvern 协议 的订单匹配过程,该过程主要是用户和 Wyvern Exchange Contract 的交互。

匹配过程围绕 买/卖双方的订单 展开。卖方创建销售订单,以固定价格或者竞拍的方式,将 NFT 挂出去;买方创建购买订单,并将卖方创建的销售订单一起,发给交换合约 Wyvern Exchange Contract。交换合约将对订单校验,校验通过后,完成两个转移:

  • 支付费用转移;
  • NFT 产品转移。

1 概述

交易过程,主要涉及订单 Order(Order 实体/ Order 参数校验/ Order 校验),费用转移,NFT 转移,因此,本文也将按照这样的顺序展开。

2 订单(Order)

2.1 订单实体

订单实体定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
struct Order {
// 交换合约 Wyvern Exchange Contracrt 的地址
address exchange;
// 订单创建者,对于卖方订单来说,是卖方账户;对于买方订单来说,是买方账户
address maker;
// 订单另一方,即,订单参与者。对于卖单,该地址为零地址;对于买单,该地址是卖方账户地址
address taker;
// 订单创建者需要支付的 relayerFee,这部分费用支付给了平台方
uint makerRelayerFee;
// 订单参与方需要支付的 relayerFee,费用仍然是支付给了平台方
uint takerRelayerFee;
// 订单创建者需要支付的协议费,这部分费用将支付给 Wyvern
uint makerProtocolFee;
// 订单参与者方需要支付的协议费,这部分费用将支付给 Wyvern
uint takerProtocolFee;
// 平台方费用接收账户
address feeRecipient;
// 费用收取方法:只用支付协议费,或者是需要同时支付协议费和平台费
FeeMethod feeMethod;
// 该订单是卖方单还是买方单
SaleKindInterface.Side side;
// 销售方式是固定价格,还是采用竞拍的方式
SaleKindInterface.SaleKind saleKind;
// 需要借助该账户,完成 NFT 转移
address target;
// 调用方式是 call 还是 delegatecall
AuthenticatedProxy.HowToCall howToCall;
// target 执行时的 calldata
bytes calldata;
/* Calldata replacement pattern, or an empty byte array for no replacement. */
bytes replacementPattern;
// 静态调用(不修改状态)的 target 账户地址;为 0 表示没有这种调用
address staticTarget;
// 静态调用时设置的额外数据,最终交给 staticTarget 处理
bytes staticExtradata;
// 该地址为 0 ,表示使用 ether 支付,否则,表示使用一个 erc20 token 支付
address paymentToken;
/* Base price of the order (in paymentTokens). */
// 如果是 saleKind 固定价格,则该值就表示固定价格;否则,真正的价格,还包括 extra 部分. 价格单位为 Wei
uint basePrice;
// 竞拍方式下,extra 表示需要额外的最大值. 价格单位为 Wei
uint extra;
// 挂单时间
uint listingTime;
// 订单过期失效时间
uint expirationTime;
// 给订单加盐,防止 hash 重复
uint salt;
}

在订单中,根据销售方式不同,订单中销售价格的确定流程为:

由于在卖单/买单中,都会存在价格计算,因此,最终最后的价格结算,是根据下述流程过程的:

注意,最终的出来的价格,就是会转给卖家的价格。
但是,protocolFee 和 relayerFee 都并不包含在这个价格里,这两个费用由买卖双方根据订单中的相关记录自己出。对于每一种 fee,卖家订单中订单中 feeRecipient 为有效地址,卖家需要支付 makerRelayerFee 给 feeRecipient,买家需要支付 takerRelayerFee 给 feeRecipient,反之亦然。对于 protocolFee,逻辑亦是如此。

实际上,在 OpenSea 的实践中,卖方 feeRecipient 为合法地址,makerRelayerFee 为 250,takerRelayerFee 为 0,因此,只有卖方支付了 relayerFee 给 OpenSea,支付的金额是其收入的 2.5%。买方没有其它额外支付。

2.2 订单构建

用户在与 Wyvern Exchange Contract 交互,需要完成订单匹配时,需要将 买/卖 双方的订单都传递给交互合约。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function atomicMatch_(
address[14] addrs,uint[18] uints,uint8[8] feeMethodsSidesKindsHowToCalls,bytes calldataBuy,bytes calldataSell,bytes replacementPatternBuy,bytes replacementPatternSell,bytes staticExtradataBuy,bytes staticExtradataSell,uint8[2] vs,bytes32[5] rssMetadata)
public
payable
{

return atomicMatch(
// 买单
Order(addrs[0], addrs[1], addrs[2], uints[0], uints[1], uints[2], uints[3], addrs[3], FeeMethod(feeMethodsSidesKindsHowToCalls[0]), SaleKindInterface.Side(feeMethodsSidesKindsHowToCalls[1]), SaleKindInterface.SaleKind(feeMethodsSidesKindsHowToCalls[2]), addrs[4], AuthenticatedProxy.HowToCall(feeMethodsSidesKindsHowToCalls[3]), calldataBuy, replacementPatternBuy, addrs[5], staticExtradataBuy, ERC20(addrs[6]), uints[4], uints[5], uints[6], uints[7], uints[8]),
// 签名
Sig(vs[0], rssMetadata[0], rssMetadata[1]),
// 卖单
Order(addrs[7], addrs[8], addrs[9], uints[9], uints[10], uints[11], uints[12], addrs[10], FeeMethod(feeMethodsSidesKindsHowToCalls[4]), SaleKindInterface.Side(feeMethodsSidesKindsHowToCalls[5]), SaleKindInterface.SaleKind(feeMethodsSidesKindsHowToCalls[6]), addrs[11], AuthenticatedProxy.HowToCall(feeMethodsSidesKindsHowToCalls[7]), calldataSell, replacementPatternSell, addrs[12], staticExtradataSell, ERC20(addrs[13]), uints[13], uints[14], uints[15], uints[16], uints[17]),
// 签名
Sig(vs[1], rssMetadata[2], rssMetadata[3]),
rssMetadata[4]
);
}

2.3 订单校验

订单校验,可以分为参数校验和订单合法性校验。
参数校验过程如下:

订单合法性校验过程如下:

可以看到,合法性校验包含了参数校验。
这两种校验方式,分别用于两种不同的场景,如果交易发起者是买家,买家只需要进行参数校验,反之,需要进行合法性校验,验证订单的签名。
这是一种减少不必要 gas 消耗的过程。

3 费用支付

费用是由卖单中的 feeMethod 指定的,收取方式有两种:

  • SplitFee: 根据卖方或者买方中的订单记录(二选一),买卖双方按照卖方订单中指定的支付币种(ether 或 erc20 token)各自支付 RelayerFee 给订单指定的 FeeRecipient,由买卖双方各自支付 ProtocolFee 给交易合约(Wyvern Exchange Contract)中指定的 protocolFeeRecipient.
  • ProtocolFee: 根据卖方或者买方中的订单记录,使用交易合约中指定的 exchangeToken 支付

在 OpenSea 平台上,makerRelayerFee 为 250,且只是从卖家收入中扣除,因此,其收入为交易额度的 2.5%,protocolFee 为 0,暂时还是没有给 Wyvern 协议费。

4 交易转账

NFT 交易需要转账。

5 NFT 转移

参考链接:
Wyvern 官网关于授权订单的介绍

© 2024 YueGS