Skip to main content

erc1155-patterns

Use when building multi-token contracts with ERC-1155. Covers batch operations, URI handling, supply tracking, hybrid fungible and non-fungible patterns, and game item architectures.

Aller à l'installation

Informations de source

Dépôt
ccashwell/evm-cortex
Dernière activité de la source
10 avril 2026 à 16:31
Langue détectée de SKILL.md
anglais
Étoiles
131
Forks
18

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
erc1155-patterns
description
Use when building multi-token contracts with ERC-1155. Covers batch operations, URI handling, supply tracking, hybrid fungible and non-fungible patterns, and game item architectures.
# ERC-1155 Multi-Token Patterns ## Standard Interface ```solidity interface IERC1155 { 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; } ``` ## Implementation Pattern ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; import {ERC1155Supply} from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol"; import {ERC1155URIStorage} from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; contract GameItems is ERC1155, ERC1155Supply, ERC1155URIStorage, Ownable { // Token type constants uint256 public constant GOLD = 0; // fungible uint256 public constant SILVER = 1; // fungible uint256 public constant SWORD = 2; // non-fungible (supply = 1 each) uint256 public constant SHIELD = 3; // semi-fungible uint256 private _nextUniqueId = 1000; mapping(uint256 tokenId => uint256 maxSupply) public caps; constructor(string memory baseUri) ERC1155(baseUri) Ownable(msg.sender) { caps[GOLD] = type(uint256).max; caps[SILVER] = type(uint256).max; caps[SWORD] = 100; caps[SHIELD] = 500; } function mintFungible(address to, uint256 id, uint256 amount) external onlyOwner { require(totalSupply(id) + amount <= caps[id], "Cap exceeded"); _mint(to, id, amount, ""); } function mintBatch(address to, uint256[] calldata ids, uint256[] calldata amounts) external onlyOwner { for (uint256 i = 0; i < ids.length; i++) { require(totalSupply(ids[i]) + amounts[i] <= caps[ids[i]], "Cap exceeded"); } _mintBatch(to, ids, amounts, ""); } function mintUnique(address to, string calldata tokenUri) external onlyOwner returns (uint256) { uint256 tokenId = _nextUniqueId++; caps[tokenId] = 1; _mint(to, tokenId, 1, ""); _setURI(tokenId, tokenUri); return tokenId; } function uri(uint256 tokenId) public view override(ERC1155, ERC1155URIStorage) returns (string memory) { return super.uri(tokenId); } function _update(address from, address to, uint256[] memory ids, uint256[] memory values) internal override(ERC1155, ERC1155Supply) { super._update(from, to, ids, values); } } ``` ## URI Handling ERC-1155 uses a single URI template with `{id}` substitution: ``` https://api.example.com/tokens/{id}.json ``` The `{id}` is replaced with the lowercase hex token ID, zero-padded to 64 characters: `https://api.example.com/tokens/0000000000000000000000000000000000000000000000000000000000000001.json` For per-token URIs, use `ERC1155URIStorage`: ```solidity _setURI(tokenId, "ipfs://QmUniqueHash"); // Emits URI(value, tokenId) ``` ## Batch Operations Batch transfers save significant gas compared to individual transfers: ```solidity // Transfer multiple token types in one tx uint256[] memory ids = new uint256[](3); uint256[] memory amounts = new uint256[](3); ids[0] = GOLD; amounts[0] = 100; ids[1] = SILVER; amounts[1] = 50; ids[2] = SWORD; amounts[2] = 1; gameItems.safeBatchTransferFrom(alice, bob, ids, amounts, ""); ``` Gas savings: batch of 10 transfers costs ~60% of 10 individual transfers. ## Receiver Interface Contracts receiving ERC-1155 tokens must implement: ```solidity interface IERC1155Receiver { function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } ``` ## Hybrid Fungible + Non-Fungible Pattern Use ID ranges to distinguish token types: ```solidity // IDs 0-999: fungible tokens (can have supply > 1) // IDs 1000+: unique NFTs (supply == 1) function isFungible(uint256 id) public pure returns (bool) { return id < 1000; } function isNonFungible(uint256 id) public view returns (bool) { return id >= 1000 && totalSupply(id) == 1; } ``` ## ERC-1155 vs ERC-721 Decision | Factor | ERC-721 | ERC-1155 | |--------|---------|----------| | Token types | One per contract | Many per contract | | Batch transfers | Not native | Built-in | | Gas (deploy) | Lower | Higher | | Gas (batch ops) | Higher | Much lower | | Marketplace support | Universal | Growing | | Fungible support | No | Yes | Choose ERC-1155 when: multiple token types, game items, mixed fungible/non-fungible, batch operations needed. ## Security Checklist - [ ] Implement both `onERC1155Received` and `onERC1155BatchReceived` in receiver contracts - [ ] Validate array lengths match in batch operations - [ ] Track supply with `ERC1155Supply` if caps are needed - [ ] Use `_update` hook for custom transfer logic (not `_beforeTokenTransfer`) - [ ] Test `supportsInterface` for ERC-1155 and ERC-165 - [ ] Guard against reentrancy (safe transfers call external code)
Voir sur GitHub