ERC721 vs. ERC721A: Batch Minting NFTs (2024)

Author: Albert Hu

Reviewed by Brady Werkheiser

Published on March 16, 20227 min read

As many NFT creators know, deploying a smart contract to Ethereum mainnet can be insanely expensive.

However, smart contract deployment costs are not the only cost blockchain engineers and NFT teams need to consider. Creating a successful NFT collection or collectible avatar project includes building a community and making it easy for users to mint, trade, and use their NFTs.

Let’s learn about a powerful NFT smart contract optimization that can help your community save gas fees on NFT minting costs:

Implementing batch minting with the ERC721A contract!

What is ERC721A?

On Jan 6th, the Azuki NFT development team publicly announced ERC721A, a new implementation of the ERC721 NFT standard that explores batch minting:

ERC721 vs. ERC721A: Batch Minting NFTs (1)

In their blog post explaining the ERC721A smart contract implementation, @locationtba and @2pmflow show estimates of how much gas can be saved when batch minting via the most commonly used NFT smart contract starter code, OpenZeppelin’s ERC721Enumerable contract, vs. batch minting NFTs using the new Azuki ERC721A contract:

ERC721 vs. ERC721A: Batch Minting NFTs (2)

This table shows how the gas used for ERC721A for an increasing number of mints scales at a much smaller constant factor.

The gas cost to mint NFTs increases by:

  • ~2k gas per extra mint using the Azuki ERC721A contract

  • ~115k gas per extra mint using the OpenZeppelin ERC721Enumerable contract

This result is actually AMAZING!

For the price of minting one single token via the ERC721Enumerable contract, a user can instead mint up to 5 tokens (or more, potentially) via the ERC721A contract.

Who wouldn’t want users to save up to 80% on their mints?

Here’s the best part:

Not only do the NFT mint prices become cheaper for individual transactions, but there would also be less network congestion and smaller gas price spikes affecting the Ethereum network during popular collection drops.

Pretty cool stuff.

Verifying the gas savings for minting multiple NFTs

I wanted to check the work myself, so I implemented two basic NFT contracts that create NFTs:

  1. One smart contract that mints using ERC721Enumerable, and

  2. One smart contract that mints using ERC721A

Next, I called the mint function on each one and logged the gas costs for each transaction.

Here are my results:

Copied

thatguyintech@albert demo-erc721a % npx hardhat testOpenZeppelin ERC721Enumerablegas to mint 1: 104138gas to mint 2: 219626gas to mint 3: 335114gas to mint 4: 450602gas to mint 5: 566090Azuki ERC721Agas to mint 1: 93704gas to mint 2: 96212gas to mint 3: 98720gas to mint 4: 101228gas to mint 5: 103736

You can find the code for these tests in this GitHub repo: demo-erc721a

The gas costs to make multiple NFTS here are slightly different than the ones shown in the Azuki blog post, but they are close, and the increase in gas fees from one mint, two mints, and multiple mints checks out.

We’ve validated the gas savings for batch minting NFTs! ✅

How does the ERC721A smart contract save gas fees with batch minting?

ERC721A makes some assumptions that influence its smart contract design:

  1. Token IDs should always increment consecutively starting from 0. Most NFT projects already do this, and Azuki is explicit about it in their assumptions.

  2. Reducing the gas costs of minting NFTs is more important than optimizing any other ERC721 call. Mints are when Ethereum network congestion happens, and they’re also users’ first impressions of an NFT collection. The easier the mint, the better the reputation.

With these assumptions in place, ERC721A makes the following contract optimizations:

  1. Reduce wasted storage of token metadata.

  2. Limit ownership state updates to only once per batch mint, instead of once per minted NFT.

We’ll take a look at how these optimizations are done, but before that we should understand what kinds of transactions cost the most gas fees.

Reducing the work required to send write transactions saves users gas

There are generally two kinds of transactions on the blockchain: writes and reads.

Writes happen when we modify or update blockchain state (e.g. sending money, writing a message, trading an NFT).

Reads happen when we request existing data to look at it.

Users always pay more gas fees for write functions than they pay for read functions.

Therefore, by reducing the number of write transactions, OR by reducing the work required to send write transactions, even if it takes more work to send read transactions later, this will reduce the NFT minting costs that users pay!

And that’s exactly what ERC721A accomplishes.

