I am currently relearning Solidity to reinforce my knowledge of its intricacies and write a "WTF Solidity Crash Course" for beginners (expert programmers may seek out other tutorials). Updates will be given on a weekly basis, covering 1-3 lessons per week.
Twitter: @0xAA_Science
Discord: WTF Academy
All code and tutorials are open source on Github: github.com/AmazingAng/WTF-Solidity
In this lecture, we will learn about the ERC1155
standard, which allows a contract to contain multiple types of tokens. We will also issue a modified version of the Boring Ape Yacht Club (BAYC) called BAYC1155
, which contains 10,000 types of tokens with metadata identical to BAYC.
EIP1155
Both the ERC20
and ERC721
standards correspond to a single token contract. For example, if we wanted to create a large game similar to World of Warcraft on Ethereum, we would need to deploy a contract for each piece of equipment. Deploying and managing thousands of contracts is very cumbersome. Therefore, the Ethereum EIP1155 proposes a multi-token standard called ERC1155
, which allows a contract to contain multiple homogeneous and heterogeneous tokens. ERC1155
is widely used in GameFi applications, and well-known blockchain games such as Decentraland and Sandbox use it.
In simple terms, ERC1155
is similar to the previously introduced non-fungible token standard ERC721: In ERC721
, each token has a tokenId
as a unique identifier, and each tokenId
corresponds to only one token; in ERC1155
, each type of token has an id
as a unique identifier, and each id
corresponds to one type of token. This way, the types of tokens can be managed heterogeneously in the same contract, and each type of token has a URL uri
to store its metadata, similar to tokenURI
in ERC721
. The following is the metadata interface contract IERC1155MetadataURI
for ERC1155
:
How to distinguish whether a type of token in ERC1155
is a fungible or a non-fungible token? It's actually simple: if the total amount of a token corresponding to a specific id
is 1
, then it is a non-fungible token, similar to ERC721
; if the total amount of a token corresponding to a specific id
is greater than 1
, then it is a fungible token because these tokens share the same id
, similar to ERC20
.
IERC1155
Interface Contract
The IERC1155
interface contract abstracts the functionalities required for EIP1155
implementation, which includes 4
events and 6
functions. Unlike ERC721
, since ERC1155
includes multiple types of tokens, it implements batch transfer and batch balance query, allowing for simultaneous operation on multiple types of tokens.
IERC1155
Events
TransferSingle
event: released during the transfer of a single type of token in a single token transfer.TransferBatch
event: released during the transfer of multiple types of tokens in a multi-token transfer.ApprovalForAll
event: released during a batch approval of tokens.URI
event: released when the metadata address changes during a change of theuri
.
IERC1155
Functions
balanceOf()
: checks the token balance of a single type returned as the amount of tokens owned byaccount
for anid
.balanceOfBatch()
: checks the token balances of multiple types returned as amounts of tokens owned byaccount
for an array ofids
.setApprovalForAll()
: grants approvals to anoperator
of all tokens owned by the caller.isApprovedForAll()
: checks the authorization status of anoperator
for a givenaccount
.safeTransferFrom()
: performs the transfer of a single type of safeERC1155
token from thefrom
address to theto
address. If theto
address is a contract, it must implement theonERC1155Received()
function.safeBatchTransferFrom()
: similar to thesafeTransferFrom()
function, but allows for transfers of multiple types of tokens. Theamounts
andids
arguments are arrays with a length equal to the number of transfers. If theto
address is a contract, it must implement theonERC1155BatchReceived()
function.
ERC1155
Receive Contract
Similar to the ERC721
standard, to prevent tokens from being sent to a "black hole" contract, ERC1155
requires token receiving contracts to inherit from IERC1155Receiver
and implement two receiving functions:
-
onERC1155Received()
: function called when receiving a single token transfer, must implement and return the selector0xf23a6e61
. -
onERC1155BatchReceived()
: This is the multiple token transfer receiving function which needs to be implemented and return its own selector0xbc197c81
in order to accept ERC1155 safe multiple token transfers through thesafeBatchTransferFrom
function.
Main Contract ERC1155
The ERC1155
main contract implements the functions specified by the IERC1155
interface contract, as well as the functions for minting and burning single/multiple tokens.
Variables in ERC1155
The ERC1155
main contract contains 4
state variables:
name
: token namesymbol
: token symbol_balances
: token ownership mapping, which records the token balancebalances
of addressaccount
for tokenid
_operatorApprovals
: batch approval mapping, which records the approval situation of the holder address to another address.
Functions in ERC1155
The ERC1155
main contract contains 16
functions:
-
Constructor: Initializes state variables
name
andsymbol
. -
supportsInterface()
: Implements theERC165
standard to declare the interfaces supported by it, which can be checked by other contracts. -
balanceOf()
: ImplementsIERC1155
'sbalanceOf()
to query the token balance. Unlike theERC721
standard, it requires the address for which the balance is queried (account
) and the tokenid
to be provided. -
balanceOfBatch()
: ImplementsbalanceOfBatch()
ofIERC1155
, which allows for batch querying of token balances. -
setApprovalForAll()
: ImplementssetApprovalForAll()
ofIERC1155
, which allows for batch authorization, and emits theApprovalForAll
event. -
isApprovedForAll()
: ImplementsisApprovedForAll()
ofIERC1155
, which allows for batch query of authorization information. -
safeTransferFrom()
: ImplementssafeTransferFrom()
ofIERC1155
, which allows for safe transfer of a single type of token, and emits theTransferSingle
event. UnlikeERC721
, this function not only requires thefrom
(sender),to
(recipient), and tokenid
, but also the transfer amountamount
. -
safeBatchTransferFrom()
: ImplementssafeBatchTransferFrom()
ofIERC1155
, which allows for safe transfer of multiple types of tokens, and emits theTransferBatch
event. -
_mint()
: Function for minting a single type of token. -
_mintBatch()
: Function for minting multiple types of tokens. -
_burn()
: Function for burning a single type of token. -
_burnBatch()
: Function for burning multiple types of tokens. -
_doSafeTransferAcceptanceCheck()
: Safety check for single type token transfers, called bysafeTransferFrom()
, ensures that the recipient has implemented theonERC1155Received()
function when the recipient is a contract. -
_doSafeBatchTransferAcceptanceCheck()
: Safety check for multiple types of token transfers, called bysafeBatchTransferFrom()
, ensures that the recipient has implemented theonERC1155BatchReceived()
function when the recipient is a contract. -
uri()
: Returns the URL where the metadata of the token of typeid
is stored forERC1155
, similar totokenURI
forERC721
. -
baseURI()
: Returns thebaseURI
.uri
is simplybaseURI
concatenated withid
, and can be overwritten by developers.
BAYC
, but as ERC1155
We have made some modifications to the boring apes BAYC
by changing it to BAYC1155
which now follows the ERC1155
standard and allows for free minting. The _baseURI()
function has been modified to ensure that the uri
for BAYC1155
is the same as the tokenURI
for BAYC
. This means that BAYC1155
metadata will be identical to that of boring apes.
Remix Demo
1. Deploy the BAYC1155
Contract

