本站域名已变更为https://blog.67v.cn,全新首页即将发布,尽情期待!!!

第八天:ERC-721——从代币到 NFT

ERC-20 的每枚代币都一样(你的 1 枚和我的 1 枚可互换),而 NFT 的每一枚都独一无二——靠的是另一个标准 ERC-721:每个 token 有全局唯一的 tokenId,所有权用 ownerOf(tokenId) 查询。今天铸造一组自己的 NFT,并把图片元数据放到 IPFS。

最小 NFT 合约

code
// 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。

读完了点一下,作者能得积分

赞赏

如果这篇内容帮到了你,不妨请作者喝杯咖啡

分享 微博 QQ

发表评论

发表评论