solidity实现智能合约教程-ERC1155合约

Posted 后端常规开发人员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了solidity实现智能合约教程-ERC1155合约相关的知识,希望对你有一定的参考价值。

文章目录

猛戳订阅学习专栏🍁🍁 👉 solidity系列合约源码+解析 👈 🍁🍁

1 介绍

ERC-1155是一种以太坊代币标准,由Enjin首席技术官Witek Radomski等人开发,并于2018年6月17日将该标准的第一个版本放置到Ethereum的github库中。其主要可用于游戏行业中道具的生成和处理。该标准的提出对nft在游戏行业的应用起到了极大的提升。在一定程度上融合了ERC-20和ERC-721的功能。

其主要用途包括了发行同质化代币和非同质化代币。同质化代币即能像ERC-20一样发布各样的代币类型,但目前为止各钱包和交易所暂未支持ERC-1155标准代币;与此同时,ERC-1155标准更是能够发行NFT,且能基于一个合约同时发行多个NFT。伴随现在区块链游戏的大火,ERC-1155标准能够给基于以太坊的上的游戏开发运行提供大大的帮助。尤其在同质化道具的生成和处理上,该标准能够极大降低成本,提高效率。

2 主要功能

该标准定义了开发者可以按照标准要求使用一些简单的功能如:

  • 设定NFT名称
  • 设定NFT总量
  • 设定NFT元数据资源URI
  • 查看地址中NFT余额
  • 查看NFT的归属地址
  • 规范如何批准NFT转移
  • 一定条件下,允许第三方地址使用某账户中的NFT
  • 允许NFT和兼容ETH的智能合约及钱包服务等第三方个体兼容
    以及一些简单的函数功能等等。

我们先来看一下标准的 ERC1155 标准的接口:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IERC1155 

    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    event TransferBatch(address indexed operator,address indexed from,address indexed to,uint256[] ids,uint256[] values);

    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    event URI(string value, uint256 indexed id);

    function balanceOf(address account, uint256 id) external view returns (uint256);

    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);

    function setApprovalForAll(address operator, bool approved) external;

    function isApprovedForAll(address account, address operator) external view returns (bool);

    function safeTransferFrom(address from,address to,uint256 id,uint256 amount,bytes calldata data) external;

    function safeBatchTransferFrom(address from,address to,uint256[] calldata ids,uint256[] calldata amounts,bytes calldata data) external;

下面我们解释一下上述每个接口函数的作用:

  • event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value) 当任何NFT的所有权更改时,会触发此事件。

  • event TransferBatch(address indexed operator,address indexed from,address indexed to,uint256[] ids,uint256[] values); 当NFT发生批量转移时会触发该事件

  • event ApprovalForAll(address indexed account, address indexed operator, bool approved); 所有者启用或禁用操作员时触发。(操作员可管理所有者所持有的NFTs)

  • event URI(string value, uint256 indexed id);; 当给某个NFT绑定或更新URI资源文件时触发

  • function balanceOf(address account, uint256 id) external view returns (uint256); 查询某地址中指定tokenId的NFT的数量

  • function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); 查询给定的地址数组中的地址对应的tokenId数组中tokenId的NFT的数量

  • function safeTransferFrom(address from,address to,uint256 tokenId,bytes calldata data) external; 将NFT的所有权从一个地址转移到另一个地址,data : 附加额外的参数(没有指定格式),传递给接收者。

  • function setApprovalForAll(address operator, bool _approved) external; 启用或禁用第三方(操作员)管理 msg.sender 所有资产,触发 ApprovalForAll 事件。

  • function getApproved(uint256 tokenId) external view returns (address operator); 获取单个NFT的授权地址

  • function safeBatchTransferFrom(address from,address to,uint256[] calldata ids,uint256[] calldata amounts,bytes calldata data) external;给指定的地址转移指定tokenId数组所对应的数量数组中的数量的NFT

3 代码示例

下面我们借助openzeppelin智能合约库来写一个ERC1155合约,来实现NFT的铸造、批量铸造、单个NFT的URI信息获取和批量URI获取等功能。
代码:

