第八天:ERC-721——从代币到 NFT
ERC-20 的每枚代币都一样(你的 1 枚和我的 1 枚可互换),而 NFT 的每一枚都独一无二——靠的是另一个标准 ERC-721:每个 token 有全局唯一的 tokenId,所有权用 ownerOf(tokenId) 查询。今天铸造一组自己的 NFT,并把图片元数据放到 IPFS。
最小 NFT 合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
contract StudyNFT is ERC721 {
uint256 public nextId = 1;
string public baseURI;
constructor(string memory _baseURI) ERC721("Study NFT", "SNFT") {
baseURI = _baseURI;
}
function mint() external {
uint256 id = nextId++;
_safeMint(msg.sender, id);
}
function tokenURI(uint256 _id) public view override returns (string memory) {
return string(abi.encodePacked(baseURI, Strings.toString(_id), ".json"));
}
}NFT 的”图片在哪”由 tokenURI 回答:它返回一个 JSON 文件的地址(通常托管在 IPFS),JSON 里写 name/description/image 字段。钱包和交易市场按这个约定展示 NFT。
metadata 上 IPFS
JSON 和图片要放去中心化存储,否则中心服务器一挂,你的 NFT 就只剩一个 tokenId。最简单的方式是用 Pinata 之类的服务把一个文件夹(0.json、1.json… + 对应图片)上传到 IPFS,拿到 ipfs://CID/ 前缀填进构造函数。本地测试也可以先用 file:// 或任意可访问 URL 占位。
mint 的两种打开方式
- 公开 mint:像上面那样谁都能调,常配合每钱包限量和白名单;
- owner mint:只有部署者能铸,用第四天的 onlyOwner modifier,适合积分凭证类。
实际项目还会考虑总限量(require(nextId <= MAX))、盲盒式揭示、版税(EIP-2981)。这些都是”标准的最后一公里”,OpenZeppelin 的文档和 wizard(wizard.openzeppelin.com)可以交互式生成骨架代码,强烈建议玩玩。
今天的作业:铸造 5 枚自己的 NFT,metadata 上传 IPFS,用 MetaMask 打开一枚看看展示效果。本地链看完,下一篇我们把合约部署到真正的测试网 Sepolia。
读完了点一下,作者能得积分
赞赏
如果这篇内容帮到了你,不妨请作者喝杯咖啡
赞赏
如果这篇内容帮到了你,不妨请作者喝杯咖啡
选个金额
微信扫码扫一下,金额 ¥6
- 扫码后按所选金额支付即可
- 赞赏完全自愿,与积分、红包互不影响
发表评论