Ethereum非同质化通证(NFT)的编写与部署

  • 前言
  • 一、创建Ethereum账户
  • 二、添加测试币
  • 三、连接到以太坊网络
  • 四、创建应用
  • 五、初始化项目并安装HARDHAT
  • 六、开始智能合约之旅
  • 七、编译及部署智能合约
    • 1.项目中配置Metamask及Alchemy
    • 2.安装 ETHERS.JS 并更新配置
    • 3.编译合约
    • 4.编写部署脚本
    • 5.部署合约
  • 总结

前言

随着非同质化通证(NFT)日渐活跃,让更多的人了解到NFT,也让更多的项目甚至个人可以通过在Ethereum区块链上发布自己的非同质化通证(基于ERC-721协议)从而走进Web3.0的世界。

在本篇文章中,将着重介绍如何在Ethereum区块链上发布自己的基于ERC-721协议的非同质化通证。其中我们将涉及到 MetaMask(区块链钱包)、Solidity(智能合约语言)、Hardhat(以太坊软件的开发环境)、Alchemy(区块链开发平台)和Pinata(星际文件系统平台)的学习和使用。并在 Goerli 测试网络上创建和部署 ERC-721 智能合约的完整过程。


一、创建Ethereum账户

要进入以太坊的世界,以太坊账户(钱包)当然是必不可少的。本文中将使用 MetaMask 这个基于浏览器的在线钱包,用来管理以太坊的账户地址。
大家可以通过这里下载安装 MetaMask 钱包,并创建一个以太坊的账户。同时,请确保钱包使用的是 “Goerli 测试网络”。


二、添加测试币

刚刚创建的以太坊账户里面是没有任何测试币的,需要通过水龙头领取一些测试币。我们可以通过这个网站“挖”一点 Goerli 测试网络的测试币,不用太多零点几个就好。挖好并获取测试币之后,稍等一会就能在 MetaMask 钱包中查看到刚刚获取的测试币了。


三、连接到以太坊网络

我们要开发以太坊网络上的应用,必不可少的就是先连接到以太坊网络。现在有很多种方式可以连接到以太坊网络,比如自己部署一个以太坊节点或者直接使用成熟的以太坊开发平台等等。在本文中,为了方便起见将直接使用成熟的开发平台 Alchemy 。这是一个区块链开发平台,能够提供应用程序接口,让我们无需自己运行区块链节点,便可与以太坊公链进行通信。
如果大家还没有Alchemy平台账号可以点击这里注册。与之类似的平台还有Infura,后续大家可以自行研究。


四、创建应用

当创建了 Alchemy 账户后,就可以在其中创建应用程序,并生成应用程序接口密钥,之后就可以用它向 Goerli 测试网络发起请求了。

  1. 登录 Alchemy 账号面板,在顶部 Apps 中鼠标悬停下拉选择 “Create App”

  2. 设置好应用的NAME和DESCRIPTION,切记在NETWORK中下拉选择Goerli网络,最后点击“Create app”创建应用。


五、初始化项目并安装HARDHAT

接下来开始我们本地开发环境的操作,本文中使用的是Ubuntu系统,并且需要安装好node及npm。如果是在Windows中也是同样的用法,不过还是建议大家安装一个WSL的Ubuntu系统。

$ sudo mkdir new-nft
$ cd new-nft

进入项目目录,使用 npm init 初始化项目。

npm init

这时会有一些问题需要回答,不要在意这些细节,它们并不重要,不断按回车键就好。就比如这样:

package name: (new-nft)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /mnt/d/Projects/new-nft/package.json:{"name": "new-nft","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"author": "","license": "ISC"
}
Is this OK? (yes)

下面开始安装HARDHAT,这是一个用于编译、部署、测试和调试以太坊软件的开发环境。在把项目部署上线之前,它可以帮助开发者在本地构建智能合约和去中心化应用程序。
仍然在项目根目录中运行

npm install --save-dev hardhat

完成后接着就可以创建HARDHAT的项目了
仍然在项目根目录中运行

npx hardhat

这时应该能看到一个欢迎消息和一些选择,使用键盘上下键选择“Create an empty 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  "Y888Welcome to Hardhat v2.9.9? What do you want to do? …
▸ Create a basic sample projectCreate an advanced sample projectCreate an advanced sample project that uses TypeScriptCreate an empty hardhat.config.jsQuit

完成后将在文件夹中生成一个 hardhat.config.js 文件,这是用来配置项目的所有设置信息的,后面会使用到。


六、开始智能合约之旅

