以太坊 ERC721 标准学习

以太坊 ERC721 标准学习

以太坊不仅支持同质化代币(如 ERC20),还支持非同质化代币(NFT),而 ERC721 是其中最著名的标准。

我个人理解:可以把 ERC721 智能合约想象成一个艺术家工作室,mintNFT 函数就像是艺术家创作新作品的过程。每当艺术家完成一件作品,就会给它一个独特的标识,并将它交给特定的人(即接收地址)。

或者说:ERC20 代币就像是银行发行的货币,每一张 100 元钞票都是一样的,可以互换。而 ERC721 代币则像是艺术家的独特作品,每一件都是独一无二的,无法互换。

什么是 ERC721 标准?

ERC721(Ethereum Request for Comments 721)是以太坊平台上的一种标准接口,用于实现非同质化代币(NFT)。与 ERC20 代币不同,每个 ERC721 代币都是独一无二的,这使得它们非常适合用于表示独特的资产,如艺术品、收藏品和游戏中的道具。

为什么 ERC721 标准很重要?

  1. 唯一性:每个 ERC721 代币都是独一无二的,具有独特的 ID,这使得它们非常适合表示独特的数字资产。

  2. 所有权:ERC721 标准确保了每个代币的所有权可以被追踪和转移,从而为数字资产提供了可靠的所有权证明。

  3. 广泛采用:由于其灵活性和功能性,ERC721 已成为数字收藏品和游戏资产的主流标准,被众多项目和平台广泛采用。

ERC721 标准的核心功能

ERC721 标准定义了一些基本函数和事件,确保代币的基本操作。以下是 ERC721 标准中最重要的一些功能:

基本函数

  • balanceOf: 返回某地址拥有的代币数量。

    function balanceOf(address _owner) public view returns (uint256 balance);
    
  • ownerOf: 返回某代币的所有者地址。

    function ownerOf(uint256 _tokenId) public view returns (address owner);
    
  • transferFrom: 将代币从一个地址转移到另一个地址。

    function transferFrom(address _from, address _to, uint256 _tokenId) public;
    
  • approve: 授权某个地址可以转移特定代币。

    function approve(address _to, uint256 _tokenId) public;
    
  • getApproved: 返回被授权可以转移特定代币的地址。

    function getApproved(uint256 _tokenId) public view returns (address operator);
    
  • setApprovalForAll: 授权或撤销某地址可以管理调用者所有代币的权限。

    function setApprovalForAll(address _operator, bool _approved) public;
    
  • isApprovedForAll: 查询某地址是否被授权管理调用者的所有代币。

    function isApprovedForAll(address _owner, address _operator) public view returns (bool);
    

事件

  • Transfer: 当代币转移时触发。

    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
    
  • Approval: 当授权发生时触发。

    event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
    
  • ApprovalForAll: 当授权或撤销某地址管理所有代币的权限时触发。

    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
    

自己实现一个简单的ERC721 NFT

pragma solidity ^0.8.0; // 指定Solidity编译器版本

import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; // 引入OpenZeppelin的ERC721标准合约
import "@openzeppelin/contracts/utils/Counters.sol"; // 引入计数器工具库

contract MyNFT is ERC721 { // 定义一个名为MyNFT的合约,继承自ERC721
    using Counters for Counters.Counter; // 使用Counters库中的Counter结构
    Counters.Counter private _tokenIds; // 定义一个私有的Counter变量,用于追踪代币ID

    constructor() ERC721("MyNFT", "MNFT") {} // 构造函数,设置代币的名称和符号

    function mintNFT(address recipient, string memory tokenURI) public returns (uint256) { // 定义一个公开函数mintNFT,用于铸造新NFT
        _tokenIds.increment(); // 代币ID自增

        uint256 newItemId = _tokenIds.current(); // 获取当前的代币ID
        _mint(recipient, newItemId); // 铸造新的NFT,并将其分配给接收者
        _setTokenURI(newItemId, tokenURI); // 设置新铸造NFT的URI

        return newItemId; // 返回新铸造的代币ID
    }
}

其中tokenURI指向的数据,通常存储在链外(例如,IPFS 或传统的 Web 服务器),而不是直接存储在区块链上,以减少链上存储的成本和复杂性。

posted @ 2021-02-01 17:29  sorachannel  阅读(956)  评论(0)    收藏  举报