// SPDX-License-Identifier: MIT;

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/utils/Counters.sol";


contract Test1155 is ERC1155 

    using Counters for Counters.Counter;
    Counters.Counter private _tokenId;

    mapping(uint => string) private _tokenURIs;

    constructor() ERC1155("https://baseUrl.com") 

    function mint(address _recipient,uint _amount, string memory _tokenUrl) public returns(uint _mintTokenId)
        require(bytes(_tokenUrl).length > 0,"The _tokenUrl must be have");
        require(_amount > 0,"The _amount must be have");
        _tokenId.increment();
        uint newTokenId = _tokenId.current();
        _mint(_recipient, newTokenId,_amount,"");
        _tokenURIs[newTokenId] = _tokenUrl;
        return newTokenId;
    

    function mintBatch(address _recipient,uint[] memory _amounts,string[] memory _tokenUrls) public returns(uint[] memory _mintTokenIds)
        require(_amounts.length > 0,"The _amounts must be have");
        require(_tokenUrls.length > 0,"The _tokenUrls must be have");
        require(_amounts.length == _tokenUrls.length,"The _tokenUrl length must be Equal _amounts length");

        uint newTokenId;
        uint[] memory returnTokenUrls = new uint[](_amounts.length);

        for(uint256 i = 0; i < _amounts.length; i++)
            _tokenId.increment();
            newTokenId = _tokenId.current();
            _tokenURIs[newTokenId] = _tokenUrls[i];
            returnTokenUrls[i] = newTokenId;
        

        _mintBatch(_recipient, returnTokenUrls,_amounts,"");

        return returnTokenUrls;
    

    function uri(uint256 _id) public view override returns(string memory _tokenUrl)
        return _tokenURIs[_id];
        
    

    function uriBatch(uint[] memory _tokenIds) public view returns(string[] memory _tokenUrls)
        require(_tokenIds.length > 0,"The _tokenId must be have");

        string[] memory returnTokenUrl = new string[](_tokenIds.length);

        for(uint256 i=0;i<_tokenIds.length;i++)
            returnTokenUrl[i] = _tokenURIs[_tokenIds[i]];
        

        return returnTokenUrl;
    


4 部署测试


我们先部署好该1155合约


我们给当前地址铸造了5个tokenId相同的NFT,并给该NFT的URI资源设定为www.test.img,从交易的output中可以看到该tokenId为1


接下来我们查询到了该地址中tokenId为1的NFT数量为5个,代表着铸造成功!


然后我们查询到tokenId为1的NFT的URI地址为www.test.img,OK,没问题
我们可以根据该流程测试批量的mint和转账方法,这里就不再一一列举。

智能合约实战 solidity 语法学习 09 [ 以太坊 ether ERC20标准API介绍及示例 ]name symbol decimals totalSupply balanceOf...

 

1. ERC20代币的标准API

https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md

2. API介绍及示例

interface Token 
    //输入地址,可以获取该地址代币的余额
    function balanceOf(address _owner) external view returns (uint256 balance);

    //将自己的token转账给_to地址,_value为转账个数
    function transfer(address _to, uint256 _value)  external returns (bool success);

    //与approve搭配使用,approve批准之后,调用transferFrom函数来转移token
    function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);

    //批准_spender账户从自己的账户转移_value个token,可以多次转移
    function approve(address _spender  , uint256 _value) external returns (bool success);

    //返回_spender还能转移_owner的token个数
    function allowance(address _owner, address _spender) external view returns (uint256 remaining);    
    /* 
      关于approve、transferFrom、allowance
      账户_owner有100个ETH,想允许_sp

以上是关于solidity实现智能合约教程-ERC1155合约的主要内容,如果未能解决你的问题,请参考以下文章

ERC1155

ERC-721与ERC-1155有什么区别?

openzeppelin-solidity

Solidity-ERC20代币的锁仓与释放-1

代币标准--ERC1155协议源码解析

,让你了解ERC-1155 多代币标准协议