Skip to content

ERC-1155

ERC-1155 is Ethereum's multi-token standard: one contract can track many fungible, non-fungible, or mixed token types by ID and transfer several IDs in one batch.

Updated

For educational purposes only; not investment advice. Investing may result in loss.

Direct answer

ERC-1155 is Ethereum’s multi-token standard. A single contract can maintain many token types, and each token ID can represent a fungible balance, a non-fungible item, or another supply design chosen by the implementation. The asset key is therefore contract address + token ID, not the token ID alone.

The standard defines single and batch balance queries, single and batch safe transfers, operator-wide approval, receiver callbacks, transfer events, and optional metadata URI behavior. It does not define who may mint, whether supply is capped, whether metadata is permanent, what legal rights a token conveys, or what any token is worth. Those properties must be verified in the exact contract, its roles, and its external dependencies.

How it works

  1. Identify the balance. balanceOf(account, id) returns the quantity an account holds for one ID. balanceOfBatch(accounts, ids) queries paired account-ID entries. Two contracts may both use ID 1 for unrelated assets, so the complete identity remains the chain, contract address, and ID.
  2. Authorize the caller. A holder may transfer its own balance or call setApprovalForAll(operator, true). That approval covers every ERC-1155 ID the holder owns in that contract; isApprovedForAll(owner, operator) reports the status. ERC-1155 does not include a native approval limited to one ID or amount.
  3. Apply a single or batch transfer. safeTransferFrom moves one ID and amount. safeBatchTransferFrom moves parallel ids and values arrays, whose lengths and ordering must match. Batching can reduce repeated transaction overhead, but it is not guaranteed to be cheaper for every implementation or workload.
  4. Check a contract recipient. After updating balances and emitting the relevant event, a compliant transfer to a contract calls onERC1155Received or onERC1155BatchReceived. An unsupported callback, wrong return value, or rejection normally reverts the transfer. This receiver check reduces accidental lockups; it does not prove that the receiving contract is trustworthy or provides a withdrawal path.
  5. Reconstruct state from events. Every mint, transfer, and burn must be reflected by TransferSingle or TransferBatch. Minting uses the zero address as from; burning uses it as to. Indexers can derive balances and net minted supply per ID from these logs, but must process the full history, chain reorganizations, and contract migrations correctly.
  6. Resolve metadata. The optional URI extension may return a shared template containing {id}. A client replaces it with the lowercase, zero-padded, 64-character hexadecimal token ID without a 0x prefix. Metadata can still be mutable, unavailable, or misleading unless the implementation and storage guarantees say otherwise.

Worked example

A game contract assigns ID 1 to gold coins, ID 7 to access passes, and ID 42 to a unique sword. Alice holds balanceOf(Alice, 1) = 500, balanceOf(Alice, 7) = 3, and balanceOf(Alice, 42) = 1.

  • Alice calls safeBatchTransferFrom with ids = [1, 7, 42] and values = [120, 1, 1]. If validation succeeds, her new balances are 500 - 120 = 380, 3 - 1 = 2, and 1 - 1 = 0; the recipient gains the corresponding quantities.
  • The contract emits TransferBatch. If the recipient is a contract, it must accept the batch through onERC1155BatchReceived; otherwise the whole transaction reverts and none of the three balance changes remains.
  • ID 42 behaves as non-fungible only because its issuance and transfer logic keep supply at 1. ERC-1155 itself does not force that rule. The same contract can later mint more of ID 1, subject to its own access control.

Risks and controls

  • Broad operator authority. A malicious or compromised operator approved through setApprovalForAll may move every ID owned in that contract. Verify the operator address and contract, use a separate wallet where appropriate, and revoke stale approvals.
  • Mint, pause, and upgrade powers. These are implementation features, not standard guarantees. Inspect role holders, proxy administrators, timelocks, supply extensions, and whether an upgrade can change balances or transfer rules.
  • Metadata and asset mismatch. A URI or hosted JSON can change while the on-chain ID stays constant. Verify content hashes, storage persistence, issuer commitments, and the rights represented outside the token contract.
  • Integration errors. Wallets and indexers can pair batch arrays incorrectly, miss historical events, mishandle reorganizations, or confuse the same ID across contracts and chains. Reconcile contract calls, logs, and final balances.
  • Receiver and reentrancy risk. Receiver callbacks execute external code during the transfer flow. Implementations and integrating protocols need appropriate state ordering and reentrancy defenses; callback support alone is not a security review.
  • Cost and liquidity risk. Batch transfers still consume gas and revert atomically if one required condition fails. Market liquidity, pricing, royalties, bridging, redemption, and off-chain enforcement are outside ERC-1155.

Common misconceptions

  • “Every ID is an NFT.” An ID can have any quantity; non-fungibility depends on the implementation’s supply and semantics.
  • “One contract means one collection.” A contract can contain many unrelated token types, and the same numeric ID in another contract identifies a different asset.
  • “Safe transfer means the asset is safe.” The callback checks receiver compatibility, not contract quality, price, metadata, or recoverability.
  • “Batching always saves gas.” It often avoids repeated overhead, but the actual result depends on the implementation, number of IDs, storage changes, calldata, and network fee model.

Sources

Navigation

Search the wiki...