Unlockable Party Pack (Polygon)


Before we start preparing the SmartContract, we need our metadata. The metadata files contain information about the NFTs: name, description, path to the image, etc. Here is a link to the official ERC721 metadata standard for a deep dive. MVP of our metadata file would look something like this.

 "description": "UPP writeUp",
 "external_url": "https://darkblock.io/",
 "image": "ipfs://bafybeigv5g54jxcxlqqqljle7s3nwb75d3gyk5xhdkd3ptfclpijqnntgm/",
 "name": "Darkblock UPP"

Now that we have our metadata, we need to store it somewhere. I highly recommend NFT.storage. Their API makes uploading files to ipfs extremely simple. They also have a desktop app, NftUp, with drag and drop uploads. 

After uploading the metadata to ipfs, you should receive an IPFS URL. I find it helpful to use the Brave browser to verify everything is working as it should. Brave has built in InterPlanetary File System support, so you can access the IPFS URL with it. It is a good practice to check everything is working before minting the NFTs :D


Hashlips has some great resources on writing minting-contracts/deploying them on chain. His Youtube channel is a great place to start your deep-dive into the EVM NFT ecosystems. For our purposes, head over to the hashlips github and grab the NFT_FULL_FLAT.sol contract. This ERC-721 minting contract is under a GPL-3.0 license, meaning you can share and modify it at will. The contract uses OpenZeppelin libraries ERC721Enumerable.sol and Ownable.sol. It was amended by hashlips and created for the purpose to teach people how to create smart contracts on the blockchain. Please review the code on your own before using any of the following code for production.

Now that we have a minting contract, we need to deploy it on chain. I strongly recommend you get familiar with Hardhad, a CLI development environment for Ethereum software. 

For this tutorial, we are going to be using Remix. Remix is a wonderful IDE that allows us to DEPLOY & RUN TRANSACTIONS IN Ethereum like BLOCKCHAINs.  

Copy the contents of NFT_FULL_FLAT.sol and head over to Remix IDE. Create a new file by pressing the file icon in the menu beneath the workspace dropdown - default_workspace. Name the file anything you like and put .sol as the file extension, i.e.  <decriptiveName.sol> ;)  

Paste the content of NFT_FULL_FLAT.sol in your newly created file in Remix.



Choose solidity compiler in the vertical menu on the left and check the box next to auto compile. This way we can quickly know if we break something while editing the contract.

Assuming everything is compiling and you are seeing the green checkmark next to the compiler icon, we can start modifying the contract. Everything above contract NFT is ERC721Enumerable... is from the OpenZeppelin libraries. Do NOT touch that.

You can start by changing NFT to a name you want to use. In the next few lines of code, there are variables we can change. For our purpose, let's set the cost to zero ether, since we are going to be minting the whole collection. Set 'maxSupply' to the number of NFTs you want to have in your Unlockable Party Pack campaign. Next, set 'maxMintAmount' & 'nftPerAddressLimit' to the same number as you just set for 'maxSupply'. Change 'revealed to' to true and 'onlyWhitelisted' to false. If you plan on having any variety in the NFTs, enumerate names of different images or traits for example the modification is done. 

If you plan on using the same metadata for all of the NFTs (same name, description, image, etc,.), you can either upload enumerate .json files to ipfs - 1.json - .json all containing the same NFT metadata, or you can simply change the tokenURI function of the minting contract. To do the latter, find the function tokenURI(uint256 tokenId) in the contract and change

   string  memory currentBaseURI = \_baseURI();

   return  bytes(currentBaseURI).length >  0

       ?  string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension))

       :  "";


   string  memory currentBaseURI = \_baseURI();

   return  bytes(currentBaseURI).length >  0

       ?  string(abi.encodePacked(currentBaseURI))

       :  "";

This way all the NFTs from the collection point to the same BaseURI.

Now we test if everything is working!



Select 'DEPLOY & RUN TRANSACTIONS' from the vertical menu on the left.

By default, we are deploying to a JavaScript VM chain, so there are no gasfees to worry about. Select ' - contracts/.sol' from the contracts dropdown menu. Hit deploy. 

You should now see it in the deployed contracts section under the 'deploy' button. Next to the contract name is the contract address. Copy the address and save it somewhere, we will need this later.

Press the angle bracket / arrow icon? next to the name of your contract. A menu should appear. The menu is a UI for the different functions of the minting contract. Super handy!

This UI can be a bit daunting at first, but don't worry it gets easier and we are only using three. 


First, we set the base URI of our tokens. It's the URI to the place where the token metadata lives. Simply paste the URI into the field and 'press setBaseURI.'

Enter the number of NFTs you want to mint in the 'mintAmount' field and hit 'mint.' Congrats, you have just minted NFTs (...well on a Javascript VM)! The contract mints tokens in an enumerated sequence, so each token gets a token ID starting with 'tokenId = 1.'

Check your work by scrolling down to 'tokenURI.'


The field next to the 'tokenURI' button takes token ID's. Try putting '1' in the field and press 'tokenURI.' If everything is working as it should, you should receive a string that looks something like 

0:string: ipfs://<someCID>/1.json

Paste the string into Brave browser to see if everything is showing up as expected. A missing backslash and everything breaks!

Now that we have made sure the contract is working as expected, we deploy it on the polygon mainnet.

Make sure you are on the 'polygon mainnet network in metamask.'

Select 'injected provider metamask' from the environment dropdown menu, '##add image##,' and press 'deploy.' Redo the steps taken in the javascript VM (set the baseUri, mint a couple of NFTs, and check if the base uri is working). Now you can mint the collection. We suggest minting the collection in batches of 100 NFTs with the ERC-721 standard.

Generate Links

Now that you have minted the collection, you can generate the claimable links using linkdrop. Linkdrop allows end users to seamlessly claim their NFT. It's a fantastic product with a great team (we have no affiliation, just love the product!).

On the linkdrop site, press 'create the campaign.' 

You will now be in the link creation flow. Sign in with your metamask wallet (make sure you are on the account that minted the NFTs).

Create a ERC-721 Campaign

Paste in the contract address you saved after deploying the contract. If you forgot to save the address, head over to pyloscan, search for your wallet address, and find the contract address.

Now that you have entered the address, you can choose to pay for the transaction fees of the NFTs (Gas-fees). Check the box before generating the urls (at the time of writing this, it is 0.02 matic).

Add Darkblocks

Now for the easy part!

Head over to the Darkblock collection upgrader. Paste in the contract address and choose a file to upload. Name the file and give it a description. You can also choose to 'allow download' or not with the toggle. Press create and voila! Every NFT in the collection now has access to the uploaded file. You can add as many files as you want.

To access the content, add the Darkblock viewer to your own website by embedding it, or installing it with npm. 

You can also view the content without the viewer on app.darkblock.io.