跳到主要内容

发行 ERC-721 NFT 集合

标准 ERC-721 在 OXN 上无修改可用。本指南覆盖基础,加上机密链 NFT 独有的模式。

标准 ERC-721

contracts/MyNFT.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyNFT is ERC721, Ownable {
uint256 private _nextTokenId;

constructor(address initialOwner)
ERC721("MyNFT", "MNFT")
Ownable(initialOwner)
{}

function safeMint(address to) external onlyOwner {
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId);
}
}

gasLimit: 3_000_000n 部署——见部署合约

机密元数据

标准 NFT 公开存 tokenURI。OXN 上你可以隐藏元数据:

contract PrivateNFT is ERC721, Ownable {
mapping(uint256 => string) private _tokenURIs;
mapping(uint256 => mapping(address => bool)) private _readApprovals;

function _setTokenURI(uint256 tokenId, string memory uri) internal {
_tokenURIs[tokenId] = uri;
}

function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_ownerOf(tokenId) != address(0), "nonexistent");
require(
msg.sender == _ownerOf(tokenId) || _readApprovals[tokenId][msg.sender],
"not authorized to view"
);
return _tokenURIs[tokenId];
}
}

只有 token owner(或被授权的读者)能取到元数据 URI。其他人看到 revert。

揭示机制

想要 NFT 在揭示日期前隐藏元数据:

uint256 public revealTime;

function tokenURI(uint256 tokenId) public view override returns (string memory) {
require(_ownerOf(tokenId) != address(0), "nonexistent");
if (block.timestamp < revealTime) {
return "ipfs://prereveal"; // 占位图
}
return _tokenURIs[tokenId];
}

revealTime 前所有人看占位。之后返回真实 URI(按需仍可门控)。

盲盒 mint

Mint 时元数据只有买家请求查看时才揭示:

mapping(uint256 => bytes) private _encryptedMetadata;

function mint(address to, bytes calldata encryptedURI) external onlyOwner {
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId);
_encryptedMetadata[tokenId] = encryptedURI; // 加密存储
}

function reveal(uint256 tokenId) external view returns (bytes memory) {
require(msg.sender == _ownerOf(tokenId), "not owner");
return _encryptedMetadata[tokenId];
}

完整示例

可运行的 Hardhat 项目见 OXN 示例仓库

下一步