I used this Smartpy code to mint 200 NFTs (max allowed per transaction) which cost cost 14 Tez - bettercalldev link.

How much could this be optimized?

3 Answers 3


By storing all tokens' metadata off-chain, the max I was able to push it was to create 425 NFTs in one transaction. In subsequent transactions, the limit is around 250 NFTs per transaction.

class TZColorsFA2(sp.Contract):
    def __init__(self, initial_auction_house_address):
            # why is the auction house address passed in and not the opposite (auction house calling this contract)?
            # --> This has to be this way because that contract needs permission for the transferring when the auction is over
            initial_auction_house_address = initial_auction_house_address, 
            ledger = sp.big_map(tkey=LedgerKey.get_type(), tvalue=sp.TNat), 
            #TZIP-16 metadata? typically hosted offchain on IPFS
            # ipfs://QmTwyN85GfziB5BGhF2ELogeJRt6CwevZY729bahQqKHiD
            token_metadata = sp.big_map({"": sp.utils.bytes_of_string('ipfs://QmTwyN85GfziB5BGhF2ELogeJRt6CwevZY729bahQqKHiD')}), 
            total_supply=sp.big_map(tkey=sp.TNat, tvalue = sp.TNat),
            allowances = sp.big_map(tkey=AllowanceKey.get_type(), tvalue=sp.TBool),
            metadata = sp.big_map({"": sp.utils.bytes_of_string('ipfs://QmVp5JbyL2dJEGg9yVZJrm4zygLBbxWtcBqVYSi9atQwak')})

    def load_test_auction(self, batch_initial_auction):
        sp.set_type_expr(batch_initial_auction, BatchLoadTestAuction.get_type())
        token_count = sp.local('token_count', batch_initial_auction.auction_id_start)
        sp.for token_delta in sp.range(0, batch_initial_auction.token_id_range):
            token_id = token_count.value + token_delta
            # make sure token doesn't exist first
            sp.verify((~self.data.total_supply.contains(token_id)), message = FA2ErrorMessage.NOT_OWNER)
            # make sure token doesn't exceed max number of tokens allowed
            sp.verify(token_id<=MAXIMAL_TOKEN_ID, message = FA2ErrorMessage.NOT_OWNER)
            to_user = LedgerKey.make(sp.self_address, token_id)
            # create unique (user, token_id) pair and record it on the ledger (this creates the NFT)
            self.data.ledger[to_user] = sp.nat(1)
            self.data.total_supply[token_id] = sp.nat(1)
            token_count.value += 1

Something I realized is that I don't need to batch create ledger entries if all the token metadata will live offchain on ipfs. The tokens can be created on the ledger as they are bought. That way I don't incur the gas fees myself and only the storage that is needed is created.


From what I see, you have configured an NFT contract, and are trying to use it in the same way as a multi-asset contract (having multiple copies of the same identical token).
Have you considered just using a multi-asset contract? the contract you're using has already implemented the right ledger signature - (owner_address, token_id) -> token_amount. you just have to allow the contract to have token_amount != 0 and then you can mint however much copies of the same token as you want, with minimal cost (the fee you pay now for minting one token).
You can do that by leaving the FA2.FA2_config(non_fungible) option as false, and using self.data.ledger[user] = FA2.Ledger_value.make(param.range) instead of the whole for loop you have.
I hope I got your intension right. If you need to have multiple copies of the same token, each with a different id, then I guess you'll have to pay for each individual copy separately, updating 200 entries in ledger, token_metadata and total_supply big maps which is costly...

  • Hey, thanks for the answer. Unfortunately, this approach won't work for me because I need to have individual token_ids to associate different metadata for each token.
    – JJJ
    Dec 24, 2021 at 22:12

I would like to do the same NFT 1000 times with the same metadata like your explain to JJJ I've tried to follow your recommandations but I'm new in tezos environment and I can't change the smart contract properly. Can you show me what it should look like or perhaps with which template I need to start.

thanks in advance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.