Cosmos 上的 NFT:CW721 为什么把转账分成两种
一条路径给地址,一条路径给合约
Cosmos 生态里的 NFT 规范叫 CW721,名字和设计都参照以太坊的 ERC-721,但因为跑在 CosmWasm 上,接口写法是消息(execute msg)而不是函数调用。最需要先弄懂的是它把“把 NFT 交出去”拆成两条:TransferNft 面向普通地址(私钥控制的账户),执行完就结束了;SendNft 面向合约地址,接收方合约必须实现 ReceiveNft,发出方还可以附带一段 msg。
这个区分是安全设计,而不是风格差异。ERC-721 里对应的机制叫 safeTransferFrom 加接收检查,而 CW721 直接在接口层把两条路分开,并提醒调用者:合约若没实现接收逻辑,代币可能永久卡在里面。附带的那段 msg 也有实际用途,官方 README 举的例子就是“把代币连同我想挂的价格一起发给交易所合约”。

授权能设到期时间
Approve 允许持有者或 operator 授权某个 spender 转走指定代币,参数里多了一个 expires——以区块时间表示的到期点。ApproveAll 则是把名下全部代币(包括将来收到的)授权给一个 operator。这两类授权在代币转手时会被清空,过期授权默认不出现在查询结果里,除非显式设置 include_expired。
对使用者,这条差异很有操作价值:与其给一个永远有效的授权、事后到处找撤销入口,不如在授权时就设定一个到期高度。查询侧对应的是 Approval、Approvals、AllOperators 等接口,能把“谁现在能动我的藏品”问清楚。
代币编号是字符串,分页靠游标
CW721 的 token_id 是合约内唯一的任意字符串,不是必须连续的数字,这一点比 ERC-721 更自由,也更考验客户端:不要假设能按数字范围遍历。列举类接口 Tokens、AllTokens 用 start_after 与 limit 做分页,README 建议默认 10 条、上限 30 条,合约可以自定不同值,所以工具不应该硬编码这两个数。
元数据方面,cw721-base 把集合信息(名称、符号)与单个代币信息分开,链下元数据存在 token_uri,链上元数据通过 NftInfo 的 extension 字段承载,还有专门的 cw721-metadata-onchain 合约示范后一种做法。也就是说,“元数据在链上还是链下”在这里是合约选型问题,两种写法都合规。
规范是分块的,别假设全都实现
README 里一句很关键的话:规范分成多个部分,合约可以只实现其中一部分,但必须实现 base。这意味着同一句 CW721 的帽子下面,可能没有 Enumerable、没有 mint 接口、没有 burn。工具开发者和买家都要按接口逐项探测,而不是看到“支持 CW721”就假定功能和别处一样。生态里另有 cw2981 之类的扩展用于版税声明,同样属于可选实现。
三个常见误区
第一,把 TransferNft 发给合约地址,以为“能到账”。正确做法是走 SendNft,并确认目标合约实现了 ReceiveNft。第二,忽略授权到期:ApproveAll 会覆盖你未来收到的代币,设了到期时间才是可控的。第三,以为链上一定存了图片:NftInfo 里只有图像链接是 URI,其他字段可能是链上结构化数据,也可能仍指向外部地址,要按实际合约判断。
一句判断口径
CW721 给 Cosmos 带来的不是“另一个 ERC-721”,而是一组更明确的接口分工:给人的路、给合约的路、带到期时间的授权、字符串化的代币编号。作为使用者,把“这个合约实现了哪些块”当成第一问,把 SendNft 与 ReceiveNft 是否闭环当成第二问,两个问题答完,绝大多数踩坑场景在动手前就排除掉了。标准文本是公开的,合约代码也是可以要求公开的——这是原生合约型 NFT 共同的透明度红利,不用白不用。
风险提示:本文只解释技术机制与操作边界,不构成投资建议,也不推荐任何项目或平台。链上规则可能随版本升级变化,判断以官方规范文本与链上实际代码为准。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。