Seaport V2.0文档翻译

Web3.0  收藏
0 / 165

Seaport

https://docs.opensea.io/v2.0/reference/seaport-overview

image.png
image.png

Seaport 是一个市场合同,用于安全有效地创建和履行 ERC721 和 ERC1155 项目的订单。每个订单包含供应商愿意提供的任意数量的物品(“offer”卖的东西)以及必须与其各自的接收者提供的任意数量的物品(“consideration”买家要付给其他人的钱)。
Seaport is a marketplace contract for safely and efficiently creating and fulfilling orders for ERC721 and ERC1155 items. Each order contains an arbitrary number of items that the offerer is willing to give (the "offer") along with an arbitrary number of items that must be received along with their respective receivers (the "consideration").

订单 Order

每个订单包含十一个关键组件:Each order contains eleven key components:

  • 订单的提供所有提供的物品,并且必须亲自履行订单(即)或通过签名(标准的 65 字节 EDCSA、64 字节 EIP-2098 或 EIP-1271 支票)或列出链上订单(即调用)。offerer``msg.sender == offerer``isValidSignature``validate

  • The offerer of the order supplies all offered items and must either fulfill the order personally (i.e. msg.sender == offerer) or approve the order via signature (either standard 65-byte EDCSA, 64-byte EIP-2098, or an EIP-1271 isValidSignature check) or by listing the order on-chain (i.e. calling validate).

  • 订单的区域是附加到订单的可选辅助帐户,具有两个额外的权限:zone

    • 该区域可以通过调用来取消它被命名为该区域的订单。(请注意,提供者也可以取消他们自己的订单,可以单独取消,也可以通过调用 立即取消所有使用当前 nonce 签名的订单)。cancel``incrementNonce
    • “受限”订单(由订单类型指定)必须由区域或要约人执行,或者必须通过调用区域上的或查看功能所指示的方式获得批准。isValidOrder``isValidOrderIncludingExtraData
    • The zone of the order is an optional secondary account attached to the order with two additional privileges:* The zone may cancel orders where it is named as the zone by calling cancel. (Note that offerers can also cancel their own orders, either individually or for all orders signed with their current nonce at once by calling incrementNonce).
  • "Restricted" orders (as specified by the order type) must either be executed by the zone or the offerer, or must be approved as indicated by a call to an isValidOrder or isValidOrderIncludingExtraData view function on the zone.

  • offer 包含可以从提供者帐户转移的一系列项目,其中每个项目由以下组件组成:

    • itemType :指定项目的类型,有效类型为 Ether(或给定链的其他原生代币)、ERC20、ERC721、ERC1155、ERC721 与“标准”(如下所述),以及 ERC1155 与标准。
    • token:指定项目代币合约的账户(空地址用于以太币或其他原生代币)。
    • identifierOrCriteria :表示 ERC721 或 ERC1155 令牌标识符,或者在基于标准的项目类型的情况下,表示由项目的有效令牌标识符集组成的 merkle 根。对于 Ether 和 ERC20 项目类型,此值将被忽略,并且对于基于标准的项目类型可以选择为零以允许任何标识符。
    • startAmount : 表示如果在订单激活时完成订单,则需要的相关项目的数量。
    • endAmount 表示如果在订单到期时履行订单,将需要的相关项目的数量。如果此值与 startAmount 项目的值不同,则根据订单激活后经过的时间线性计算已实现金额。

The offer contains an array of items that may be transferred from the offerer's account, where each item consists of the following components:* The itemType designates the type of item, with valid types being Ether (or other native token for the given chain), ERC20, ERC721, ERC1155, ERC721 with "criteria" (explained below), and ERC1155 with criteria.

  • The token designates the account of the item's token contract (with the null address used for Ether or other native tokens).

  • The identifierOrCriteria represents either the ERC721 or ERC1155 token identifier or, in the case of a criteria-based item type, a merkle root composed of the valid set of token identifiers for the item. This value will be ignored for Ether and ERC20 item types, and can optionally be zero for criteria-based item types to allow for any identifier.

  • The startAmount represents the amount of the item in question that will be required should the order be fulfilled at the moment the order becomes active.

  • The endAmount represents the amount of the item in question that will be required should the order be fulfilled at the moment the order expires. If this value differs from the item's startAmount, the realized amount is calculated linearly based on the time elapsed since the order became active.

  • consideration 包含为完成订单而必须接收的一系列项目。它包含与提供的项目相同的所有组件,并且还包括一个将接收每个项目的组件 recipient。该数组可以由履行者在订单履行时扩展,以支持“小费”(例如中继者或推荐支付)。

  • The consideration contains an array of items that must be received in order to fulfill the order. It contains all of the same components as an offered item, and additionally includes a recipient that will receive each item. This array may be extended by the fulfiller on order fulfillment so as to support "tipping" (e.g. relayer or referral payments).

  • orderType 根据两个不同的偏好,指定订单的四种类型之一:

    • FULL 表示订单不支持部分填充,而 PARTIAL 允许填充订单的一部分,重要的警告是每个项目必须被提供的分数完全整除(即除法后没有余数)。
    • OPEN 指示执行订单的调用可以由任何账户提交,而 RESTRICTED 要求订单要么由要约人执行,要么由订单所在区域执行,或者调用 isValidOrder 或 isValidOrderIncludingExtraData 在区域上的查看功能。
  • startTime 指示订单激活的区块时间戳。

  • endTime 指示订单到期的区块时间戳。该值 和 startTime 与每个项目的 startAmount``endAmount 一起使用以得出它们的当前金额。

  • zoneHash 表示一个任意的 32 字节值,当执行受限订单时,该值将提供给区域,区域在确定是否授权订单时可以使用该值。

  • salt 表示订单的任意熵源。

  • conduitKey 是一个 bytes32 值,指示在执行转移时应将哪个管道(如果有)用作令牌批准的来源。默认情况下(即当设置为零散列时),offer 方将直接向 Seaport 授予 ERC20、ERC721 和 ERC1155 令牌批准,以便它可以在履行期间执行订单指定的任何转移。相反,选择使用管道的提议者将授予与提供的管道密钥相对应的管道合同的代币批准,然后 seaport 将指示该管道转移相应的代币。

  • nonce 指示必须与给定提议者的当前随机数匹配的值。

