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 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.