2. View Metadata URI

3. mint
and view position changes
In the mint
section, enter the account address, id
, and quantity, and click the mint
button to mint. If the quantity is 1
, it is a non-fungible token; if the quantity is greater than 1
, it is a fungible token.

In the blanceOf
section, enter the account address and id
to view the corresponding position.

4. Batch mint
and view position changes
In the "mintBatch" section, input the "ids" array and the corresponding quantity to be minted. The length of both arrays must be the same. To view the recently minted token "id" array, input it as shown.
Similarly, in the "transfer" section, we transfer tokens from an address that already owns them to a new address. This address can be a normal address or a contract address; if it is a contract address, it will be verified whether it has implemented the "onERC1155Received()" receiving function. Here, we transfer tokens to a normal address by inputting the "ids" and corresponding "amounts" arrays. To view the changes in holdings of the address to which tokens were just transferred, select "view balances".
Summary
In this lesson, we learned about the ERC1155
multi-token standard proposed by Ethereum's EIP1155
. It allows for a contract to include multiple homogeneous or heterogeneous tokens. Additionally, we created a modified version of the Bored Ape Yacht Club (BAYC) - BAYC1155
: an ERC1155
token containing 10,000 tokens with the same metadata as BAYC. Currently, ERC1155
is primarily used in GameFi. However, I believe that as metaverse technology continues to develop, this standard will become increasingly popular.