前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >NFT新手教程: 如何编写和部署NFT(第1部分)

NFT新手教程: 如何编写和部署NFT(第1部分)

作者头像
Tiny熊
发布2022-05-25 16:11:00
3.8K0
发布2022-05-25 16:11:00
举报

译文出自:登链翻译计划[1] 译者:翻译小组[2] 校对:Tiny 熊[3]

本教程是 NFT 系列的第一部分,将带你逐步了解如何使用以太坊和 Inter Planetary File System(IPFS)编写和部署一个非同质化(ERC-721 代币)智能合约。

随着 NFT 将区块链带入公众视野,现在是一个极好的机会,通过在以太坊区块链上发布自己的 NFT(ERC-721 代币)来宣传自己。

Alchemy[4] 非常自豪能够为 NFT 领域的大公司提供支持,包括 Makersplace(最近在佳士得创造了 6900 万美元的数字艺术品销售记录)、Dapper Labs(NBA Top Shot & Crypto Kitties 的创造者)、OpenSea(世界上最大的 NFT 市场)、Zora、Super Rare、NFTfi、基金会、Enjin、Origin Protocol、Immutable 等等。

在本教程中,我们将通过使用MetaMask[5]、Solidity[6]、Hardhat[7]、Pinata[8]和Alchemy[9]在 Ropsten 测试网络上创建和部署一个 ERC-721 智能合约。

在本教程的第二部分,将讨论如何使用我们的智能合约来铸造一个 NFT,在第三部分,我们将解释如何在 MetaMask 上查看你的 NFT。

当然,如果你在任何时候有问题,不要犹豫,请联系Alchemy Discord[10]或访问Alchemy 的 NFT API 文档[11]!

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

有一堆方法可以向以太坊区块链提出请求,但为了方便起见,我们将使用Alchemy[12]上的免费账户,这是一个区块链开发者平台和 API,允许我们与以太坊链进行通信,而无需运行我们自己的节点。

在本教程中,我们还将利用 Alchemy 开发者工具进行监控和分析,以了解我们的智能合约部署中的幕后情况。如果你还没有 Alchemy 账户,你可以免费注册这里[13]

第 2 步:在 Alchemy 你创建应用获取 API 密钥

一旦你创建了 Alchemy 账户,你可以通过创建一个应用程序来生成一个 API 密钥。我们通过 API 密钥向 Ropsten 测试网络发出请求。如果你想了解更多关于测试网络的信息,请查看本指南[14]

  1. 导航到 Alchemy 仪表板的 Create App页面,将鼠标悬停在导航栏的 App上,并点击 Create App

创建你的应用程序

  1. 为你的应用命名(我们使用 My First NFT!),提供一个简短的描述,环境选择 Staging,并为你的网络选择 Ropsten

配置应用

  1. 点击 Create app,就可以了! 你的应用应该出现在下面的表格中。

