Meta, meta, meta... METADATA!!

All I see is dark brown trunk, light brown trunk, silver.

Meta, meta, meta... METADATA!!
Photo by Markus Spiske / Unsplash

I should start by saying that none of this post is a recommendation for how to do something. It's simply how I did the metadata for Ether Tree. Probably lots of better ways to do this, and it might not translate well (or at all) to a larger collection. But, this is what I did...

What is metadata?

Metadata is data that provides information about other data.  You can maybe think of it as a description, which is one class of metadata. For our purposes here, I am referring to the descriptive information about individual tokens in an NFT collection. Whether your wassie has duck feet, or your ape has a captain's hat, or your lion is blowing a big bubble. That's all metadata.

In a strange way, you can think about it as your NFTs DNA. The metadata is it's genotype, the image itself is its phenotype. (Geneticists in the house say "HAY!", and tell me your favourite nucleic acid. Mine's Thymine).

Derp has a 'blep' mouth. It's all in his metadata.

That's all on chain with the NFT, right?

Nope. If we are talking about Ethereum (and I am), data storage is very expensive. That's because the chain has to carry that data around forever to every node. If you wanted to store all that metadata on Ethereum it would cost a literal fortune!

What we store on Ethereum is a token URI (unique resource identifier) that points off the main chain to the metadata. In almost all cases (but not all) this URI points to a URL. That URL resolves to a JSON file that has all the juicy metadata in it, and that in turn resolves to the location of the all important image associated with the NFT.

Ah, but I hear you say, if that's just coming from a URL what if it changes? And you are right to ask that. It has happened (see this example, which appears to be making a point rather than being outright malicious).

There is a solution though, with two main approaches. One is to load the data onto the InterPlanetary File System (IPFS). (While we are here, I am still not convinced by the 'Inter' there, pretty sure this is all still just on earth...). That's a peer to peer data sharing system that persists data forever. The other option is a different blockchain that achieves the level of permanence and decentralisation of Ethereum but at a much much lower cost. An example is Arweave, and it's Arweave I used for Ether Tree.

IPFS - not available on Mars

But wait!

I'm getting ahead of myself. Before we talk about storage, let's talk about how I made the metadata in the first place. Being cutting edge I used the latest tech.

A spreadsheet.

Excel to be precise (hey, who you calling boomer?!). I created a spreadsheet with six columns, the first being the token IDs 0 to 99, then five columns for the traits. Into this spreadsheet I created the range of traits I wanted. I actually did it this way around, creating the range of traits first on a spreadsheet, before making all the individual images.

Arweave

Next I needed to get all 100 images somewhere permanent, so you can own an Ether Tree and never be worried the image will turn into a cat pic or something. To do that I created a directory with all the images in, identified 0.png through to 99.png. I then bought some Arweave token and uploaded the assets to the Arweave chain using a command line tool call arkb. I'll post more on that another time if anyone asks.

That then gave me a URL for that folder of resources, and meant I can get to the image with that URL then '/0.png' (for example).

Metadata!

Back to my spreadsheet, and I can now put the image URL in for each token. To create the JSON output I looked at some scripting solutions, but in the end just wrote my own excel formula to concat the JSON string into existance. This is that formula:

=CONCATENATE($X$2,$X$3,$K$1,$X$3,$X$4,$X$3,K2,$X$3,$X$5,$X$3,$M$1,$X$3,$X$4,$X$3,M2,$X$3,$X$5,$X$3,$N$1,$X$3,$X$4,$X$3,N2,$X$3,$X$5,$X$3,$O$1,$X$3,$X$4,$X$3,O2,$X$3,$X$5,$X$3,$P$1,$X$3,$X$4,$X$6,$X$7,$Q$1,$X$3,$X$5,$X$8,Q2,$X$3,$Y$2,$X$5,$X$7,$R$1,$X$3,$X$5,$X$8,R2,$X$3,$Y$2,$X$5,$X$7,$S$1,$X$3,$X$5,$X$8,S2,$X$3,$Y$2,$X$5,$X$7,$T$1,$X$3,$X$5,$X$8,T2,$X$3,$Y$2,$X$5,$X$7,$U$1,$X$3,$X$5,$X$8,U2,$X$3,$Y$2,$Y$6,$Y$2)

Feel a little sick right now, dontcha?

There are more elegant ways to do this (but possibly not less elegant ways). Like I said, this post isn't a recommendation, just how I did it.

I then copied those 100 JSON strings into their own text files, called n.json (n being the token ID). Then back to Arweave, and upload that folder with those json files.

I now have a URL from Arweave that when appended with the tokenID.json will return the metadata for the token, and from there the image and wonderful trait data for your tree. All that is left for me to do it add that URL as the base token URI in my contract and we are meta meta meta metadone!

Still there friend? Want to here about the NFT contract, and The Forest, and Yellow Bird's nest? What, not even a little bit??