The orderType designates one of four types for the order depending on two distinct preferences:
FULL indicates that the order does not support partial fills, whereas PARTIAL enables filling some fraction of the order, with the important caveat that each item must be cleanly divisible by the supplied fraction (i.e. no remainder after division).
OPEN indicates that the call to execute the order can be submitted by any account, whereas RESTRICTED requires that the order either be executed by the offerer or the zone of the order, or that a magic value indicating that the order is approved is returned upon calling an isValidOrder or isValidOrderIncludingExtraData view function on the zone.

The startTime indicates the block timestamp at which the order becomes active.
The endTime indicates the block timestamp at which the order expires. This value and the startTime are used in conjunction with the startAmount and endAmount of each item to derive their current amount.
The zoneHash represents an arbitrary 32-byte value that will be supplied to the zone when fulfilling restricted orders that the zone can utilize when making a determination on whether to authorize the order.
The salt represents an arbitrary source of entropy for the order.
The conduitKey is a bytes32 value that indicates what conduit, if any, should be utilized as a source for token approvals when performing transfers. By default (i.e. when conduitKey is set to the zero hash), the offerer will grant ERC20, ERC721, and ERC1155 token approvals to Seaport directly so that it can perform any transfers specified by the order during fulfillment. In contrast, an offerer that elects to utilize a conduit will grant token approvals to the conduit contract corresponding to the supplied conduit key, and Seaport will then instruct that conduit to transfer the respective tokens.
The nonce indicates a value that must match the current nonce for the given offerer.

订单完成度 Order Fulfillment

订单通过以下四种方法之一完成: Orders are fulfilled via one of four methods:

  • 调用两个“标准”函数中的一个,fulfillOrder``fulfillAdvancedOrder,其中将构造第二个隐含订单,调用者作为要约人,已履行订单的 consideration 作为要约,已履行订单的要约作为 consideration(使用“高级” 订单包含应与一组“标准解析器”一起填写的部分,这些“标准解析器”为已履行订单上的每个基于标准的项目指定一个标识符和相应的包含证明)。所有 offer 项目将从订单的提供者转移到履行者,然后所有 consideration 项目将从履行者转移到指定的接收者。

Calling one of two "standard" functions, fulfillOrder and fulfillAdvancedOrder, where a second implied order will be constructed with the caller as the offerer, the consideration of the fulfilled order as the offer, and the offer of the fulfilled order as the consideration (with "advanced" orders containing the fraction that should be filled alongside a set of "criteria resolvers" that designate an identifier and a corresponding inclusion proof for each criteria-based item on the fulfilled order). All offer items will be transferred from the offerer of the order to the fulfiller, then all consideration items will be transferred from the fulfiller to the named recipient.

  • 调用“基本”函数,fulfillBasicOrder 提供六种基本路线类型之一(ETH_TO_ERC721``ETH_TO_ERC1155``ERC20_TO_ERC721``ERC20_TO_ERC1155``ERC721_TO_ERC20``ERC1155_TO_ERC20),将从组件子集派生要履行的订单,假设相关订单符合以下条件:
    • 该订单仅包含一个 offer 项目,并且包含至少一个 consideration 项目。
    • 该订单仅包含一个 ERC721 或 ERC1155 项目,并且该项目不是基于标准的。
    • 订单的提供者是第一 consideration 项目的接收者。
    • 所有其他物品都具有相同的以太币(或其他原生代币)或 ERC20 物品类型和代币。
    • 该订单不提供以以太币(或其他原生代币)作为其商品类型的商品。
    • 每个项目上的 startAmount``endAmount 必须与该项目匹配(即项目不能有升序/降序数量)。
    • 所有“忽略”的项目字段(即 token``identifierOrCriteria 原生项目和 identifierOrCriteria ERC20 项目)都设置为空地址或零。
    • 如果订单中有 ERC721 商品,则该商品的金额为。1
    • 如果订单有多个 consideration 项目,且除第一 consideration 项目外的所有 consideration 项目与 offer 项目的项目类型相同,offer 项目数量不小于除第一 consideration 项目数量外的所有 consideration 项目数量之和。

Calling the "basic" function, fulfillBasicOrder with one of six basic route types supplied (ETH_TO_ERC721, ETH_TO_ERC1155, ERC20_TO_ERC721, ERC20_TO_ERC1155, ERC721_TO_ERC20, and ERC1155_TO_ERC20) will derive the order to fulfill from a subset of components, assuming the order in question adheres to the following:
The order only contains a single offer item and contains at least one consideration item.
The order contains exactly one ERC721 or ERC1155 item and that item is not criteria-based.
The offerer of the order is the recipient of the first consideration item.
All other items have the same Ether (or other native tokens) or ERC20 item type and token.
The order does not offer an item with Ether (or other native tokens) as its item type.
The startAmount on each item must match that item's endAmount (i.e. items cannot have an ascending/descending amount).
All "ignored" item fields (i.e. token and identifierOrCriteria on native items and identifierOrCriteria on ERC20 items) are set to the null address or zero.
If the order has an ERC721 item, that item has an amount of 1.
If the order has multiple consideration items and all consideration items other than the first consideration item have the same item type as the offered item, the offered item amount is not less than the sum of all consideration item amounts excluding the first consideration item amount.

  • 调用两个“可用履行”函数中 fulfillAvailableOrders``fulfillAvailableAdvancedOrders的一个,并且,其中一组订单与一组履行一起提供,指定哪些offer项目可以聚合到不同的转移中,哪些consideration项目可以相应地聚合,以及任何订单已经已取消、有无效时间或已被完全执行将被跳过,而不会导致其余可用订单恢复。此外,一旦找到 maximumFulfilled 可用订单,任何剩余的订单都将被跳过。与标准履行方法类似,所有offer项目将从各自的offer者转移到履行者,然后所有consideration项目将从履行者转移到指定的接收者。