至此,环境搭建工作基本告一段落,接下来就开启智能合约之旅。这里有个小建议,为了项目中的文件条理清晰,建议在项目目录中新建如下两个文件夹。

mkdir contracts
mkdir scripts

contracts 用来保存非同质化通证智能合约代码
scripts 用来存放用于部署智能合约和与之进行交互的脚本文件

使用编辑器打开 new-nft 项目目录,这里推荐使用Visual Studio Code来编写Solidity 语言代码。当然,如果习惯使用 WebStorm 也是可以的。

在 contracts 文件夹中创建一个名为 NewNFT.sol 的文件。

下面是非同质化通证智能合约的代码,它基于 OpenZeppelin 库的 ERC-721 实现。可以直接复制粘贴以下内容到 NewNFT.sol 文件。

//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 NewNFT is ERC721URIStorage, Ownable {using Counters for Counters.Counter;Counters.Counter private _tokenIds;constructor() ERC721("NewNFT", "NFT") {}function mintNFT(address recipient, string memory tokenURI)public onlyOwnerreturns (uint256){_tokenIds.increment();uint256 newItemId = _tokenIds.current();_mint(recipient, newItemId);_setTokenURI(newItemId, tokenURI);return newItemId;}
}

因为在合约代码中用到了 OpenZeppelin 合约库继承类,所以需要在命令行中运行

npm install @openzeppelin/contracts

将该库安装到项目目录中

步骤是完成了,但是这些代码究竟是什么意思呢?别急,下面来逐行分解一下。

在智能合约中,导入了三个 OpenZeppelin 智能合约类:

  • @openzeppelin/contracts/token/ERC721/ERC721.sol
    包含 ERC-721 标准的实现,非同质化通证智能合约继承此标准。(要使编写的非同质化通证有效,智能合约必须实现 ERC-721 标准的所有方法。)官方文档中有详细的 ERC-721 接口定义。
  • @openzeppelin/contracts/utils/Counters.sol
    提供了只能以 1 为增量或减量的计数器。智能合约使用一个计数器来跟踪非同质化通证总铸造量,并在新的非同质化通证上设置唯一ID。(每个使用智能合约铸造的非同质化通证必须分配一个唯一ID,唯一ID仅由存在的非同质化通证总量决定。例如,用智能合约铸造的第一个非同质化通证的ID是“1”,那么第二个非同质化通证的ID则是“2”,以此类推)
  • @openzeppelin/contracts/access/Ownable.sol
    在智能合约上设置了访问控制,因此只有智能合约的所有者可以铸造非同质化通证。
    (注意:访问控制完全是可选的。如果希望任何人都能使用这个智能合约铸造非同质化通证,则删除第 10 行的 Ownable 和第 17 行的 onlyOwner)。

下面则是自定义的非同质化通证智能合约,合约非常短,只包含一个计数函数、一个构造函数和独立函数。这要归功于我们继承的 OpenZepelin 合约,它们实现了创建非同质化通证所需的大多数方法。例如 owerOf 函数,其作用是返回非同质化通证所有者,以及 transferFrom 函数,其作用是将非同质化通证的所有权从一个账户转移到另一个账户。

在这个ERC-721构造函数中,请注意到传递了2个字符串参数,“NewNFT”和“NFT”。 第一个变量是智能合约的名称,第二个变量是其符号。这两个变量是可以随意更改的。

最后,函数 mintNFT(address recipient, string memory tokenURI) 允许铸造NFT。这个函数包含两个参数:

  • address recipient 指定了接收新铸造非同质化通证的地址
  • string memory tokenURI 这是一个可以解析为JSON的字符串,用于描述非同质化通证的元数据。

非同质化通证的元数据是它的核心灵魂所在,使它拥有可配置的属性,例如名称、描述、图像和其他属性。

mintNFT 调用了继承的ERC-721库中的一些方法,最终返回一个数字,代表新铸造非同质化通证的ID。


七、编译及部署智能合约

前面,已经完成了智能合约的编写,并且也完成了相关基础设施的安装,同时也创建了 Metamask 钱包、Alchemy 帐户。下面将开始编译及部署编写的智能合约。

1.项目中配置Metamask及Alchemy

从钱包发送的每笔交易都需要使用独有的私钥签名。为了给程序提供此项许可,可以安全地将私钥(和Alchemy应用程序接口密钥)存储在一个环境配置文件中。

首先,在项目目录中安装 dotenv 软件包:

npm install dotenv --save

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

  • 按照官方文档说明导出 MetaMask 私钥
  • 在 Alchemy 的 Apps 中找到项目,并点击 “ACTIONS” 中的 “VIEW KEY”,即可显示出API URL。将 HTTPS 接口复制到剪贴板。

    现在 .env 文件应该长得像这样:
