You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于CW721 NFT实现拍卖智能合约?

解决方案:让CW721持有者发送NFT时携带拍卖配置参数

核心思路:复用CW721标准的SendNft消息字段

CW721标准的SendNft消息本身支持在msg字段传入任意二进制数据,该数据会被完整转发到接收合约的ReceiveNft消息中。你不需要修改现有CW721合约的核心逻辑,只需让调用者在发送SendNft时把拍卖参数编码后放入msg字段,再由拍卖合约解码即可。

具体实现步骤

1. 定义拍卖配置的自定义结构体

在拍卖合约中定义包含必要参数的结构体:

use cosmwasm_std::{Uint128, Timestamp};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct AuctionInitParams {
    pub start_time: Timestamp,
    pub duration: u64, // 单位:秒
    pub min_bid: Uint128,
    // 可按需添加其他参数,比如手续费比例、预留出价地址等
}

2. 持有者调用SendNft时携带编码后的参数

用户(NFT持有者)调用CW721合约的SendNft时,将AuctionInitParams序列化为Base64编码字符串(或直接二进制,依客户端工具支持情况),放入msg字段。示例Rust客户端代码:

use cosmwasm_std::to_binary;
use cw721::Cw721ExecuteMsg;

// 构造拍卖参数
let auction_params = AuctionInitParams {
    start_time: Timestamp::from_seconds(1717248000), // 示例时间戳
    duration: 86400, // 24小时
    min_bid: Uint128::new(1000000), // 1个原生代币
};

// 序列化为二进制并转Base64
let encoded_params = base64::encode(to_binary(&auction_params).unwrap());

// 构造SendNft消息
let send_nft_msg = Cw721ExecuteMsg::SendNft {
    contract: "auction-contract-address".to_string(),
    token_id: "nft-123".to_string(),
    msg: Some(encoded_params),
};

3. 拍卖合约解码ReceiveNft中的自定义数据

在拍卖合约的receive_nft处理函数中,提取Cw721ReceiveMsg的msg字段并解码为AuctionInitParams:

use cosmwasm_std::{Binary, DepsMut, Env, MessageInfo, Response, StdError};
use cw721::Cw721ReceiveMsg;

pub fn receive_nft(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
    msg: Cw721ReceiveMsg,
) -> Result<Response, StdError> {
    // 解码自定义参数
    let auction_params: AuctionInitParams = match msg.msg {
        Some(encoded) => {
            let binary = Binary::from_base64(&encoded)?;
            deps.api.addr_validate(&msg.sender)?; // 验证发送者地址合法性
            serde_json::from_slice(&binary)?
        }
        None => return Err(StdError::generic_err("缺少拍卖初始化参数")),
    };

    // 执行拍卖初始化逻辑:检查时间合法性、存储拍卖数据、设置状态等
    // 示例:
    // let auction_id = format!("{}_{}", msg.token_id, env.block.time.nanos());
    // save_auction(deps.storage, &auction_id, &auction_params, &msg.sender, &msg.token_id)?;

    Ok(Response::new()
        .add_attribute("action", "auction_initiated")
        .add_attribute("token_id", msg.token_id)
        .add_attribute("min_bid", auction_params.min_bid.to_string()))
}

CW721合约架构建议

你当前的基础CW721实现完全满足需求,不需要修改核心逻辑——标准SendNft的msg字段已经能承载自定义参数。如果后续需要扩展(比如限制特定NFT可发起拍卖),再考虑在CW721合约中添加SendNftToAuction自定义执行消息,内部调用标准SendNft并做额外校验即可,现阶段优先复用标准字段实现核心功能。

避坑提示

  • 必须在拍卖合约中验证参数合法性:比如start_time不能早于当前区块时间、duration不能为0、min_bid必须大于0等。
  • 确保编码解码格式一致:客户端和合约要统一使用相同的编码方式(如Base64+JSON或Protobuf二进制),避免解码失败。
  • 二次验证发送者身份:虽然CW721合约已校验持有者身份,但拍卖合约再次验证msg.sender的合法性更安全。

内容的提问来源于stack exchange,提问作者cowboy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:52:46