I'm currently building an NFT fantasy league game on ethereum where I want to add the functionality of on demand minting of random tokens. For that I need to keep track of the tokens that are available for minting so that I can choose random ones from them. The only strategy I could find was to store the token Ids for a player in an array, and pop the id after minting. This eliminates any chance of collisions since the token now doesn't exist in the array anymore and if I land on the same index, a new Id is there.
But the problem is I can't find any way of populating an array so big (in my case 40000 integers from 1-40000). It runs out of gas if I use a for loop and populate it in the smart contract or even if I pass the entire array from javascript as an argument in a function.
Is there any way to populate arrays of this size other than doing it in batches using multiple transactions (it allows me to send an array 1000 integers to the contract but that leads to way to many transactions when I have hundreds of players each having 40 thousand tokens). Also if there's a different way to accomplish this task other than using arrays I'd be open to that too.
pragma solidity ^0.8.9;
contract test {
mapping(uint16=>uint16[]) public availableTokens;
//Player=>tokens mapping
function pushNumbers(uint16 player) public {
uint16 i = 0; //tokens
for (i=0; i<40000; i++){
availableTokens[player].push(i);
}
}
//Runs out of gas
}