In this project, we showcase our journey from creating our NFT idea to the full minting and deployment of our smart contract and Dapp.
-
Source code:
-
Deployed App: https://cryptobaras-minter.herokuapp.com/
-
Collection: Open Sea
We generated 100 unique CryptoBaras using the HashLips art-generator:
https://github.com/HashLips/hashlips_art_engine/blob/main/src/config.js
Install the latest version of node:
node -v # To check node js version
v16.14.0 # version installed
We developed our concept around capybaras utilizing free icons from canva.com.
Read more on the Canva License Agreement.
Once we had all our icons, we generated individual layers for each character and prop using Photoshop. Take a look at the psd file.
The following layers were used in our concept:
- Backgrounds
- Faces
- Glasses
- Hats
The rarity weight was attached in the file name for each asset, as such: green_bg#10.png
. Where the variable, rarityDelimiter
, is denoted by the delimiter #
The layer assets labeled with #10
(for regular), #5
(for rare assets), and #2
(for super rare).
Multiple layerConfigurations
were added to the collection. The different configurations yield added rarities to some of the prop/character combinations.
const layerConfigurations = [
{
growEditionSizeTo: 10,
layersOrder: [
{ name: "Backgrounds" },
{ name: "Faces" },
{ name: "Glasses" },
],
},
{
growEditionSizeTo: 20,
layersOrder: [
{ name: "Backgrounds" },
{ name: "Faces" },
{ name: "Hats" },
],
},
{
growEditionSizeTo: 40,
layersOrder: [
{ name: "Backgrounds" },
{ name: "Faces" },
],
},
{
growEditionSizeTo: 100,
layersOrder: [
{ name: "Backgrounds" },
{ name: "Faces" },
{ name: "Glasses" },
{ name: "Hats" }
],
}
];
We also mixed up the layerConfigurations
order on how the images are saved by setting the variable shuffleLayerConfigurations
in the config.js
file to true.
Because of this, the images are saved in a shuffle order. This means that when minting, one would not be able predict what combination of props might result based on the number of already minted CryptoBars.
The images to be created were outputted to the build/images
directory and the json in the build/json
directory:
node index.js
The program will output all the images in the build/images
directory along with the metadata files in the build/json
directory. Each collection will have a _metadata.json
file that consists of all the metadata in the collection inside the build/json
directory.
The build/json
folder also will contain all the single json files that represent each image file. The single json file of a image looks like this:
{
"name": "Cryptobaras #1",
"description": "To Be Or Not To Be Cryptobara",
"image": "ipfs://QmXwnf99NoKwVvKpJ5WnrEmbbqtpEarJqF6jUXUzmkSZhk/1.png",
"dna": "a350a741f5ee6e5a6242ff9fe1e360faa3672d7f",
"edition": 1,
"date": 1644770031593,
"attributes": [
{
"trait_type": "Backgrounds",
"value": "yellow_bg"
},
{
"trait_type": "Faces",
"value": "moss_capy"
},
{
"trait_type": "Glasses",
"value": "blue_shades"
},
{
"trait_type": "Hats",
"value": "pink_sun_hat"
}
],
"compiler": "HashLips Art Engine"
}
Metadata is particularly important in creating NFTs. It is the image’s information - it contains information such as the name, description, image IPFS, DNA, edition attributes, etc. This information will be displayed on OpenSea attributes.
// General metadata for Ethereum
const namePrefix = "CryptoBara_TestRun";
const description = "To Be Or Not To Be A CryptoBara";
const baseUri = "ipfs://QmXwnf99NoKwVvKpJ5WnrEmbbqtpEarJqF6jUXUzmkSZhk"
Create a preview image collage of your collection, run:
npm run preview
In order to export gifs based on the layers created, we set the export on the gif
object in the src/config.js
file to true
.
Setting the repeat: -1
will produces a one time render and repeat: 0
produces loop forever.
const gif = {
export: true,
repeat: 0,
quality: 100,
delay: 500,
};
To see the percentages of each attribute across the collection, run:
npm run rarity
For example, the red glasses has a weight of #10, tricolor glasses has a weight of #2 (which makes them super rare), and the yellow shades has a weight of #5 (which makes them rate). The output looks like this:
...
Trait type: Glasses
{
trait: 'red_frame',
weight: '10',
occurrence: '19 in 100 editions (19.00 %)'
}
{
trait: 'tricolor_glasses_sr',
weight: '2',
occurrence: '2 in 100 editions (2.00 %)'
}
{
trait: 'yellow_shades_r',
weight: '5',
occurrence: '5 in 100 editions (5.00 %)'
}
...
Pixelate.js will take your current images and pixalate them, by running the code below. The pixalated images are stored in a new images folder.
node utils/pixelate.js
Here's a sample:
The images folder was uploaded to Pinata.
We used Pinata to host and upload our images and obtain their CID.
Check out our Solidity Contract.
smart_contract.mov
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
dapp_code.mov
We created a user-friendly interface to interact with the contract. In this web app, the user is able to:
- Check Available CryptoBaras for minting
- Retrieve the cost of a CryptoBara
- Mint
- Retrieve TokenIDs
- Get Metadata for a TokenID
Clone this repository and run our Dapp with the following command:
streamlit run app.py
Here's the finished product:
https://medium.com/@timanovsky/heroku-buildpack-to-support-deployment-from-subdirectory-e743c2c838dd
https://www.youtube.com/watch?v=fzH7Gjadmj0&t=7263s&ab_channel=HashLipsNFT