来聊聊以太坊代币标准 ERC-20、ERC-721、和ERC-1155

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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Solidity中,可以通过使用智能合约来实现ERC20代币的锁仓与释放。以下是一个简单的锁仓合约示例: ``` pragma solidity ^0.8.0; import "./IERC20.sol"; import "./SafeMath.sol"; contract TokenVesting { using SafeMath for uint256; address public beneficiary; uint256 public cliff; uint256 public start; uint256 public duration; uint256 public released; IERC20 public token; constructor( address _beneficiary, uint256 _cliff, uint256 _duration, address _token ) public { require(_beneficiary != address(0)); require(_cliff <= _duration); beneficiary = _beneficiary; cliff = _cliff; duration = _duration; start = block.timestamp; token = IERC20(_token); } function release() public { uint256 unreleased = releasableAmount(); require(unreleased > 0); released = released.add(unreleased); token.transfer(beneficiary, unreleased); } function releasableAmount() public view returns (uint256) { return vestedAmount().sub(released); } function vestedAmount() public view returns (uint256) { uint256 currentBalance = token.balanceOf(address(this)); uint256 totalBalance = currentBalance.add(released); if (block.timestamp < start.add(cliff)) { return 0; } else if (block.timestamp >= start.add(duration)) { return totalBalance; } else { return totalBalance.mul(block.timestamp.sub(start)).div(duration); } } } ``` 在这个合约中,当创建合约时,需要传入受益人地址、锁仓期、释放期、代币地址等信息。锁仓期结束后,受益人可以通过调用 `release()` 函数来释放锁仓代币。如果释放函数被调用,但是当前时间还没有到达释放期,则会抛出异常。 为了保证代币不能被提前释放,合约还实现了 cliff 的概念,即在锁仓期结束之前,代币不能被释放。当 cliff 结束之后,代币将按照线性方式释放,直到释放期结束。 需要注意的是,以上示例只是一个简单的锁仓合约示例,实际生产环境中需要更加严格地考虑各种情况和安全性问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值