API_URL="https://eth-goerli.alchemyapi.io/v2/api-key"
PRIVATE_KEY="metamask-private-key"

后续将要使用到这些变量

这里请千万注意,任何时候都不要提交 .env 文件! 请确保永远不要与任何人共享或公开 .env 文件,因为MetaMask钱包的私钥保存在这个文件中。如果使用git,请确保将 .env 添加到 gitignore 文件中。

2.安装 ETHERS.JS 并更新配置

Ethers.js 是一个软件库,使用它能够更加方便的按照标准以太坊 JSON RPC 方法打包项目,从而更容易与以太坊网络发出请求。

HARDHAT使我们更容易将插件集成到工具和扩展功能中。 我们将利用 Ethers 插件完成合约部署(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: "goerli",networks: {hardhat: {},goerli: {url: API_URL,accounts: [`0x${PRIVATE_KEY}`]}},
}

这里请注意文件的第9行和第12行,指定了默认的网络及网络使用的配置。本文中使用的是Goerli测试网,所以配置为goerli,实际使用时按实际情况修改即可,不然在编译时会出现网络不存在的报错。

3.编译合约

在项目根目录中运行

npx hardhat compile

如果出现类似

Compiled 13 Solidity files successfully

说明编译通过了,合约一切正常。

4.编写部署脚本

在 scripts 文件夹中,创建一个新的 deploy.js 文件,添加以下内容:

async function main() {const NewNFT = await ethers.getContractFactory("NewNFT")const newNFT = await NewNFT.deploy()await newNFT.deployed()console.log("Contract deployed to address:", newNFT.address)
}main().then(() => process.exit(0)).catch((error) => {console.error(error)process.exit(1)
})

来看看这段脚本是什么意思:

const NewNFT = await ethers.getContractFactory("NewNFT")

ethers.js 中的 ContractFactory 是用于部署新智能合约的抽象对象。因此这里的 NewNFT 是非同质化通证合约实例的工厂。使用 hardhat-ethers 插件时,ContractFactory 和合约实例默认与第一个签名账户相连。

const newNFT = await NewNFT.deploy()

调用 ContractFactory 代码中的 deploy() 函数会启动合约部署,然后返回解析为合约的 Promise。 这个对象包括智能合约中每个函数的对应调用方法。

5.部署合约

在项目根目录中运行

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

如果看到以下信息则表示合约部署成功了:

Contract deployed to address: 0x094180BBc8f5e8e9697C0F633D4004e3ecea6510

然后可以在Etherscan测试网中搜索到这个部署成功的智能合约了。如果暂时无法看到,不要着急需要稍等片刻,让网络同步一会儿:

可以看到,From地址与 MetaMask 帐户中地址一致,To地址将显示“合约创建”。 如果点击“Txn Hash”(交易哈希)进入交易,将在“To”字段中看到部署成功的合约地址:

至此,一个崭新的非同质化通证智能合约已经在以太坊区块链上部署完成!

挺神奇的,不过这其中到底发生了什么呢?如果想了解可以打开 Alchemy 仪表盘中 Explorer 选项卡,在 All Apps 中选择刚刚部署的应用“NewNFT”,这样就会展示出详情:

这里出现了一系列的 JSON-RPC 调用,这要感谢 Hardhat/Ethers 在背后完成的这些事情,在调用 deploy() 函数时,它默默做了这些事情。

其中,有两个调用比较重要:

  • eth_sendRawTransaction,这是实际将我们的合约写入 Goerli 测试链的请求。
  • eth_getTransactionByHash,这是读取有关交易给定哈希值的请求(即发送交易时的典型模式)。

总结

在本文中,通过一个具体的例子操作了Ethereum非同质化通证(NFT)的编写与部署,后续还将用一篇文章讲述如何通过这个智能合约铸造一个非同质化通证,以及如何在以太坊钱包中显示出这个通证。见Ethereum非同质化通证(NFT)的铸造与展示

