以太坊 ERC721 标准学习
以太坊 ERC721 标准学习
以太坊不仅支持同质化代币(如 ERC20),还支持非同质化代币(NFT),而 ERC721 是其中最著名的标准。
我个人理解:可以把 ERC721 智能合约想象成一个艺术家工作室,mintNFT 函数就像是艺术家创作新作品的过程。每当艺术家完成一件作品,就会给它一个独特的标识,并将它交给特定的人(即接收地址)。
或者说:ERC20 代币就像是银行发行的货币,每一张 100 元钞票都是一样的,可以互换。而 ERC721 代币则像是艺术家的独特作品,每一件都是独一无二的,无法互换。
什么是 ERC721 标准?
ERC721(Ethereum Request for Comments 721)是以太坊平台上的一种标准接口,用于实现非同质化代币(NFT)。与 ERC20 代币不同,每个 ERC721 代币都是独一无二的,这使得它们非常适合用于表示独特的资产,如艺术品、收藏品和游戏中的道具。
为什么 ERC721 标准很重要?
-
唯一性:每个 ERC721 代币都是独一无二的,具有独特的 ID,这使得它们非常适合表示独特的数字资产。
-
所有权:ERC721 标准确保了每个代币的所有权可以被追踪和转移,从而为数字资产提供了可靠的所有权证明。
-
广泛采用:由于其灵活性和功能性,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 服务器),而不是直接存储在区块链上,以减少链上存储的成本和复杂性。

浙公网安备 33010602011771号