Cube

What is ERC-1155?

Learn what ERC-1155 is, why it exists, and how this multi-token standard handles fungible, non-fungible, and batch asset transfers.

What is ERC-1155? hero image

Introduction

ERC-1155 is a token standard for smart contracts that can manage many token types inside a single contract. That sounds like a small design tweak, but it solves a real problem: earlier standards made developers choose between the world of fungible tokens, like currencies, and the world of non-fungible tokens, like unique collectibles, and often forced them to deploy separate contracts for each asset type.

The deeper idea is that a token is not fundamentally “an ERC-20” or “an ERC-721.” At the lowest level, a token system is just a rule for assigning balances of some asset identifier to addresses. ERC-1155 makes that asset identifier explicit. Instead of saying “this whole contract is one token” or “this whole contract is a collection of unique items,” it says: this contract contains many IDs, and each ID has its own balance distribution. Once you see that shift, the standard makes sense.

That is why ERC-1155 became especially attractive for applications like games, digital collectibles, tickets, memberships, and mixed asset systems. A game might need gold, wood, swords, skins, and one-of-one artifacts. Under older patterns, that could mean many separate contracts. Under ERC-1155, they can all live under one contract interface, with shared approval logic, shared transfer semantics, and efficient batch operations.

Why was ERC-1155 created and what specific problem does it solve?

To understand why ERC-1155 exists, start with the friction in the earlier standards. ERC-20 models one fungible asset per contract: if the contract is for USDC, every unit is interchangeable with every other unit. ERC-721 models a collection of unique items: each token ID represents a distinct NFT. Both are useful, but both tie the contract structure to a narrow asset shape.

That coupling creates cost and complexity. Suppose an on-chain game has 100 item types. Some are stackable, like potions. Some are unique, like named artifacts. Some are semi-fungible, like concert tickets where many copies are identical before the event but become distinct memorabilia afterward. If each type needs its own contract, or if fungible and non-fungible assets need separate standards, then deployment costs multiply, approval flows fragment, and moving a player’s inventory becomes awkward. The blockchain sees many separate contracts when the application really sees one inventory system.

ERC-1155 removes that mismatch by changing the level of abstraction. The contract is no longer the token; the contract is a container for many token IDs. Each ID can behave like a fungible asset, a non-fungible asset, or something in between, depending on how the implementation defines supply and usage. The standard itself explicitly allows a single deployed contract to include any combination of fungible, non-fungible, and semi-fungible tokens.

The most important practical consequence is efficiency. If Alice wants to send Bob 100 units of item ID 3, 200 units of item ID 6, and 5 units of item ID 13, ERC-1155 can do that in one batch transfer. The assets may be different kinds of things in application terms, but mechanically they are all just updates to balances keyed by (owner, id). That shared structure is what makes the standard click.

How does ERC-1155 store balances using owner and token ID?

The simplest useful way to think about ERC-1155 is this: the contract maintains a two-dimensional ledger. One dimension is the address that owns something. The other is the token ID that names what is owned. The value stored at that intersection is the balance.

So instead of a ledger that looks like balance[owner], as in the common ERC-20 pattern, ERC-1155 conceptually looks like balance[owner][id]. If balance[Alice][7] = 50, Alice owns 50 units of token type 7. If balance[Alice][42] = 1, Alice owns one unit of token type 42. If no one else can ever hold token ID 42, then that ID functions like an NFT. If many people can each hold quantities of token ID 7, that ID functions like a fungible token.

This is the compression point of ERC-1155: fungibility is not a property of the whole contract; it is a property of how a particular token ID is used. The standard does not force a universal interpretation of IDs. It gives a common transfer and balance interface, then lets the contract’s supply rules and application logic determine whether a given ID is interchangeable, unique, or partially interchangeable.

That flexibility is powerful, but it also creates an important subtlety. ERC-1155 does not define a canonical on-chain way to ask, “is this ID fungible or non-fungible?” Some implementations use supply conventions, such as treating totalSupply(id) = 1 as NFT-like. Others encode type information into the bits of the ID itself. The standard leaves that choice to implementations. So tools often need project-specific assumptions or off-chain indexing to interpret IDs correctly.

How do ERC-1155 single and batch transfers work under the hood?

