如何创建NFT并OpenSea上展示《alchemy How to Develop an NFT Smart Contract》译

2022-11-12 10:58:31 浏览数 (1)

翻译:1_bit 原文:https://docs.alchemy.com/docs/how-to-develop-an-nft-smart-contract-erc721-with-alchemy

注:英文不好各位多多担待

1.如何使用 Alchemy 开发一个 NFT 智能合约

在你第一次使用 solidity 时开发一个智能合约部署在区块链上,你可能会觉得有点难。有关更多的合约安全、节省 gas 这些你都会在开发时经历。

幸运的是,在过去的几个月中,开发人员构建了许多智能合约开发的工具使得开发更加简单。

这些工具例如 OpenZeppelin Wizard (智能合约向导),可以通过鼠标点击后生成一个安全、可靠的智能合约,通过智能合约向导与 Alchemy 和一些 web3 的开发者工具将会使合约开发变得前所未有的简单、快速和可靠。

在本教程中,你将会学习如何使用 Alchemy 、OpenZeppelin Wizard (智能合约向导)、Remix 、goerli网络开发和部署 ERC721 的智能合约。

准确的说,你将会学习以下内容:

  • 如何使用 OpenZeppelin 和 Remix 编写和修改智能合约
  • 获取免费的 Goerli ETH https://goerlifaucet.com/
  • 在 Goerli 测试网络上部署便宜的 gas 合约
  • 在 FileBase 上对 NFT token 的元数据进行托管
  • 铸造 NFT 以及在 OpenSea 进行查看

在 youtube 上有对应的视频教程:https://youtu.be/veBu03A6ptw

首先我们从创建智能合约开始。

注:下面标题序号为了读者看的更清楚所以是自己所标注的

1.2 使用 OpenZeppelin 开发 ERC721 标准的智能合约

在之前说过,本教程中,你将会使用 OpenZeppelin 去此案一个只能合约,这么做有两个重要的原因:

  • 将会使你的合约安全
  • 他将会使你的合约符合标准(遵循标准意思是自动化了不需要自己写)

当你编写一个智能合约时,安全是很关键的,有很多智能合约由于安全性太差,导致数亿美元被恶意盗窃的例子。

你也不想在你合约部署在区块链网络上后就会被窃取吧?

OpenZeppelin 就是由此而生,是最大的智能合约标准维护者之一,允许开发人员使用已经被 OpenZeppelin 进行代码审计后的可靠合约代码。

接下来你需要做的第一件事就是打开这个链接 https://docs.openzeppelin.com/contracts/4.x/wizard 去创建安全的合约代码。

当你进入页面后,你将会看到以下的编辑器:

点击在左上角(往右边数第二个)的 ERC721 按钮,选择你要使用的 ERC 标准:

现在,你已经选择你合约的标准,在左侧的菜单中,你可以看到一些选项。

让我们从选择 token 的名称和符号开始。点击在文本框中的 “MyToken” 并且给他一个名称,对应的 Symbol 类型的文本框也可以改成你想要的名字,不过在 Base URI 文本框中我们可以留空,这个可以给用户进行传递,因为 IPFS 的元数据我们将会存储在 OpenSea 中。

1.3 选择 NFT token 的功能

现在需要你去选择一些你想要添加到合约中的功能(剩下的一句没翻译,感觉啰嗦了):

在本节中,你需要集成以下所列出的功能:

  • Mintable (铸币)你将会创建一个 mint 方法并且只有特殊账户可使用(一般是 owner)
  • Autoincrement IDs( tokenid 自动加1)这个功能将会自动的为你的 NFT 的 ID 自动分配增量 ID
  • Enumerable(枚举)能够访问链上的 token 枚举 以及 totalSupply 之类的功能,像 ERC721 的 URI 默认情况下是不存在的,需要将元数据和对应的图片进行关联。(其实这里我不是很清楚啥意思)
  • URI Storage 存储一个 URI 与 NFT 关联(这个需要我们传入的)

