ERC-1155 Multi-Token Standard
A standard interface for contracts that manage multiple token types. A single deployed contract may include any combination of fungible tokens, non-fungible tokens or other configurations (e.g. semi-fungible tokens).
What is meant by Multi-Token Standard?
The idea is simple and seeks to create a smart contract interface that can represent and control any number of fungible and non-fungible token types. In this way, the ERC-1155 token can do the same functions as an ERC-20 and ERC-721 token, and even both at the same time. And best of all, improving the functionality of both standards, making it more efficient, and correcting obvious implementation errors on the ERC-20 and ERC-721 standards.
The ERC-1155 token is described fully in EIP-1155.
- Batch Transfer: Transfer multiple assets in a single call.
- Batch Balance: Get the balances of multiple assets in a single call.
- Batch Approval: Approve all tokens to an address.
- Hooks: Receive tokens hook.
- NFT Support: If supply is only 1, treat it as NFT.
- Safe Transfer Rules: Set of rules for secure transfer.
The batch transfer works very similar to regular ERC-20 transfers. Let's look at the regular ERC-20 transferFrom function:
1// ERC-202function transferFrom(address from, address to, uint256 value) external returns (bool);34// ERC-11555function safeBatchTransferFrom(6 address _from,7 address _to,8 uint256 calldata _ids,9 uint256 calldata _values,10 bytes calldata _data11) external;12Show allCopy
The only difference in ERC-1155 is that we pass the values as an array and we also pass an array of id's. For example given
ids=[3, 6, 13] and
values=[100, 200, 5], the resulting transfers will be
- Transfer 100 tokens with id 3 from
- Transfer 200 tokens with id 6 from
- Transfer 5 tokens with id 13 from
In ERC-1155 we only have
transfer. To use it like a regular
transfer, just set the from address to the address that's calling the function.
The respective ERC-20
balanceOf call likewise has its partner function with batch support. As a reminder, this is the ERC-20 version:
1// ERC-202function balanceOf(address owner) external view returns (uint256);34// ERC-11555function balanceOfBatch(6 address calldata _owners,7 uint256 calldata _ids8) external view returns (uint256 memory);9Copy
Even simpler for the balance call, we can retrieve multiple balances in a single call. We pass the array of owners, followed by the array of token ids.
For example given
_ids=[3, 6, 13] and
_owners=[0xbeef..., 0x1337..., 0x1111...], the return value will be
1[2 balanceOf(0xbeef...),3 balanceOf(0x1337...),4 balanceOf(0x1111...)5]6Copy
1// ERC-11552function setApprovalForAll(3 address _operator,4 bool _approved5) external;67function isApprovedForAll(8 address _owner,9 address _operator10) external view returns (bool);11Show allCopy
The approvals are slightly different than ERC-20. Instead of approving specific amounts, you set an operator to approved or not approved via
Reading the current status can be done via
isApprovedForAll. As you can see, it's an all or nothing. You cannot define how many tokens to approve or even which token class.
This is intentionally designed with simplicity in mind. You can only approve everything for one address.
1function onERC1155BatchReceived(2 address _operator,3 address _from,4 uint256 calldata _ids,5 uint256 calldata _values,6 bytes calldata _data7) external returns(bytes4);8Copy
Given the EIP-165 support, ERC-1155 supports receive hooks for smart contracts only. The hook function must return a magic predefined bytes4 value which is given as:
When the receiving contract returns this value, it is assumed the contract accepts the transfer and knows how to handle the ERC-1155 tokens. Great, no more stuck tokens in a contract!
When the supply is just one, the token is essentially a non-fungible token (NFT). And as is standard for ERC-721, you can define a metadata URL. The URL can be read and modified by clients, see here.
We've touched on a few safe transfer rules already in the previous explanations. But let's look at the most important of the rules:
- The caller must be approved to spend the tokens for the
_fromaddress or the caller must equal
- The transfer call must revert if
_toaddress is 0.
- length of
_idsis not the same as length of
- any of the balance(s) of the holder(s) for token(s) in
_idsis lower than the respective amount(s) in
_valuessent to the recipient.
- any other error occurs.
Note: All batch functions including the hook also exist as versions without batch. This is done for gas efficiency, considering transferring just one asset will likely still be the most commonly used way. We've left them out for simplicity in the explanations, including safe transfer rules. The names are identical, just remove the 'Batch'.