以太坊區塊鏈大幅改變了數位資產的創建與管理方式。在這些進展中,ERC-1155 標準是一項值得關注的創新。由 Enjin 團隊推出的 ERC-1155,旨在透過在單一智能合約中支援同質化代幣、非同質化代幣及半同質化代幣的創建,來簡化並提升區塊鏈上數位資產的管理效率。
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);
}
}
撰寫部署腳本:為 Hardhat Ignition 部署模組建立新檔案 ignition/modules/RadToken.js,並加入以下程式碼。
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 範例展示了在單一合約下管理多種代幣類型的便利性,為新一代去中心化應用程式開啟了大門。
實用資源