在当前教程中,你应该不想创建一个 NFT 还有一些增发、销毁、暂停、投票之类需要“经济学”支持的NFT,那么就不要勾选 BurnablePausableVotes

  • Burnable - 销毁 token
  • Pausable - token 转移、销售等
  • Votes -投票类

如果你想去学习更多看这里:https://docs.openzeppelin.com/contracts/4.x/api/token/erc721

现在你已经有了需要的功能,OpenZeppelin 将会填充剩下的合约代码,此时你应该在合约向导中看到跟下面差不多的代码:

代码语言:javascript复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

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

contract Alchemy is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable {
    constructor() ERC721("Alchemy", "ALC") {}

    function safeMint(address to, uint256 tokenId, string memory uri)
        public
        onlyOwner
    {
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    // The following functions are overrides required by Solidity.

    function _beforeTokenTransfer(address from, address to, uint256 tokenId)
        internal
        override(ERC721, ERC721Enumerable)
    {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

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

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

是时候复制我们的代码去 Remix 上修改和部署了。

1.4 在 REMIX 上修改和部署你的 ERC721 合约

现在你已经有了一个 ERC721 的智能合约,现在开始让我们去修改和部署它到 Goerli 测试网络上。你将会使用 Remix IDE,它是一个为 solidity 设计的免费的智能合约 web 端的开发环境。

首先,你可能注意到了,在 OpenZeppelin Wizard 编辑器的顶部,有一个 “Open in Remix” 的按钮:

点击按钮后将会在浏览器中打开一个新的页面。

1.5 使用 Remix 修改你的NFT 智能合约

从合约代码的头部开始, “SPDX-License-Identifier” 是你的开源标准协议,在 web3 应用中开源是可以保持项目的可信度的,是需要去做的。

代码语言:javascript复制
// SPDX-License-Identifier: MIT

接着是 pragma,这是用于指定当前智能合约的编译版本,如果你使用 ^ 符号就表示当前合约代码使用在 0.8.0 到 0.8.9 之间适用。

代码语言:javascript复制
pragma solidity ^0.8.4;

然后我们导入库并且初始化(还没到)我们的智能合约:

代码语言:javascript复制
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

接着开始初始化合约,继承这些导入的库标准:

代码语言:javascript复制
 contract Alchemy is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable {...}

你可以注意到,这个 safemint 方法有一个 “only owner” 的修饰,这个修饰只允许当前合约的所有者调用这个方法去铸造 NFT,如果你想所有人都可以使用 mint 方法,那么 你可以删除 Mint 方法的 onlyOwner 修饰:

代码语言:javascript复制
function safeMint(address to, string memory uri) public {
    uint256 tokenId = _tokenIdCounter.current();
    _tokenIdCounter.increment();
    _safeMint(to, tokenId);
    _setTokenURI(tokenId, uri);
}

你也可以去删除在合约引入说明中的 Ownable:

代码语言:javascript复制
import "@openzeppelin/contracts/access/Ownable.sol";

现在每个人都可以去使用 mint 创建 NFT 了,但你需要避免用户 mint 过多的 NFT,那么就需要制定一个 mint NFT 的最大上限。

比如说你想要用户创造上限为 10000 的 NFT,那么新建一个 uint256 的变量,这个变量名叫做 MAX_SUPPLY,给与值为 10000:

代码语言:javascript复制
Counters.Counter private _tokenIdCounter;
    uint256 MAX_SUPPLY = 100000;

    constructor() ERC721("Alchemy", "ALCH") {}

接着,让我们进入 safeMint 方法中增加 require 判断当前对应的 NFT 数量:

代码语言:javascript复制
require(_tokenIdCounter.current() <= MAX_SUPPLY, "I'm sorry we reached the cap");

现在,你一讲限制了所提供最大的 NFT 数,那么此时就编译智能合约在 Goerli 测试网上部署吧。你需要创建一个免费的 Alchemy 账户(主要是提供了RPC)。

1.6 创建免费 Alchemy 账户

首先,让我们去 alchemy.com 导航上点击 Login 创建一个新的账户:

选择 ethereum :

给你的应用和你的团队命名,选择 goerli 网络,最后点击“create app”创建项目:

当你完成上面的流程后,我们将会跳转到控制面板,点击你刚刚命名的应用进入,此时,点击在右上角的 “VIEW KEY” 按钮可以查看 APIKEY 和 HTTPURL 等信息:

下一步,你需要去添加 Alchemy 的 Goerli 的 RPC Provider 到 Metamask ,如果你没有安装 metamask,请确保安装,若没有 wallet 请先按照以下教程添加一个 wallet 到你的浏览器中,点击“add network”:

你将会跳转到以下页面,你需要填写 goerli 网络和 RPC URL 信息:

添加以下信息到表单中:

  • Network name: Alchemy Goerli 网络名
  • New RPC URL: the HTTP URL of the Goerli Alchemy Application 你刚刚在 alchemy 上的 http 的 rpc url
  • Chain ID: 5
  • Currency Symbol: GoerliETH 网络标识
  • Block Explorer: https://goerli.etherscan.io

非常棒,你刚刚已经把 alchemy 的 goerli 网络添加到了 metamask 。

现在就准备开始在 goerli 中部署我们的智能合约吧,但是我们需要 get some goerli test eth(文字限定所以就不翻译了,此处获取 goerli test eth 可以查找对应的 faucet,such as goerlifaucet.com)。

1.7 编译和部署 NFT 智能合约在 goerli 测试网络上

返回 remix,让我们点击网页左侧菜单中的蓝色 compiler 按钮进行编译:

此时点击 部署按钮进入到 “Deploy and Run Transactions" 菜单中,点击 环境 Environment 在下拉菜单中选择 “injected Web3”。

确保 metamask wallet 已经连接了 goerli network,在 Contract 的下拉菜单中 选择 NFT 智能合约(你要编译的)没然后点击 Deploy部署(一定要先编译):

此时 metamask 将会弹出一个窗口,点击 sign,并且继续支付 gas 费用。

如果一切工作都很顺利,那么在 10秒之后,你可以看到这个合约列表下将会出现已经部署的合约:

1.8 什么是 NFT 元数据

为了让合约返回一个 OpenSea 的元数据,我们需要设置一个 URI,ERC721 的 tokenUri 方法会返回一个 HTTP 或 IPFS 的URL,例如 ipfs://bafkreig4rdq3nvyg2yra5x363gdo4xtbcfjlhshw63we7vtlldyyvwagbq ,查询时,这个 URL 将会返回一个 JSON 数据,其中包括了你的 token 的元数据。

你可以查看更多官方所提供的元数据标准 https://docs.opensea.io/docs/metadata-standards。

1.8 怎么样去格式化你的 NFT 元数据

根据 OpenSea 的文档,一个 NFT 的元数据应该是存储在 json 文件中,这个文件接口如下:

代码语言:javascript复制
{ 
  "description": "YOUR DESCRIPTION",
  "external_url": "YOUR URL",
  "image": "IMAGE URL",
  "name": "TITLE", 
  "attributes": [
    {
      "trait_type": "Base", 
      "value": "Starfish"
    }, 
    {
      "trait_type": "Eyes", 
      "value": "Big"
    }, 
    {
      "trait_type": "Mouth", 
      "value": "Surprised"
    }, 
    {
      "trait_type": "Level", 
      "value": 5
    }, 
    {
      "trait_type": "Stamina", 
      "value": 1.4
    }, 
    {
      "trait_type": "Personality", 
      "value": "Sad"
    }, 
    {
      "display_type": "boost_number", 
      "trait_type": "Aqua Power", 
      "value": 40
    }, 
    {
      "display_type": "boost_percentage", 
      "trait_type": "Stamina Increase", 
      "value": 10
    }, 
    {
      "display_type": "number", 
      "trait_type": "Generation", 
      "value": 2
    }]
  }

一下是一个有关这些属性的简短说明:

属性

说明

image

这是图片的 URL, 可以是任何的图像,可以是 IPFS 上存储的 URL 路径,建议使用 350 350 的大小

image_data

SVG图像,如果你想使用动态图像(不建议),只有在你数据中不包括 image 时可以使用

external_url

这个 URL 是显示在 OpenSea 资源下凡的图片URL,你可以在 OpenSea 之外的站点上查看

description

这个NFT 的描述

name

这个NFT 的名称

attributes

属性,将会显示在 OpenSea 页面上

background_color

OpenSea 上项目的背景色,必须是十六进制不需要添加“#”之类的前置

animation_url

多媒体 url

了解了一些元数据内容后,学习如何存储元数据在 IPFS上。

1.9 在 IPFS 存储元数据

首先,导航去 fillebase 创建一个账户。

登录后,点击左侧菜单的 bucket 按钮 创建一个新的 bucket:

进入 bucket,点击上传按钮,上传你想要作为 NFT 使用的图片。

上传你完毕后,复制 IPFS GateWay 网关的 URL:

使用一个文本编辑器,复制下面的 json code:

代码语言:javascript复制
{ 
  "description": "This NFT proves I've created and deployed my first ERC20 smart contract on Goerli with Alchemy Road to Web3",
  "external_url": "Alchemy.com/?a=roadtoweb3weekone",
  "image": "https://ipfs.filebase.io/ipfs/bafybeihyvhgbcov2nmvbnveunoodokme5eb42uekrqowxdennt2qyeculm",
  "name": "A cool NFT", 
  "attributes": [
    {
      "trait_type": "Base", 
      "value": "Starfish"
    }, 
    {
      "trait_type": "Eyes", 
      "value": "Big"
    }, 
    {
      "trait_type": "Mouth", 
      "value": "Surprised"
    }, 
    {
      "trait_type": "Level", 
      "value": 5
    }, 
    {
      "trait_type": "Stamina", 
      "value": 1.4
    }, 
    {
      "trait_type": "Personality", 
      "value": "Sad"
    }, 
    {
      "display_type": "boost_number", 
      "trait_type": "Aqua Power", 
      "value": 40
    }, 
    {
      "display_type": "boost_percentage", 
      "trait_type": "Stamina Increase", 
      "value": 10
    }, 
    {
      "display_type": "number", 
      "trait_type": "Generation", 
      "value": 2
    }]
  }

随后保存文件为 “metadata.json”,返回到 bucket 中上传 metadata.json 文件:

最后,点击 CID 并且进行赋值,你将需要这个在铸造 NFT 时 使用到:

1.10 铸造你的 NFT

返回到 remix 中,在你部署的合约之下,找到对应的方法列表:

橙色方法时写入区块链的方法,蓝色方法时读取区块链内容的方法。

点击 safeMint 方法的下拉选项,复制你的地址,并且添加对应的 URI字段,这个字段格式如下:

代码语言:javascript复制
ipfs://<your_metadata_cid>

单击交易后弹出一个 metamask 的窗口,支付 gas。

点击 sign 后将会铸造你的第一个 nft。

接着转移到 OpenSea 检查你的元数据是否被正确读取到。

1.11 在 OpenSea 上展现你的 NFT

进入 OpenSEA 的测试网络 https://testnets.opensea.io/zh-CN 并使用钱包登录,此时点击你的头像,你可以看到一个新铸造的 NFT,如果你的图片没有显示,点击 refresh metadata 按钮进行刷新:

有时候 OpenSea 需要一段时间 6h 后显示这个 NFT:

0 人点赞