[Ethereum] What does ERC1155 have to do with Opensea (and other NFT marketplaces’) “gas free minting”

erc-1155nft

I have been trying to figure out how ERC1155 "helps" with NFT marketplaces like Opensea and Rarible implement "gas free minting". Here's an excerpt from Opensea's blog:

NFTs made with the Collection Manager follow the ERC-1155 standard, partly to help with gas-free minting and partly to help us add exciting features in the near future…

You can read more here: https://blog.opensea.io/announcements/introducing-the-collection-manager/

I understand how ERC1155 works and have even implemented and deployed a couple, but I still don't understand how ERC1155 helps with gas free minting. I looked up all over the Internet and people talk about it as if it's an obvious thing, but I don't know how "gas free minting" (also known as lazy minting, which basically means the tokens are not on chain until later) has anything to do with ERC1155.

Also many say ERC1155 "saves gas" on NFT trading, which I also cannot understand, because NFTs (unless they're talking about the fungible parts of the ERC1155) get traded one at a time. How can ERC1155 help with low gas fees?

Can someone please enlighten me? Thank you!

Best Answer

Lazy minting or "Gas Free" minting can be done using both the ERC1155 standard or the ERC721 standard. There is certainly nothing preventing OpenSea and other marketplaces from using an ERC721 for lazy minting.

The reason ERC1155 is becoming the popular choice for lazy minting is because:

  • You have the ability to create Fungible and Non-Fungible assets
  • ERC1155s uses ID substitution pattern in the uri() function. This allows for easy linkage to the metadata with just the tokenId which makes it easier to lazy mint.
  • There is a large reduction in gas cost when using ERC1155 that increases the users experience.

Using the two basic examples below from OpenZeppelin we can see the gas savings:

  • Minting with an ERC721 costs 96,073
  • Safe Transfer for ERC721 costs 61,542
  • Minting with an ERC1155 costs 51,935
  • Safe Transfer for ERC1155 costs 53,492
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";


contract MyERC721 is ERC721, ERC721URIStorage, Ownable {
    constructor() ERC721("MyToken", "MTK") {}

    function safeMint(address to, uint256 tokenId, string memory uri)
        public
        onlyOwner
    {
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    // The following functions are overrides required by Solidity.

    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }
}

contract MyERC1155 is ERC1155, Ownable {
    constructor() ERC1155("") {}

    function setURI(string memory newuri) public onlyOwner {
        _setURI(newuri);
    }

    function mint(address account, uint256 id, uint256 amount, bytes memory data)
        public
        onlyOwner
    {
        _mint(account, id, amount, data);
    }

    function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
        public
        onlyOwner
    {
        _mintBatch(to, ids, amounts, data);
    }
}

How can ERC1155 help with low gas fees?

ERC1155 helps with low gas fees even with basic transfer transactions because it stores data more efficiently inside the contract. If you look inside the OpenZeppelin ERC1155 contract you will see that you only need to update two mappings to transfer the token.

_balances[id][from] = fromBalance - amount;
_balances[id][to] += amount;

But for the ERC721 you have to update 3 mappings which raises the gas cost

_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
Related Topic