1Do App

NFT Market

maker 在链下签署具体 NFT 与对价,buyer 用一次性 Token/NFT Pull 或精确原生币完成原子结算。

6 个章节onedo-nft-market
01

市场模型

NFT Market 是针对具体 ERC-721 tokenId 的签名订单市场。订单在链下创建和传播,成交前资产仍由双方钱包持有;链上只记录已经成交或取消的订单。

当前实现处理全额、点对点交换,不提供拍卖、部分成交、合集出价、批量 NFT、ERC-1155、版税结算或市场协议费。

02

五类订单

  • NftForTokenOrder:maker 提供指定 NFT,buyer 支付 ERC-20。
  • TokenForNftOrder:maker 提供 ERC-20,buyer 支付指定 NFT。
  • NftForNativeOrder:maker 提供指定 NFT,buyer 支付原生币。
  • NativeForNftOrder:maker 提供原生币,buyer 支付指定 NFT。
  • NftForNftOrder:maker 与 buyer 交换两个订单中明确指定的 NFT。
  • expiry 为 0 表示没有合约级到期限制;nonce 是订单 salt,不是自动递增的账户 nonce。tokenId 可以为 0。
Signed order fields
struct NftForTokenOrder {
  address nft;
  uint256 tokenId;
  address erc20;
  uint256 tokenAmount;
  uint256 expiry;
  uint256 nonce;
}

struct TokenForNftOrder {
  address nft;
  uint256 tokenId;
  address erc20;
  uint256 tokenAmount;
  uint256 expiry;
  uint256 nonce;
}

struct NftForNativeOrder {
  address nft;
  uint256 tokenId;
  uint256 nativeAmount;
  uint256 expiry;
  uint256 nonce;
}

struct NativeForNftOrder {
  address nft;
  uint256 tokenId;
  uint256 nativeAmount;
  uint256 expiry;
  uint256 nonce;
}

struct NftForNftOrder {
  address giveNft;
  uint256 giveTokenId;
  address wantNft;
  uint256 wantTokenId;
  uint256 expiry;
  uint256 nonce;
}
03

签名与结算流程

步骤 1

签署具体订单

maker 使用 NFT Market Order on 1Do / 1 的 EIP-712 domain 签名;verifyingContract 是 maker 钱包。

步骤 2

准备 buyer 资产

ERC-20 或 NFT 付款通过 buyer 钱包的一次性 Pull 上下文;原生币付款直接附加在 maker Runtime 调用上。

步骤 3

验证 maker 意图

应用检查字段、expiry、订单消费状态,并通过 maker 钱包 ERC-1271 验证签名。

步骤 4

原子交换

订单被标记 consumed,双方资产在同一交易移动;任一 Pull、转账或签名检查失败都会整体回滚。

04

五类资产路径

  • NFT → Token:buyer 用 Token Pull 把 ERC-20 交给 maker,应用把 maker NFT 转给 buyer。
  • Token → NFT:buyer 用 NFT Pull 把指定 NFT 交给 maker,应用把 maker ERC-20 转给 buyer。
  • NFT → 原生币:buyer 直接附带精确 msg.value,应用把 maker NFT 转给 buyer。
  • 原生币 → NFT:buyer 用 NFT Pull 交付指定 NFT,应用从 maker 钱包发送原生币。
  • NFT → NFT:buyer 用 NFT Pull 交付 wantNft,应用把 maker 的 giveNft 转给 buyer。
  • Token/NFT Pull 路径要求 buyer 钱包支持相应 Pull 能力,但不要求 buyer 启用 NFT Market;maker 钱包必须启用当前市场 logic,且 Registry 仍允许该地址。
05

取消、事件与状态

  • 每类订单都可由 maker 钱包 self-call 精确取消;成交和取消都会消费该完整订单,没有 nonce floor 或批量取消。
  • 订单不绑定指定 buyer,也不包含 app logic 地址;任何 buyer 都可提交有效成交,升级或切换兼容 logic 前应评估旧签名兼容性。
  • 合约没有公开 consumedOrders getter。索引服务应按 maker 钱包地址监听 Filled / Cancelled 事件并结合模拟调用维护状态。
  • 事件由 maker 钱包地址发出。NftForToken 与 TokenForNft 使用完整 EIP-712 digest;两类原生币订单和 NftForNft 使用 struct hash。
  • 从链下订单服务删除报价不等于链上取消;禁用应用也不会抹除订单,未来重新启用后,未过期且未消费的签名仍可能有效。
06

接收与资产边界

  • buyer 提供 NFT 时,钱包 Pull 路径使用 safeTransferFrom 将 NFT 送入 maker 钱包。
  • maker 提供 NFT 时,应用使用 transferFrom 发给 buyer,不会执行 ERC721Receiver 回调;合约型 buyer 应确认自身能安全持有该 NFT。
  • 原生币付款必须与订单金额完全一致,收款地址拒收原生币会导致整笔成交失败。
  • ERC-20 使用 SafeERC20;fee-on-transfer、rebasing 与其他非标准余额语义没有专门适配。

订单只覆盖明确资产

NFT Market 不会给应用 logic 地址留下 ERC-20 allowance 或 NFT operator,但签名一旦成交,会按订单移动具体资产。签名前应逐项核对合约地址、tokenId、数量、链和 maker 钱包。