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
合约,该合约已经包含了所有必要的功能。
注意事项
- 安全性:确保在合约中处理所有输入时进行必要的验证和检查,以防止潜在的攻击。
- 兼容性:与其他智能合约或 dApp 进行交互时,确保符合标准接口以保持兼容性。
- 扩展性:根据具体需求选择适当的扩展合约,以提高功能的灵活性和扩展性。
欢迎访问我的 GitHub 查看更多相关项目,或通过WeChat(ID: lk34041515)与我联系,共同探讨技术问题。
创作权保护
本文由 [Leon-Kay] 学习总结编写,水平有限,内容仅供参考,作为个人记录使用。若有疏漏,请不吝赐教。版权归作者所有,未经授权,禁止转载、摘编或以其他方式使用本文内容。如需合作或转载本文,请联系作者获得授权。