Smart contract written in [[Solidity]] for the Skin-Z NFTs.
Should have the following features
- Randomized mints
- Set # of each type of Skin to mint
- All data stored in a decentralized way (on chain or IPFS)
- Deployable on [[Arbitrum]]
- 0.01 ETH mint fee
- Ability for owner to withdraw portion of locked fee directly to a wallet (arbitrum) (tax savings)
Potential features:
- chainlink VRF for randomization on mints
- ability to add new NFTs for future mints
## Randomized Minting
A key aspect here is making it very difficult for people to "engineer" their way into getting a rare NFT.
Using the ETH mainnet, the best we can do is randomize based on the block number, which isn't super secure.
### Arbitrum randomization
On arbitrum, we can access the ETH block number, the Arbitrum block number, and the Arbitrum OS contract version.This allows us to make it even more difficult to game the system.
### Randomization seeds
Using a randomization seed, we can further increase the complexity.
#### Token ID as Seed
This adds complexity in that targetting a specific TokenID runs the risk of someone not gaming the system minting that ID before you get your desired state.
#### Chainlink VRF as Seed
Using Chainlink VRF, seeds could be randomly generated by paying a fee in LINK. This would ensure that gaming the system is as near to impossible as can be achieved on a blockchain.
## Minting fees
We need charge the user a fee in order to make a profit for artists.
Those fees will be held by the NFT contract, with the owner having the ability to withdraw those fees to a target address.
Making a deposit of 0.01 directly to the contract should return funds / revert. Must call the `claim` method with a token ID.
## Token Claiming
Following the standard layed out by Loot for Adventurers. Giving the minter control over token ID is important. This allows early adopters to snag cool numbers like *420* and *69*.
Tokens should only be mintable from this `claim` method.
`claim` should require a 0.01 ETH deposit be included with the call.
## TokenURI
We should generate the token JSON data URI on chain like Loot for Adventurers does. This way, we can customize the Name field of the NFT and include the TokenID in it.
This also significantly reduces the amount of IPFS files that need pinned.
The image section should be `ipfs://<content_id_here>` linking to a PNG/SVG/JPG or other format of artwork for the specified NFT.
This IPFS data should be pinned using pinata.cloud, but it should be noted that owners of these NFTs may want to pin their content as well to ensure the artwork lasts a lifetime.
## Premint Definitions
Needing a way to store IPFS CIDs and NFT amounts, this data should be stored on chain as well. This removes any need for a centralized minter.
By storing this data in a struct like
```solidity
structSkinData{
stringimage;
stringname;
uint256count;
}
```
We can define a set count of each NFT that should be minted.
Once a count reaches 0, no more of that NFT image should be created.
## Randomization optimizations
By only randomizing which type of NFT we mint, and not caring about the amount of those NFTs that remain to be minted, we can simplify our minting calculations.
For example, say we had `SkinData[]` which contained all the NFTs to mint. If we selected a random element from this array, and minted it, followed by reducing it's `count` field. We could then remove elements as their `count` hits 0, making the randomization calculation not require iterating over the entire list of skins (saving gas).
### Drawbacks
We'll likely mint all of the "rare" NFTs early, leaving only common ones to be minted by the end.