如何创建 NFT

本教程将引导您使用以太坊和星际文件系统 (IPFS) 编写和部署不可替代 (ERC721) 令牌智能合约。

完成本指南的预计时间:~15 分钟

即使你一直生活在岩石下,你也会注意到每个主要新闻媒体都在描述 NFT 的兴起。

随着 NFT 将区块链带入公众视野,现在是通过在以太坊区块链上发布您自己的 NFT(ERC-721 代币)来了解炒作的绝佳机会!

在本教程中,我们将逐步使用MetamaskSolidityHardhatPinataAlchemy在 Goerli 测试网络上创建和部署 ERC-721 智能合约(如果您还不明白其中的任何含义,请不要担心——我们会解释)。

第 1 步:连接到以太坊网络

有很多方法可以向以太坊区块链发出请求,但为了让事情变得最简单,我们将在Alchemy上使用一个免费帐户,这是一个区块链开发平台和 API,允许我们与以太坊链进行通信而无需运行我们自己的节点。

在本教程中,我们还将利用 Alchemy 的开发人员工具进行监控和分析,以了解智能合约部署的幕后情况。

第 2 步:创建您的应用程序(和 API 密钥)

创建 Alchemy 帐户后,您可以通过创建应用程序来生成 API 密钥。这将允许我们向 Goerli 测试网络发出请求。如果您想了解有关测试网络的更多信息,请查看本指南。

1、通过将鼠标悬停在导航栏中的“应用程序”上并单击“创建应用程序”,导航到 Alchemy 仪表板中的“创建应用程序”页面

2、为您的应用命名(我们选择“我的第一个 NFT!”),提供简短描述,为环境选择“Staging”(用于您的应用簿记),并为您的网络选择“Goerli”。

3、单击“创建应用程序”即可!您的应用程序应出现在下表中。

第3步:创建以太坊账户(地址)

我们需要一个以太坊账户来发送和接收交易。在本教程中,我们将使用 Metamask,这是浏览器中的一个虚拟钱包,用于管理您的以太坊帐户地址。如果您想了解更多有关以太坊交易如何运作的信息,请查看以太坊基金会的此页面

您可以在此处免费下载并创建 Metamask 帐户。当您正在创建一个帐户时,或者如果您已经有一个帐户,请确保切换到右上角的“Goerli 测试网络”(这样我们就不会处理真钱)。

第 4 步:从Faucet添加ETH

为了将我们的智能合约部署到测试网络,我们需要一些假 Eth。要获取 Eth,您可以前往Goerli Faucet 并输入您的 Goerli 帐户地址,然后单击“发送给我 Eth”。不久之后,您应该会在您的 Metamask 帐户中看到 Eth!

第 5 步:检查您的余额

为了仔细检查我们的余额,让我们使用Alchemy 的 composer 工具发出eth_getBalance请求。这将返回我们钱包中的 ETH 数量。输入您的 Metamask 帐户地址并单击“发送请求”后,您应该会看到如下响应:

{“jsonrpc”:“2.0”,“id”:0,“结果”:“0xde0b6b3a7640000”}

注意:这个结果是在 wei 而不是 eth 中。魏被用作以太的最小面额。从 wei 到 eth 的转换是:1 eth = 10¹⁸ wei。因此,如果我们将 0xde0b6b3a7640000 转换为十进制,我们将得到 1*10¹⁸,等于 1 eth。

呸!我们的假钱都在那里!🤑

第6步:初始化我们的项目

首先,我们需要为我们的项目创建一个文件夹。导航到您的命令行并键入:

mkdir my-nft
cd my-nft

现在我们在我们的项目文件夹中,我们将使用 npm init 来初始化项目。如果您还没有安装 npm,请按照这些说明进行操作(我们还需要Node.js,所以也下载它!)。

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"
}

批准 package.json,我们就可以开始了!

第 7 步:下载Hardhat

Hardhat 是一个用于编译、部署、测试和调试以太坊软件的开发环境。它可以帮助开发人员在部署到实时链之前在本地构建智能合约和 dApp。

导航到终端并确保您位于 my-nft 项目文件夹中,然后运行:

npm install --save-dev hardhat

查看此页面以获取有关安装说明的更多详细信息。

第 8 步:创建 Hardhat 项目

在我们的项目文件夹中运行:

npx hardhat

