How to store your NFT metadata

Rahul Ravindran

I will be addressing these issues in this article. More specifically, we will show you how to:

  1. Upload Images to IPFS
  2. Generate compliant JSON NFT metadata
  3. Upload metadata files to IPFS

Don’t worry if some of these words don’t make sense right now. I will be explaining them as and when required.

How NFT Minting Works

Mekaverse NFTs

To understand why we’re doing what we’re doing, we need to understand how NFT minting works. If you know this already, feel free to skip this section.

Let’s say you want to mint a collection of 10,000 NFTs. What does that really mean?

This means that you’re writing some code (called a smart contract) that tells the blockchain to initialize a table for you. This table stores ownership and metadata information about your NFTs. More specifically, each row of the table consists of the following information:

  1. The Token Identifier (or ID)
  2. The Owner of the Token
  3. The Metadata associated with the token

Here is an example table:


You can see here that the ID is nothing but a unique positive integer that identifies a particular NFT. The Owner column stores the addresses associated with each NFT’s holder. Finally, the Metadata is a column that may contain data of the NFT or about the NFT.

It is possible to store the entire image in the Metadata column of the table. However, storing data on a blockchain is expensive. To give you some context, our collection of 10,000 squirrels occupies a disk space of 600 MB. If we wanted to store 600 MB worth of data on the Ethereum blockchain, it would cost us $1 million dollars.

This is clearly not a great option. Therefore, in most cases, instead of storing data of the NFT, we instead simply store data about the NFT. This data (or metadata) is stored in a format called JSON. If you don’t know what JSON is, don’t worry about it. For our purposes, think of them like Python dictionaries (encapsulated in {}) that you encountered in the previous article to define layers.

This JSON file needs to have information about the NFT such as its name, description, image URL, attributes, etc. In order to make sure that everyone in the ecosystem (including NFT marketplaces like OpenSea) understands what’s in our JSON files, we need to format them in a way that is compliant with the standards. In our case, we will use the standards recommended by OpenSea.

