以太坊区块链显著改变了数字资产的创建与管理方式。在这些进步中,ERC-1155 标准作为一项重要创新脱颖而出。ERC-1155 由 Enjin 团队推出,旨在通过在单个智能合约中支持同质化代币、非同质化代币以及半同质化代币的创建,全面提升区块链上数字资产的管理效率。
ERC-1155 的开发初衷是解决 ERC-20 和 ERC-721 等早期代币标准的不足。ERC-20 适用于同质化代币(每个代币完全相同且可互换),ERC-721 适用于非同质化代币(每个代币独一无二),但这两种标准在处理多种代币类型时,在适用范围和效率上均存在局限。
ERC-1155 的主要优势包括:
批量转账:ERC-1155 支持批量转账,允许在单笔交易中转移多种代币类型,大幅降低 gas 费用并提升交易速度。
单合约管理多种代币:该标准允许单个合约同时管理同质化代币和非同质化代币,简化部署流程并降低成本。
安全转账检查:ERC-1155 确保代币仅发送至兼容地址,提升交易安全性,防止因操作失误造成损失。
以下是 ERC-1155 的一些实际应用场景:
游戏:支持在单个合约内管理完整的游戏内经济体系,涵盖消耗品到稀有装备等各类道具。
数字艺术:使艺术家能够无缝发行限量版和开放版作品。
代币化资产:现实世界资产可通过 ERC-1155 进行代币化管理。
编写并部署 ERC-1155 代币
在本教程中,我们将创建一个名为 RAD Token 的基础 ERC-1155 代币。该示例将演示如何在单个合约框架内管理不同类型的资产。
搭建开发环境:开始前,请确保已安装 Node.js 和 npm,然后初始化你的 Hardhat 项目:
mkdir rad-token
cd rad-token
npm init -y
安装 Hardhat 和 OpenZeppelin 合约库
npm install --save-dev hardhat
npm install @openzeppelin/contracts
初始化 Hardhat
npx hardhat出现提示时,选择"Create an empty hardhat.config.js"。
编写 RADToken 合约:创建新文件 contracts/RADToken.sol,并粘贴以下合约代码。
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract RADToken is ERC1155, Ownable {
constructor(address initialOwner, string memory baseURI) ERC1155(baseURI) Ownable(initialOwner) {
}
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);
}
function setURI(string memory newuri) public onlyOwner {
_setURI(newuri);
}
function uri(uint256 tokenId) public view override returns (string memory) {
return string(abi.encodePacked(super.uri(tokenId), Strings.toString(tokenId), ".json"));
}
function burn(address account, uint256 id, uint256 amount) public onlyOwner {
_burn(account, id, amount);
}
function burnBatch(address account, uint256[] memory ids, uint256[] memory amounts)
public
onlyOwner
{
_burnBatch(account, ids, amounts);
}
}
编写部署脚本:创建新文件 ignition/modules/RadToken.js,用于 Hardhat Ignition 部署模块,并添加以下代码。
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");
module.exports = buildModule("RADTokenModule", (m) => {
const deployer = m.getAccount(0);
const baseURI = m.getParameter(
"baseURI",
"<https://gateway.pinata.cloud/ipfs/Qmar8RRAZ5QoVPTzvrRk9PcFSm9YKbkanxmd951nXk2bgM/>"
);
const radToken = m.contract("RADToken", [deployer, baseURI]);
return { radToken };
});
编写测试脚本:创建新文件 test/RadToken.js,用于测试合约,并添加以下代码:
const { expect } = require("chai");
const { ethers } = require("hardhat");
const {
loadFixture,
} = require("@nomicfoundation/hardhat-toolbox/network-helpers");
describe("RADToken", function () {
async function deployRADTokenFixture() {
const [owner, addr1, addr2, ...addrs] = await ethers.getSigners();
const RADToken = await ethers.getContractFactory("RADToken");
const baseURI =
"https://gateway.pinata.cloud/ipfs/Qmar8RRAZ5QoVPTzvrRk9PcFSm9YKbkanxmd951nXk2bgM/";
const radToken = await RADToken.deploy(owner.address, baseURI);
return { radToken, owner, addr1, addr2, addrs };
}
describe("Minting", function () {
it("Should mint a token", async function () {
const { radToken, addr1 } = await loadFixture(deployRADTokenFixture);
await radToken.mint(addr1.address, 1, 100, "0x");
expect(await radToken.balanceOf(addr1.address, 1)).to.equal(100);
});
it("Should mint multiple tokens in batch", async function () {
const { radToken, addr1 } = await loadFixture(deployRADTokenFixture);
await radToken.mintBatch(addr1.address, [1, 2], [100, 200], "0x");
expect(await radToken.balanceOf(addr1.address, 1)).to.equal(100);
expect(await radToken.balanceOf(addr1.address, 2)).to.equal(200);
});
});
describe("URI Management", function () {
it("Should return correct token URI", async function () {
const { radToken } = await loadFixture(deployRADTokenFixture);
expect(await radToken.uri(1)).to.equal(
"https://gateway.pinata.cloud/ipfs/Qmar8RRAZ5QoVPTzvrRk9PcFSm9YKbkanxmd951nXk2bgM/1.json"
);
});
it("Should set new URI and return correct token URI", async function () {
const { radToken } = await loadFixture(deployRADTokenFixture);
const newBaseURI = "https://newbase.uri/";
await radToken.setURI(newBaseURI);
expect(await radToken.uri(1)).to.equal("https://newbase.uri/1.json");
});
});
});
测试合约代码:使用以下命令运行测试:
npx hardhat test部署 RADToken 合约:使用以下命令编译并部署合约:
npx hardhat compile
npx hardhat ignition --network localhost --show-logs ignition/modules/RadToken.js
下一步
ERC-1155 代表了以太坊代币标准的重大进步,相较于前代标准,它提供了更强的灵活性、更高的效率和更广泛的实用性。RAD Token 示例展示了在单个合约下管理多种代币类型的便捷性,为新一代去中心化应用打开了大门。
实用资源