ERC1155
Smart contract ERC1155 utilities and implementations
This set of interfaces and contracts are all related to the ERC-1155 Multi Token Standard.
The ERC consists of three interfaces which fulfill different roles, found here as IERC1155
, IERC1155MetadataURI
and IERC1155Receiver
.
ERC1155
implements the mandatory IERC1155
interface, as well as the optional extension IERC1155MetadataURI
, by relying on the substitution mechanism to use the same URI for all token types, dramatically reducing gas costs.
Additionally there are multiple custom extensions, including:
- designation of addresses that can pause token transfers for all users (
ERC1155Pausable
). - destruction of own tokens (
ERC1155Burnable
).
This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC-1155 (such as _mint
) and expose them as external functions in the way they prefer.
Core
Extensions
Utilities
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
Implementation of the basic standard multi-token. See https://eips.ethereum.org/EIPS/eip-1155 Originally based on code by Enjin: https://github.com/enjin/erc-1155
Functions
- constructor(uri_)
- supportsInterface(interfaceId)
- uri()
- balanceOf(account, id)
- balanceOfBatch(accounts, ids)
- setApprovalForAll(operator, approved)
- isApprovedForAll(account, operator)
- safeTransferFrom(from, to, id, value, data)
- safeBatchTransferFrom(from, to, ids, values, data)
- _update(from, to, ids, values)
- _updateWithAcceptanceCheck(from, to, ids, values, data)
- _safeTransferFrom(from, to, id, value, data)
- _safeBatchTransferFrom(from, to, ids, values, data)
- _setURI(newuri)
- _mint(to, id, value, data)
- _mintBatch(to, ids, values, data)
- _burn(from, id, value)
- _burnBatch(from, ids, values)
- _setApprovalForAll(owner, operator, approved)
IERC1155Errors
IERC1155MetadataURI
IERC1155
ERC165
IERC165
Events
Errors
IERC1155Errors
- ERC1155InsufficientBalance(sender, balance, needed, tokenId)
- ERC1155InvalidSender(sender)
- ERC1155InvalidReceiver(receiver)
- ERC1155MissingApprovalForAll(operator, owner)
- ERC1155InvalidApprover(approver)
- ERC1155InvalidOperator(operator)
- ERC1155InvalidArrayLength(idsLength, valuesLength)
IERC1155MetadataURI
IERC1155
ERC165
IERC165
constructor(string uri_)
internal
#See ERC1155._setURI
.
supportsInterface(bytes4 interfaceId) → bool
public
#Returns true if this contract implements the interface defined by
interfaceId
. See the corresponding
ERC section
to learn more about how these ids are created.
This function call must use less than 30 000 gas.
uri(uint256) → string
public
#This implementation returns the same URI for all token types. It relies on the token type ID substitution mechanism defined in the ERC.
Clients calling this function must replace the \{id\}
substring with the
actual token type ID.
balanceOf(address account, uint256 id) → uint256
public
#Returns the value of tokens of token type id
owned by account
.
balanceOfBatch(address[] accounts, uint256[] ids) → uint256[]
public
#setApprovalForAll(address operator, bool approved)
public
#Grants or revokes permission to operator
to transfer the caller's tokens, according to approved
,
Emits an IERC1155.ApprovalForAll
event.
Requirements:
operator
cannot be the zero address.
isApprovedForAll(address account, address operator) → bool
public
#Returns true if operator
is approved to transfer account
's tokens.
safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes data)
public
#Transfers a value
amount of tokens of type id
from from
to to
.
This function can potentially allow a reentrancy attack when transferring tokens
to an untrusted contract, when invoking IERC1155Receiver.onERC1155Received
on the receiver.
Ensure to follow the checks-effects-interactions pattern and consider employing
reentrancy guards when interacting with untrusted contracts.
Emits a IERC1155.TransferSingle
event.
Requirements:
to
cannot be the zero address.- If the caller is not
from
, it must have been approved to spendfrom
's tokens viaERC1155.setApprovalForAll
. from
must have a balance of tokens of typeid
of at leastvalue
amount.- If
to
refers to a smart contract, it must implementIERC1155Receiver.onERC1155Received
and return the acceptance magic value.
safeBatchTransferFrom(address from, address to, uint256[] ids, uint256[] values, bytes data)
public
#xref:ROOT:erc1155#batch-operations[Batched] version of ERC1155.safeTransferFrom
.
This function can potentially allow a reentrancy attack when transferring tokens
to an untrusted contract, when invoking IERC1155Receiver.onERC1155BatchReceived
on the receiver.
Ensure to follow the checks-effects-interactions pattern and consider employing
reentrancy guards when interacting with untrusted contracts.
Emits either a IERC1155.TransferSingle
or a IERC1155.TransferBatch
event, depending on the length of the array arguments.
Requirements:
ids
andvalues
must have the same length.- If
to
refers to a smart contract, it must implementIERC1155Receiver.onERC1155BatchReceived
and return the acceptance magic value.
_update(address from, address to, uint256[] ids, uint256[] values)
internal
#Transfers a value
amount of tokens of type id
from from
to to
. Will mint (or burn) if from
(or to
) is the zero address.
Emits a IERC1155.TransferSingle
event if the arrays contain one element, and IERC1155.TransferBatch
otherwise.
Requirements:
- If
to
refers to a smart contract, it must implement eitherIERC1155Receiver.onERC1155Received
orIERC1155Receiver.onERC1155BatchReceived
and return the acceptance magic value. ids
andvalues
must have the same length.
NOTE: The ERC-1155 acceptance check is not performed in this function. See ERC1155._updateWithAcceptanceCheck
instead.
_updateWithAcceptanceCheck(address from, address to, uint256[] ids, uint256[] values, bytes data)
internal
#Version of ERC1155._update
that performs the token acceptance check by calling
IERC1155Receiver.onERC1155Received
or IERC1155Receiver.onERC1155BatchReceived
on the receiver address if it
contains code (eg. is a smart contract at the moment of execution).
Overriding this function is discouraged because it poses a reentrancy risk from the receiver. So any
update to the contract state after this function would break the check-effect-interaction pattern. Consider
overriding ERC1155._update
instead.
_safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes data)
internal
#Transfers a value
tokens of token type id
from from
to to
.
Emits a IERC1155.TransferSingle
event.
Requirements:
to
cannot be the zero address.from
must have a balance of tokens of typeid
of at leastvalue
amount.- If
to
refers to a smart contract, it must implementIERC1155Receiver.onERC1155Received
and return the acceptance magic value.
_safeBatchTransferFrom(address from, address to, uint256[] ids, uint256[] values, bytes data)
internal
#xref:ROOT:erc1155#batch-operations[Batched] version of ERC1155._safeTransferFrom
.
Emits a IERC1155.TransferBatch
event.
Requirements:
- If
to
refers to a smart contract, it must implementIERC1155Receiver.onERC1155BatchReceived
and return the acceptance magic value. ids
andvalues
must have the same length.
_setURI(string newuri)
internal
#Sets a new URI for all token types, by relying on the token type ID substitution mechanism defined in the ERC.
By this mechanism, any occurrence of the \{id\}
substring in either the
URI or any of the values in the JSON file at said URI will be replaced by
clients with the token type ID.
For example, the https://token-cdn-domain/\{id\}.json
URI would be
interpreted by clients as
https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json
for token type ID 0x4cce0.
See ERC1155.uri
.
Because these URIs cannot be meaningfully represented by the IERC1155.URI
event,
this function emits no events.
_mint(address to, uint256 id, uint256 value, bytes data)
internal
#Creates a value
amount of tokens of type id
, and assigns them to to
.
Emits a IERC1155.TransferSingle
event.
Requirements:
to
cannot be the zero address.- If
to
refers to a smart contract, it must implementIERC1155Receiver.onERC1155Received
and return the acceptance magic value.
_mintBatch(address to, uint256[] ids, uint256[] values, bytes data)
internal
#xref:ROOT:erc1155#batch-operations[Batched] version of ERC1155._mint
.
Emits a IERC1155.TransferBatch
event.
Requirements:
ids
andvalues
must have the same length.to
cannot be the zero address.- If
to
refers to a smart contract, it must implementIERC1155Receiver.onERC1155BatchReceived
and return the acceptance magic value.
_burn(address from, uint256 id, uint256 value)
internal
#Destroys a value
amount of tokens of type id
from from
Emits a IERC1155.TransferSingle
event.
Requirements:
from
cannot be the zero address.from
must have at leastvalue
amount of tokens of typeid
.
_burnBatch(address from, uint256[] ids, uint256[] values)
internal
#xref:ROOT:erc1155#batch-operations[Batched] version of ERC1155._burn
.
Emits a IERC1155.TransferBatch
event.
Requirements:
from
cannot be the zero address.from
must have at leastvalue
amount of tokens of typeid
.ids
andvalues
must have the same length.
_setApprovalForAll(address owner, address operator, bool approved)
internal
#Approve operator
to operate on all of owner
tokens
Emits an IERC1155.ApprovalForAll
event.
Requirements:
operator
cannot be the zero address.
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
Required interface of an ERC-1155 compliant contract, as defined in the ERC.
Functions
Events
balanceOf(address account, uint256 id) → uint256
external
#Returns the value of tokens of token type id
owned by account
.
balanceOfBatch(address[] accounts, uint256[] ids) → uint256[]
external
#xref:ROOT:erc1155#batch-operations[Batched] version of IERC777.balanceOf
.
Requirements:
accounts
andids
must have the same length.
setApprovalForAll(address operator, bool approved)
external
#Grants or revokes permission to operator
to transfer the caller's tokens, according to approved
,
Emits an IERC1155.ApprovalForAll
event.
Requirements:
operator
cannot be the zero address.
isApprovedForAll(address account, address operator) → bool
external
#Returns true if operator
is approved to transfer account
's tokens.
safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes data)
external
#Transfers a value
amount of tokens of type id
from from
to to
.
This function can potentially allow a reentrancy attack when transferring tokens
to an untrusted contract, when invoking IERC1155Receiver.onERC1155Received
on the receiver.
Ensure to follow the checks-effects-interactions pattern and consider employing
reentrancy guards when interacting with untrusted contracts.
Emits a IERC1155.TransferSingle
event.
Requirements:
to
cannot be the zero address.- If the caller is not
from
, it must have been approved to spendfrom
's tokens viaERC1155.setApprovalForAll
. from
must have a balance of tokens of typeid
of at leastvalue
amount.- If
to
refers to a smart contract, it must implementIERC1155Receiver.onERC1155Received
and return the acceptance magic value.
safeBatchTransferFrom(address from, address to, uint256[] ids, uint256[] values, bytes data)
external
#xref:ROOT:erc1155#batch-operations[Batched] version of ERC1155.safeTransferFrom
.
This function can potentially allow a reentrancy attack when transferring tokens
to an untrusted contract, when invoking IERC1155Receiver.onERC1155BatchReceived
on the receiver.
Ensure to follow the checks-effects-interactions pattern and consider employing
reentrancy guards when interacting with untrusted contracts.
Emits either a IERC1155.TransferSingle
or a IERC1155.TransferBatch
event, depending on the length of the array arguments.
Requirements:
ids
andvalues
must have the same length.- If
to
refers to a smart contract, it must implementIERC1155Receiver.onERC1155BatchReceived
and return the acceptance magic value.
TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value)
event
#Emitted when value
amount of tokens of type id
are transferred from from
to to
by operator
.
TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values)
event
#Equivalent to multiple IERC1155.TransferSingle
events, where operator
, from
and to
are the same for all
transfers.
ApprovalForAll(address indexed account, address indexed operator, bool approved)
event
#Emitted when account
grants or revokes permission to operator
to transfer their tokens, according to
approved
.
URI(string value, uint256 indexed id)
event
#Emitted when the URI for token type id
changes to value
, if it is a non-programmatic URI.
If an IERC1155.URI
event was emitted for id
, the standard
guarantees that value
will equal the value
returned by IERC1155MetadataURI.uri
.
import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
Interface that must be implemented by smart contracts in order to receive ERC-1155 token transfers.
Functions
onERC1155Received(address operator, address from, uint256 id, uint256 value, bytes data) → bytes4
external
#Handles the receipt of a single ERC-1155 token type. This function is
called at the end of a safeTransferFrom
after the balance has been updated.
NOTE: To accept the transfer, this must return
bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))
(i.e. 0xf23a6e61, or its own function selector).
onERC1155BatchReceived(address operator, address from, uint256[] ids, uint256[] values, bytes data) → bytes4
external
#Handles the receipt of a multiple ERC-1155 token types. This function
is called at the end of a safeBatchTransferFrom
after the balances have
been updated.
NOTE: To accept the transfer(s), this must return
bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))
(i.e. 0xbc197c81, or its own function selector).
import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol";
Extension of ERC1155
that allows token holders to destroy both their
own tokens and those that they have been approved to use.
Functions
ERC1155
- supportsInterface(interfaceId)
- uri()
- balanceOf(account, id)
- balanceOfBatch(accounts, ids)
- setApprovalForAll(operator, approved)
- isApprovedForAll(account, operator)
- safeTransferFrom(from, to, id, value, data)
- safeBatchTransferFrom(from, to, ids, values, data)
- _update(from, to, ids, values)
- _updateWithAcceptanceCheck(from, to, ids, values, data)
- _safeTransferFrom(from, to, id, value, data)
- _safeBatchTransferFrom(from, to, ids, values, data)
- _setURI(newuri)
- _mint(to, id, value, data)
- _mintBatch(to, ids, values, data)
- _burn(from, id, value)
- _burnBatch(from, ids, values)
- _setApprovalForAll(owner, operator, approved)
IERC1155Errors
IERC1155MetadataURI
IERC1155
ERC165
IERC165
Events
Errors
ERC1155
IERC1155Errors
- ERC1155InsufficientBalance(sender, balance, needed, tokenId)
- ERC1155InvalidSender(sender)
- ERC1155InvalidReceiver(receiver)
- ERC1155MissingApprovalForAll(operator, owner)
- ERC1155InvalidApprover(approver)
- ERC1155InvalidOperator(operator)
- ERC1155InvalidArrayLength(idsLength, valuesLength)
IERC1155MetadataURI
IERC1155
ERC165
IERC165
burn(address account, uint256 id, uint256 value)
public
#burnBatch(address account, uint256[] ids, uint256[] values)
public
#import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Pausable.sol";
ERC-1155 token with pausable token transfers, minting and burning.
Useful for scenarios such as preventing trades until the end of an evaluation period, or having an emergency switch for freezing all token transfers in the event of a large bug.
This contract does not include public pause and unpause functions. In
addition to inheriting this contract, you must define both functions, invoking the
Pausable._pause
and Pausable._unpause
internal functions, with appropriate
access control, e.g. using AccessControl
or Ownable
. Not doing so will
make the contract pause mechanism of the contract unreachable, and thus unusable.
Functions
Pausable
ERC1155
- supportsInterface(interfaceId)
- uri()
- balanceOf(account, id)
- balanceOfBatch(accounts, ids)
- setApprovalForAll(operator, approved)
- isApprovedForAll(account, operator)
- safeTransferFrom(from, to, id, value, data)
- safeBatchTransferFrom(from, to, ids, values, data)
- _updateWithAcceptanceCheck(from, to, ids, values, data)
- _safeTransferFrom(from, to, id, value, data)
- _safeBatchTransferFrom(from, to, ids, values, data)
- _setURI(newuri)
- _mint(to, id, value, data)
- _mintBatch(to, ids, values, data)
- _burn(from, id, value)
- _burnBatch(from, ids, values)
- _setApprovalForAll(owner, operator, approved)
IERC1155Errors
IERC1155MetadataURI
IERC1155
ERC165
IERC165
Events
Errors
Pausable
ERC1155
IERC1155Errors
- ERC1155InsufficientBalance(sender, balance, needed, tokenId)
- ERC1155InvalidSender(sender)
- ERC1155InvalidReceiver(receiver)
- ERC1155MissingApprovalForAll(operator, owner)
- ERC1155InvalidApprover(approver)
- ERC1155InvalidOperator(operator)
- ERC1155InvalidArrayLength(idsLength, valuesLength)
IERC1155MetadataURI
IERC1155
ERC165
IERC165
_update(address from, address to, uint256[] ids, uint256[] values)
internal
#import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol";
Extension of ERC-1155 that adds tracking of total supply per id.
Useful for scenarios where Fungible and Non-fungible tokens have to be clearly identified. Note: While a totalSupply of 1 might mean the corresponding is an NFT, there is no guarantees that no other token with the same id are not going to be minted.
NOTE: This contract implies a global limit of 2**256 - 1 to the number of tokens that can be minted.
CAUTION: This extension should not be added in an upgrade to an already deployed contract.
Functions
ERC1155
- supportsInterface(interfaceId)
- uri()
- balanceOf(account, id)
- balanceOfBatch(accounts, ids)
- setApprovalForAll(operator, approved)
- isApprovedForAll(account, operator)
- safeTransferFrom(from, to, id, value, data)
- safeBatchTransferFrom(from, to, ids, values, data)
- _updateWithAcceptanceCheck(from, to, ids, values, data)
- _safeTransferFrom(from, to, id, value, data)
- _safeBatchTransferFrom(from, to, ids, values, data)
- _setURI(newuri)
- _mint(to, id, value, data)
- _mintBatch(to, ids, values, data)
- _burn(from, id, value)
- _burnBatch(from, ids, values)
- _setApprovalForAll(owner, operator, approved)
IERC1155Errors
IERC1155MetadataURI
IERC1155
ERC165
IERC165
Events
Errors
ERC1155
IERC1155Errors
- ERC1155InsufficientBalance(sender, balance, needed, tokenId)
- ERC1155InvalidSender(sender)
- ERC1155InvalidReceiver(receiver)
- ERC1155MissingApprovalForAll(operator, owner)
- ERC1155InvalidApprover(approver)
- ERC1155InvalidOperator(operator)
- ERC1155InvalidArrayLength(idsLength, valuesLength)
IERC1155MetadataURI
IERC1155
ERC165
IERC165
totalSupply(uint256 id) → uint256
public
#Total value of tokens in with a given id.
totalSupply() → uint256
public
#Total value of tokens.
exists(uint256 id) → bool
public
#Indicates whether any token exist with a given id, or not.
_update(address from, address to, uint256[] ids, uint256[] values)
internal
#Transfers a value
amount of tokens of type id
from from
to to
. Will mint (or burn) if from
(or to
) is the zero address.
Emits a IERC1155.TransferSingle
event if the arrays contain one element, and IERC1155.TransferBatch
otherwise.
Requirements:
- If
to
refers to a smart contract, it must implement eitherIERC1155Receiver.onERC1155Received
orIERC1155Receiver.onERC1155BatchReceived
and return the acceptance magic value. ids
andvalues
must have the same length.
NOTE: The ERC-1155 acceptance check is not performed in this function. See ERC1155._updateWithAcceptanceCheck
instead.
import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol";
ERC-1155 token with storage based token URI management.
Inspired by the ERC721URIStorage
extension
Functions
ERC1155
- supportsInterface(interfaceId)
- balanceOf(account, id)
- balanceOfBatch(accounts, ids)
- setApprovalForAll(operator, approved)
- isApprovedForAll(account, operator)
- safeTransferFrom(from, to, id, value, data)
- safeBatchTransferFrom(from, to, ids, values, data)
- _update(from, to, ids, values)
- _updateWithAcceptanceCheck(from, to, ids, values, data)
- _safeTransferFrom(from, to, id, value, data)
- _safeBatchTransferFrom(from, to, ids, values, data)
- _setURI(newuri)
- _mint(to, id, value, data)
- _mintBatch(to, ids, values, data)
- _burn(from, id, value)
- _burnBatch(from, ids, values)
- _setApprovalForAll(owner, operator, approved)
IERC1155Errors
IERC1155MetadataURI
IERC1155
ERC165
IERC165
Events
Errors
ERC1155
IERC1155Errors
- ERC1155InsufficientBalance(sender, balance, needed, tokenId)
- ERC1155InvalidSender(sender)
- ERC1155InvalidReceiver(receiver)
- ERC1155MissingApprovalForAll(operator, owner)
- ERC1155InvalidApprover(approver)
- ERC1155InvalidOperator(operator)
- ERC1155InvalidArrayLength(idsLength, valuesLength)
IERC1155MetadataURI
IERC1155
ERC165
IERC165
uri(uint256 tokenId) → string
public
#This implementation returns the concatenation of the _baseURI
and the token-specific uri if the latter is set
This enables the following behaviors:
-
if
_tokenURIs[tokenId]
is set, then the result is the concatenation of_baseURI
and_tokenURIs[tokenId]
(keep in mind that_baseURI
is empty per default); -
if
_tokenURIs[tokenId]
is NOT set then we fallback tosuper.uri()
which in most cases will containERC1155._uri
; -
if
_tokenURIs[tokenId]
is NOT set, and if the parents do not have a uri value set, then the result is empty.
_setURI(uint256 tokenId, string tokenURI)
internal
#Sets tokenURI
as the tokenURI of tokenId
.
_setBaseURI(string baseURI)
internal
#Sets baseURI
as the _baseURI
for all tokens
import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";
Interface of the optional ERC1155MetadataExtension interface, as defined in the ERC.
Functions
Events
uri(uint256 id) → string
external
#Returns the URI for token type id
.
If the \{id\}
substring is present in the URI, it must be replaced by
clients with the actual token type ID.
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
Simple implementation of IERC1155Receiver
that will allow a contract to hold ERC-1155 tokens.
When inheriting this contract, you must include a way to use the received tokens, otherwise they will be
stuck.
Functions
supportsInterface(bytes4 interfaceId) → bool
public
#Returns true if this contract implements the interface defined by
interfaceId
. See the corresponding
ERC section
to learn more about how these ids are created.
This function call must use less than 30 000 gas.
onERC1155Received(address, address, uint256, uint256, bytes) → bytes4
public
#onERC1155BatchReceived(address, address, uint256[], uint256[], bytes) → bytes4
public
#import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Utils.sol";
Library that provide common ERC-1155 utility functions.
See ERC-1155.
Available since v5.1.
Functions
checkOnERC1155Received(address operator, address from, address to, uint256 id, uint256 value, bytes data)
internal
#Performs an acceptance check for the provided operator
by calling IERC1155Receiver.onERC1155Received
on the to
address. The operator
is generally the address that initiated the token transfer (i.e. msg.sender
).
The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA).
Otherwise, the recipient must implement IERC1155Receiver.onERC1155Received
and return the acceptance magic value to accept
the transfer.
checkOnERC1155BatchReceived(address operator, address from, address to, uint256[] ids, uint256[] values, bytes data)
internal
#Performs a batch acceptance check for the provided operator
by calling IERC1155Receiver.onERC1155BatchReceived
on the to
address. The operator
is generally the address that initiated the token transfer (i.e. msg.sender
).
The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA).
Otherwise, the recipient must implement IERC1155Receiver.onERC1155Received
and return the acceptance magic value to accept
the transfer.