A FUD-less NFT Collectible Drop: The Radioactive Punks Guide
How we launched Radioactive Punks, a 3K pre-generated on-chain NFT collectible, without a single technical issue on launch-day.
On October 6th I had a full-on panic attack waiting for minting to go live on my latest technical NFT project Radioactive Punks $RPUNK. What if I cause FUD and it all falls apart?
I did everything in my power to make sure this launch would go perfectly, but I was doing things I had never seen anyone try before and was terrified I had overlooked something. I remember wishing so bad that there was some article or tutorial that could walk me through the entire convoluted process to make sure I had covered my bases. Something written by someone who had literally gone through the whole process by themselves start to finish.
Well today I hope to be that person for you
Long Story Short
Luckily, I had nothing to worry about, and the entire drop went perfectly. About 30 minutes after minting had opened up, and all was well, and we had minted over 300 punks. I was able to breathe a massive sigh of relief, knowing that my test suite & QA had done me well.
After that, we focused on building a goofy, fun-loving community around this rad parody project with dope art by Pixantle. A week later, our community is still just as positive and goofy as ever, and we’ve minted 1000 punks! I haven’t seen a single ounce of FUD or anger in the Discord, and I’m very proud of that, as I’ve seen some Discords get nasty.
So, the for the rest of this article, I’m going to share all the nifty Web3 things I learned during the development of the technology for Radioactive Punks. That way, you can follow along and use this as a guide for your next drop (I hope)!
The highlights from the drop I’m most proud of before we dive in:
- The Web2.5 minting site is hosted decentralized on IPFS but protected via a CDN to avoid DDoS, maintain perfect uptime, and allow for secure HTTPS connections.
- The metadata and image data that is hosted on-chain via Arweave to create better data permanence
- The in-depth JSON metadata goes beyond the minimum standards set by places like OpenSea, FND, SR, etc., to create better provenance for each NFT. We include file type and file dimensions in our image metadata.
- Our dedication to warding off bots and discouraging on-contract minting (an unfair advantage for the technically inclined) by requiring an EIP712 signed data transaction signature to mint a new Punk.
Alrighty, let’s get into it, ya punks!
📖 Precursor: Why is this important?
Collectibles are a fun way to get into NFTs without spending 20k on a piece of artwork. Still, they can also quickly become expensive financial decisions, and we, as the creators of these NFTs, need to take that seriously. People trust us to create incredible artwork and communities and rock-solid NFT technology that will last a lifetime of trading on the open market.
No NFT project can be too small to be taken seriously from a technical perspective because you never know how the market will react ($DOGE, $BAYC). Your drop could go in a direction you never saw coming and see prices soar to 5ETH. Your drop could also fall victim to some vulnerability in the contract that ruins the metadata, making prices plummet to 0ETH, and now you have thousands of NFT holders who hate you forever!
Every week I hear horror stories of drop websites breaking, bots buying up every NFT in a collection before the community can, insiders reserving all the rare ones for themselves, or contracts being stolen and drained of their funds. These types of drop-ruining tales cause amazing collections of incredible artwork to get FUD’d out of existence.
This pressure is intimidating for both collectors and devs! No one wants to buy a broken NFT, and no one wants to be the team that wrote its contract. We all have to work together to keep trust high in the space.
So when my friend Pixantle reached out to me about doing a collectible, I decided I’d do what I can to make an iron-clad system that others can reuse because I am both a creator and a collector who wants solid NFTs.
So how did I avoid all of these pitfalls that are currently scaring off consumers and causing devs and Discords alike to lose their minds?
📜 The Contract
In the end, this is the most critical part of your drop, and it must be developed with extreme care, as you’re going to be stuck with it forever.
I am a fan of using the Truffle framework to develop and test my contracts, so that I will be referring to that throughout the article. Still, Hardhat is another beautiful alternative with all the same tools available to it! Remix IDE is the industry standard for in-browser development, but I’ve personally never used it and can’t attest to how well it works for big production projects, so be forewarned.
🧪 Offline Development and Testing
You are developing an art/financial contract that effects peoples’ wallets, and you should not be taking that lightly, even if you are selling DickButts or a parody Punk project like us. These early tech-adopters trust you with their crypto in exchange for a cool NFT, so test your contract and use trusted frameworks.
Truffle comes with incredible tooling and scaffolding for testing your contract. It automatically deploys your contract to a local Ganache Test Ethereum Network when you run their built-in dev/test commands and runs your tests against that fresh network.
In terms of building the contract itself, you should use OpenZeppelin’s modules as the building blocks of your contract. After that, try to find currently verified contracts that you can get ideas and snippets from, as they are currently working in real life and you know that code does what it needs to do! In a perfect world, you try to write as little customized code as possible and use the OpenZeppelin modules as much as humanly possible, as their code is thoroughly tested and trustworthy.
🤓 Now Write Good Tests and Lots of Tests
We need 100% full test coverage, or as freaking close as we can get without losing our minds.
Use a coverage tool to help you not lose your mind finding the holes in your test suite. I’ve already done the hard work to vet this one for you if you’re using TruffleJS or Hardhat!
I cannot stress enough how critical it is not to get lazy here and just test the happy code paths. People will try to wreck your contract as there is massive value in doing so. They will look in every little corner of your contract to find something you didn’t test.
Using Providers to Access Networks
At this point we’re ready to start deploying this thing to real networks, even if they are real test networks. The only way to do that is to go get yourself an RPC Provider, and I suggest AlchemyAPI or Infura alongside Truffle’s build in HDWalletProvider. For this project I used Alchemy. Either way, yourtruffle-config.js
will end up with its networks
defined something like this.
🔗 Rinkeby Testing — Deploying, Verifying, and Minting
The importance of testing things out on a test network cannot be overstated enough, and my suggestion is to use Rinkeby as it’s reliable and consistent. The faucet also works great as long as you have a public Twitter account! It gives you fake Monopoly money $ETH to spend on the Rinkeby network.
OpenSea and Rarible allow us to preview NFTs minted to the Rinkeby test network on their sites, so take advantage of this and use them to find bugs in the formatting of your NFT metadata by minting NFTs on the Rinkeby network.
Etherscan allows you to interact with verified contracts on the Rinkeby network, so utilize this as a chance to learn how to verify your contract and engage with it in their UX. Truffle has an excellent plugin for verifying your contract via the CLI on any network. If you have issues with it, I suggest flattening your contract and manually verifying it on the Etherscan site yourself.
🔐 Minting Security
When it comes down to it, it is very difficult to keep a contract from being abused. We saw it happen with The Sevens and in the Meebit Hack.
To protect the contract as best I could I did the following.
- Either do not set the final metadata until just before the drop or use a reveal mechanic to reveal the NFT metadata after the drop. That way, the metadata will not leak and you will lower the ease at which people can game the rarity. The first approach is tougher because you can end up stuck in a gas war before launch. Either way, all this requires is making sure your 721 tokens are set up to have their
tokenURI
orbaseURI
updated by only the owner or admins of the contract. You can update either of those to change where your metadata points and reveal the final data properly. - Require an EIP712 signed data transaction signature to mint. This means on your front end, requiring people to log in using something like Metamask and asking them to sign a transaction before letting them mint. This has become the industry standard for logging into any Web3 site (see Foundation, SuperRare, and Rarible), and this is why. It allows you a better chance to verify where and who transactions are being sent from.
- Use OpenZeppelin’s Ownable class to mark methods asonlyOwner that way, you know for sure no one else can call them. You can even go one layer deeper and use their Admin system to give specific wallets the rights to do certain things but not all of the things. Don’t be one of those drops that let the token owner update their metadata. Only the contract owner should be able to do that.
So far I have no seen a single person successfully mint on contract or via another contract. I’m sure someone could write some crazy Selenium bot to use our website but at that point, kudos!
🐠 Personal Security / Phishing
You’ve already tested your contract fully both offline and on the Rinkeby network, so unless the contract’s logic is inherently faulty, you should be okay now! Your contract will do precisely what you told it to do.
So what else is there to worry about? The wallet. Every contract has to be deployed from some wallet, and the entire project is only as secure as the seed phrase to that wallet. Keep it safe. If someone manages to get that wallet, they now have admin rights on the contract and wreak havoc. We’ve seen this happen to more than a few collections, and it’s heartbreaking every time.
I suggest using a dedicated secure wallet that is never used as a hot wallet for anything as your drop wallet.
For more info on wallet security, see:
✅ Develop the Front End to Ensure Successful Transactions
Developing a minting front end is quite the trivial task actually and there are tons and tons of tutorials on the internet about how to use the Web3 library to make a button that can call yourCoolMintMethod
. I don’t want to waste time here with that!
What I do want to take the time to remind you of is that you need to overestimate gas for hyped collectible drops.
If people push gas price in gwei to insane heights you may suddenly find that the suggested gas limit for their transactions are too low and they start to waste gas on failed transactions. Here’s the snippet in web3.js and ethers.js to properly overestimate your gas limit and avoid that entirely:
⛽️ Avoid Gas Wars When Activating Sales
I’ve seen many contracts with a simple on and off switch titled activated
which starts or ends sales on the contract and is public for all to see. This seems simple and smart. You have full control and transparency at all times!
But that absolutely is not the case.
When there is a massive gas war and you haven’t made any money off of your drop yet, you will not be afford to get the transaction mined and have to push your drop. It’s embarrassing and it causes people to lose faith in the project.
I suggest setting a public variable called droptime
to a block.number
or block.timestamp
value way in the future instead of a simple boolean like active
, and only allowing minting after that time or block has passed. This allows you to do a few things:
- Publicly display the droptime on your site and on Etherscan using
read
methods aka no gas required - Update the time when you inevitably decide to change the drop date and have it be instantly publicly available
- You don’t get stuck paying massive gas fees because you wont need to flip the switch when gas is at 100+ or 200+ for no good reason
⛓ Host Your Data Decentralized on IPFS or Arweave
If you want to have people genuinely care about your NFT, you need to take special care of the metadata. The two industry standards are IPFS and Arweave, which have significant differences. I prefer Arweave, but I’ll tell you about both.
IPFS is similar to torrenting and other P2P networks. As long as someone has the file, the client can get the file. If no one has the file anymore, no one can get the file. You can avoid this by pinning the file personally, which requires some effort. If the file gets deleted from the network due to inactivity and no pinning, you need someone to reupload it and cause IPFS to recreate the same link with the same hash. Data is served via the IPFS gateway.
Arweave a genuine blockchain, and in exchange for the token $AR, you can store files permanently on that blockchain. Every node which runs the chain agrees to store all the data permanently. Data is served via the Arweave gateway.
In the end, both will do the trick in a pinch and will allow you to serve metadata and image files using a decentralized network. They both have excellent JS and CLI tooling you can use to upload your data with a simple script.
For all Radioactive Punks the user can head to Etherscan and use the read method tokenURI
to get given their metadata URL. From there, they can simply click on the image
or image_url
properties to retrieve the image.
🌐 Put Your Site Behind a CDN
put this last because this is the very last thing you should do. Once you have a sick contract that’s thoroughly tested and a radical website that works perfectly on the Rinkeby and Main test networks, you need to protect your site and put it behind a CDN. This will avoid downtime during considerable surges in traffic, aka the second minting is open. This will also prevent any DDoS issues stemming from your enemies trying to ruin you… you have those too, right?
I used bunny.cdn personally. Any CDN will do. Pick your poison!
🌐 Use HTTPS on your Site
While Web3 technically means HTTPS vs. HTTP isn’t a huge deal because all your transactions are happening via the blockchain, it’s still good practice to secure your site and make people feel safe.
Be sure to ensure your site is fully functioning with HTTPS before your drop; otherwise, you will get complaints about your drop being sketchy!
bunny.cdn and GoDaddy made this simple for me.
🤘🏼💀 Summary
I’m a dev and haven’t written an essay in probably nine years, so this was pretty intense, but I’m so grateful you’ve gotten this far. As a treat, here is a tl;dr of what I’ve gone over
- Develop and test your contract using Truffle or Hardhat
- Test your contract interactions on the Rinkeby network using Etherscan, Opensea, and Rarible
- Decentralize all your data using IPFS or Arweave
- Make sure you have complete test coverage on your solidity files
- Use a secure wallet to deploy your contract
- Be very aware of phishing scams etc. on your deploy wallet to avoid someone gaining access to the contract and ruining everything.
- Use Web3 or ethers.js on your Front End to make contract calls
- Use EIP712 signatures to ward off bots and discourage on-contract minting which provides an unfair advantage to other devs
- Overestimate gas on your minting transactions to avoid failed transaction
- Use a CDN to prevent downtime and make your website HTTPS secure
- If you’re cool, host your website on IPFS or Arweave and make the sales site decentralized!
Stay sludgy, punks!
~ White Lights
If you appreciated this article, please mint a Radioactive Punk and save it from demise before Nuclear Winter dawns on 08/26/21 when all minting is frozen!
Oh! And join the discord anytime if you want to shoot me some tech questions