When it comes to NFT mints: mo’ storage, mo’ problems. Less storage, less problems.

Brilliant, right?

So how do ERC721A smart contract optimizations work?

Let’s take a quick tour of the code to really understand how the optimizations work.

The base ERC721 contract tracksOwners,Balances,Token ApprovalsandOperator Approvals:

Copied

/////////////////////// ERC721 ///////////////////////// Mapping from token ID to owner addressmapping(uint256 => address) private _owners;// Mapping owner address to token countmapping(address => uint256) private _balances;// Mapping from token ID to approved addressmapping(uint256 => address) private _tokenApprovals;// Mapping from owner to operator approvalsmapping(address => mapping(address => bool)) private _operatorApprovals;

Now, in the ERC721Enumerable extension contract, OpenZeppelin adds additional state to track tokenIds and owned tokens:

Copied

/////////////////////////// ERC721Enumerable ///////////////////////////// Mapping from owner to list of owned token IDsmapping(address => mapping(uint256 => uint256)) private _ownedTokens;// Mapping from token ID to index of the owner tokens listmapping(uint256 => uint256) private _ownedTokensIndex;// Array with all token ids, used for enumerationuint256[] private _allTokens;// Mapping from token id to position in the allTokens arraymapping(uint256 => uint256) private _allTokensIndex;

Without this extra storage, the base ERC721 contract cannot implement important NFT collection functions such astotalSupply(),tokenOfOwnerByIndex, andtokenByIndex.

These functions are necessary for keeping tokenIds organized and for handling other NFT logistics. That’s why so many NFT projects use ERC721Enumerable.

However, maintaining these three additional mappings and one extra array means that for every call to mint a new NFT, all of this state has to be updated.

For example_ownedTokens,_ownedTokensIndex,_allTokens, and_allTokensIndexwill each have new data added into their storage.

By studying existing NFT projects, the Azuki team noticed that most NFT projects do not need the excessive set of storage variables, so they re-architected and simplified their design.

The ERC721A contract leverages some new structs to re-implement the base ERC721 state variables for ownership and tracking balances:

Copied

//////////////////////// ERC721A ////////////////////////// Mapping from token ID to ownership details// An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details.mapping(uint256 => TokenOwnership) private _ownerships;// Mapping owner address to address datamapping(address => AddressData) private _addressData;// Mapping from token ID to approved addressmapping(uint256 => address) private _tokenApprovals;// Mapping from owner to operator approvalsmapping(address => mapping(address => bool)) private _operatorApprovals;struct TokenOwnership { address addr; uint64 startTimestamp;}struct AddressData { uint128 balance; uint128 numberMinted;}

The magic lies in how these new structs are used.

In the ERC721A_safeMintimplementation, owner balances are updated only once, no matter how many NFTs are minted in the batch call.

In the code below, you can see that there is a single assignment to the_addressDatamapping via_addressData[to]=AddressData(...);.

Copied

// Update the owner balance data only once.AddressData memory addressData = _addressData[to];_addressData[to] = AddressData( addressData.balance + uint128(quantity), addressData.numberMinted + uint128(quantity));_ownerships[startTokenId] = TokenOwnership(to, uint64(block.timestamp));uint256 updatedIndex = startTokenId;// Emittingfor (uint256 i = 0; i < quantity; i++) { emit Transfer(address(0), to, updatedIndex); require( _checkOnERC721Received(address(0), to, updatedIndex, _data), "ERC721A: transfer to non ERC721Receiver implementer" ); updatedIndex++;}currentIndex = updatedIndex;

In the base ERC721 contract before, this assignment would have had to be done in a loop, one time for each NFT being minted in the batch group. Now it’s done in a single update.

With fewer maps to update, and fewer instances of updates to begin with, each mint transaction costs a lot less, especially as the batch size gets larger and larger!

What are the risks of using ERC721A contracts to generate multiple NFTs?

Cheaper mints sound awesome! Are there any downsides? (Yes)

The tradeoff of the ERC721A contract design is thattransferFromandsafeTransferFromtransactions cost more gas, which means it may cost more to gift or sell an ERC721A NFT after minting.

The ERC721A_safeMintlogic makes efficiency gains by not setting explicit owners of specific tokenIDs when they are consecutive IDs minted by the same owner.

For example, in the photo below, there are two batch mint calls, one by Alice to mint tokens #100, #101, and #102 all in one call, and another call by Bob to mint tokens #103 and #104.