Transfer typeFunctionAtomicityMain checksBest for
Single transfersafeTransferFromSingle id/value atomiczero address; caller auth; sufficient balanceone id to one recipient
Batch transfersafeBatchTransferFromMultiple ids/values atomicids and values length match; per-id checksmultiple ids in one call
Figure 110.1: ERC-1155 single vs batch transfers

ERC-1155 defines two main transfer functions: safeTransferFrom for one token ID and safeBatchTransferFrom for many IDs at once. The word safe matters. It does not mean “economically safe” or “free from bugs.” It means the transfer includes checks intended to prevent tokens from being sent to contracts that cannot handle them.

For a single transfer, the caller moves _value units of token ID _id from _from to _to. The contract must enforce the core invariants: the recipient cannot be the zero address, the caller must be _from or an approved operator, and _from must have enough balance. If any of those conditions fail, the transfer must revert.

For a batch transfer, the same logic is applied across arrays of IDs and values. The arrays must have the same length, and the ordering matters: the change for ids[0] and values[0] is part of the same atomic operation as the change for ids[1] and values[1], and so on. If one element is invalid, the entire batch reverts. That atomicity is a big part of the standard’s usefulness. It lets an application move a whole inventory or settle a complex in-game trade as a single state transition.

A concrete example makes this clearer. Imagine Alice is trading with Bob inside a game. She sends Bob 100 gold tokens under ID 1, 3 healing potions under ID 2, and 1 rare shield under ID 99. Under ERC-1155, those three balance updates can happen in one safeBatchTransferFrom call. The contract checks that Alice is authorized, verifies she has enough of each ID, subtracts the amounts from her balances, adds them to Bob’s balances, emits the required transfer event, and then, if Bob is a contract rather than a regular externally owned account, asks Bob’s contract whether it accepts the transfer. If Bob’s contract rejects it or returns the wrong magic value, the whole transaction reverts. The mechanism is designed so that “all assets moved correctly” and “the recipient contract explicitly accepted them” are part of the same operation.

Why does ERC-1155 call receiver hooks and what risks do they introduce?

HookFunctionAccept valueCalled whenPrimary risk
Single receiver hookonERC1155Received0xf23a6e61single safeTransferFrom to a contractreentrancy via external call
Batch receiver hookonERC1155BatchReceived0xbc197c81safeBatchTransferFrom to a contractreentrancy across batch items
Figure 110.2: ERC-1155 receiver hooks compared

One of the oldest ways tokens get lost is by being sent to a smart contract that has no idea what to do with them. ERC-1155 tries to reduce that risk for its safe transfer functions by requiring a handshake when the recipient is a contract.

If the recipient has code, the ERC-1155 contract must call onERC1155Received for a single transfer or onERC1155BatchReceived for a batch transfer. To accept the transfer, the recipient must return the exact required magic value: 0xf23a6e61 for single transfers or 0xbc197c81 for batch transfers. If it does not, the transfer must revert.

This is a contract-to-contract acknowledgment protocol. Its purpose is straightforward: make the receiving contract say, on-chain and in the same transaction, “yes, I know I am receiving ERC-1155 tokens and I accept them.” That is what the word safe is buying you.

But the mechanism has a consequence that smart readers should not miss: calling the receiver hook means calling external code during a transfer. That creates a reentrancy surface. OpenZeppelin explicitly warns that safeTransferFrom and safeBatchTransferFrom can potentially allow reentrancy when transferring to untrusted contracts, and recommends standard defenses like checks-effects-interactions and reentrancy guards where appropriate.

So the receiver hook solves one problem while introducing another engineering responsibility. It helps prevent accidental token loss to unaware contracts, but because it is an external call, implementations and integrators must reason carefully about state updates around it.

How do ERC-1155 events drive indexing and token discovery?

In many token standards, events are mostly thought of as logs for wallets and explorers. In ERC-1155, they are more central than that. The standard requires that transfers emit either TransferSingle or TransferBatch, and this event stream is how external observers are expected to reconstruct balances and token existence over time.

That design choice matters because ERC-1155 does not require the contract to expose on-chain enumeration of every existing token ID. There is no mandatory built-in list of all IDs, all holders, or all minted assets. Instead, indexers infer that information by following the emitted events. The standard’s caveat is explicit: enumeration and existence are meant to be derived from emitted events rather than an on-chain registry of IDs.

