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
TransferSingleevent: released during the transfer of a single type of token in a single token transfer.TransferBatchevent: released during the transfer of multiple types of tokens in a multi-token transfer.ApprovalForAllevent: released during a batch approval of tokens.URIevent: 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 byaccountfor anid.balanceOfBatch(): checks the token balances of multiple types returned as amounts of tokens owned byaccountfor an array ofids.setApprovalForAll(): grants approvals to anoperatorof all tokens owned by the caller.isApprovedForAll(): checks the authorization status of anoperatorfor a givenaccount.safeTransferFrom(): performs the transfer of a single type of safeERC1155token from thefromaddress to thetoaddress. If thetoaddress is a contract, it must implement theonERC1155Received()function.safeBatchTransferFrom(): similar to thesafeTransferFrom()function, but allows for transfers of multiple types of tokens. Theamountsandidsarguments are arrays with a length equal to the number of transfers. If thetoaddress 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 selector0xbc197c81in order to accept ERC1155 safe multiple token transfers through thesafeBatchTransferFromfunction.
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 balancebalancesof addressaccountfor 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
nameandsymbol. -
supportsInterface(): Implements theERC165standard to declare the interfaces supported by it, which can be checked by other contracts. -
balanceOf(): ImplementsIERC1155'sbalanceOf()to query the token balance. Unlike theERC721standard, it requires the address for which the balance is queried (account) and the tokenidto be provided. -
balanceOfBatch(): ImplementsbalanceOfBatch()ofIERC1155, which allows for batch querying of token balances. -
setApprovalForAll(): ImplementssetApprovalForAll()ofIERC1155, which allows for batch authorization, and emits theApprovalForAllevent. -
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 theTransferSingleevent. 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 theTransferBatchevent. -
_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 typeidis stored forERC1155, similar totokenURIforERC721. -
baseURI(): Returns thebaseURI.uriis simplybaseURIconcatenated 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.