Here is a JSON metadata file for a sample NFT.


   "description": "Friendly OpenSea Creature",      
   "image": "https://opensea-prod.appspot.com/puffs/3.png",  
   "name": "Dave Starbelly",   
   "attributes": [
       { "trait_type": "Base", "value": "Starfish" },      
       { "trait_type": "Eyes", "value": "Big" },      
       { "trait_type": "Mouth","value": "Surprised" },

Storing metadata in this format on the blockchain is still very expensive. Hence, we add an additional layer of abstraction, and upload this JSON to the cloud as well and simply store a URL pointing to the JSON file.

Therefore, at the end of the data, all you’re storing on the blockchain is https://mywebsite.com/my-nft.json.

To summarize, here is what we need to do:

  1. Upload all our images online and get a URL associated with each image. (This URL will go into our metadata).
  2. Generate a separate JSON file for each image containing metadata in the standard shown above (Image URL, attributes/traits, name, etc.)
  3. Upload all the JSON files to the cloud and get a URL associated with each JSON file.

Uploading Images to IPFS


Uploading images to the internet is pretty simple. We’re sure you must have used a service like Google Drive, GitHub, or AWS to upload folders to the cloud.

While uploading images to such centralized services (AWS, Google Drive, your own server, etc.) would work, it would not be a very good idea.

Why not? For two reasons, mainly.

Centralized Storage tends to be location based

Imagine you upload an image of a dog (called dog.jpeg) to a centralized storage service. Your dog image would then be available by accessing a URL (something like https://mystorage.com/dog.jpeg).

However, it is very easy to swap this image for another. I could upload another image with the same name (dog.jpeg) that replaces the original image.

Now, if I visited the same URL as before (https://mystorage.com/dog.jpeg), I will see a different image. You can see why this is not ideal in NFT world. People spend thousands of dollars on NFTs and they would be pissed if you simply replaced an avatar with extremely rare traits with something else.

Centralized Storage can be taken down

Let’s say you upload an image to a Google Drive or AWS. If you removed the image from these services or the services themselves shut down, the URL pointing to the image would break. Therefore, it is very easy to pull the rug if your images and data exist on a centralized storage service.

For these reasons, almost every serious NFT project uses a service called IPFS (or Interplanetary File System).

IPFS is a peer-to-peer filesharing system that is decentralized, uses content-based addressing, and is secure.

If none of the words above make sense, don’t worry. All you need to know is this:

IPFS used content-based addressing

On the IPFS network, the address (URL) of a file will be dependent on the content of the file. If you change the contents of a file, then the address of the file on the IPFS will also change.

Therefore, on the IPFS network, it is impossible to make one URL point to two different images.

IPFS never goes down

Like most decentralized systems (like blockchains), IPFS never goes down. This means that once you’ve uploaded a file (or image) to IPFS, it will always be available as long as at least one node in the network has the file. This means that you cannot pull the rug at will. Nor is there a threat that the system will be shut down.

We’re not going to go into the nitty-gritties of how IPFS works. If you’re interested, we suggest you give the following two articles a read:

  1. https://hackernoon.com/a-beginners-guide-to-ipfs-20673fedd3f
  2. https://docs.ipfs.io/how-to/mint-nfts-with-ipfs/#a-short-introduction-to-nfts

Uploading to IPFS is as easy as uploading to Google Drive, thanks to a service called Pinata.

Go to the Pinata website and create an account. It’s free if you’re uploading up to 1 GB of data.

Once you have signed up, you will be taken to the Pin Manager window. Upload your folder using the interface. Once you’ve uploaded your folder, you will get a CID associated with it. It should look something like this.

Pinata screen

This CID was generated based on the contents of the folder. If the contents of the folder change (an image removed, an image swapped with another of the same name, etc.), the CID will also change.

For my folder, the CID is QmRvSoppQ5MKfsT4p5Snheae1DG3Af2NhYXWpKNZBvz2Eo.

Therefore, the IPFS URL for this folder is ipfs://QmRvSoppQ5MKfsT4p5Snheae1DG3Af2NhYXWpKNZBvz2Eo.

This URL will not open in a browser. In order to do that, you can use a HTTP URL of an IPFS gateway. Try visiting this link: https://ipfs.io/ipfs/QmRvSoppQ5MKfsT4p5Snheae1DG3Af2NhYXWpKNZBvz2Eo/00001.png

This will display an image that I named 00001.png and uploaded to my folder.

Congratulations! That is all there is to uploading images on IPFS using Pinata. For the next step, you will need the CID. Keep that handy.

Generate compliant NFT JSON metadata


Since we uploaded our images to IPFS, we now have IPFS URLs for each and every image.

Our next task is to create a JSON file for each image and populate it with data (including the image URL) in a format that is compliant and understandable by platforms like NFT marketplaces.

Fortunately, the generative-art-nft library does all the heavy lifting for you.

Check that the metadata.py file exists in the repository. If not, clone the latest version of the repository and transfer the assets and output folders into the new repo.

Open the metadata.py file in a text editor. Don’t worry if you don’t understand the code here. The only things you need to fill are BASE_NAME, BASE_URL, and BASE_JSON.

In line 17, replace ←Your CID Code → with the CID code of the image folder you uploaded to Pinata.

In line 18, add a base name for your NFTs. This is strictly optional. If you do not add a base name, your NFTs will be named 0, 1, 2, and so on. If you put a base name like “Scrappy Squirrel #”, your NFTs will be named Scrappy Squirrel #0, Scrappy Squirrel #1, etc.

Finally, in line 22, add a description for your collection. Like the base name, this is optional.

Sample inputs

Now, open a Terminal in this folder and run the following command.

python metadata.py

The program will ask you the edition to generate metadata for. In our case, it was v2, so that’s what we enter.

It should take less than 15 seconds to generate 10,000+ JSON files. All these files will be conveniently available in a json folder within your edition folder.

That’s it for step 2!

Upload JSON metadata files to IPFS

The third step is probably the simplest. Just like you did with the images, upload your json folder to Pinata.


Congratulations! You now have a very good setup for your NFT metadata. The last and most important step is to write a smart contract that can use this metadata and assign ownership to various holders. That is, however, a topic of a future article. Stay tuned!

1 Comment

  1. Marina
    July 26, 2022

    Hi, nice to meet you. My name is Marina Paleo, I am Media Foundation CMO. I want to get in touch with Eat The Blocks in order to explain more about the first decentralized content delivery network (dCDN). Thanks!

Leave a Reply

More great articles

Getting Started With Hardhat Smart Contract Framework

Hardhat is a new smart contract framework that is gaining popularity in the past year. It makes development and debugging…

Read Story

Creating a new Contract from another Contract in Solidity

Introduction In blockchain development, mining sets of data into a blockchain is quite an expensive process because fees are charged…

Read Story

Top Visual Studio Plugins for Web3 and Blockchain Development in 2022

Although web3 development tools are still pretty new as compared web2 there are some pretty nifty VS code plugins that…

Read Story

Never miss a minute

Get great content to your inbox every week. No spam.
[contact-form-7 id="6" title="Footer CTA Subscribe Form"]