This keeps the base standard lean, but it pushes work outward. Wallets, marketplaces, analytics platforms, and game backends usually need an indexer. If an implementation fails to emit events correctly, the contract may still compile and store balances, but the broader ecosystem will have trouble understanding what happened. In practice, ERC-1155 is a standard where on-chain state and off-chain indexing are tightly coupled.

What are the trade-offs of ERC-1155’s approval model versus ERC-20 and ERC-721?

Approval modelGranularityUXMain riskStandard support
Operator approval (setApprovalForAll)All tokens in contractSingle approval for many assetsBroad operator trust requiredBase ERC-1155
Per-amount allowance (ERC-20 style)Specific amounts per tokenFiner control; more stepsHigher complexity and UX frictionRequires extension or custom logic
Figure 110.3: Operator approvals vs per-amount allowances

ERC-1155 uses an operator approval model centered on setApprovalForAll and isApprovedForAll. This means an owner can authorize another address to manage all of their ERC-1155 tokens in that contract. The model is closer to ERC-721 than to ERC-20.

The benefit is simplicity. If a marketplace, game engine, or vault contract needs to move a user’s assets, the user gives one approval for the whole contract instead of juggling many per-token allowances. In a multi-asset system, that can make the UX much cleaner.

The cost is granularity. The standard approval model is all-or-nothing at the contract level. You cannot natively approve only 10 units of ID 5, or only a subset of IDs, through the base ERC-1155 interface. That is a real tradeoff. It reduces complexity in the standard, but it means users place broader trust in approved operators.

This limitation has inspired extensions. For example, ERC-7604 proposes permit-style off-chain signed approvals for ERC-1155, but it depends on a separate allowance extension because base ERC-1155 does not support per-amount approvals by itself. That is a good example of what is fundamental versus conventional here: the core standard optimizes for shared multi-token management, not fine-grained allowance semantics.

How does ERC-1155 URI templating work and what are its metadata trust limits?

ERC-1155 includes an optional metadata URI mechanism, and its design is as revealing as the transfer model. Instead of requiring a distinct on-chain URI string for every token ID, implementations can return a shared URI template containing {id}. Clients then replace {id} with the token ID encoded as lowercase hexadecimal, left-padded to 64 characters, with no 0x prefix.

This is a gas-saving design. If a project has thousands of token IDs, storing a completely separate URI per ID on-chain can be expensive. A shared pattern like https://example.com/metadata/{id}.json lets the contract store one template while clients derive token-specific URLs deterministically.

The mechanism is simple, but the implications are larger. ERC-1155 metadata is often off-chain JSON. That makes display rich and flexible, but it also means the standard does not, by itself, guarantee availability, authenticity, or immutability of the metadata. If the URI points to a centralized server, the server can fail or change content. If it points to IPFS, the content is content-addressed, which helps integrity, but availability still depends on the content being provided or pinned.

This is one of the places where developers often over-assume what the standard gives them. ERC-1155 standardizes where to look for metadata and how to form the URI. It does not guarantee that the returned metadata is permanent, honest, or even retrievable. If stronger integrity guarantees are needed, an extension like ERC-2477 can publish on-chain hashes for the metadata referenced by uri(id). If controlled metadata updates are part of the design, ERC-5185 sketches one way to make those updates deterministic and auditable. Those are not part of base ERC-1155, but they exist because the base standard deliberately leaves metadata trust assumptions open.

The practical consequence shows up in marketplaces and wallets. When NFT content fails to display, the problem is often not the transfer logic at all; it is broken or unavailable metadata. OpenSea’s own support materials explicitly point users to metadata issues as a common cause of missing NFT content and provide a metadata refresh mechanism. That is a reminder that token standards define asset ownership semantics more precisely than they define presentation semantics.

How can you determine totalSupply or existence for an ERC-1155 token ID?

A common question is: how many units of a given ERC-1155 token exist? The base standard does not require a totalSupply(id) function. That surprises people coming from ERC-20 or from NFT interfaces where uniqueness is central.

The reason is philosophical as much as technical. ERC-1155 standardizes balances and transfers, not every piece of asset accounting an application might want. Supply tracking can be added, but it is an extension, not a base requirement. OpenZeppelin’s ERC1155Supply extension is a common example: it tracks per-ID supply, provides totalSupply(id), and exposes exists(id) as totalSupply(id) > 0.