然后您应该会看到一条欢迎消息和选择您想要执行的操作的选项。选择“创建一个空的 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 👷‍
? What do you want to do?
Create a sample project
❯ Create an empty hardhat.config.js
Quit

这将为我们生成一个hardhat.config.js文件,我们将在其中指定项目的所有设置(第 13 步)。

第 9 步:添加项目文件夹

为了让我们的项目井井有条,我们将创建两个新文件夹。在命令行中导航到项目的根目录并键入:

mkdir contracts
mkdir scripts

contracts/是我们保存 NFT 智能合约代码的地方

scripts/是我们将保留脚本以部署并与我们的智能合约交互的地方

第10步:写我们的合同

现在我们的环境已经设置好了,接下来是更令人兴奋的事情:编写我们的智能合约代码!

在您喜欢的编辑器(我们喜欢VSCode)中打开 my-nft 项目。智能合约是用一种叫做 Solidity 的语言编写的,我们将用它来编写我们的 MyNFT.sol 智能合约。

1. 导航到“contracts”文件夹并创建一个名为 MyNFT.sol 的新文件

2. 下面是我们的 NFT 智能合约代码,它基于OpenZeppelin库的 ERC721 实现。将以下内容复制并粘贴到您的 MyNFT.sol 文件中。

注意:如果您想通过智能合约为 NFT 附加价格,请查看本教程。

//Contract based on https://docs.openzeppelin.com/contracts/3.x/erc721
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.3;

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


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

    constructor() public 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;
    }
}

1. 因为我们从 OpenZepplin 合约库继承类,所以在命令行中运行以下命令将库安装到我们的文件夹中:

npm 安装@openzeppelin/ contracts @3.1.0-solc-0.7

那么,这段代码究竟做了什么?让我们逐行分解它。

在第 5-7 行,我们的代码继承了三个OpenZepplin智能合约类:

- @openzeppelin/contracts/token/ERC721/ERC721.sol包含ERC721标准的实现,我们的NFT智能合约将继承该标准。(要成为有效的 NFT,您的智能合约必须实现 ERC721 标准的所有方法。)要了解有关继承的 ERC721 功能的更多信息,请查看此处的接口定义。

- @openzeppelin/contracts/utils/Counters.sol 提供了只能递增或递减 1 的计数器。我们的智能合约使用一个计数器来跟踪铸造的 NFT 总数,并为我们的新 NFT 设置唯一 ID。每个使用智能合约铸造的 NFT 都必须分配一个唯一 ID——这里我们的唯一 ID 仅由现有 NFT 的总数决定。例如,我们用智能合约铸造的第一个 NFT 的 ID 为“1”,第二个 NFT 的 ID 为“2”,等等。

- @openzeppelin/contracts/access/Ownable.sol 在我们的智能合约上设置访问控制,因此只有智能合约的所有者(您)才能铸造 NFT。请注意,包括访问控制完全是一种偏好。如果您希望任何人都能够使用您的智能合约铸造 NFT,请删除第 10 行的 Ownable 和第 17 行的 onlyOwner 一词。

在第 10-28 行,我们有自定义的 NFT 智能合约,它非常短——它只包含一个计数器、一个构造函数和一个函数!这要归功于我们继承的 OpenZepplin 合约,它实现了我们创建 NFT 所需的大部分方法,例如 ownerOf(返回 NFT 的所有者)和 transferFrom(转移 NFT 的所有权)。

在第 14 行,您会注意到我们将 2 个字符串“MyNFT”和“NFT”传递给 ERC721 构造函数。第一个变量是智能合约的名称,第二个是它的符号。您可以随意命名这些变量中的每一个!

最后,从第 16 行开始,我们有函数 mintNFT() 允许我们铸造 NFT!你会注意到这个函数有两个变量:

- 地址收件人指定将接收您新鲜铸造的 NFT 的地址

- string memory tokenURI 是一个字符串,应该解析为描述 NFT 元数据的 JSON 文档。NFT 的元数据真正赋予它生命,使其具有额外的属性,例如名称、描述、图像和其他属性。在本教程的第 2 部分中,我们将描述如何配置此元数据。

mintNFT从继承的 ERC721 库中调用一些方法,并最终返回一个数字,代表新铸造的 NFT 的 ID。

第 11 步:将 Metamask 和 Alchemy 连接到您的项目

现在我们已经创建了 Metamask 钱包、Alchemy 账户并编写了我们的智能合约,是时候连接这三者了。

