EasyAsset is a wonderful service for building NFTs on Bitcoin/Counterparty.
However, I’m bothered by the URL format:
It is not immutable. I suggest changing it to something like this:
This URL contains a hash. It makes the NFT permanent.
Why it Matters
EasyAsset repeats an old mistake made by Monegraph in 2014.
Like many modern NFTs, MGAAAAAAAAAAA‘s metadata is a link to a json file. Open it and you may see this:
While the content of the json looks good – even by modern standards – the fatal mistake is lack of onchain metadata to verify the data.
All I can be certain of is that in 2014 the asset’s metadata was a URL;
static.mccoyspace.com/mgaaaaaaaaaaa.json. And that this URL currently returns the above json data.
We have no way of telling whether the data we see today is the same as it was in 2014.
EasyAsset URLs face the same issue.
My suggestion is to put the json file’s hash inside the URL. In the example
easyasset.art/j/24lf1HKGp_V3q5Jj5lMx.json, the hash equates to
24lf1HKGp_V3q5Jj5lMx. This is the sha256 hash of the json file.
The URL is the asset’s onchain metadata (engraved on the bitcoin blockchain). It can never be erased or modified*. The timestamp is also tamper-proof.
When someone in the future opens the URL, and the hash matches, they can can be certain that the asset is the same as the original. This is what we mean by immutable.
Even if the URL dies, anyone with a copy of the file can recreate the token – meaning the URL itself should be thought of as a temporary pointer. The hash is the permanent address!
In case EasyAsset does not implement the fix, you can easily enough make your asset immutable. I can think of two ways:
- Make your NFT with EasyAsset. Copy the json file, change the file name to its hash, and serve it from your own domain. E.g.
mydomain.com/24lf1HKGp_V3q5Jj5lMx.json. Please double-check the hash after you’ve uploaded it. I messed this up with XDP OLGA at first because the FTP uploader was not set to binary.
- Alternatively, use EasyAsset as before, and then make a broadcast from the issuer address. Format:
Notice that for the most efficient op_return encoding, asset descriptions must be maximum 52 characters. Broadcast texts should be no longer than 54.
The Geeky Details
The hash from my example (
24lf1HKGp_V3q5Jj5lMx) is the sha256 checksum truncated at 120 bits and represented as Base64url.
Sha256 is the most common hashing algorithm.
Base64 contains 6 bits of info per character, versus 4 bits for hex, in an ascii text field. Therefore more compressed.
Base64url is a the same as Base64 except
/ are replaced by
_ to make it suitable for filenames.
Truncating the hash is advisable so the asset issuance can fit op_return. A full hash would work too, but a less efficient and more expensive Bitcoin encoding would be used. Technically, also a full arweave link would work with Counterparty, but a soft limit of 200 chars in FreeWallet prevents this.
A 120-bit hash is extremely strong. Theoretically, finding a collision is similar to mining bitcoin blocks. After more than a decade, with millions invested in ASIC hardware and the energy consumption of a small nation, the best collision is at 92 bits. With your NFT protected by 120 bits, it is a whopping 26 million times stronger (simplified to show the point.)
I put the hash of the json file onchain, while the image hashes are inside the json file. Such modularity makes it easier for wallets, explorers, archivers, etc to verify and backup the parts of the NFTs they care about. For example, when I archived Dogeparty and Counterparty in 2022 I only backed up images under a certain file size. With modular json and file hashes, immutable NFTs are still preserved minus any HD images (which collectors should save on multiple thumb drives).
The issuer of an asset can at any time update the metadata. (The only way of permanently locking it would be to send the issuance right to a burn address, like I did with SALVATION.)
Still, an update will not erase former descriptions. It stays forever as part of the asset’s history. An immutable json link is thus forever an immutable, timestamped part of the token.