Ethereum非同质化通证(NFT)的编写与部署相关推荐

  1. Ethereum非同质化通证(NFT)的铸造与展示

    Ethereum非同质化通证(NFT)的铸造与展示 前言 一.安装 Web3.js 二.创建 mint-nft.js 文件 三.获取合约应用程序二进制接口 四.使用IPFS为非同质化通证配置元数据 五 ...

  2. 如何理解非同质化通证技术

    NFT的全称是"Non-Fungible Tokens",即非同质化代币,它的特征在于其拥有独特.唯一的标识,自身不可分割,且无法两两等值互换. 它是一项基于区块链的记账技术,之前 ...

  3. 非同质化通证在商业模式中如何应用

    相信很多人都知道NFT,NFT英文全称是Non-Fungible Token,译成中文是"非同质化代币",是一种基于区块链技术的数字资产权利凭证,可以通俗地将其理解为登记在区块链上 ...

  4. NFT行业新机遇 非同质化的电子书或将改变市场格局

    10月11日,首期杂志类NFT系列<加密艺术年鉴>上线国内最多元化的NFT加密文化平台秘宝,仅仅1分钟内第一批100份NFT的发售瞬间被抢购一空.<加密艺术年鉴>并不仅仅只是杂 ...

  5. 烤仔星选·NFT实验室 | 非同质化代币在游戏领域的应用

    烤仔星选创作计划进行期间,烤仔将定期转载参与活动的优秀作品哟,关注烤仔星选创作计划,让我们一起为产出er们加油打 call 吧- 点击"阅读原文",了解烤仔星选创作计划 作者:NF ...

  6. 剖析非同质化代币ERC721-全面解析ERC721标准

    最新内容会更新在主站深入浅出区块链社区 原文链接:剖析非同质化代币ERC721-全面解析ERC721标准 什么是ERC-721?现在我们看到的各种加密猫猫狗狗都是基于ERC-721创造出来的,每只都是 ...

  7. 链游知识01:同质化和非同质化资产标准是什么?

    前言:链游知识是链游玩家专门推出的针对入门玩家的游戏知识科普,从小白到高玩,看链游玩家就够了. 区块链游戏诞生于17年末18年初,至今也不到2年的时间,虽然目前已经有很多团队和项目方在做区块链游戏了, ...

  8. 元宇宙电商——非同质化商品的新模式

    近年来,随着虚拟世界的火爆,互联网公司.科技公司纷纷推出元宇宙概念."元宇宙"成为了当下的热门词汇,元宇宙作为一种全新的商业模式正在快速发展,吸引了不少投资者的目光,那么投资者该如 ...

  9. 探索如何在武汉链(基于ETH)的一个合约中实现同质化与非同质化功能

    id:BSN_2021 公众号:BSN研习社 目标:跟大家一块去研究下1155标准中提供的案例 章节流程: 1.核心文件 2.核心方法 3.汇总 在eip-1155中看到如下图所示一段内容,并提供了一 ...

最新文章

  1. 【组队学习】【34期】百度飞桨AI达人创造营
  2. Puppet Host资源介绍(二十一)
  3. 【转载】为何要十跪父母
  4. ML之catboost:基于自带Pool数据集实现二分类预测
  5. Dataset之HiggsBoson:Higgs Boson(Kaggle竞赛)数据集的简介、下载、案例应用之详细攻略
  6. ML之ME/LF:机器学习中常见模型评估指标/损失函数(LiR损失、L1损失、L2损失、Logistic损失)求梯度/求导、案例应用之详细攻略
  7. 2016-8-2更新日志
  8. mysql 增加 date 列_mysql数据库修改添加Date格式列的方法
  9. 在IntelliJ IDEA里配置Go开发环境
  10. 【英语学习】【医学】无机化学 - 化合物命名(1) - 离子化合物
  11. 逻辑回归模型(Logistic Regression)及Python实现
  12. REPNZ SCANS
  13. element-UI table自定义表头
  14. 图易服装PDM产品数据管理系统
  15. 06、Flutter FFI 类
  16. 微信小程序开发一个简单的摇骰子游戏
  17. 七牛非Cocoapods 手动集成霹雳直播SDK(通用版)
  18. 验证码爬取并识别-云大urp教务系统大作战(1)
  19. 霍兰德人格分析雷达图
  20. 未来计算机长啥样,未来人类到底会长成啥样?科学家公布最终模拟图!

热门文章

  1. 除了中国知网和谷歌文学还有哪些好的有权威的资源站?
  2. 解决方案之Android 国际化资源完美兼容6.0,7.0,8.0
  3. C#使用表达式树不能包含动态操作,使用反射的方式来实现T类型
  4. 记一道MISC图片题(拖延癌晚期)
  5. MySQL 8.0 全文检索功能 根据中文字符检索相关数据
  6. 使用gpg来加密数据
  7. setInterval()的三种写法
  8. MFC 利用opencv实现视频播放
  9. 送书 |《Python数据分析从小白到专家》
  10. 【自动驾驶行业观察】奥迪A8自动驾驶功能剖析