ERC-1155

ERC-1155 is a multi-token standard: one contract holds many token IDs, and each ID carries its own supply. An ID with a supply of one behaves like an ERC-721 token; an ID with a supply of a million behaves like an ERC-20. The standard does not require choosing between the two up front.

What it buys#

  • One deployment for a whole catalogue. A game with a thousand item types deploys one contract rather than a thousand.
  • Batch operations. safeBatchTransferFrom moves several IDs in a single call, which is the main gas argument for the standard.
  • Both token shapes at once. Fungible currency and non-fungible items can live in the same contract and be transferred together.

The balance mapping is two-dimensional — balanceOf(account, id) — which is the structural difference from both of the standards it merges.

As with ERC-721, ERC-165 interface detection is mandatory: a compliant contract answers supportsInterface(0xd9b67a26) with true, and that is how callers tell what they are dealing with.

The tradeoff#

Tooling support is thinner than for ERC-721, and the flexibility is not free: because an ID’s supply is a runtime fact rather than a property of the interface, a consumer cannot tell from the application binary interface whether it is looking at something unique. The base standard does not even define a supply query — totalSupply comes from OpenZeppelin’s optional ERC1155Supply extension, and indexers without it reconstruct supply from TransferSingle and TransferBatch events. They do not all do it the same way.

Approvals are collection-wide only. There is no per-ID approve, just setApprovalForAll — so the approval-scope caution on the NFT page applies here with no finer-grained alternative.

The stranding pitfall on that page does not carry over. ERC-1155 has no unsafe transfer variant: safeTransferFrom and safeBatchTransferFrom are the only ways to move a token, and both invoke onERC1155Received or onERC1155BatchReceived on a contract recipient. The mistake ERC-721 permits is not expressible here.

Metadata comes from uri(uint256), and the detail implementers most often miss is that the returned string may contain the literal token {id}, which clients substitute with the ID as lowercase hex, zero-padded to 64 characters, with no 0x prefix — not the decimal form, and not the prefixed form most other tooling produces. One URI can then serve a whole catalogue.