This is useful, but even here, interpretation matters. If totalSupply(id) = 1, people often call that ID an NFT. That may be a reasonable current description, but it is not a permanent guarantee unless the contract also guarantees no more of that ID can ever be minted. OpenZeppelin’s own documentation is careful on this point: a supply of one does not prove long-term uniqueness if future minting is still possible.

Supply tracking also reveals how delicate hook ordering can be. A known OpenZeppelin advisory described versions of ERC1155Supply where total supply was updated only after the receiver callback during minting. That created a temporary inconsistency: during the callback, the recipient already had the minted balance, but reported total supply had not yet been updated. If another system relied on accurate supply at that moment, it could be exploited. The fix was to correct the ordering so supply accounting stayed consistent across the callback boundary.

This is a good illustration of a broader lesson: ERC-1155’s batch transfers and receiver hooks are elegant, but the moment you add derived accounting like total supply, staking weights, or cap checks, you must think carefully about when state becomes true relative to external calls.

When should a project choose ERC-1155 over ERC-20 or ERC-721?

ERC-1155 is often associated with gaming, and that is not accidental. Games naturally think in inventories. An inventory is a mapping from player to item type to quantity. That is almost exactly the ERC-1155 mental model.

Imagine a role-playing game. Gold is fungible. Health potions are fungible in smaller batches. A season pass might have 10,000 identical copies. A trophy awarded to tournament winners might exist in only 50 copies. A legendary sword might be unique. If all of these live in one ERC-1155 contract, the game can share transfer logic, approvals, metadata conventions, and indexing patterns across the full asset set.

This is not only about gas savings, though gas savings matter. It is also about coherence. A player’s wallet, the game backend, and a marketplace can reason about the whole asset universe through one interface. The standard’s design is unusually well aligned with applications where many distinct assets are conceptually part of one system rather than independent tokens with separate identities.

That said, ERC-1155 is not automatically the best choice for every project. If a system wants each asset to have highly individualized contract logic, deeply custom per-token permissions, or simple ecosystem assumptions optimized for one token class only, separate ERC-20 or ERC-721 contracts may still be cleaner. ERC-1155 gains efficiency by unifying structure. If your assets do not really share structure, the benefits shrink.

How do wallets and contracts detect ERC-1155 support (ERC-165) and manage interoperability?

ERC-1155 requires ERC-165 interface detection. A compliant contract must implement supportsInterface and return true for the ERC-1155 interface ID 0xd9b67a26. This is how wallets, marketplaces, and other contracts can discover that they are interacting with an ERC-1155 token contract.

That requirement matters because ERC-1155 is modular. There is the base interface, the optional metadata URI interface, and the receiver interface for accepting safe transfers. Tools need a programmatic way to ask what a contract supports. ERC-165 is the agreed language for that kind of self-description.

Interoperability, though, is always only partial. Two contracts can both be ERC-1155-compliant and still make very different design choices about token ID encoding, minting policy, supply tracking, URI mutability, or whether certain IDs are intended to be unique. The standard gives a shared transport layer for balances and transfers. It does not force a shared worldview for what each ID means.

What are ERC-1155’s main limitations and integration pitfalls?

ERC-1155 works best when the application can treat many assets as entries in one common ledger. It works less cleanly when users or integrators need strong per-asset guarantees that the base standard does not express.

One pressure point is semantics. Because the standard does not define a canonical on-chain distinction between fungible and non-fungible IDs, external tooling often has to infer or be told what each ID represents. Another is metadata trust. The URI mechanism is efficient, but off-chain metadata introduces availability and integrity assumptions outside the chain itself. A third is approval granularity: operator-wide approvals are convenient, but they are blunt.

The transfer hooks also create a subtle boundary. They protect against one class of loss, but they mean every safe transfer to a contract is also an interaction with potentially adversarial code. That is not a flaw in the standard so much as a consequence of trying to make contract recipients explicit participants in the transfer.

Finally, the lack of mandatory enumeration means ERC-1155 is rarely a purely on-chain user experience. In practice, good ERC-1155 systems depend on event indexing, metadata hosting, and client conventions. The standard is very good at encoding ownership changes; it is much less opinionated about discovery and display.

Conclusion

ERC-1155 is best understood as a shift in perspective: a token contract can be a whole asset ledger, not just one asset. By indexing balances by both owner and token ID, the standard can represent fungible, non-fungible, and semi-fungible assets through one interface, and that shared structure makes batch operations and mixed inventories efficient.

