Skip to main content

ERC-1155 Tutorial

Overview

ERC-1155 is a multi-token standard that enables a single smart contract to manage multiple token types simultaneously. Unlike ERC-20, which supports one fungible asset per contract, ERC-1155 allows each token ID within the same contract to represent a different asset.

This makes ERC-1155 highly suitable for commodity infrastructure where multiple metals, grades, or warehouse lots must be managed under a unified system.

For example, a single RareEarthMetals contract can define:

  • Token ID 1 → Lithium
  • Token ID 2 → Neodymium
  • Token ID 3 → Cobalt
  • Token ID 4 → Palladium

Each ID represents a distinct commodity, while still benefiting from:

  • Gas-efficient batch minting
  • Batch transfers
  • Unified approval mechanisms
  • Reduced deployment overhead

Within Watr Network, ERC-1155 is particularly useful for:

  • Rare earth metal inventories
  • Multi-commodity vault systems
  • Tokenized warehouse receipts
  • Batch issuance of metal units
  • Managing commodity classes under a single registry

This tutorial walks through:

  • Implementing ERC-1155 using OpenZeppelin
  • Deploying the contract
  • Minting individual metal tokens
  • Batch minting multiple metals
  • Transferring tokens
  • Querying balances per token ID

We use OpenZeppelin Contracts for secure and production-grade ERC-1155 implementation.


Install Dependencies

npm install --save-dev hardhat
npm install @openzeppelin/contracts

RareEarthMetals.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract RareEarthMetals is ERC1155, Ownable {

uint256 public constant LITHIUM = 1;
uint256 public constant NEODYMIUM = 2;
uint256 public constant COBALT = 3;
uint256 public constant PALLADIUM = 4;

constructor() ERC1155("https://api.watr.network/metadata/{id}.json") {}

function mint(address to, uint256 id, uint256 amount) public onlyOwner {
_mint(to, id, amount, "");
}

function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts)
public
onlyOwner
{
_mintBatch(to, ids, amounts, "");
}

function burn(address from, uint256 id, uint256 amount) public onlyOwner {
_burn(from, id, amount);
}
}

Interaction Examples

Mint Single Metal

await contract.mint("RECIPIENT", 1, 500);

Mint Batch

await contract.mintBatch("RECIPIENT", [1,2,3], [100,200,300]);

Transfer

await contract.safeTransferFrom("SENDER","RECIPIENT",1,50,"0x");

Balance Of

const balance = await contract.balanceOf("WALLET", 1);

When to Use ERC-1155

ERC-1155 is recommended when:

  • Multiple commodities must coexist in one contract
  • Batch operations are required
  • Gas optimization is critical
  • Semi-fungible assets (e.g., warehouse lots) are involved
  • Centralized registry logic is desired for multiple token classes