从您的虚拟钱包发送的每笔交易都需要使用您唯一的私钥进行签名。为了向我们的程序提供此权限,我们可以安全地将私钥(和 Alchemy API 密钥)存储在环境文件中。

要了解有关发送交易的更多信息,请查看有关使用 web3 发送交易的教程。

首先,在您的项目目录中安装 dotenv 包:

npm install dotenv --save

然后,在我们项目的根目录中创建一个.env文件,并将您的 Metamask 私钥和 HTTP Alchemy API URL 添加到其中。

注意:您的 .env 文件必须命名为 .env !不要将名称更改为 xx.env

- 按照这些说明从 Metamask 导出您的私钥

- 请参阅下文以获取 HTTP Alchemy API URL 并将其复制到剪贴板

你的.env应该是这样的:

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

第 12 步:安装 Ethers.js

Ethers.js 是一个库,它通过使用更用户友好的方法包装标准 JSON-RPC 方法,使与以太坊交互和向以太坊发出请求变得更加容易。

Hardhat 使得集成插件以获得额外的工具和扩展功能变得超级容易。我们将利用Ethers 插件进行合约部署(Ethers.js有一些超级干净的合约部署方法)。

在您的项目目录类型中:

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

在下一步中,我们还将在我们的hardhat.config.js中需要以太币。

第 13 步:更新 hardhat.config.js

到目前为止,我们已经添加了几个依赖项和插件,现在我们需要更新hardhat.config.js以便我们的项目了解所有这些。

将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.7.3",
   defaultNetwork: "goerli",
   networks: {
      hardhat: {},
      goerli: {
         url: API_URL,
         accounts: [`0x${PRIVATE_KEY}`]
      }
   },
}

第 14 步:编译我们的合约

为了确保到目前为止一切正常,让我们编译我们的合约。编译任务是内置安全帽任务之一。

从命令行运行:

npx hardhat compile

您可能会收到有关 SPDX 许可证标识符未在源文件中提供的警告,但无需担心 - 希望其他一切看起来都不错!如果没有,您可以随时在Alchemy discord中留言。

第 15 步:编写我们的部署脚本

现在我们的合约已经编写好了,配置文件也准备好了,是时候编写我们的合约部署脚本了。

导航到scripts/文件夹并创建一个名为deploy.js的新文件,向其中添加以下内容:

async function main() {
   // Grab the contract factory
   const MyNFT = await ethers.getContractFactory("MyNFT");

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

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

Hardhat 在他们的Contracts 教程中解释了每一行代码的作用,做得非常出色,我们在这里采用了他们的解释。

const MyNFT = await ethers.getContractFactory("MyNFT");

ethers.js 中的ContractFactory是用于部署新智能合约的抽象,因此这里的 MyNFT 是我们 NFT 合约实例的工厂。当使用hardhat-ethers插件时, ContractFactoryContract实例默认连接到第一个签名者。

const myNFT = await MyNFT.deploy();

ContractFactory上调用deploy()将开始部署,并返回解析为Contract的Promise 。这是为我们的每个智能合约功能提供方法的对象。

第 16 步:部署我们的合约

我们终于准备好部署我们的智能合约了!导航回项目目录的根目录,并在命令行中运行:

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

然后你应该看到类似的东西:

Contract deployed to address: 0xb8949d5685588fd73Fd002585D9f18F48c0078Fa

如果我们去Goerli etherscan并搜索我们的合约地址,我们应该能够看到它已经部署成功。交易看起来像这样:

发件人地址应与您的 Metamask 帐户地址匹配,收件人地址将显示“合约创建”。如果我们点击进入交易,我们将在收件人字段中看到我们的合约地址:

哎呀!您刚刚将 NFT 智能合约部署到以太坊链 🎉

要了解幕后发生的事情,让我们导航到Alchemy 仪表板中的资源管理器选项卡。如果您有多个 Alchemy 应用程序,请确保按应用程序过滤并选择“MyNFT”。

在这里,您将看到 Hardhat/Ethers 在我们调用.deploy()函数时在后台为我们进行的一些 JSON-RPC 调用。

这里需要指出的两个重要的是eth_sendRawTransaction,这是将我们的智能合约实际写入 Goerli 链的请求,以及eth_getTransactionByHash,这是在给定哈希值的情况下读取有关我们交易的信息的请求(发送交易时的典型模式)。

要了解有关发送交易的更多信息,请查看有关使用 Web3 发送交易的教程。

最后更新于