创建一个NFT项目,发行,并且上传到IPFS

/ 默认分类 / 0 条评论 / 1530浏览

如何从头开始部署NFT项目

创建一个目录

mkdir my-nft
cd my-nft

初始化项目

npm init

如何回答安装问题的例子

package name: (my-nft)
version: (1.0.0)
description: My first NFT!
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/thesuperb1/Desktop/my-nft/package.json:

{
  "name": "my-nft",
  "version": "1.0.0",
  "description": "My first NFT!",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

安装安全帽HARDHAT

安全帽是一个用于编译、部署、测试和调试以太坊软件的开发环境。 在部署到实时链上之前,它帮助开发者在本地构建智能合约和去中心化应用程序。

my-nft项目内运行

npm install --save-dev hardhat

创建安全帽HARDHAT项目

npx hardhat

然后看到选项,选择Create an empty hardhat.config.js创建一个新的hardhat.config.js文件

888    888                      888 888               888
888    888                      888 888               888
888    888                      888 888               888
8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888
888    888     "88b 888P"  d88" 888 888 "88b     "88b 888
888    888 .d888888 888    888  888 888  888 .d888888 888
888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.
888    888 "Y888888 888     "Y88888 888  888 "Y888888  "Y888
👷 Welcome to Hardhat v2.0.11 👷‍
? 您想做什么? …
Create a sample project
❯ Create an empty hardhat.config.js
Quit

添加项目文件夹

mkdir contracts # 存放代码
mkdir scripts   # 存放脚本

Demo合约

contracts文件夹下创建MyNFT.sol,输入基于 OpenZeppelin 库的 ERC-721 实现代码

//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";

contract MyNFT is ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721("MyNFT", "NFT") {}

    function mintNFT(address recipient, string memory tokenURI)
        public onlyOwner
        returns (uint256)
    {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(recipient, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }
}

安装OpenZeppelin合约库继承类

npm install @openzeppelin/contracts

创建环境变量

安装 dotenv 软件包

npm install dotenv --save

在项目根目录下创建.env,输入以下内容,对应的在hardhat.config.js中使用

API_URL="https://eth-ropsten.alchemyapi.io/v2/your-api-key"
PRIVATE_KEY="your-metamask-private-key"

安装Ethers.js

npm install --save-dev @nomiclabs/hardhat-ethers ethers@^5.0.0

更新hardhat.config.js

/**
* @type import('hardhat/config').HardhatUserConfig
*/
require('dotenv').config();
require("@nomiclabs/hardhat-ethers");
const { API_URL, PRIVATE_KEY } = process.env;
module.exports = {
   solidity: "0.8.1",
   defaultNetwork: "ropsten",
   networks: {
      hardhat: {},
      ropsten: {
         url: API_URL,
         accounts: [`0x${PRIVATE_KEY}`]
      }
   },
}

编译合约

npx hardhat compile

部署脚本

scripts文件夹下,创建文件deploy.js

async function main() {
  const MyNFT = await ethers.getContractFactory("MyNFT")

  // Start deployment, returning a promise that resolves to a contract object
  const myNFT = await MyNFT.deploy()
  await myNFT.deployed()
  console.log("Contract deployed to address:", myNFT.address)
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error)
    process.exit(1)
  })

部署合约

到根目录运行以下代码

npx hardhat --network ropsten run scripts/deploy.js

可以看到如下信息,此时合约已经部署成功

Contract deployed to address: 0x81c587EB0fE773404c42c1d2666b5f557C470eED

安装alchemy-web3

npm install @alch/alchemy-web3

创建一个mint-nft.js文件

require("dotenv").config()
const API_URL = process.env.API_URL
const PUBLIC_KEY = process.env.PUBLIC_KEY
const PRIVATE_KEY = process.env.PRIVATE_KEY

const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
const web3 = createAlchemyWeb3(API_URL)

const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
const contractAddress = "0x81c587EB0fE773404c42c1d2666b5f557C470eED"
const nftContract = new web3.eth.Contract(contract.abi, contractAddress)

async function mintNFT(tokenURI) {
  const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce

  //the transaction
  const tx = {
    from: PUBLIC_KEY,
    to: contractAddress,
    nonce: nonce,
    gas: 500000,
    data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(),
  }

  const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)
  signPromise
    .then((signedTx) => {
      web3.eth.sendSignedTransaction(
        signedTx.rawTransaction,
        function (err, hash) {
          if (!err) {
            console.log(
              "The hash of your transaction is: ",
              hash,
              "\nCheck Alchemy's Mempool to view the status of your transaction!"
            )
          } else {
            console.log(
              "Something went wrong when submitting your transaction:",
              err
            )
          }
        }
      )
    })
    .catch((err) => {
      console.log(" Promise failed:", err)
    })
}

更新.env文件

API_URL = "https://eth-ropsten.alchemyapi.io/v2/your-api-key"
PRIVATE_KEY = "your-private-account-address"
PUBLIC_KEY = "your-public-account-address"

上传图片和Json文件到IPFS,到https://app.pinata.cloud/或者https://nft.storage/注册一个账号

图片直接上传,并获取到IPFS链接

QmUZETppzhxrC4i9AAQnRgsPVTp79jegDjGs2N6zdJfDai

创建一个nft-metadata.json文件,添加以下代码,下列数据除key之外都可随意修改

{
  "attributes": [
    {
      "trait_type": "Breed",
      "value": "Maltipoo"
    },
    {
      "trait_type": "Eye color",
      "value": "Mocha"
    }
  ],
  "description": "The world's most adorable and sensitive pup.",
  "image": "ipfs://QmUZETppzhxrC4i9AAQnRgsPVTp79jegDjGs2N6zdJfDai",
  "name": "Ramses"
}

上传nft-metadata.json文件到pinata

使用https://gateway.pinata.cloud/ipfs/<metadata-hash-code>就可查看,例如

https://gateway.pinata.cloud/ipfs/Qma8o7ovmNt5HPBgPVSuw2SQo9fUB15dv2ysiMMxYeC9W4

部署NFT

根目录运行

node scripts/mint-nft.js

显示内容

The hash of your transaction is: 0x10e5062309de0cd0be7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0
Check Alchemy's Mempool to view the status of your transaction!

这样就成功发行NFT

在区块浏览器验证合约代码

区块浏览器注册https://bscscan.com/账户, 找到API-KEYSApi-Key Token

.env中添加环境变量VERIFY_API_KEY输入这个Api-Key Token

更新hardhat.config,加入以下代码

etherscan: {
    // Your API key for Etherscan
    // Obtain one at https://etherscan.io/
    apiKey: VERIFY_API_KEY
  },

开始验证

根目录运行,如果报错可先清理artifactscache目录

npx hardhat verify --network ropsten 0x5B9EF19e1840C3Ad148c09a465D5xxxxxxxxx

出现如下内容即成功

for verification on the block explorer. Waiting for verification result...
Successfully verified contract MyNFT on Etherscan.

参考链接: https://ethereum.org/zh/developers/tutorials/how-to-write-and-deploy-an-nft/ https://ethereum.org/zh/developers/tutorials/how-to-mint-an-nft/