Calling one of two "fulfill available" functions, fulfillAvailableOrders and fulfillAvailableAdvancedOrders, where a group of orders are supplied alongside a group of fulfillments specifying which offer items can be aggregated into distinct transfers and which consideration items can be accordingly aggregated, and where any orders that have been cancelled, have an invalid time, or have already been fully filled will be skipped without causing the rest of the available orders to revert. Additionally, any remaining orders will be skipped once maximumFulfilled available orders have been located. Similar to the standard fulfillment method, all offer items will be transferred from the respective offerer to the fulfiller, then all consideration items will be transferred from the fulfiller to the named recipient.

  • 调用两个“匹配”函数中的一个,并且,matchOrders``matchAdvancedOrders 其中一组明确的订单与一组履行指定哪些 offer 项目适用于哪些 consideration 项目一起提供(并且“高级”案例以与标准类似的方式运行方法,但支持通过提供的 numerator``denominator 和小数值以及一个可选 extraData 参数进行部分填充,当满足受限订单类型时,该参数 isValidOrderIncludingExtraData 将作为调用区域上的视图函数的一部分提供)。请注意,以这种方式履行的订单没有明确的履行者;相反,Seaport 将简单地确保每个订单的需求一致。

Calling one of two "match" functions, matchOrders and matchAdvancedOrders, where a group of explicit orders are supplied alongside a group of fulfillments specifying which offer items to apply to which consideration items (and with the "advanced" case operating in a similar fashion to the standard method, but supporting partial fills via supplied numerator and denominator fractional values as well as an optional extraData argument that will be supplied as part of a call to the isValidOrderIncludingExtraData view function on the zone when fulfilling restricted order types). Note that orders fulfilled in this manner do not have an explicit fulfiller; instead, Seaport will simply ensure coincidence of wants across each order.
虽然标准方法在技术上可用于履行任何订单,但在某些情况下存在关键效率限制:
While the standard method can technically be used for fulfilling any order, it suffers from key efficiency limitations in certain scenarios:

  • 与简单“热路径”的基本方法相比,它需要额外的调用数据。
  • 它要求履行者批准每个 consideration 项目,即使 consideration 项目可以使用 offer 项目来履行(在履行为 ERC721 或 ERC1155 项目提供 ERC20 项目并且还包括具有相同的 consideration 项目的订单时通常是这种情况用于支付费用的 ERC20 项目类型)。
  • 它可能导致不必要的转移,而在“匹配”情况下,这些转移可以减少到更小的集合。
    It requires additional calldata compared to the basic method for simple "hot paths".
    It requires the fulfiller to approve each consideration item, even if the consideration item can be fulfilled using an offer item (as is commonly the case when fulfilling an order that offers ERC20 items for an ERC721 or ERC1155 item and also includes consideration items with the same ERC20 item type for paying fees).
    It can result in unnecessary transfers, whereas in the "match" case those transfers can be reduced to a more minimal set.

余额和批准要求 Balance & Approval Requirements

创建 offer 时,应检查以下要求以确保订单可以履行:
When creating an offer, the following requirements should be checked to ensure that the order will be fulfillable:

  • 提供者应在所有提供的项目中有足够的余额。
    The offerer should have sufficient balance of all offered items.
  • 如果订单未指示使用管道,则要约人应为所有提供的 ERC20、ERC721 和 ERC1155 项目的 Seaport 合同设置足够的批准。
    If the order does not indicate to use a conduit, the offerer should have sufficient approvals set for the Seaport contract for all offered ERC20, ERC721, and ERC1155 items.
  • 如果订单确实表明使用管道,则要约人应为所有提供的 ERC20、ERC721 和 ERC1155 项目的相应管道合同设置足够的批准。
    If the order does indicate to use a conduit, the offerer should have sufficient approvals set for the respective conduit contract for all offered ERC20, ERC721 and ERC1155 items.

履行基本订单时,需要检查以下要求以确保订单可以履行:
When fulfilling a basic order, the following requirements need to be checked to ensure that the order will be fulfillable:

  • 需要进行上述检查以确保要约人仍有足够的余额和批准。
  • 履行者应该对所有 consideration 项目有足够的余额,除了那些项目类型与订单提供的项目类型相匹配的项目——例如,如果履行的订单提供 ERC20 项目,并且要求提供者提供 ERC721 项目和相同的 ERC20 项目到另一个收件人,履行者需要拥有 ERC721 项目,但不需要拥有 ERC20 项目,因为它将来自提供者。
  • 如果履行者不选择使用管道,他们需要为已履行订单上的所有 ERC20、ERC721 和 ERC1155 consideration 项目设置足够的 seaport 合同批准,但项目类型与订单提供的项目匹配的 ERC20 项目除外类型
  • 如果履行者确实选择使用管道,则他们需要为已履行订单上的所有 ERC20、ERC721 和 ERC1155 consideration 项目为其各自的管道设置足够的批准,但项目类型与订单提供的项目类型匹配的 ERC20 项目除外.
  • 如果已履行的订单将以太币(或其他原生代币)指定为 consideration 项目,则履行者必须能够将这些项目的总和提供为 msg.value
    The above checks need to be performed to ensure that the offerer still has sufficient balance and approvals.
    The fulfiller should have sufficient balance of all consideration items except for those with an item type that matches the order's offered item type — by way of example, if the fulfilled order offers an ERC20 item and requires an ERC721 item to the offerer and the same ERC20 item to another recipient, the fulfiller needs to own the ERC721 item but does not need to own the ERC20 item as it will be sourced from the offerer.
    If the fulfiller does not elect to utilize a conduit, they need to have sufficient approvals set for the Seaport contract for all ERC20, ERC721, and ERC1155 consideration items on the fulfilled order except for ERC20 items with an item type that matches the order's offered item type.
    If the fulfiller does elect to utilize a conduit, they need to have sufficient approvals set for their respective conduit for all ERC20, ERC721, and ERC1155 consideration items on the fulfilled order except for ERC20 items with an item type that matches the order's offered item type.
    If the fulfilled order specifies Ether (or other native tokens) as consideration items, the fulfiller must be able to supply the sum total of those items as msg.value.

