从合约编写到 OpenSea 上架,一篇带你亲手跑完整流程。
什么是 NFT 与 ERC-721
非同质化代币(NFT)让每一件链上资产都独一无二,而 ERC-721 正是以太坊社区公认的 NFT 标准。它约定了如何查余额、查归属、安全转移资产,并提供授权机制,实现区块链上的“收藏品”体验和交易市场流通。
准备:开发环境与关键词
关键词:Solidity、OpenZeppelin、Hardhat、Sepolia 测试网、NFT、ERC-721、IPFS metadata、OpenSea
在开始动手前,确保已安装 Node ≥ 18,并配置好「MetaMask + Sepolia faucet」领取测试 ETH。👇
👉 想立刻发一个限量 NFT?从这里跳转到完整实战模板仓库!
第一步:使用 OpenZeppelin Wizard 生成基础合约
- 打开 Wizard
点击左侧 ERC-721
- Name:Football Players
- Symbol:FTP
- 勾选
Mintable、Auto increment IDs、Ownable
- Wizard 自动生成
FootballPlayers.sol代码雏形。
我们将对其稍作精简,将版权头锁定在 SPDX MIT 兼容性,Solidity 版本 0.8.24,并移除多余接口。精简示例
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract FootballPlayers is ERC721, Ownable {
uint256 private _nextTokenId;
constructor() ERC721("Football Players", "FTP") Ownable(msg.sender) {}
function safeMint(address to) public onlyOwner {
_safeMint(to, _nextTokenId++);
}
}代码解析
ERC721:核心 NFT 功能库。Ownable:仅部署者能 mint,安全性更好。_nextTokenId:递增编号,自动生成独一无二的 tokenId。
第二步:搭建 Hardhat 项目
关键词:Hardhat、TypeScript、测试网、部署脚本
npm init -y
npm install --save-dev hardhat
npx hardhat init # 选择 TypeScript
npm install --save-dev @nomicfoundation/hardhat-ethers dotenv
npm install @openzeppelin/contracts在 .env 里填写:
PRIVATE_KEY=你的私钥
INFURA_SEPOLIA_ENDPOINT=https://sepolia.infura.io/v3/你的ProjectId调整 hardhat.config.ts:
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-ethers";
import "dotenv/config";
const config: HardhatUserConfig = {
solidity: "0.8.24",
networks: {
sepolia: {
url: process.env.INFURA_SEPOLIA_ENDPOINT,
accounts: [process.env.PRIVATE_KEY!],
},
},
};
export default config;新建点火模块 ignition/modules/FootballPlayers.ts:
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
export default buildModule("FootballPlayers", (m) => ({
contract: m.contract("FootballPlayers"),
}));一键三命令
npx hardhat compile
npx hardhat test
npx hardhat ignition deploy ignition/modules/FootballPlayers.ts --network sepolia部署示例输出:0x98d74ad6E86... 即为合约地址。
第三步:添加元数据(metadata)
关键词:IPFS、JSON、tokenURI、OpenSea
NFT 的魅力在于 链上记录 + 链下展示——把高清图片、描述、属性放在 IPFS 更高效。
- 用 NFT.Storage 把图片压缩上传,获得长链接:
ipfs://bafkreiAxxxxx。 - 创建 JSON 结构:
{
"name": "Football Players #0",
"description": "意大利十号新星,由 AI 即时合成",
"image": "ipfs://bafkreiAxxxxx"
}- 把 JSON 文件夹整体再上传一次,得到统一基 URI:
ipfs://bafybeixxxx/
合约里覆盖 _baseURI():
function _baseURI() internal pure override returns (string memory) {
return "ipfs://bafybeixxxx/";
}并在 tokenURI 中拼合 .json 后缀:
function tokenURI(uint256 tokenId) public view override returns (string memory) {
_requireOwned(tokenId);
return string.concat(_baseURI(), Strings.toString(tokenId), ".json");
}第四步:进阶功能升级(可选)
| 功能扩展 | OpenZeppelin 模块 | 作用 |
|---|---|---|
| Burnable | ERC721Burnable | 允许销毁已发行的 NFT,降低流通量 |
| Pausable | ERC721Pausable | 紧急暂停转移与铸币,保障安全 |
| Enumerable | ERC721Enumerable | 全局枚举 + 分页查询,利于大厅展示 |
| URI Storage | ERC721URIStorage | 代币级 URI 映射,单个 JSON 自由替换,灵活但成本高 |
使用 Wizard 重新勾选这些模块,Hardhat 编译后可将 代币上限、暂停开关、销毁接口 一并集成。完整升级后的合约已开源 GitHub,可直接 fork。
第五步:验证并上架 OpenSea
- 合约地址复制到 Sepolia 浏览器。
- Hardhat 控制台执行 5 次
safeMint(可把 IPFS 单个 URI 作为参数传入)。 - 打开 OpenSea Sepolia 版,输入合约地址,即可看到绿色认证标记,完成上架!
资源与下一步
- ERC-721 官方文档:eips.ethereum.org/EIPS/eip-721
- OpenSea Metadata 规范:docs.opensea.io
- 拓展阅读:可升级 NFT 合约、Layer2 发行、动态 SVG 链上艺术。
常见问题 FAQ
Q1:部署在 mainnet 需要多少 gas?
不带元数据的简单合约约 0.02 ETH(随网络拥堵浮动),附 URI Storage 可能翻倍。
Q2:能否在部署后追加 NFT?
若_baseURI指向固定 IPFS 文件夹且文件夹不可编辑,则无法追加;若想永不超过总量,可在safeMint中硬顶。
Q3:如何保证图片永久存储?
使用分布式协议如 IPFS + Filecoin、Arweave,并用 Pinning 服务重钉。
Q4:OpenSea 必须验证合约吗?
不强制,但验证后可展示资产图像和属性,提升可信度和交易流动性。
Q5:能否用 Remix 一键部署?
完全可以。把上述 Solidity 代码粘到 Remix→ Compile→ Deploy to Injected Web3→ MetaMask 即可。
Q6:测试 NFT 能否直接换成 ETH?
测试网资产仅在测试环境流通,无实际经济价值,但流程与主网一致,方便调试与展示。