手把手制作可验证随机的生成艺术 NFT:从 0 到上架实战

·

关键词:NFT、生成艺术、Chainlink VRF、Solidity、IPFS、去中心化存储、智能合约、Sepolia 测试网、OpenSea、狗品种 NFT


什么是生成艺术 NFT?

生成艺术 NFT 通过算法实时“绘制”独一无二的视觉作品,并将彩色狗头像、像素风景、抽象几何等所有随机特征完整记录在链上。与直接上传 JPEG 的传统 NFT 不同,每个 Token 的基因都由可验证随机数生成,因此持有者在铸造前无法预知会得到哪一幅作品,极大提升开盲盒般的惊喜感。


前提准备

  1. 基础软件

    • Node.js ≥ 16
    • Git
    • 一个支持 Solidity 的编辑器(VS Code 推荐)。
  2. 测试网钱包 & 代币

    • MetaMask 连接 Sepolia,确保账户拥有少量 Sepolia ETH 与 LINK。

👉 零成本领取 Sepolia 测试代币,立即开工!


第一步:一键克隆开源模板

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 随机数订阅

  1. 打开 Chainlink VRF,切换至 Sepolia。
  2. Connect Wallet 后点击 Create subscription ⇒ 记下 subscriptionId
  3. 准备 2 枚测试 LINK(可在 faucets.chain.link 领取),随后向订阅账户转入 LINK 作为随机数请求油费。

第三步:开发智能合约骨架

新建 RandomIpfsNft.sol,核心功能表如下:

文件名/片段作用
enum Breed枚举狗品种:PUG、SHIBA_INU、ST_BERNARD
VRFConsumerBaseV2获取链上可验证随机数
ERC721URIStorageNFT 元数据与 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


第五步:合约构造函数

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。


第六步:铸造流程拆解

  1. 用户调用 requestNft() 并附带足额 ETH。
  2. 合约发出 VRF 请求,并将 msg.sender 与随机数 ID 存入映射。
  3. fulfillRandomWords 自动回调,根据随机数取模决定狗品种,铸造并绑定正确 URI。

关键控制位:

uint256[3] memory chanceArray = [10, 30, 100];  // 出现概率

概率说明:


第七步:提现与安全退出

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 测试网

  1. 合约部署后返回地址。
  2. 访问 OpenSea 测试网,粘贴地址即可查看 Collection
  3. 支持转移、挂单、竞价,全流程与主网无异。

👉 观看铸造教程视频,30 秒看懂盲盒 NFT


常见问题解答 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 发行