履行标准订单时,需要检查以下要求以确保订单可以履行:
When fulfilling a standard order, the following requirements need to be checked to ensure that the order will be fulfillable:

  • 需要进行上述检查以确保要约人仍有足够的余额和批准。
  • 在收到所有提供的物品后,履行者应该对所有 consideration 项目有足够的余额——例如,如果履行的订单提供了 ERC20 物品,并且需要向提供者提供 ERC721 物品,并且向另一个接收者提供相同的 ERC20 物品,金额小于或等于提供的金额,履行者不需要拥有 ERC20 项目,因为它将首先从提供者处收到。
  • 如果履行者不选择使用管道,他们需要为已履行订单上的所有 ERC20、ERC721 和 ERC1155 consideration 项目的 seaport 合同设置足够的批准。
  • 如果履行者确实选择使用管道,则他们需要为已履行订单上的所有 ERC20、ERC721 和 ERC1155 consideration 项目为其各自的管道设置足够的批准。
  • 如果已履行的订单将以太币(或其他原生代币)指定为 consideration 项目,则履行者必须能够将这些项目的总和提供为。msg.value
    The above checks need to be performed to ensure that the offerer still has sufficient balance and approvals.
    The fulfiller should have sufficient balance of all consideration items after receiving all offered items — by way of example, if the fulfilled order offers an ERC20 item and requires an ERC721 item to the offerer and the same ERC20 item to another recipient with an amount less than or equal to the offered amount, the fulfiller does not need to own the ERC20 item as it will first be received from the offerer.
    If the fulfiller does not elect to utilize a conduit, they need to have sufficient approvals set for the Seaport contract for all ERC20, ERC721, and ERC1155 consideration items on the fulfilled order.
    If the fulfiller does elect to utilize a conduit, they need to have sufficient approvals set for their respective conduit for all ERC20, ERC721, and ERC1155 consideration items on the fulfilled order.
    If the fulfilled order specifies Ether (or other native tokens) as consideration items, the fulfiller must be able to supply the sum total of those items as msg.value.

在履行一组匹配订单时,需要检查以下要求以确保订单可以履行:
When fulfilling a set of match orders, the following requirements need to be checked to ensure that the order will be fulfillable:

  • 为将作为履行的一部分执行的执行采购 ERC20、ERC721 或 ERC1155 项目的每个帐户必须在触发执行时在 Seaport 或指定的渠道上具有足够的余额和批准。请注意,先前的执行可能会为后续执行提供必要的平衡。
  • 涉及以太币(或其他原生代币)的所有执行的总和必须以。 请注意,提供者和接收者是同一帐户的执行将从最终执行集中被过滤掉。msg.value
    Each account that sources the ERC20, ERC721, or ERC1155 item for an execution that will be performed as part of the fulfillment must have sufficient balance and approval on Seaport or the indicated conduit at the time the execution is triggered. Note that prior executions may supply the necessary balance for subsequent executions.
    The sum total of all executions involving Ether (or other native tokens) must be supplied as msg.value. Note that executions where the offerer and the recipient are the same account will be filtered out of the final execution set.

部分填充 Partial Fills

在构建订单时,offer 方可以选择通过设置适当的订单类型来启用部分成交。然后,支持部分执行的订单可以在相应订单的一部分中执行,从而允许后续执行绕过签名验证。总结一下部分填充的几个关键点:
When constructing an order, the offerer may elect to enable partial fills by setting an appropriate order type. Then, orders that support partial fills can be fulfilled for some fraction of the respective order, allowing subsequent fills to bypass signature verification. To summarize a few key points on partial fills:

  • 当创建支持部分成交的定单或确定要在这些定单上成交的分数时,定单上的所有项目(offer 和 consideration)必须完全可被提供的分数整除(即除法后没有余数)。
  • 如果要填写的所需部分会导致要填写的订单数量超过全部订单数量,则该部分将减少为剩余要填写的数量。这适用于部分填充尝试和完全填充尝试。如果不需要这种行为(即填充应该是“全部或无”),则履行者可以使用“基本”订单方法(如果可用)(这需要填写全部订单金额),或使用“匹配” order 方法,并明确提供一个要求收到全部所需金额的订单。
    • 举例来说:如果一个履行者尝试履行订单的 1/2,但另一个履行者首先履行订单的 3/4,则原始履行者最终将履行订单的 1/4。
  • 如果部分可成交订单上的任何项目指定了不同的“startAmount”和“endAmount”(例如,它们是递增数量或递减数量的项目),则在确定当前价格之前,该分数将应用于这两个数量。这确保了在构建订单时可以选择完全可分的数量,而不依赖于最终完成订单的时间。
  • 部分填写可以与基于标准的项目组合,以支持构建提供或接收多个项目的订单,否则这些项目将无法部分填写(例如 ERC721 项目)。
    • 举个例子:offer 者可以创建一个部分可成交的订单,为给定集合中最多 10 个 ERC721 项目提供最多 10 个 ETH;然后,任何履行者都可以履行该订单的一部分,直到它被完全履行(或取消)。
      When creating orders that support partial fills or determining a fraction to fill on those orders, all items (both offer and consideration) on the order must be cleanly divisible by the supplied fraction (i.e. no remainder after division).
      If the desired fraction to fill would result in more than the full order amount being filled, that fraction will be reduced to the amount remaining to fill. This applies to both partial fill attempts as well as full fill attempts. If this behavior is not desired (i.e. the fill should be "all or none"), the fulfiller can either use a "basic" order method if available (which requires that the full order amount be filled), or use the "match" order method and explicitly provide an order that requires the full desired amount be received back.
      By way of example: if one fulfiller tries to fill 1/2 of an order but another fulfiller first fills 3/4 of the order, the original fulfiller will end up filling 1/4 of the order.
      If any of the items on a partially fillable order specify a different "startAmount" and "endAmount (e.g. they are ascending-amount or descending-amount items), the fraction will be applied to both amounts prior to determining the current price. This ensures that cleanly divisible amounts can be chosen when constructing the order without a dependency on the time when the order is ultimately fulfilled.
      Partial fills can be combined with criteria-based items to enable constructing orders that offer or receive multiple items that would otherwise not be partially fillable (e.g. ERC721 items).
      By way of example: an offerer can create a partially fillable order to supply up to 10 ETH for up to 10 ERC721 items from a given collection; then, any fulfiller can fill a portion of that order until it has been fully filled (or cancelled).

