0

玩转Web3:创建属于自己的ERC-721(NFT)

 3 months ago
source link: https://aoppp.com/wan-zhuan-web3-chuang-jian-shu-yu-zi-ji-de-erc-721-nft/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

玩转Web3:创建属于自己的ERC-721(NFT)

大家好,本章是 《玩转Web3》 的第三章,我们本次使用 Solidity 进行 ERC721 合约编写,来创造属于我们自己的 NFT,我们会将 NFT 图片上传到 IPFS,并将整个合约部署到 Rinkeby 测试网络。

前提知识了解

NFT了解

ERC-721 就是为了创造所谓的 非同质化代币NFT (下文我们都简称NFT),NFT藏品已经非常流行了,如 AzukiCryptoZunksCryptokitties 项目等,
都是采用 721 标准创建的,NFT 的使用场景也挺丰富,如:

  • 数字艺术(或实物艺术):艺术作品是NFT最受欢迎的使用案例。 数字艺术拍卖是NFT的第一个应用,并且还在继续发展。
  • 游戏:提供游戏内购和游戏收藏。
  • 房地产:将房产和智能合约Token化,并进行买卖。
  • 金融:贷款、期货等金融工具,并承担其他责任。
  • 软件标题:软件授权,确保反盗版和隐私。
  • 演唱会门票/体育比赛门票:为了保证在卖票过程中不发生欺诈行为,粉丝可以在一个地方查看以往的经历。
  • KYC合规性:为特定用户的KYC创建代币。

NFT 在合约中的表现形式

// 查NFT数量
function balanceOf(address _owner) external view returns (uint256);
// 查token的属主
function ownerOf(uint256 _tokenId) external view returns (address);
// 也是转账函数,更加安全点 solidity是支持多态的,所以是同名函数
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
// 也是转账函数,更加安全点
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
// 将from这个地址的tokenID编号的NFT转给to这个地址
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
//  此函数批准另一个实体代表所有者转让代币的权限
function approve(address _approved, uint256 _tokenId) external payable;
// 授权或者取消授权operator这个地址转移你所有NFT
function setApprovalForAll(address _operator, bool _approved) external;
// 查询tokenId编号的NFT授权给了谁(查询谁可以转走你的NFT!)
function getApproved(uint256 _tokenId) external view returns (address);
// 查询某个operator是否有权转移某个owner的这一Collection中的所有NFT(查询某个地址是否可以转走你这个Collection的所有NFT!)
function isApprovedForAll(address _owner, address _operator) external view returns (bool);

// 当代币的所有权从一个人变为另一个人时,该事件被触发。 发出的信息包括哪个账户转移了代币,哪个账户收到了代币,以及哪个代币(通过ID)被转移。
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
// 当用户批准另一个用户获得代币的所有权时,该事件就会被触发,也就是说,每当approve函数被执行时,该事件就会被触发。 它发出的信息包括:当前哪个账户拥有该代币,哪个账户被批准在未来拥有该代币,以及哪个代币(通过ID)被批准转让其所有权。
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
// 调用setApprovalForAll触发事件
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
  • openzeppelin 中有 tokenURI 用来查看 NFT 的描述数据
  • openzeppelin 中有 awardItem 用来铸造 NFT 的描述数据 (这里为了方便没有设置铸造门槛,真实情况我们可以编写白名单进行铸造限制等)

IPFS了解

NFT 是所谓的数字资产,这些资产都是需要存储介质的,可以是中心化服务器,也可以是分布式去中心化的,IPFS 就是点对点的文件系统,官方称为 星际文件系统,是一个分布式存储和共享文件的网络传输协议,他可以尽可能地保证我们文件的存在。

  • 官网安装: https://ipfs.io/#install

可以使用 cli 版或者 desktop 版,都差不多,我们这边是采用 go-ipfs,这个工具使用起来非常简单,这里就不多去说明,可以查阅这篇登链社区的文章 https://learnblockchain.cn/2018/12/25/use-ipfs

我们的操作流程如下:

  • Remix IDE 构建 ERC-721 合约
  • 创建 NFT 元数据上传到 ipfs 并写入到区块中
  • 部署到 Rinkeby 测试网络

构建ERC-721合约

我们还是使用 openzeppelin 来进行合约的快速编写

  • aopnft.sol
// "SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

contract AOPNFT is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721("AOPNFT", "AOPNFT") {}

    // 铸造NFT方法
    function awardItem(address player, string memory tokenURI)
        public
        returns (uint256)
    {
        _tokenIds.increment();

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

        return newItemId;
    }
}

我们可以先使用 JavaScript VM 来进行合约部署测试,保证正常了我们再进行测试链部署,部署成功后,我们需要创建 NFT 啦。

创建NFT

将NFT图片上传到IPFS上

# nft原图
ipfs add apple.png     # QmaeC5SBeGuQyLaXLAehLMnwWy8ruj123Ki1DK3RcbxJSd
# nft描述文件
ipfs add apple.json    # QmRVSjT169HWZetXrDbAwXdZuBWV4dhixBTuM1H6RM9Ucc

通过 ipfs 协议去访问描述文件:ipfs://QmRVSjT169HWZetXrDbAwXdZuBWV4dhixBTuM1H6RM9Ucc

10
10
  • 通过合约的 TOKENURI 方法获取 nft 的资源路径,需要传入我们铸造 nft 时返回的 tokenId
tokenuri(1) // ipfs://QmRVSjT169HWZetXrDbAwXdZuBWV4dhixBTuM1H6RM9Ucc

这个时候,我们的 NFT 就创造成功了,接下来让我们部署到测试网络上去吧。

将合约部署到Rinkeby网络

10

然后 Deploy,这一步需要我们使用小狐狸去签名确认,然后就部署成功了,合约地址为 0x5bCc79242339b8F231d5D358EEa370781EA713d1,当然也可以通过测试网络的浏览器去在线查看和调式 https://rinkeby.etherscan.io/address/0x5bcc79242339b8f231d5d358eea370781ea713d1

  • 然后我们在测试网络进行铸造

可以看到,我们的在测试网络的 NFT 已经铸造成功了

同时也可以将合约加入到我们的小狐狸钱包,剩下的就给大家自己操作啦。

这一章,我们了解 NFT 的创作过程,可以发现,NFT 的本质是图片,其次在于描述文件,描述文件越丰富,NFT 就可以更加多样化,本章中我们 NFT 是存储在 IPFS 这个文件系统上,不容易丢失,当然你也可以存储在自己的服务器或者托管到第三方服务器,都不一样,NFT 对应的只是一个资源地址罢了,所以投资有风险,入市需谨慎。
如果是单纯地编写合约,那么不是开发人员根本不懂如何与合约交互,那门槛就更高了,我们需要让更多的人来参与我们的项目,所以我们需要构建合约的客户端,之后我们会创建合约的 web客户端,这样就可以让更多的人参与了。

本文为作者原创或转载,允许转载,由憧憬在 aoppp.com发布 转载请说明文章出处。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK