【openzeppelin学习系列】ERC721

openzeppelin学习系列文章

提示:本文是我在学习智能合约开发过程中的一些思考和总结。在这个复杂且不断发展的领域中,可能存在一些疏漏或不准确之处。我非常欢迎和鼓励大家提出意见和建议,让我们可以共同讨论、纠正错误,并提高我们对区块链技术和智能合约的理解与掌握。希望通过这种开放的交流,我们都能在这一领域得到成长和进步。



一、简介

ERC721 是一种基于以太坊区块链的不可替代代币(NFT)标准。与 ERC20 标准的可替代代币不同,ERC721 代币是独特的,不可互换的,这使得它们非常适合用于数字收藏品、游戏资产、艺术品等领域。

二、接口

interface IERC721 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    function balanceOf(address owner) external view returns (uint256 balance);
    function ownerOf(uint256 tokenId) external view returns (address owner);
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    function transferFrom(address from, address to, uint256 tokenId) external;
    function approve(address to, uint256 tokenId) external;
    function getApproved(uint256 tokenId) external view returns (address operator);
    function setApprovalForAll(address operator, bool _approved) external;
    function isApprovedForAll(address owner, address operator) external view returns (bool);
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}

核心方法

  • balanceOf(address owner): 返回指定地址拥有的代币数量。
  • ownerOf(uint256 tokenId): 返回某个 tokenId 的所有者地址。
  • safeTransferFrom(address from, address to, uint256 tokenId): 安全转移 tokenId 代币。
  • transferFrom(address from, address to, uint256 tokenId): 转移 tokenId 代币。
  • approve(address to, uint256 tokenId): 授权另一地址操作指定的 tokenId。
  • getApproved(uint256 tokenId): 获取被授权管理特定 tokenId 的地址。
  • setApprovalForAll(address operator, bool _approved): 授权或撤销操作某个账户管理所有代币。
  • isApprovedForAll(address owner, address operator): 查询某个账户是否被授权管理所有代币。

三、扩展合约

1. ERC721Enumerable

功能:允许枚举所有代币及其所有者的合约扩展。

使用方法

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

contract MyEnumerableNFT is ERC721Enumerable {
    constructor() ERC721("MyEnumerableNFT", "MNFT") {}

    function mintNFT(address recipient, uint256 tokenId) public {
        _mint(recipient, tokenId);
    }
}

主要方法

  • totalSupply(): 返回合约中所有代币的数量。
  • tokenByIndex(uint256 index): 返回指定索引处的代币 ID。
  • tokenOfOwnerByIndex(address owner, uint256 index): 返回某个所有者在指定索引处的代币 ID。

2. ERC721URIStorage

功能:允许为代币分配和管理元数据 URI。

使用方法

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

contract MyURINFT is ERC721URIStorage {
    constructor() ERC721("MyURINFT", "MNFT") {}

    function mintNFT(address recipient, uint256 tokenId, string memory tokenURI) public {
        _mint(recipient, tokenId);
        _setTokenURI(tokenId, tokenURI);
    }
}

主要方法

  • _setTokenURI(uint256 tokenId, string memory tokenURI): 设置指定代币 ID 的元数据 URI。

3. ERC721Pausable

功能:允许暂停和恢复代币的所有传输操作。

使用方法

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

contract MyPausableNFT is ERC721Pausable, Ownable {
    constructor() ERC721("MyPausableNFT", "MNFT") {}

    function mintNFT(address recipient, uint256 tokenId) public onlyOwner {
        _mint(recipient, tokenId);
    }

    function pause() public onlyOwner {
        _pause();
    }

    function unpause() public onlyOwner {
        _unpause();
    }

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

主要方法

  • _pause(): 暂停所有代币转移操作。
  • _unpause(): 恢复所有代币转移操作。
  • _beforeTokenTransfer: 在每次代币转移前调用,检查是否已暂停。

4. ERC721Burnable

功能:允许用户销毁(burn)他们的代币,从而减少总供应量。

使用方法

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";

contract MyBurnableNFT is ERC721Burnable {
    constructor() ERC721("MyBurnableNFT", "MNFT") {}

    function mintNFT(address recipient, uint256 tokenId) public {
        _mint(recipient, tokenId);
    }

主要方法

  • burn(uint256 tokenId): 销毁调用者持有的指定 tokenId 的代币。

5. ERC721Royalty

功能:允许在代币销售时收取版税。

使用方法

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Royalty.sol";

contract MyRoyaltyNFT is ERC721Royalty {
    constructor() ERC721("MyRoyaltyNFT", "MNFT") {}

    function mintNFT(address recipient, uint256 tokenId, address receiver, uint96 feeNumerator) public {
        _mint(recipient, tokenId);
        _setTokenRoyalty(tokenId, receiver, feeNumerator);
    }
}

主要方法

  • _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator): 设置指定代币 ID 的版税信息。

6.ERC721Metadata

功能ERC721Metadata 是 ERC721 标准的一个扩展,用于为不可替代代币(NFT)提供详细的元数据。这些元数据通常包括代币的名称、符号以及每个代币的唯一 URI(统一资源标识符),用于指向代币的详细信息,如图像、描述等。

接口

interface IERC721Metadata is IERC721 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

核心方法

  • name(): 返回代币的名称,如 “CryptoKitties”。
  • symbol(): 返回代币的符号,如 “CK”。
  • tokenURI(uint256 tokenId): 返回指定 tokenId 的 URI,指向代币的详细信息。

使用方法

要实现 ERC721Metadata 扩展,通常会使用 OpenZeppelin 提供的 ERC721URIStorage 合约,该合约已经包含了所有必要的功能。

注意事项

  1. 安全性:确保在合约中处理所有输入时进行必要的验证和检查,以防止潜在的攻击。
  2. 兼容性:与其他智能合约或 dApp 进行交互时,确保符合标准接口以保持兼容性。
  3. 扩展性:根据具体需求选择适当的扩展合约,以提高功能的灵活性和扩展性。

欢迎访问我的 GitHub 查看更多相关项目,或通过WeChat(ID: lk34041515)与我联系,共同探讨技术问题。

创作权保护

本文由 [Leon-Kay] 学习总结编写,水平有限,内容仅供参考,作为个人记录使用。若有疏漏,请不吝赐教。版权归作者所有,未经授权,禁止转载、摘编或以其他方式使用本文内容。如需合作或转载本文,请联系作者获得授权。

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值