Sequence of Events 事件顺序

履行订单 Fulfill Order

通过 fulfillOrder``fulfillAdvancedOrder 履行订单

  1. 哈希顺序

    • 为 offer 项目和 consideration 项目派生哈希
    • 检索提议者的当前随机数
    • 导出订单哈希
      Hash order
      Derive hashes for offer items and consideration items
      Retrieve current nonce for the offerer
      Derive hash for order
  2. 执行初始验证

    • 确保当前时间在订单范围内
    • 确保订单类型的调用者有效;如果订单类型受限且调用方不是 offerer 或 zone,调用 zone 判断订单是否有效
      Perform initial validation
      Ensure current time is inside order range
      Ensure valid caller for the order type; if the order type is restricted and the caller is not the offerer or the zone, call the zone to determine whether the order is valid
  3. 检索和更新订单状态

    • 确保订单不被取消
    • 确保订单未满
      • 如果订单部分成交,必要时减少提供的成交量,以免订单被超额成交
    • 如果尚未验证,请验证订单签名
    • 根据偏好 + 可用数量确定要填充的分数
    • 更新订单状态(已验证 + 成交率)
      Retrieve and update order status
      Ensure order is not cancelled
      Ensure order is not fully filled
      If the order is partially filled, reduce the supplied fill amount if necessary so that the order is not overfilled
      Verify the order signature if not already validated
      Determine fraction to fill based on preference + available amount
      Update order status (validated + fill fraction)
  4. 确定每个项目的金额

    • 比较起始金额和结束金额
      • 如果它们相等:将填充分数应用于任何一个,确保它干净地划分,并使用该数量
      • 如果不是:将填充分数应用于两者,确保它们都干净地划分,然后根据当前时间找到线性拟合
        Determine amount for each item
        Compare start amount and end amount
        if they are equal: apply fill fraction to either one, ensure it divides cleanly, and use that amount
        if not: apply fill fraction to both, ensuring they both divide cleanly, then find linear fit based on current time
  5. 应用标准解析器

    • 确保每个标准解析器都引用基于标准的订单项
    • 如果项目具有非零标准根,则通过包含证明确保为每个项目提供的标识符有效
    • 更新每个项目类型和标识符
    • 确保所有剩余项目均不基于标准
      Apply criteria resolvers
      Ensure each criteria resolver refers to a criteria-based order item
      Ensure the supplied identifier for each item is valid via inclusion proof if the item has a non-zero criteria root
      Update each item type and identifier
      Ensure all remaining items are non-criteria-based
  6. 发出 OrderFulfilled 事件

    • 包括更新的项目(即在金额调整和标准解决之后)
      Emit OrderFulfilled event
      Include updated items (i.e. after amount adjustment and criteria resolution)
  7. 将要约项目从要约人转移到来电者

    • 根据订单类型,直接使用管道或 seaport 获得批准
      Transfer offer items from offerer to caller
      Use either conduit or Seaport directly to source approvals, depending on order type
  8. 将 consideration 项目从呼叫者转移到相应的接收者

    • 使用管道或 seaport 直接获得批准,具体取决于履行者声明的偏好
      Transfer consideration items from caller to respective recipients
      Use either conduit or Seaport directly to source approvals, depending on the fulfiller's stated preference

注意:fulfillBasicOrder 以类似的方式工作,但有一些例外:它从订单元素的子集重建订单,跳过线性拟合量调整和标准解析,要求全部订单量是可填写的,并执行更少量的转移默认情况下,当优惠项目与附加 consideration 项目共享相同的类型和令牌时。
Note: fulfillBasicOrder works in a similar fashion, with a few exceptions: it reconstructs the order from a subset of order elements, skips linear fit amount adjustment and criteria resolution, requires that the full order amount be fillable, and performs a more minimal set of transfers by default when the offer item shares the same type and token as additional consideration items.

匹配订单 Match Orders

