ERC-20(代币标准)
总供应量: ERC-20代币具有总供应量,这意味着在代币合约创建时,就要确定代币的总数量。
可分割性: ERC-20代币是可分割的,也就是说,你可以拥有和传输小数部分的代币。这种特性使得ERC-20代币更适合作为货币或用于表示资产。
接口: ERC-20定义了一组基本的方法和事件,例如transfer(address to, uint256 value)用于向其他地址转移代币,balanceOf(address owner)用于查询账户余额等。
标准接口: ERC-20标准定义了代币合约应该实现的一组接口,以确保不同代币合约之间的兼容性。
其标准定义的主要功能:
totalSupply: 通过该函数可以获取代币的总供应量。
balanceOf: 允许查询指定地址的代币余额。
transfer: 用于将代币从一个地址转移到另一个地址。
transferFrom: 允许另一个地址调用合约来转移代币,前提是事先得到了授权。
approve: 允许一个地址授权另一个地址能够转移自己名义下的代币。
allowance: 允许查询一个地址被授权可以转移的代币数量。
这些函数的实现使得不同的代币合约之间可以一起工作,也使得钱包和其他服务能够与这些代币进行交互。ERC-20标准的制定促使了以太坊生态系统中许多代币的互操作性,使得它们可以在相同的基础设施上运行和被支持。
ERC-20 实现如下:
ERC-20 合约(使用 OpenZeppelin 的 ERC-20 实现):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
contract Yourtokenname is ERC20, Ownable, ERC20Permit {
constructor(address initialOwner)
ERC20("yourtokenname", "symbolname")
Ownable(initialOwner)
ERC20Permit("yourtokenname")
{}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
ERC-721(不可替代代币标准)
以太坊区块链上最早和最流行的NFT标准之一
唯一性: ERC-721代币是不可替代的,每一个都有唯一的标识符。这使得它们非常适合代表独特的资产,如游戏中的道具、艺术品等。
可传输性: ERC-721代币可以在地址之间转移,但每个代币的唯一性保持不变。
接口: ERC-721定义了一组方法和事件,例如transferFrom(address from, address to, uint256 tokenId)用于转移代币,ownerOf(uint256 tokenId)用于查询代币的所有者等。
标准接口: ERC-721标准确保了不同的ERC-721代币合约之间的互操作性。
以下是ERC-721 标准接口的一些核心函数:
balanceOf: 允许查询指定地址拥有的特定 ERC-721 代币数量。
ownerOf: 允许查询特定 ERC-721 代币的当前所有者。
approve: 允许代币所有者授权另一个地址可以转移特定 ERC-721 代币。
getApproved: 允许查询一个 ERC-721 代币当前被授权转移的地址。
setApprovalForAll: 允许代币所有者授权一个地址可以转移他们名下所有的 ERC-721 代币。
isApprovedForAll: 允许查询一个地址是否被授权转移一个代币所有者名下的所有 ERC-721 代币。
transferFrom: 允许经过授权的地址将 ERC-721 代币从一个地址转移到另一个地址。
safeTransferFrom: 与 transferFrom 相似,但增加了一个额外的检查,以确保接收代币的合约能够处理接收操作。
ERC-721 代币通常用于表示独特的数字资产,如数字艺术品、虚拟房地产、游戏中的唯一物品等。这一标准的制定促使了 NFT 生态系统的发展,并使得不同的平台和应用能够在相同的标准下互操作。
ERC-721 实现如下:
ERC-721 合约(使用 OpenZeppelin 的 ERC-721 实现):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract Yourtoken is ERC721, ERC721Burnable, Ownable {
uint256 private _nextTokenId;
constructor(address initialOwner)
ERC721("yourtoken", "MTK")
Ownable(initialOwner)
{}
function safeMint(address to) public onlyOwner {
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId);
}
}
在虚拟机中运行如下:
ERC-1155(多功能代币标准)
另一种以太坊上的NFT标准,它与ERC-721不同,支持在同一合约内创建多种不同类型的资产。这种标准允许一个智能合约管理多个代币类型,提高了效率和灵活性
多代币支持: ERC-1155允许在同一个合约中管理多种类型的代币。这意味着一个合约可以同时包含不同种类的代币,例如可替代和不可替代代币。
经济效率: ERC-1155通过批量转账和原子操作提高了经济效率,减少了交易的繁琐性。
接口: ERC-1155定义了一组方法和事件,例如safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes data)用于安全转移代币,balanceOf(address owner, uint256 id)用于查询特定类型代币的余额等。
标准接口: ERC-1155标准确保了不同的ERC-1155代币合约之间的互操作性。
以下是 ERC-1155 标准接口的核心功能:
balanceOf: 允许查询指定地址拥有的特定代币 ID 的数量。
balanceOfBatch: 允许查询指定地址拥有的多个代币 ID 的数量。
setApprovalForAll: 允许代币所有者授权一个地址可以转移他们名下所有的代币。
isApprovedForAll: 允许查询一个地址是否被授权转移一个代币所有者名下的所有代币。
safeTransferFrom: 与 transferFrom 相似,但增加了一个额外的检查,以确保接收代币的合约能够处理接收操作。
safeBatchTransferFrom: 与 safeTransferFrom 相似,但支持同时转移多个代币。
mint: 允许代币合约的所有者创建新的代币,并将它们分配给指定地址。
mintBatch: 允许代币合约的所有者创建多个新的代币,并将它们分配给指定地址。
burn: 允许代币所有者销毁特定代币 ID 的数量。
burnBatch: 允许代币所有者销毁多个代币 ID 的数量。
ERC-1155 的灵活性在于,它可以同时支持多种类型的代币(例如,可以包含 ERC-20 和 ERC-721 类型的代币)。这种设计可以减少区块链上的交易成本,并提高合约的效率。ERC-1155 代币合约通常用于游戏中的资产管理,其中一个合约可以包含游戏中的多种类型的道具和货币。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol";
contract Yourtoken is ERC1155, Ownable, ERC1155Burnable {
constructor(address initialOwner) ERC1155("") Ownable(initialOwner) {}
function setURI(string memory newuri) public onlyOwner {
_setURI(newuri);
}
function mint(address account, uint256 id, uint256 amount, bytes memory data)
public
onlyOwner
{
_mint(account, id, amount, data);
}
function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
public
onlyOwner
{
_mintBatch(to, ids, amounts, data);
}
}
在虚拟机中运行如下:
下面来谈谈NFT:
NFT代表非同质化代币(Non-Fungible Token)。它是一种数字资产,具有独特性和不可替代性。与加密货币(如比特币或以太坊的普通代币)不同,NFT不是可互换的,每个都有独特的属性和信息,使其在数字资产领域中独一无二。
NFT有一些关键的特征和概念:
唯一性: 每个NFT都是唯一的,有独特的标识符,使其与其他代币或NFT区别开来。
不可替代性: NFT不可替代,因为它们不是按数量相同和互相替代的标准化代币。每个NFT代表特定的数字或实物资产。
可分割性: 尽管每个NFT本身是不可分割的,但某些NFT标准允许其所有者分割其所有权,使其成为部分可分割的资产。
智能合约: NFT通常是通过智能合约创建和管理的,这样可以定义其属性、所有权和其他功能。
区块链技术: NFT基于区块链技术构建,通常使用以太坊区块链上的智能合约。这使得NFT的所有权和传输可以透明、可追溯和不可篡改。
NFT在数字艺术、虚拟游戏物品、音乐、房地产等领域得到广泛应用
下面是一个使用 OpenZeppelin 的 ERC-721 实现:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyNFT is ERC721, Ownable {
using SafeMath for uint256;
// 存储每个NFT的元数据
mapping(uint256 => string) private _tokenURIs;
// 事件,用于通知NFT被创建
event NFTCreated(address indexed owner, uint256 tokenId, string tokenURI);
constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
// 创建新的NFT
function createNFT(address to, uint256 tokenId, string memory tokenURI) external onlyOwner {
_mint(to, tokenId);
_setTokenURI(tokenId, tokenURI);
emit NFTCreated(to, tokenId, tokenURI);
}
// 获取NFT的元数据URI
function getTokenURI(uint256 tokenId) external view returns (string memory) {
return _tokenURIs[tokenId];
}
// 内部方法,设置NFT的元数据URI
function _setTokenURI(uint256 tokenId, string memory tokenURI) internal {
_tokenURIs[tokenId] = tokenURI;
}
}
上述合约中,createNFT 函数允许所有者创建新的NFT,并分配给指定地址。每个NFT都有一个唯一的ID(tokenId),并且可以关联一个元数据URI,通常用于指向NFT的详细信息和图像等信息。
下面是使用 ERC-1155 和 OpenZeppelin 的实现来创建简单的 NFT :
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyNFT is ERC1155, Ownable {
using SafeMath for uint256;
// 存储每个NFT的URI
mapping(uint256 => string) private _tokenURIs;
// 用于生成唯一的NFT ID
uint256 private _currentTokenID = 1;
// 事件,用于通知NFT被创建
event NFTCreated(address indexed owner, uint256 indexed tokenId, string tokenURI);
constructor() ERC1155("https://myapi.com/api/token/{id}.json") {
// 可以在构造函数中添加逻辑
}
// 创建新的NFT
function createNFT(address to, uint256 amount, string memory tokenURI) external onlyOwner {
uint256 tokenId = _currentTokenID;
_mint(to, tokenId, amount, "");
_setTokenURI(tokenId, tokenURI);
_currentTokenID = _currentTokenID.add(1);
emit NFTCreated(to, tokenId, tokenURI);
}
// 获取NFT的元数据URI
function getTokenURI(uint256 tokenId) external view returns (string memory) {
return _tokenURIs[tokenId];
}
// 内部方法,设置NFT的元数据URI
function _setTokenURI(uint256 tokenId, string memory tokenURI) internal {
_tokenURIs[tokenId] = tokenURI;
}
}
上述合约代码使用 ERC-1155 标准,并通过调用 _mint 函数来创建新的 NFT。_mint 函数由 OpenZeppelin 提供,用于在合约中铸造新的代币。请注意,这里我们使用了一个简单的 _currentTokenID 变量来生成唯一的 NFT ID。