基于ERC1155标准实现一个代币合约

  • 木西
  • 发布于 2025-02-27 13:32
  • 阅读 341

前言本文主要依托于openzeppelin库实现一个ERC1155标准的代币,包含了合约的开发,测试,部署以及和ERC20标准,ERC721标准的区别和使用场景分析。ERC20、ERC721、ERC1155标准特点ERC20标准:同质化、可分割性、标准化、兼容性、流通性;ERC721

前言

本文主要依托于openzeppelin库实现一个ERC1155标准的代币,包含了合约的开发,测试,部署以及和ERC20标准,ERC721标准的区别和使用场景分析。

ERC20、ERC721、ERC1155标准

特点

  • ERC20标准:同质化、可分割性、标准化、兼容性、流通性;
  • ERC721标准:非同质化、不可分割性、所有权验证、元数据、稀缺性;
  • ERC1155标准:多功能性、效率、灵活性、批量操作、兼容性、安全性;

    使用场景

  • ERC20标准:ERC-20代币广泛应用于ICO、代币化资产、DApp的实用代币、去中心化自治组织(DAO)的治理代币,以及作为在以太坊生态系统内转移价值的手段
  • ERC721标准:ERC-721代币被广泛应用于各类NFT项目中,包括数字艺术、游戏内资产、数字收藏品、虚拟地产等

  • ERC1155标准:ERC-1155代币标准提供了更为高效的代币管理方式,适用于需要在同一合约中管理多种资产的场景;

标准区别

  • ERC20标准:同质化代币,具有可分割性以及可替代性,类似于货币;
  • ERC721标准:非同质化代币,具有不可分割性以及不可替代性,类似于艺术品;
  • ERC1155标准:在一个合约中包装多个同质化与非同质化代币,提供了更灵活高效的搭配;

    ERC1155合约

    合约功能:铸造,销毁,批量销毁和铸造,转账、查看、验证等相关的功能;

    
    // SPDX-License-Identifier: MIT
    // Compatible with OpenZeppelin Contracts ^5.0.0
    pragma solidity ^0.8.22;

import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; import {ERC1155Burnable} from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

contract GameToken is ERC1155, Ownable, ERC1155Burnable { constructor(address initialOwner) ERC1155("ipfs://QmcN49MKt4MbSXSGckAcpvFqtea43uuPD2tvmuER1mG67s") 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);
}

}

#### ERC1155合约测试

const {ethers,getNamedAccounts,deployments} = require("hardhat"); const { assert,expect } = require("chai"); describe("GameToken",async()=>{ let GameToken;//合约 let addr1;//第一个账户 let addr2;//第二个账户 let firstAccount//第一个账户 let secondAccount//第二个账户; let mekadata="ipfs://QmcN49MKt4MbSXSGckAcpvFqtea43uuPD2tvmuER1mG67s" let mekadata1="ipfs://QmTL5CJsEUGGPxBi3VNYnFebGScrs8ANa5aeK98QGb5Prn" let tokenId=0; beforeEach(async()=>{ await deployments.fixture(["gametoken"]); [addr1,addr2]=await ethers.getSigners(); firstAccount=(await getNamedAccounts()).firstAccount; secondAccount=(await getNamedAccounts()).secondAccount; const GameTokenDeployment = await deployments.get("GameToken"); GameToken = await ethers.getContractAt("GameToken",GameTokenDeployment.address);//已经部署的合约交互 }) describe("GameToken测试用例",async()=>{ it("测试用例",async()=>{ const owner = await GameToken.owner(); console.log("owner",owner) //修改URI await GameToken.setURI(mekadata1); console.log(await GameToken.uri(0)) //铸造说明如果数量是1是非同质化代币,数量大于1是同质化代币 //铸造单个 参数说明:地址,tokenid,数量,唯一标识或其他参说 await GameToken.mint(firstAccount,0,100,'0x11'); console.log("tokenid 为0",await GameToken.balanceOf(firstAccount,0)) //销毁单个 销毁tokenid为0的10个 await GameToken.burn(firstAccount,0,10); //查看余额为90 console.log('销毁后firstAccount查看余额',await GameToken.balanceOf(firstAccount,0)) await GameToken.mint(firstAccount,1,1,'0x11'); console.log("tokenid 为1",await GameToken.balanceOf(firstAccount,1)) //返回的value为0说明不存在 console.log("tokenid 为3不存在",await GameToken.balanceOf(firstAccount,3)) //批量铸造 await GameToken.mintBatch(firstAccount,[2,3,4],[200,300,400],'0x22'); console.log(firstAccount) //addr数字和id的数组长度必须一致 返回余额的数组 console.log("tokenid 为数组",await GameToken.balanceOfBatch([firstAccount,firstAccount,firstAccount],[2,3,4])) //批量销毁 tokenid为2,3,4的100个 await GameToken.burnBatch(firstAccount,[2,3,4],[100,100,100]); //查看firstAccount余额为 100,200,300 console.log('销毁后firstAccount查看余额',await GameToken.balanceOfBatch([firstAccount,firstAccount,firstAccount],[2,3,4])) //单个转账 //把tokenid为1的转给secondAccount await GameToken.safeTransferFrom(firstAccount,secondAccount,1,1,'0x'); console.log("firstAccount的余额",await GameToken.balanceOf(firstAccount,1)) console.log("secondAccount的余额",await GameToken.balanceOf(secondAccount,1)) //批量转账 //把tokenid为2,3的转给secondAccount await GameToken.safeBatchTransferFrom(firstAccount,secondAccount,[2,3],[100,200],'0x'); console.log("firstAccount的余额",await GameToken.balanceOfBatch([firstAccount],[4])) console.log("secondAccount的余额",await GameToken.balanceOfBatch([secondAccount,secondAccount,secondAccount],[1,2,3])) console.log(await GameToken.uri(4)) }) }) })

#### ERC1155合约部署

module.exports = async function ({getNamedAccounts,deployments}) { const firstAccount= (await getNamedAccounts()).firstAccount; const {deploy,log} = deployments; const GameToken=await deploy("GameToken",{ from:firstAccount, args: [firstAccount],//参数 log: true, }) console.log("gametoken合约",GameToken.address)

} module.exports.tags = ["all","gametoken"];

部署指令

npx hardhat deploy


#### 总结
以上就是基于ERC1155标准实现的综合代币合约,包含了开发、测试、部署流程,在测试文件中对合约单个或批量铸造、销毁、转移代币等相关功能进行相关测试。简单一句话:ERC1155代币就是ERC20和ERC721标准的综合使用。
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
木西
木西
江湖只有他的大名,没有他的介绍。