通过或匹配一组订单时,步骤 1 到 6 几乎相同,但针对每个提供的订单执行。从那里开始,实现与标准实现不同:matchOrders``matchAdvancedOrders**

  1. 应用履行
    • 确保每次履行都涉及一个或多个 offer 项目和一个或多个 consideration 项目,所有这些项目都具有相同的类型和令牌,并且每个 offer 项目具有相同的批准源和每个 consideration 项目的相同收件人
    • 将每个优惠项目和每个 consideration 项目的金额减少到零,并跟踪每个优惠项目的总减少金额
    • 比较每个项目的总金额,并将剩余金额加回订单相应一侧的第一个项目
    • 为每个履行返回一个执行
  2. 扫描每个 consideration 项目并确保没有一个仍然有非零的剩余金额
  3. 作为每次执行的一部分执行传输
    • 根据原始订单类型,直接使用管道或 seaport 获得批准
    • 忽略每次执行 where or (注意:当前实现不执行最后一次优化)to == from``amount == 0**
      When matching a group of orders via matchOrders or matchAdvancedOrders, steps 1 through 6 are nearly identical but are performed for each supplied order. From there, the implementation diverges from standard fulfillments:

7 Apply fulfillments
Ensure each fulfillment refers to one or more offer items and one or more consideration items, all with the same type and token, and with the same approval source for each offer item and the same recipient for each consideration item
Reduce the amount on each offer item and each consideration item to zero and track total reduced amounts for each
Compare total amounts for each and add back the remaining amount to the first item on the appropriate side of the order
Return a single execution for each fulfillment
8 Scan each consideration item and ensure that none still have a nonzero amount remaining
9 Perform transfers as part of each execution
Use either conduit or Seaport directly to source approvals, depending on the original order type
Ignore each execution where to == from or amount == 0 (NOTE: the current implementation does not perform this last optimization)

已知限制和解决方法 Known Limitations and Workarounds

  • 由于所有 offer 和 consideration 项目都在内存中相互分配,因此在某些情况下,实际收到的项目数量将与订单指定的数量不同 - 特别是,这包括具有转移费用机制的项目。包含此类商品的订单(或更广泛地说,应满足某些履行后状态的商品)应利用“受限”订单类型,并通过区域合同路由订单履行,该合同在订单履行后执行必要的检查完成了。

As all offer and consideration items are allocated against one another in memory, there are scenarios in which the actual received item amount will differ from the amount specified by the order — notably, this includes items with a fee-on-transfer mechanic. Orders that contain items of this nature (or, more broadly, items that have some post-fulfillment state that should be met) should leverage "restricted" order types and route the order fulfillment through a zone contract that performs the necessary checks after order fulfillment is completed.

  • 由于所有 offer 项目都直接从 offer 方获取,并且所有 consideration 项目都直接提供给指定的收件人,因此在某些情况下,这些帐户可能会增加订单履行的 gas 成本或阻止订单完全履行,具体取决于被转移的项目。如果有问题的项目是 Ether 或类似的原生代币,接收者可以投入应付的后备,甚至从提交者那里花费多余的 gas。如果所讨论的项目是带有传输挂钩的代币(如 ERC1155 和 ERC777)或非标准代币实现,则提供者和接收者都可以利用类似的机制。对此类问题的潜在补救措施包括在初始传输失败时将 Ether 包装为 WETH 作为后备,并允许提交者指定应分配的气体量作为给定履行的一部分。支持明确履行的订单也可以选择不使用有问题或不需要的 offer 项目,只要全部收到所有 consideration 项目。

As all offer items are taken directly from the offerer and all consideration items are given directly to the named recipient, there are scenarios where those accounts can increase the gas cost of order fulfillment or block orders from being fulfilled outright depending on the item being transferred. If the item in question is Ether or a similar native token, a recipient can throw in the payable fallback or even spend excess gas from the submitter. Similar mechanics can be leveraged by both offerers and receives if the item in question is a token with a transfer hook (like ERC1155 and ERC777) or a non-standard token implementation. Potential remediations to this category of issue include wrapping Ether as WETH as a fallback if the initial transfer fails and allowing submitters to specify the amount of gas that should be allocated as part of a given fulfillment. Orders that support explicit fulfillments can also elect to leave problematic or unwanted offer items unspent as long as all consideration items are received in full.

  • 由于履行可以按照履行者指定的任何顺序执行,只要履行都是可执行的,由于受限订单在执行之前通过区域验证,并且由于订单可以与其他订单组合或提供额外的 consideration 项目,因此任何具有如果应付以太币接收者或 onReceived 1155 传输挂钩能够修改该状态,则可修改状态有在执行期间修改该状态的风险。举例来说,假设提供者提供 WETH 并需要一些 ERC721 项目作为 consideration,其中 ERC721 应该具有一些额外的属性,例如没有用于铸造其他 ERC721 项目。然后,即使要约人通过检查财产的限制令强制 ERC721 拥有该财产,恶意履行者可能包括第二个订单(甚至只是一个额外的 consideration 项目),该订单在将 ERC721 项目出售给造币厂之前将其转移给供应商。针对此问题的一类补救措施是使用未执行的受限命令 isValidOrder 并且实际上要求通过它们路由订单履行,以便他们可以执行履行后验证。保留订单可组合性的另一个有趣的解决方案是“以火攻克”,并让 offer 者在需要额外保证的订单上包含“验证器”ERC1155 consideration 项;这将是一个包含 ERC1155 接口但实际上不是 1155 代币的合约,而是利用 onReceived 钩子作为验证预期不变量是否得到支持的一种手段,如果检查失败,则恢复“转移”(因此在上面的示例中,此钩子将确保提供者是相关 ERC721 项目的所有者,并且它尚未用于铸造其他 ERC721)。这种机制的主要限制是可以通过此路由在带内提供的数据量;只有三个参数(“from”、“identifier”和“amount”)可供使用。

