记录一次纯手动铸造NFT,共花费1美分

nft火的时候还是22年吧,当时很不认可这个东西,觉得这才是纯泡沫。近两年也一直听说整体价格持续下降,市场萎靡。前两天一看,比较出名的那些还是得几百U起步,几万几十万U的地板价也是不少,刷新了我的三观。为什么想去看,是因为ledger flex可以设置nft屏保,我想去买个几十u的二次元nft。结果幻想破灭了,首先没有几十u的一线nft,其次没有及格二次元,最后,我没有ledger flex啊!

反正就是,买nft是不可能的,不如自己铸造一个。简单了解之后,决定先用最简单的方式跑一下基础流程:

  • polygon链,兼容evm,手续费低。
  • wizard.openzeppelin.com 创建合约模板
  • remix.ethereum.org 上线合约

建议使用新钱包,不要相信我的安全审计能力,虽然我觉得这种基础功能没什么大问题。

1. 设计合约

在wizard.openzeppelin.com,选择ERC721,左侧勾选Mintable、URI Storage、Ownable。

生成后的模板简单修改:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {ERC721URIStorage} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

contract MyToken is ERC721, ERC721URIStorage, Ownable {
    uint256 private _nextTokenId = 1;

    constructor(address initialOwner)
        ERC721("MyToken", "MTK")
        Ownable(initialOwner) // 部署时手动指定 Owner
    {}

    function safeMint(address to, string calldata uri) external onlyOwner {
        require(bytes(uri).length != 0, "EmptyURI"); // 确保 URI 不为空
        uint256 tokenId = _nextTokenId++;
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    function setTokenURI(uint256 tokenId, string calldata uri) external onlyOwner {
        require(_ownerOf(tokenId) != address(0), "NonexistentToken");
        require(bytes(uri).length != 0, "EmptyURI");
        _setTokenURI(tokenId, uri);
    }

    function nextTokenId() external view returns (uint256) {
        return _nextTokenId;
    }

    // 保留 totalSupply(),返回已铸造的总数量(不考虑销毁)
    function totalSupply() external view returns (uint256) {
        return _nextTokenId - 1;
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

以下内容可以修改:

  • 名称("MyToken"),比如改成“My Art Collection”
  • 符号("MTK"),比如改成“ART”、“NFTX”
  • 铸造函数名称("safeMint"),比如改成“1mint”、“whatever123123”,(不要改_safeMint)

2. 部署合约

提前准备好一个新钱包,我使用metamask,0.1POL应该就够了,我放了两个,便宜的很。

前往 remix.ethereum.org

左侧新建一个 MyNFT.sol 其它文件可以不删,没有影响。将修改后的合约粘贴保存。

转到左侧 Solidity compiler,compiler我选了默认的0.8.30,也符合pragma solidity ^0.8.27;的要求。

Advanced Configurations 中,选中Optimization 200

EVM Version 默认的prague部署时提示我Incompatible EVM for the selected chain,尝试降级到之前到 cancun

点击 Compile MyNFT.sol,侧边栏显示绿勾 Compile successful后进行下一步。

图片[1]-记录一次纯手动铸造NFT,共花费1美分-THsInk

Deploy & run transactions标签页

Environment 选 Injected Provider – MetaMask,如果没有这个选项,应该是没有提前链接好钱包,刷新再试一下。

确认 MetaMask 当前网络是 Polygon Mainnet (137) network(或测试网),不应该显示Main (1) network,如果没有正确显示网络,尝试在metamask切换一下网络。

其余默认即可,在deploy后输入owner地址,部署即可

图片[2]-记录一次纯手动铸造NFT,共花费1美分-THsInk

需要在metamask确认,共计消耗0.041POL,合$0.01USD

图片[3]-记录一次纯手动铸造NFT,共花费1美分-THsInk

3. 铸造nft

在Deployed Contracts可以选择刚部署到合约。操作到这我才发现整个流程可以一个命令行操作都没有。通过输入字段,点击按钮即可铸造。

首先准备好图片,上传到ipfs,我是自建了网关pin并且设置了白名单,那些ipfs服务商太黑了,比存储桶都贵了。

获取图片地址,比如 ipfs://Qm隐私保护-图片-n91111

写一个json文件,同样上传到ipfs并获取地址,比如ipfs://Qm隐私保护-json-n91111,json内容如下

{
  "name": "True NFT #1",
  "description": "This Is The True NFT Collection",
  "image": "ipfs://Qm隐私保护-json-n91111",
  "attributes": [
    { "trait_type": "Title", "value": "刷牙青衣" },
    { "trait_type": "Style", "value": "anime" },
    { "trait_type": "Character Name", "value": "Qing Yi" },
    { "trait_type": "Source Name", "value": "ZZZ" },
    { "trait_type": "Additional Element 1", "value": "Life Scenes" },
    { "trait_type": "Additional Element 2", "value": "🥱" },
    { "trait_type": "Generation Difficulty", "value": 35, "display_type": "number" },
    { "trait_type": "Rating", "value": "R" },
    { "trait_type": "Generation Time", "value": 175214000, "display_type": "date" }
  ]
}

attributes意义不大,写一条意思一下就行了。我为了多测试几种类型,多写了些。

在Deployed Contracts 输入接收铸造的地址和json的ipfs cid,safemint即可,随后在钱包签名,确认后即可在钱包看到:

随后可选验证合约,在polygonscan合约地址,下方的Contract标签页,点击Verify and Publish 上传合约源码即可。需要注册登录,我懒得传了。

ai发的常用操作,辩证地看,比如对于我这种偶尔mint一个的来说,不适合使用文件夹cid:

  • 铸造 NFT(Owner 权限)safeMint(to, uri)
    • to:接收 NFT 的钱包地址
    • uri:完整的 metadata URI(如 ipfs://CID/1.json
    • 点击 → MetaMask 确认 → 铸造完成后,在钱包(切换到对应网络)就能看到 NFT。
  • 修改 tokenURI(Owner 权限)setTokenURI(tokenId, uri)
    • 适合单独更新某个 NFT 的元数据。
  • 查询 NFT 信息
    • tokenURI(tokenId) → 查看某个 NFT 的元数据链接
    • ownerOf(tokenId) → 查看持有人
    • totalSupply() → 已铸造的数量
  • 转移 NFT(持有人权限)
    • safeTransferFrom(from, to, tokenId)
      • from:当前持有人地址
      • to:目标接收地址
      • tokenId:NFT 的 ID
    • 或直接在钱包/市场前端转移。

4. 在新设备mint / 调用合约

简单方法,用 Remix 的 “At Address” 功能,不需要验证合约、重新部署、其它工具。

在新设备的 Remix 打开你的 .sol 合约文件,并编译。

Deploy & Run Transactions 面板里,找到 At Address 输入框。

填你的合约地址 → 点击 At Address

Remix 会加载链上的实例,显示所有可用方法(mint、转移等),可以直接调用。

5. 总结

向上取整,合约部署花费0.041,mint一个nft花费0.0044,总计花费0.045POL,1美分,还是挺便宜。也算是体验了三年前火热的nft了😄

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!无需注册,过短或乱码评论会被屏蔽。
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容