ERC721 vs. ERC721A: Batch Minting NFTs (3)

The ERC721A contract only has to set the ownership metadata twice: once for the Alice’s batch and once for Bob’s batch.

However, this means that transferring a tokenID that does not have an explicit owner address set, the contract has to run a loop across all of the tokenIDs until it reaches the first NFT with an explicit owner address to find the owner that has the right to transfer it, and then set a new owner, thus modifying ownership state more than once to maintain correct groupings.

Here’s a test to simulate transfer scenarios and log gas costs:

ERC721 vs. ERC721A: Batch Minting NFTs (4)

They way to read this chart is to go x-axis first, and then y-axis, like:

  • “Mint a batch of 1 NFT, then transfer tokenID 0”, or

  • “Mint a batch of 3 NFTs, then transfer tokenID 1”, or

  • “Mint a batch of 5 NFTs, then transfer tokenID 4”

From these results, we can see that transferring tokenIDs in the middle of a larger mint batch (i.e. t1, t2) costs more than transferring tokenIDs on the ends of the batch (i.e. t0, t4).

Note that this quick experiment only tracks the cost of a single transfer after mint.

A workaround to decrease transfer costs after batch minting NFTs

Here’s an interesting solution to minimize the total cost of transferring your entire batch of NFTs (original source from William Entriken @fulldecent):

  1. Always mint the maximum allowed number of NFTs during the batch mint.

  2. When transferring, start with the ODD numbered tokens first in ASCENDING order.

  3. After that, transfer EVEN numbered tokens.

ERC721 vs. ERC721A: Batch Minting NFTs (5)

This strategy works because it forces population of the_addressDatamapping, making subsequent transfers cheaper to execute.

Examples of NFT projects using ERC721A contracts

Here is a set of projects that are currently using the ERC721A contract:

  • @AzukiZen

  • @cerealclubnft

  • @TheLostGlitches

  • @standardweb3

  • @KittyCryptoGang

  • @XRabbitsClub

  • @WhaleTogether

  • @pixelpiracynft

  • @dastardlyducks

  • @MissMetaNFT

  • @StarcatchersNFT

  • @LivesOfAsuna

  • @richsadcatnft

  • @themonkeypoly

  • @womenofcrypto_

  • @TravelToucans

  • @HuhuNFT

ERC721A Alternatives for batch minting NFTs

And for those who are more adventurous, take some time to check out an even newer optimization of the ERC721 standard called ERC721Psi:

ERC721 vs. ERC721A: Batch Minting NFTs (6)

We won’t get into ERC721Psi in this article, but if you’re curious and want to learn more about how that one works, let me know by shooting me a tweet @thatguyintech, and I’ll be sure to do another deep dive on it!

We can even explore deploying some sample projects using Alchemy.

Are ERC721A contracts still considered NFTs?

The short answer is yes, ERC721A contracts are definitely NFTs.

Any contract that implements the ERC721 token standard or ERC1155 interfaces are considered non-fungible tokens or semi-fungible tokens.

ERC721A is an extension and optimization of the ERC721 standard.

The same is true for ERC721Enumerable and ERC721Psi.

They’re all part of the ERC721 family!

How to burn ERC721A tokens

When you want to get rid of an NFT or a token that you have in your wallet, but you don’t want to give it to another person, and you don’t want to sell it, you can burn it by sending it to a specific wallet address that no one uses.

A lot of people like to use the same burn addresses because they are easy to remember.

For example, the 0 address:

0x0000000000000000000000000000000000000000

However, when it comes to ERC721A NFTs, you cannot transfer tokens to the 0 address to burn NFTs because most tokens minted in a batch are mapped to the 0 address by default.

Pick another address with which to burn your ERC721A NFTs and you’ll be fine!

For example, another common burn address is the "0xdead" address: 0x000000000000000000000000000000000000dEaD

Will you use the ERC721A contract to batch mint your NFTs?

The ERC721A contract is a powerful way to save your community gas costs and save the Ethereum network from unnecessary congestion by batch minting NFTs.

Let us know what kind of an NFT project you’re building and how we can help! We have tools to help you deploy, monitor, notify, and market your next NFT collection.

Don’t wait, shoot us a tweet @AlchemyPlatform or send a DM and let’s chat!

