关键词:NFT、生成艺术、Chainlink VRF、Solidity、IPFS、去中心化存储、智能合约、Sepolia 测试网、OpenSea、狗品种 NFT
什么是生成艺术 NFT?
生成艺术 NFT 通过算法实时“绘制”独一无二的视觉作品,并将彩色狗头像、像素风景、抽象几何等所有随机特征完整记录在链上。与直接上传 JPEG 的传统 NFT 不同,每个 Token 的基因都由可验证随机数生成,因此持有者在铸造前无法预知会得到哪一幅作品,极大提升开盲盒般的惊喜感。
前提准备
基础软件
- Node.js ≥ 16
- Git
- 一个支持 Solidity 的编辑器(VS Code 推荐)。
测试网钱包 & 代币
- MetaMask 连接 Sepolia,确保账户拥有少量 Sepolia ETH 与 LINK。
第一步:一键克隆开源模板
git clone https://github.com/smartcontractkit/smart-contract-examples.git
cd smart-contract-examples/ultimate-nft-repo
yarn安装完成后,在项目根目录创建 .env 并填入以下值(免费注册 Alchemy、Etherscan 可获取):
ETHERSCAN_API_KEY=<YourKey>
SEPOLIA_URL=https://eth-sepolia.alchemyapi.io/v2/<YourAlchemyKey>
PRIVATE_KEY=<YourWalletPrivateKey>第二步:创建 VRF 随机数订阅
- 打开 Chainlink VRF,切换至 Sepolia。
- Connect Wallet 后点击 Create subscription ⇒ 记下
subscriptionId。 - 准备 2 枚测试 LINK(可在 faucets.chain.link 领取),随后向订阅账户转入 LINK 作为随机数请求油费。
第三步:开发智能合约骨架
新建 RandomIpfsNft.sol,核心功能表如下:
| 文件名/片段 | 作用 |
|---|---|
enum Breed | 枚举狗品种:PUG、SHIBA_INU、ST_BERNARD |
VRFConsumerBaseV2 | 获取链上可验证随机数 |
ERC721URIStorage | NFT 元数据与 URI 的管理 |
Ownable() | 合约所有者可操作提现、升级等 |
关键随机数变量
uint64 private immutable i_subscriptionId;
bytes32 private immutable i_gasLane;
uint32 private immutable i_callbackGasLimit;
uint16 private constant REQUEST_CONFIRMATIONS = 3;
uint32 private constant NUM_WORDS = 1;第四步:上传作品图至 IPFS
- 登录 Pinata(无需 KYC)。
点击 Upload → File 上传 3 张狗图,分别命名:
- PUG.png
- SHIBA.png
- ST_BERNARD.png
- 复制 IPFS
cid,在合约初始化阶段填入数组dogTokenUris[3]。
第五步:合约构造函数
constructor(
address _vrfCoordinator,
uint64 _subscriptionId,
bytes32 _gasLane,
uint256 _mintFee,
uint32 _callbackGas,
string[3] memory _uris
) VRFConsumerBaseV2(_vrfCoordinator) ERC721("Random IPFS Dog", "RDOG") {
i_subscriptionId = _subscriptionId;
i_gasLane = _gasLane;
i_mintFee = _mintFee;
i_callbackGasLimit = _callbackGas;
_initializeContract(_uris);
}mintFee 代表铸造一次需支付的 Sepolia ETH 金额,可根据测试网行情设为 0.001 ETH。
第六步:铸造流程拆解
- 用户调用
requestNft()并附带足额 ETH。 - 合约发出 VRF 请求,并将
msg.sender与随机数 ID 存入映射。 fulfillRandomWords自动回调,根据随机数取模决定狗品种,铸造并绑定正确 URI。
关键控制位:
uint256[3] memory chanceArray = [10, 30, 100]; // 出现概率概率说明:
- 0–9 机率 10% → PUG
- 10–39 机率 20% → SHIBA_INU
- 40–99 机率 60% → ST_BERNARD
第七步:提现与安全退出
function withdraw() external onlyOwner {
(bool success, ) = payable(owner()).call{value: address(this).balance}("");
require(success, "Withdraw failed");
}采用最新推荐 call 方法,避免 transfer 发生 Gas 限制回滚。
第八步:本地测试脚本
添加 Hardhat 任务 scripts/mint.js:
const { ethers } = require("hardhat");
async function main() {
const RDOG = await ethers.getContract("RandomIpfsNft");
const tx = await RDOG.requestNft({ value: ethers.utils.parseEther("0.001") });
console.log("Mint transaction:", tx.hash);
await tx.wait();
console.log("Verified random dog NFT minted!");
}
main().catch((error) => { console.error(error); process.exit(1); });运行:
npm run deploy --network sepolia
npx hardhat run scripts/mint.js --network sepolia第九步:上架 OpenSea 测试网
- 合约部署后返回地址。
- 访问 OpenSea 测试网,粘贴地址即可查看 Collection。
- 支持转移、挂单、竞价,全流程与主网无异。
常见问题解答 FAQ
Q1:为什么一定要用 Chainlink VRF,而不是 block.timestamp?
A:block.timestamp 可被矿工操纵,而 Chainlink VRF 提供加密证明,确保公平性。
Q2:铸造费 0.001 ETH 最终会流向谁?
A:进入合约余额,withdraw() 只能由合约所有者一次性提取,用于补偿创作者与开发成本。
Q3:图片 uri 能否日后替换?
A:当前 ERC721URIStorage 一经 _setTokenURI 上链即锁定;如需升级,可把 URI 指向动态 API 并添加多签治理逻辑。
Q4:如何快速测试多个随机结果?
A:Hardhat 本地分叉脚本或 console.log 需配合 Foundry test 并发 50 次,可复现极端分布。
Q5:主网部署是否复杂?
A:主网与 Sepolia 流程 99% 一致,仅把测试 LINK → 主网 LINK,gasPrice、gasLimit 调高即可。
小结
我们完成了 Solidity 合约编写 + IPFS 存储 + VRF 随机数 + 前端交互 全流程。恭喜!你已成功把独特的狗品种生成艺术带到区块链。
👉 阅读进阶:如何免费推广 NFT 发行