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 钱包。