ERC721 vs. ERC721A: Batch Minting NFTs (2024)

FAQs

What are the disadvantages of ERC721A? ›

The ERC721A contract encounters a significant drawback during token trading, notably in transferring actions, where costs tend to exceed those of batch minting. This drawback is due from the contract's practice of only setting ownership metadata for the first token, leaving the rest unset.

What's the difference between ERC-721 and ERC721A? ›

The ERC721A standard is a notable advancement in the world of non-fungible tokens (NFTs) and smart contract standards. It builds upon the foundation set by its predecessor, ERC-721, and introduces valuable improvements to enhance the functionality, usability, and overall efficiency of non-fungible tokens.

What are the benefits of ERC721A? ›

One of the major advantages of ERC721A is its support for batch minting. This allows creators to efficiently mint large numbers of NFTs, and it also enables the contract to track the ownership of multiple NFTs simultaneously.

Should I use ERC721Enumerable? ›

Conclusion. Developers might use ERC721Enumerable when they need a way to keep track of all the tokens within a contract or all tokens owned by a specific account, without wanting to rely on external parties and reading from events. Also if they do not need or care for batch minting.

What is the difference between ERC721A and erc1155? ›

ERC-721 vs ERC-1155: Major Differences

Token Support: ERC-721 only supports the creation of NFTs, while ERC-1155 not only supports the creation of NFTs but also fungible and semi-fungible tokens, facilitating the conversion of these types of tokens to NFTs and vice-versa.

How much does it cost to mint ERC-721 gas? ›

For example, minting an ERC-721 NFT costs between 100,000 to 200,000 gas per asset. These prices are prohibitively expensive for many use cases. Off-chain minting solves this problem. The operator needs to inform their users that the operator controls the offchain minting policy.

Should I use ERC-721 or erc1155? ›

ERC-721 is popular for creating NFTs, enabling the representation of unique digital assets such as artwork, collectibles, and in-game items. ERC-1155 provides flexibility by supporting multiple token types in a single contract, making it suitable for complex token ecosystems like gaming platforms.

How does ERC721A work? ›

2. Smart Contracts. ERC721A relies on smart contracts deployed on the Ethereum blockchain to define the behavior of the tokens. These contracts include functions for minting new tokens, transferring ownership, and querying information about a specific token.

What is ERC721A? ›

The ERC721A implementation was created by Azuki, and its main purpose is to allow for gas-efficient minting of multiple NFTs in one transaction. With this implementation, users will save on gas fees over the long run if they are minting more than one token at a time.

What does ERC stand for in Ethereum? ›

Key Takeaways. An ERC20 token is a standard for creating and issuing smart contracts on the Ethereum blockchain. ERC stands for "Ethereum Request for Comment," and the ERC20 standard was implemented in 2015.

What is ERC 721A? ›

The ERC-721A is a more flexible and robust standard for creating and managing NFTs on the Ethereum blockchain, with additional features that can help to address some of the limitations and challenges of the original ERC-721 standard. The biggest gain is the gas-saving aspect when minting multiple NFTs.

What is the difference between ERC20 and ERC-721? ›

The key difference between ERC20 and ERC721 tokens lies in their fungibility. ERC20 tokens are fungible and represent a uniform asset, while ERC721 tokens are non-fungible and symbolize a set of unique assets. Additionally, ERC721 tokens cannot be divided into smaller units.

What is ERC20 vs ERC-721 vs ERC1155? ›

ERC1155 was created in 2018 to allow for both fungible and non-fungible tokens to exist on a single contract. ERC20 tokens are fungible, which means each token is identical and interchangeable. Examples include cryptocurrencies like DAI and USDC. ERC721 tokens are non-fungible, meaning each token is unique.

Top Articles
Latest Posts
Article information

Author: Tuan Roob DDS

Last Updated:

Views: 5457

Rating: 4.1 / 5 (42 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Tuan Roob DDS

Birthday: 1999-11-20

Address: Suite 592 642 Pfannerstill Island, South Keila, LA 74970-3076

Phone: +9617721773649

Job: Marketing Producer

Hobby: Skydiving, Flag Football, Knitting, Running, Lego building, Hunting, Juggling

Introduction: My name is Tuan Roob DDS, I am a friendly, good, energetic, faithful, fantastic, gentle, enchanting person who loves writing and wants to share my knowledge and understanding with you.