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.
safeBatchTransferFrommoves 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.