Hey everyone! I’m trying to figure out how to randomly distribute NFTs but keep the total numbers the same. Here’s what I want:
- 200 super rare
- 300 rare
- 500 common
The tricky part is I want the minting to be random, so you might get any type, but at the end, the totals should match what I listed above.
I tried some code that does the random part, but it messes up the final numbers. They end up different from what I wanted at the start.
Here’s a simplified version of what I tried:
function mintRandomNFT(address buyer) public {
require(totalMinted < maxSupply, "All NFTs minted");
require(buyerMintCount[buyer] < maxPerBuyer, "Max per buyer reached");
uint256 randomNum = getRandomNumber(remainingNFTs);
NFTType nftType = determineNFTType(randomNum);
mintNFT(buyer, nftType);
updateCounts(nftType);
}
function getRandomNumber(uint256 max) internal returns (uint256) {
return uint256(keccak256(abi.encodePacked(block.timestamp, buyer, totalMinted))) % max;
}
Any ideas on how to keep it random but still end up with the right numbers? Thanks!
I’ve encountered this issue before in my NFT projects. The solution lies in implementing a dynamic probability system where the chances for each NFT type are recalculated as minting occurs. As NFTs are minted, the remaining supply for each type decreases, so it becomes essential to adjust the probabilities to ensure that the predetermined total numbers are eventually met. In my experience, continuously updating these probabilities along with implementing a final check for the last few mints can help maintain randomness while achieving the desired distribution. Although this approach introduces additional complexity, it provides a fair and controlled minting process.
hey flyingeagle, interesting challenge you’ve got there!
have you considered using a reservoir sampling algorithm? it’s pretty nifty for maintaining randomness while hitting specific counts. basically, you’d start with a ‘reservoir’ of your desired NFT distribution, then as people mint, you swap out NFTs from the reservoir with decreasing probability. it keeps things random but guarantees your final numbers.
here’s a super simplified pseudocode idea:
reservoir = [200 super rare, 300 rare, 500 common]
for each mint:
if reservoir not empty:
index = random(0, reservoir.length - 1)
mint(reservoir[index])
remove reservoir[index]
else:
mint(random NFT from remaining pool)
might need some tweaking for solidity, but could be a good starting point. what do you think? have you tried anything like this before?
yo FlyingEagle, i think ur gonna need to use a weighted randomness approach. instead of pure random, assign probabilities based on remaining amounts of each type. as u mint, adjust the weights. this way u keep the randomness but ensure u hit ur target numbers. might need to tweak ur getRandomNumber function for this.