Best/standard approach for minting 10000 NFTs

Hi there, wondering what the best approach of mining 10000 or more NFTs is? I’ve come up a few approaches listed below:

1). A single function mint() with no for loop inside with which only 1 NFT can be minted each time the function is called. The function will be called 10000 times;
2). A single function batchMint() with a for loop inside with which up to 100 NFTs can be minted each time. The function will be called 100 times;
3). A single function batchMint() with a for loop inside with which all 10000 NFTs can be minted in one call. The function will be called just once.

I suppose 3) will easily reach block gas limit and 1) will cost too much effort and time. 2) seems to be fine, but not sure if it is golden.

Therefore, I’m wondering if there is a standard approach for doing this. Thanks.

1 Like

Not a financial advice, this is what I do myself:

    constructor(string memory name, string memory symbol, address payable _multisig, address _WBTCaddress, uint _cutoffTimestamp) ERC721(name, symbol) {
        multisig = _multisig;
        cutoffTimestamp = _cutoffTimestamp;
        WBTCaddress = _WBTCaddress;
        WBTC = IERC20(WBTCaddress);

        for (uint i=0; i<128; i++) {
            _mint(multisig, i); 
        }
    }

I premint 128 NFTs with low serial numbers. I have no idea if that is the right way, but seems “good enough” and “easy enough” :innocent:

For 10000+ google for a pattern “pull” rather than “push”, someone can claim (lazy mint) when needed maybe potentially?

3 Likes

Hey @marsxr, thanks for the reply. How you did it looks very intuitive to me.

One of the motivating examples for me to ask this question is HashMask. They minted over 16,000 NFTs across a long array of transactions, most of which have fewer than 40 NFTs minted in each one. That is then roughly 400 transactions over multiple days. I don’t know how they did it, but they didn’t look like being programmatically generated.

1 Like

Hi @maxaero,

Hashmarks contract uses a for loop:

    function mintNFT(uint256 numberOfNfts) public payable {
        require(totalSupply() < MAX_NFT_SUPPLY, "Sale has already ended");
        require(numberOfNfts > 0, "numberOfNfts cannot be 0");
        require(numberOfNfts <= 20, "You may not buy more than 20 NFTs at once");
        require(totalSupply().add(numberOfNfts) <= MAX_NFT_SUPPLY, "Exceeds MAX_NFT_SUPPLY");
        require(getNFTPrice().mul(numberOfNfts) == msg.value, "Ether value sent is not correct");

        for (uint i = 0; i < numberOfNfts; i++) {
            uint mintIndex = totalSupply();
            if (block.timestamp < REVEAL_TIMESTAMP) {
                _mintedBeforeReveal[mintIndex] = true;
            }
            _safeMint(msg.sender, mintIndex);
        }

        /**
        * Source of randomness. Theoretical miner withhold manipulation possible but should be sufficient in a pragmatic sense
        */
        if (startingIndexBlock == 0 && (totalSupply() == MAX_NFT_SUPPLY || block.timestamp >= REVEAL_TIMESTAMP)) {
            startingIndexBlock = block.number;
        }
    }

sorry for the noob question - I assume that batch minting will have the lowest fees here but there will still be a gas price for each NFT that is minted regardless so you are just minimizing the costs of running the contract ?

1 Like

Hi @soulbank,

Batch minting just lowers the cost per mint. Alternatively you could allow users to mint (and hence pay the cost of minting), either by buying a token (such as through a sale contract) or where the contract was setup to allow them to mint (such as a Merkle Proof)

1 Like

Hi @abcoathup, to have a contract setup to allow people to mint using a Merkle Proof is something new to me. Wondering if you could be more specific about this?

1 Like

Hi @maxaero,

Have a look at the Uniswap UNI claim. https://uniswap.org/blog/uni/