发行 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 示例仓库。