As fulfillments may be executed in whatever sequence the fulfiller specifies as long as the fulfillments are all executable, as restricted orders are validated via zones prior to execution, and as orders may be combined with other orders or have additional consideration items supplied, any items with modifiable state are at risk of having that state modified during execution if a payable Ether recipient or onReceived 1155 transfer hook is able to modify that state. By way of example, imagine an offerer offers WETH and requires some ERC721 item as consideration, where the ERC721 should have some additional property like not having been used to mint some other ERC721 item. Then, even if the offerer enforces that the ERC721 have that property via a restricted order that checks for the property, a malicious fulfiller could include a second order (or even just an additional consideration item) that uses the ERC721 item being sold to mint before it is transferred to the offerer. One category of remediation for this problem is to use restricted orders that do not implement isValidOrder and actually require that order fulfillment is routed through them so that they can perform post-fulfillment validation. Another interesting solution to this problem that retains order composability is to "fight fire with fire" and have the offerer include a "validator" ERC1155 consideration item on orders that require additional assurances; this would be a contract that contains the ERC1155 interface but is not actually an 1155 token, and instead leverages the onReceived hook as a means to validate that the expected invariants were upheld, reverting the "transfer" if the check fails (so in the case of the example above, this hook would ensure that the offerer was the owner of the ERC721 item in question and that it had not yet been used to mint the other ERC721). The key limitation to this mechanic is the amount of data that can be supplied in-band via this route; only three arguments ("from", "identifier", and "amount") are available to utilize.

  • 由于所有 consideration 项目均在创建订单时提供,因此不支持在创建后动态调整收件人或金额(例如修改版税支付信息)。但是,区域可以强制给定的受限订单包含新的动态计算的 consideration 项目,方法是派生它们并手动提供它们或确保它们存在,因为 consideration 项目可以任意扩展,重要的警告是不超过原始可以花费优惠项目金额。isValidZoneIncludingExtraData

As all consideration items are supplied at the time of order creation, dynamic adjustment of recipients or amounts after creation (e.g. modifications to royalty payout info) is not supported. However, a zone can enforce that a given restricted order contains new dynamically computed consideration items by deriving them and either supplying them manually or ensuring that they are present via isValidZoneIncludingExtraData since consideration items can be extended arbitrarily, with the important caveat that no more than the original offer item amounts can be spent.

  • 由于所有基于标准的项目都与特定令牌相关联,因此没有本地方式来构建项目指定跨令牌标准的订单。此外,基于特定标准的项目的每个潜在标识符必须与任何其他标识符具有相同的数量。

As all criteria-based items are tied to a particular token, there is no native way to construct orders where items specify cross-token criteria. Additionally, each potential identifier for a particular criteria-based item must have the same amount as any other identifier.

  • 由于包含金额递增或递减的项目的订单可能无法像履行者希望的那样快速履行(例如交易花费的时间比预期的要长),因此这些订单的履行可能会提供更大的项目数量,或者收到比他们预期或预期更小的物品数量。防止这些结果的一种方法是使用,为履行者提供对比订单,明确指定要花费的最大允许 offer 项目和要收回的 consideration 项目。在处理包含短期持续时间以及金额递增或递减的项目时,应特别小心,因为已实现的金额可能会在短时间内发生明显变化。matchOrders