第 3 步:创建一个以太坊账户(地址) {#create-eth-address}

我们需要一个以太坊账户来发送和接收交易。在本教程中,我们将使用 MetaMask,这是一个浏览器中的虚拟钱包,用于管理你的以太坊账户地址。

你可以免费下载MetaMask[15]并创建一个账户。或者如果你已经有一个账户,确保切换到右上方的 Ropsten测试网络(这样我们就不用花费真的以太币)。

设置Ropsten为你的网络

第 4 步:从水龙头添加以太币 {#step-4-add-ether-from-a-faucet}

为了将我们的智能合约部署到测试网络,我们需要一些假的 ETH。你可以去FaucETH[16]获得 ETH,输入你的 Ropsten 账户地址,点击 Request funds,然后在下拉菜单中选择 Ethereum Testnet Ropsten,最后再次点击 Request funds 按钮。你应该很快在你的 MetaMask 账户中看到收到的 ETH!

第 5 步:检查你的余额 {#check-balance}

为了再次确定我们的余额,让我们使用Alchemy 的 composer 工具[17]做一个eth_getBalance[18]请求。这将返回我们钱包中的 ETH 数量。在你输入你的 MetaMask 账户地址并点击 发送请求后,你应该看到一个像这样的响应:

代码语言:javascript
复制
{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}
  • 注意: 余额的结果返回以 wei 为单位,而不是 eth, Wei 是以太币的最小单位,转换关系是:1 eth = 1018 wei. 因为如果我们转换 0xde0b6b3a7640000 为 10 进制,者是 1*1018 , 等于 1 ETH(这个测试网上的假币).

第 6 步: 初始化工程

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

代码语言:javascript
复制
mkdir my-nft
    cd my-nft

现在我们进入了项目文件夹,我们将使用npm init来初始化项目。如果你还没有安装 npm,按照这个说明[19](我们还需要 Node.js,所以也下载它!)

代码语言:javascript
复制
npm init

初始化项目时,需要进行一些设置,以回答问题的方式设置,如何回答安装问题并不重要,以下是我们的做法,以供参考:

代码语言:javascript
复制
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"
    }

第 7 步: 安装 Hardhat

Hardhat[20]是一个开发环境,用于编译、部署、测试和调试你的以太坊软件。它可以帮助开发者在部署到真实链之前在本地构建智能合约和 dApps。

在我们的 my-nft 项目中运行:

代码语言:javascript
复制
npm install --save-dev hardhat

查看这个页面,了解更多关于安装说明[21]的细节。

第 8 步:创建 Hardhat 项目 {#create-hardhat-project}

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

代码语言:javascript
复制
npx hardhat

然后你应该看到一个欢迎信息和选择你想做什么的选项。这里选择 Create an empty hardhat.config.js

代码语言:javascript
复制
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 步:添加项目文件夹 {#add-project-folders}

为了使我们的项目有条理,我们将创建两个新的文件夹。在你的命令行中导航到项目的根目录,然后输入:

代码语言:javascript
复制
mkdir contracts
    mkdir scripts
  • contracts/ 是我们保存 NFT 智能合约代码的地方
  • scripts/ 是我们保存脚本的地方,用于部署和与我们的智能合约进行交互。

第 10 步:编写我们的合约

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

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

  1. 导航到contracts文件夹,并创建一个名为 MyNFT.sol 的新文件。
  2. 下面是我们的 NFT 智能合约代码,我们基于OpenZeppelin[24]库的 ERC-721 实现。复制并粘贴以下内容到你的 MyNFT.sol 文件中:
代码语言:javascript
复制
//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](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;
       }
   }
  1. 因为我们要从 OpenZeppelin 合约库中继承基础合约类,在你的命令行中运行npm install @openzeppelin/contracts来把这个库安装到我们的工程中。

那么,上面这段代码到底做了什么?让我们逐行分解:

在我们的智能合约的顶部,我们导入了三个OpenZeppelin[25]智能合约类:

  • @openzeppelin/contracts/token/ERC721/ERC721.sol 包含 ERC-721 标准的实现,我们的 NFT 智能合约将继承这个标准。(要成为一个有效的 NFT,你的智能合约必须实现 ERC-721 标准的所有方法)。要了解更多关于继承的 ERC-721 功能,请查看接口定义这里[26]
  • @openzeppelin/contracts/utils/Counters.sol 提供了只能加 1 或减 1 的计数器。我们的智能合约使用计数器来跟踪已铸币的 NFT 总数,并在我们的新 NFT 上设置唯一的 ID。(每个使用智能合约铸造的 NFT 必须被分配一个唯一的 ID-- 在本文案例中,我们的唯一 ID 只是由存在的 NFT 总数决定。例如,我们用智能合约铸造的第一个 NFT 的 ID 是 1,我们的第二个 NFT 的 ID 是 2,等等)。
  • @openzeppelin/contracts/access/Ownable.sol 在我们的智能合约上设置了访问控制[27],所以只有智能合约的所有者(你)可以铸币 NFT。(注意,包括访问控制完全是一种偏好。如果你希望任何人都能使用你的智能合约铸造 NFT,请删除第 10 行的 Ownable 一词和第 17 行的 onlyOwner)。

在我们的导入语句之后,我们有了自定义的 NFT 智能合约,它出乎意料地短 -- 它只包含一个计数器、一个构造函数和一个函数!这要归功于我们继承的 OpenZeppelin 合约,它实现了我们需要创建 NFT 的大部分方法,,例如ownerOf,它返回 NFT 的所有者,以及transferFrom,它将 NFT 的所有权从一个账户转移到另一个账户。

在我们的 ERC-721 构造函数中,你会注意到我们传递了两个字符串,MyNFTNFT。第一个变量是智能合约的名称,第二个是其符号。你可以随心所欲地给这些变量命名!

最后,我们有我们的函数mintNFT(address recipient, string memory tokenURI),用来铸造一个 NFT,你会注意到这个函数接收了两个变量:

  • address recipient指定将收到你新铸的 NFT 的地址
  • string memory tokenURI是一个字符串,应该解析为一个描述 NFT 元数据的 JSON 文档。NFT 的元数据实际上是给它带来生命的东西,允许它有可配置的属性,如名称、描述、图像和其他属性。在本教程的第二部分,我们将描述如何配置这个元数据。

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

第 11 步:在项目配置 MetaMask 和 Alchemy

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

从你的虚拟钱包发出的每一笔交易都需要使用你独特的私钥进行签名。为了向我们的程序提供这种许可,我们可以在环境文件中安全地存储我们的私钥(和 Alchemy API 密钥)。

要了解更多关于发送交易的信息,请查看本教程[28]关于使用 web3 发送交易。

首先,在你的项目目录下安装 dotenv 包。

代码语言:javascript
复制
npm install dotenv --save

然后,在我们项目的根目录下创建一个.env文件,将你的 MetaMask 私钥和 HTTP Alchemy API URL 加入到文件中。

  • 按照这些说明[29],从 MetaMask 导出你的私钥
  • 请看下面的说明,以获得 HTTPAlchemyAPI URL,并将其复制到你的剪贴板上

Copy your Alchemy API URL

.env 文件的内容类似:

代码语言:javascript
复制
API_URL="https://eth-ropsten.alchemyapi.io/v2/your-api-key"
    PRIVATE_KEY="your-metamask-private-key"

要将这些变量实际连接到我们的代码,我们将在步骤 13 中修改 hardhat.config.js 文件中来引用这些变量。

不提交 .env, 请确保不要共享或公开 .env文件,因为这样做会泄露你的密钥 。如果使用版本控制,请添加 .env到 .gitignore 文件里。

第 12 步: 安装 Ethers.js

Ethers.js 是一个库,通过更友好的方法包装标准 JSON-RPC 方法[30],以便用户更容易与以太坊链进行交互。

Hardhat 通过集成插件[31]的方式非常容易就可以获得额外的工具和功能扩展。我们将利用Ethers 插件[32]进行合约部署(Ethers.js[33]有一些很简洁的合约部署方法)。

在项目目录下输入以下命令以安装 Ethers.js:

代码语言:javascript
复制
npm install --save-dev @nomiclabs/hardhat-ethers ethers@^5.0.0

在下一步中,我们还将在 hardhat.config.js 中 ethers。

第 13 步: 修改 hardhat.config.js

前面,我们已经添加了几个依赖和插件,现在需要更新 hardhat.config.js,以便项目知道所有相关的配置和插件。

更新 hardhat.config.js,使其看起来像这样:

代码语言:javascript
复制
/**
    * @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}`]
          }
       },
    }

第 14 步:编译合约

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

在命令行上运行:

代码语言:javascript
复制
npx hardhat compile

你可能会得到一个关于源文件中没有提供 SPDX 许可证标识符的警告,但不需要担心这个问题。

第 15 步: 编写部署脚本

现在我们的合约已经写好了,我们的配置文件也可以使用了,现在是时候写我们的合约部署脚本了。

进入到 scripts/文件夹,创建一个名为 deploy.js 的新文件,添加以下内容:

代码语言:javascript
复制
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)
  })

Hardhat 在合约教程[34]中对这些代码的每一行都做了很好的解释,我们在这里采用了他们的解释。

代码语言:javascript
复制
const MyNFT = await ethers.getContractFactory("MyNFT");

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

代码语言:javascript
复制
const myNFT = await MyNFT.deploy();

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

第 16 步:部署合约

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

代码语言:javascript
复制
npx hardhat --network ropsten run scripts/deploy.js

然后你应该看到类似这样的提示:

代码语言:javascript
复制
Contract deployed to address: 0x81c587EB0fE773404c42c1d2666b5f557C470eED

如果去Ropsten etherscan[35]并搜索合约地址,我们应该能够看到它已经被成功部署。如果你不能立即看到它,请等待一段时间,因为它可能需要一些时间。该交易将看起来像这样。

在Etherscan上查看您的交易地址

From地址应与你的 MetaMask 账户地址一致,收件人地址将显示为 Contract Creattion(合约创建)。如果我们点击进入交易,我们会在To字段下看到我们的合约地址。

在Etherscan上查看您的合约地址

耶~,你刚刚把你的 NFT 智能合约部署到了以太坊链上!

为了了解背后的交易的情况,让我们浏览一下Alchemy dashboard[36], 如果你有多个 Alchemy 应用,请确保按应用过滤并选择 "MyNFT"。

使用Alchemy的资源管理器仪表板查看 "引擎 "下的调用

在这里,你会看到 Hardhat/Ethers 在我们调用.deploy()函数时,在交易背后为我们发起的的少量 JSON-RPC 调用。这里有两个重要的调用是 eth_sendRawTransaction[37],这是实际把我们的智能合约写入到 Ropsten 链的请求。和 eth_getTransactionByHash[38],这是一个读取交易的哈希值的请求(发送交易时的一个典型模式)。要了解更多关于发送交易的信息,请查看这个使用 Web3 发送交易[39]的教程。

本教程的第一部分就到此为止。接下来还有第二部分,将通过铸造 NFT 与我们的智能合约进行交互,及第三部分,展示如何在以太坊钱包中查看你的 NFT。

原文: https://ethereum.org/en/developers/tutorials/how-to-write-and-deploy-an-nft/

参考资料

[1]

登链翻译计划: https://github.com/lbc-team/Pioneer

[2]

翻译小组: https://learnblockchain.cn/people/412

[3]

Tiny 熊: https://learnblockchain.cn/people/15

[4]

Alchemy: https://alchemy.com/?r=7d60e34c-b30a-4ffa-89d4-3c4efea4e14b

[5]

MetaMask: https://metamask.io/

[6]

Solidity: https://learnblockchain.cn/docs/solidity/

[7]

Hardhat: https://learnblockchain.cn/docs/hardhat/getting-started/

[8]

Pinata: https://pinata.cloud/

[9]

Alchemy: https://alchemy.com/signup/eth

[10]

Alchemy Discord: https://discord.gg/gWuC7zB

[11]

Alchemy的NFT API文档: https://docs.alchemy.com/alchemy/enhanced-apis/nft-api

[12]

Alchemy: https://alchemy.com/?r=7d60e34c-b30a-4ffa-89d4-3c4efea4e14b

[13]

这里: https://alchemy.com/?r=7d60e34c-b30a-4ffa-89d4-3c4efea4e14b

[14]

本指南: https://docs.alchemyapi.io/guides/choosing-a-network

[15]

MetaMask: https://metamask.io/download.html

[16]

FaucETH: https://fauceth.komputing.org

[17]

Alchemy的composer工具: https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D

[18]

eth_getBalance: https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance

[19]

这个说明: https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm

[20]

Hardhat: https://learnblockchain.cn/docs/hardhat/getting-started/

[21]

安装说明: https://learnblockchain.cn/docs/hardhat/getting-started/#%E5%AE%89%E8%A3%85

[22]

VSCode: https://code.visualstudio.com/

[23]

Solidity: https://learnblockchain.cn/docs/solidity/

[24]

OpenZeppelin: https://docs.openzeppelin.com/contracts/3.x/erc721

[25]

OpenZeppelin: https://openzeppelin.com/

[26]

这里: https://eips.ethereum.org/EIPS/eip-721

[27]

访问控制: https://docs.openzeppelin.com/contracts/3.x/access-control

[28]

本教程: https://ethereum.org/en/developers/tutorials/sending-transactions-using-web3-and-alchemy/

[29]

这些说明: https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key

[30]

标准JSON-RPC方法: /developers/docs/apis/json-rpc/

[31]

插件: https://hardhat.org/plugins/

[32]

Ethers插件: https://hardhat.org/plugins/nomiclabs-hardhat-ethers.html

[33]

Ethers.js: https://github.com/ethers-io/ethers.js/

[34]

合约教程: https://learnblockchain.cn/docs/hardhat/tutorial/testing-contracts.html

[35]

Ropsten etherscan: https://ropsten.etherscan.io/

[36]

Alchemy dashboard: https://dashboard.alchemyapi.io/explorer

[37]

eth_sendRawTransaction: /developers/docs/apis/json-rpc/#eth_sendrawtransaction

[38]

eth_getTransactionByHash: /developers/docs/apis/json-rpc/#eth_gettransactionbyhash

[39]

使用Web3发送交易: https://ethereum.org/en/developers/tutorials/sending-transactions-using-web3-and-alchemy/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 深入浅出区块链技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第 1 步:连接到以太坊网络
  • 第 2 步:在 Alchemy 你创建应用获取 API 密钥
  • 第 3 步:创建一个以太坊账户(地址) {#create-eth-address}
  • 第 4 步:从水龙头添加以太币 {#step-4-add-ether-from-a-faucet}
  • 第 5 步:检查你的余额 {#check-balance}
  • 第 6 步: 初始化工程
  • 第 7 步: 安装 Hardhat
  • 第 8 步:创建 Hardhat 项目 {#create-hardhat-project}
  • 第 9 步:添加项目文件夹 {#add-project-folders}
  • 第 10 步:编写我们的合约
  • 第 11 步:在项目配置 MetaMask 和 Alchemy
  • 第 12 步: 安装 Ethers.js
  • 第 13 步: 修改 hardhat.config.js
  • 第 14 步:编译合约
  • 第 15 步: 编写部署脚本
  • 第 16 步:部署合约
    • 参考资料
    相关产品与服务
    云开发 CLI 工具
    云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档