Its power comes from what it unifies, and its tradeoffs come from what it leaves open. ERC-1155 gives you a common machinery for many asset types, but it does not fully standardize the meaning of each ID, the trust model of metadata, or fine-grained approval rules. If you remember one thing tomorrow, remember this: **ERC-1155 treats tokens as entries in a multi-asset ledger, and that is why it is both flexible and demanding. **

How do you evaluate a token before using or buying it?

Before you buy or approve an ERC-1155 token, check its on-chain mechanics and metadata so you know what you’re actually trading. Use Cube Exchange to inspect contract details, verify assumptions, and then execute the trade or set approvals from your funded Cube account.

Frequently Asked Questions

How does ERC-1155 represent fungible versus non-fungible assets inside the same contract?
+
ERC-1155 makes fungibility a property of each token ID: the contract stores balances as balance[owner][id], and whether an ID behaves like a fungible token or an NFT depends on how that ID is used by the implementation. The standard does not provide a canonical on‑chain query for “is this ID fungible?”, so projects commonly rely on conventions (e.g., totalSupply(id) == 1) or encode type bits into the ID and require off‑chain tooling to interpret them.
Why are ERC-1155 transfer functions called safe, and does that introduce any new risks?
+
‘Safe’ transfers require the recipient contract to implement onERC1155Received or onERC1155BatchReceived and return the exact magic value (0xf23a6e61 for single, 0xbc197c81 for batch) to accept the tokens; if it does not, the transfer must revert. Because the transfer makes an external call to the recipient during the same transaction, this handshake prevents accidental loss but creates a reentrancy surface that integrators must defend against.
How do ERC-1155 batch transfers work and why are they useful for games and mixed-asset systems?
+
safeBatchTransferFrom takes arrays of ids and values and applies all updates atomically: the arrays must match in length and if any element is invalid the whole batch reverts, enabling efficient single-call moves of mixed inventories. This atomicity both reduces gas costs and lets complex multi-item trades or inventory transfers happen as one consistent state change.
Does ERC-1155 provide on-chain enumeration or totalSupply for each token ID?
+
The base ERC-1155 standard does not require on‑chain enumeration or a totalSupply(id); instead external indexers reconstruct token existence and ownership from TransferSingle/TransferBatch events, so correct event emission is essential for wallets and marketplaces to discover tokens. Implementations can add supply-tracking extensions (for example OpenZeppelin’s ERC1155Supply) when on‑chain supply queries are needed.
What are the trade-offs of ERC-1155’s approval model compared with ERC-20 or ERC-721?
+
ERC-1155 uses an operator model via setApprovalForAll/isApprovedForAll so an owner authorizes another address to manage all their tokens in that contract, which simplifies UX across many asset types but does not allow native per‑ID or per‑amount approvals in the base standard. That granularity trade-off has motivated extensions (for example permit-style proposals) to add finer-grained, off‑chain-signed approvals.
How should I trust or verify metadata for ERC-1155 tokens given the standard’s URI mechanism?
+
ERC-1155’s metadata uses a URI template with {id} replaced by the lowercase hex id (left-padded to 64 chars), which is gas-efficient but points to off‑chain JSON that the standard does not guarantee to be available, immutable, or authentic. For stronger on‑chain integrity guarantees projects can adopt extensions that publish metadata hashes on-chain (for example ERC-2477) or controlled update schemes (for example proposals like ERC-5185).
If an ERC-1155 token’s totalSupply is 1, can I assume it is a permanent NFT?
+
A reported totalSupply(id) of one is often treated as NFT-like, but ERC-1155 does not by itself prevent future minting of the same ID, so totalSupply == 1 does not guarantee permanent uniqueness unless the contract also enforces an immutable minting policy. OpenZeppelin and the article explicitly caution that supply=1 is not a permanent proof of uniqueness without such guarantees.
Are there upgrade or implementation pitfalls when adding per-ID supply tracking to ERC-1155 contracts?
+
There are known implementation risks: OpenZeppelin warns the ERC1155Supply extension should not be added in an upgrade to an already‑deployed contract, and earlier versions had a totalsupply inconsistency where supply was updated after the receiver callback causing temporary inconsistencies and potential exploits; upgrading to patched implementations and careful ordering of supply updates relative to receiver hooks is the recommended mitigation.

Your Trades, Your Crypto