What's the recommended way to allow users to mint random ERC-721 tokens, reveal metadata, and offer full transparency in 2022?

Hello, everybody,

I'm writing an ERC-721 contract to launch a collection of paintings and I'm considering a few semi-generative variations to make the total supply about 1,000 tokens with multiple rarities.

I'd like to use a reveal step so that collectors will only know what random token and rarity they get after the collection has sold out or some time has passed but I'm slightly confused about the use of a provenance hash and the randomness mechanism.

The short version question is: What's the recommended way to allow users to mint random ERC-721 tokens, reveal metadata, and offer full transparency in 2022?

And here's the long version.

Of course I want to offer transparency so I learned all I could about the provenance hash and I'm considering generating the hash with the actual metadata (hashing the full JSON files including the IPFS CID for images instead of just the images, is that somehow better or just unnecessary?) before the sale starts but only pointing to placeholder images at first and then uploading the final metadata and images and setting the baseURI on reveal time.

But I'm not sure about the random part. I've read about the BAYC approach with a startingIndex (which apparently the contract doesn't use correctly) coming from the block number of the last token minted but I'm not sure if that's still a good approach in 2022. As it looks like BAYC is not a great example of this approach I'd appreciate it if you could point me to a contract doing it the right way.

I initially thought about randomizing the token ID on mint with a Chainlink VRF call but with many tokens that would be too expensive.

Another option I considered was just making one call to Chainlink VRF on reveal and then expanding that number using the random number with keccak256 and them modulo operator to shuffle the token IDs and run a loop over all the tokens calling _setTokenURI to point each token to a JSON metadata file on IPFS. For this to work fine I suppose I shouldn't put these files in just one IPFS directory so each CID would be different and unrelated to the token ID but I worry that this solution may be too expensive because of the loop and calls to _setTokenURI.

For reference here are a couple of URLs I've already explored.

I'm also going to take the liberty to tag @PatrickAlphaC as he seems to be our resident Chainlink VRF expert.

Thank you!

You got it, if you want to cut down on costs, just make one Chainlink VRF call and update all the values of the NFTs with that one call (you can get multiple random numbers back from a Chainlink VRF call in the new version of chainlink VRF!)

Thank you, Patrick.

Can you clarify what do you mean by "update all values of the NFTs"? Calling _setTokenURI for each of them? If so, is it safe to assume the gas cost will be lower than calling Chainlink VRF on mint for each token?

Something like that. So when you get your Chainlink VRF response, your fulfil request loops through the tokens and updates them with their random variables from the response.

Yes, doing this would lower the cost by massive magnitudes than calling the Chainlink VRF on each NFT.

Thank you so much. Cheers!