As orders that contain items with ascending or descending amounts may not be filled as quickly as a fulfiller would like (e.g. transactions taking longer than expected to be included), there is a risk that fulfillment on those orders will supply a larger item amount, or receive back a smaller item amount, than they intended or expected. One way to prevent these outcomes is to utilize matchOrders, supplying a contrasting order for the fulfiller that explicitly specifies the maximum allowable offer items to be spent and consideration items to be received back. Special care should be taken when handling orders that contain both brief durations as well as items with ascending or descending amounts, as realized amounts may shift appreciably in a short window of time.

  • 由于在执行部分成交时,支持部分成交的订单上的所有项目都必须是“完全可分割的”,因此应谨慎构建具有多个项目的订单。一个简单的启发式方法是从一个“单元”捆绑包开始(例如,1 个 NFT 项目 A、3 个 NFT 项目 B 和 5 个 NFT 项目 C 用于 2 ETH),然后将倍数应用于该单元捆绑包(例如,这些单元中的 7 个导致 7 NFT 项目 A、21 NFT 项目 B 和 35 NFT 项目 C 的部分订单(14 ETH)。

As all items on orders supporting partial fills must be "cleanly divisible" when performing a partial fill, orders with multiple items should to be constructed with care. A straightforward heuristic is to start with a "unit" bundle (e.g. 1 NFT item A, 3 NFT item B, and 5 NFT item C for 2 ETH) then applying a multiple to that unit bundle (e.g. 7 of those units results in a partial order for 7 NFT item A, 21 NFT item B, and 35 NFT item C for 14 ETH).

  • 由于无法从账户中“获取”以太币,任何包含以太币或其他原生代币作为 offer 项目的订单(包括“隐含”镜像订单)必须由执行订单的调用者作为 msg.value 提供。这也解释了为什么没有基本的订单路线类型,因为在这些情况下不能从提供者那里获取以太币。这种机制的一个重要收获是,从技术上讲,任何人都可以代表给定的提议者提供以太币(而提议者自己必须提供所有其他物品)。这也意味着必须在最初调用订单或订单组时提供所有以太币(并且在执行期间,外部来源不能增加 offer 项目的可用金额,就像代币余额的情况一样)。ERC721_TO_ERC20``ERC1155_TO_ERC20

As Ether cannot be "taken" from an account, any order that contains Ether or other native tokens as an offer item (including "implied" mirror orders) must be supplied by the caller executing the order(s) as msg.value. This also explains why there are no ERC721_TO_ERC20 and ERC1155_TO_ERC20 basic order route types, as Ether cannot be taken from the offerer in these cases. One important takeaway from this mechanic is that, technically, anyone can supply Ether on behalf of a given offerer (whereas the offerer themselves must supply all other items). It also means that all Ether must be supplied at the time the order or group of orders is originally called (and the amount available to spend by offer items cannot be increased by an external source during execution as is the case for token balances).

  • 由于调用者可以任意设置履行时 consideration 数组的扩展(即“小费”),因此所有匹配订单已经签署或验证的履行可以在提交时抢先运行,而领先者可以修改任何提示。因此,重要的是,以这种方式完成的订单要么利用具有强制适当分配 consideration 扩展的区域的“受限”订单类型,要么每个 offer 项目都已完全用完,并且每个 consideration 项目都在订单创建时适当声明。

As extensions to the consideration array on fulfillment (i.e. "tipping") can be arbitrarily set by the caller, fulfillments where all matched orders have already been signed for or validated can be frontrun on submission, with the frontrunner modifying any tips. Therefore, it is important that orders fulfilled in this manner either leverage "restricted" order types with a zone that enforces appropriate allocation of consideration extensions, or that each offer item is fully spent and each consideration item is appropriately declared on order creation.

  • 由于已验证(通过对还是可以实现的。在这些情况下,如果供应商不再希望订单可以履行,他们必须明确取消先前已验证的相关订单。validate

As orders that have been verified (via a call to validate) or partially filled will skip signature validation on subsequent fulfillments, orders that utilize EIP-1271 for verifying orders may end up in an inconsistent state where the original signature is no longer valid but the order is still fulfillable. In these cases, the offerer must explicitly cancel the previously verified order in question if they no longer wish for the order to be fulfillable.

  • 由于通过“可用履行”方法履行的订单仅在这些订单已被取消、完全履行或无效时才会被跳过,因此仍可能对无法履行的订单尝试履行(例如,撤销批准或余额不足)。这种情况(以及订单格式问题)将导致整批失败。对这种失败情况的一种补救措施是在构建调用时从执行区域或包装合约执行额外的检查,并根据这些检查过滤订单。

As orders filled by the "fulfill available" method will only be skipped if those orders have been cancelled, fully filled, or are inactive, fulfillments may still be attempted on unfulfillable orders (examples include revoked approvals or insufficient balances). This scenario (as well as issues with order formatting) will result in the full batch failing. One remediation to this failure condition is to perform additional checks from an executing zone or wrapper contract when constructing the call and filtering orders based on those checks.

  • 由于必须在取消时提供订单参数,因此本应保密的订单(例如未公开发布)将在取消时显示。虽然如果没有相应的签名,这些订单将无法履行,但在没有广播意图的情况下取消私人订单目前需要提供者(或区域,如果订单类型受到限制并且区域支持它)增加随机数。

As order parameters must be supplied upon cancellation, orders that were meant to remain private (e.g. were not published publically) will be made visible upon cancellation. While these orders would not be fulfillable without a corresponding signature, cancellation of private orders without broadcasting intent currently requires the offerer (or the zone, if the order type is restricted and the zone supports it) to increment the nonce.

  • 由于订单履行尝试可能在被包含在区块中之前就已公开,因此这些订单存在被抢先交易的风险。如果提供的商品包含递增金额或 consideration 商品包含递减金额,则这种风险会被放大,因为在另一个感兴趣的履行者尝试履行相关订单之前,会有额外的动机让订单未履行。补救措施包括使用私有内存池(例如 flashbots)和/或限制订单,在这些订单中,各个区域执行提交-显示方案。
    As order fulfillment attempts may become public before being included in a block, there is a risk of those orders being front-run. This risk is magnified in cases where offered items contain ascending amounts or consideration items contain descending amounts, as there is added incentive to leave the order unfulfilled until another interested fulfiller attempts to fulfill the order in question. Remediation efforts include utilization of a private mempool (e.g. flashbots) and/or restricted orders where the respective zone enforces a commit-reveal scheme.

用法 Usage

首先,安装依赖并编译:
First, install dependencies and compile:

yarn install
yarn build

接下来,运行 linter 和测试:
Next, run linters and tests:

yarn lint:check
yarn test
yarn coverage

要分析气体使用情况(请注意,由于测试中的随机输入,目前气体使用情况有点不确定):
To profile gas usage (note that gas usage is mildly non-deterministic at the moment due to random inputs in tests):

yarn profile

Foundry 测试 Foundry Tests

首先,安装 Foundry(假设是 Linux 或 macOS 系统):
First, install Foundry (assuming a Linux or macOS system):

curl -L https://foundry.paradigm.xyz | bash

这将下载 foundryup。要启动 Foundry,请运行:
This will download foundryup. To start Foundry, run:

foundryup

要安装依赖项:
To install dependencies:

forge install

运行测试:
To run tests:

forge test

以下修饰符也可用:
The following modifiers are also available:

  • 级别 2 (-vv):还显示测试期间发出的日志。
  • 级别 3 (-vvv):还显示失败测试的堆栈跟踪。
  • 级别 4 (-vvvv):显示所有测试的堆栈跟踪,并显示失败测试的设置跟踪。
  • 级别 5 (-vvvvv):始终显示堆栈跟踪和设置跟踪。
    Level 2 (-vv): Logs emitted during tests are also displayed.
    Level 3 (-vvv): Stack traces for failing tests are also displayed.
    Level 4 (-vvvv): Stack traces for all tests are displayed, and setup traces for failing tests are displayed.
    Level 5 (-vvvvv): Stack traces and setup traces are always displayed.
forge test  -vv

有关 Foundry 测试和使用的更多信息,请参阅 Foundry Book 安装说明

For more information on foundry testing and use, see Foundry Book installation instructions.

现在 cryptochou 将 seaport 的解析放在了一个 GitHub 上,链接如下:

https://github.com/cryptochou/seaport-analysis