Everyone is talking about Bored Apes, CryptoPunks, and Azuki, but have you ever wondered how they were created? This article might help answer that question.
Below is an overview of what we will do:
git clone[git@github.com](mailto:git@github.com):HashLips/hashlips_art_engine.git
npm install
index.js
script selects a random image for each attribute, e.g. background, eye color etc found in the layers
folder and merges them into a single asset. Run npm run generate
to output the art in the build/images
directory.build/images
folder we created above. Copy the CID value.config.js
in the art engine project, update the following values:
namePrefix
, the prefix of the NFT name, e.g. for Azuki #1, Azuki is the namePrefix.description
, the description of the NFT collection.baseUri
, the base IPFS uri which references to the material you have uploaded using Pinata, and it will look something like ipfs://<IMAGES_FOLDER_CID>
, e.g. ipfs://QmeoAsjESagveRXyZYENYZHMAskWSWqwqVWfNuAp42yKrS
npm run update_info
. This updates the JSON files in build/json
.MyNFT.sol
file in the contracts
folder.NFTLowerGas.sol
from my repo. This file is adapted from SimpleNftLowerGas.sol
from Hashlips. The main difference is I removed the hidden functionality, e.g. a placeholder is shown instead of the original NFT image until the collection owner chooses to reveal the images. Removing the functionality reduces the friction during the development and deployment process.MyNFT.sol
, rename the contract name from NFTLowerGas to MyNFT. Matching the file name against the contract name is a best practice.MyNFT.sol
.Deploy & Run Transactions
tab, choose the Injected Web3 environment and select the MyNFT contract._NAME
is the name of the ERC721 token._SYMBOL
usually abbreviates the _NAME
, e.g. the symbol for Bored Ape Yacht Club is BAYC._URIPREFIX
is the IPFS uri that points to the JSON folder we uploaded, e.g. mine is ipfs://QmbUT1yg2BNhwV1r7h9vgDusjXh7mpvjfyX7JBPjUMpJ7H/
, it’s the CID points to the JSON folder, and it’s important to include the /
at the end.setPaused
function with the input value of false
.mint
function, remember to specify the _mintAmount
, e.g. 2.Note: the MetaMask dialog will show every time we make a transaction. Make sure we are on the test network so we don’t spend any real ether.
We could customise some important values in the JavaScript files and the smart contract. Here I will briefly mention that we could set the rarity of each attribute of the NFT, e.g. if we look at the layers/Eyeball
folder, we have two files, Red#50.png
and White#50.png
, an equal chance of the image having either a red or white eyeball. You can see more in README.md of the art engine project. Some examples for the values we can customise in the smart contract are cost
(the price of minting one NFT), maxSupply
(the total number of NFT available) etc.
To recap, we have generated some art images with JavaScript by combining the assets that someone has already designed and made for us. We uploaded the generated artwork and the JSON metadata to Pinata Cloud. Finally, we deployed a Solidity smart contract on the Ropsten testnet to mint our NFTs. We can view those NFTs easily on OpenSea. I hope this tutorial was helpful, and I’d love it if you could share it with others so more people can benefit from it.