Metadata

Metadata

Introduction

Description

The basic idea of metadata is to add data to smart-contracts about the smart-contracts themselves. That data can then be used off chain for a variety of purposes:

  • LIGO (or any other high level language) source code and the version of the compiler used to compile it
  • The type of contract (is it an FA 1.2? some permission scheme brick?)
  • The author of the contract (possibly for legal reasons)
  • Ways to interact with the contract
  • Other things that I do not have in mind

We want this data to be reliably available offchain, to be common knowledge, and easy to add for smart-contract developers.

Other kinds of metadata

Many readers may find other popular forms of metadata conspicuously missing:

  • For example, this post does not concern itself with linking to a Wiki where people can add data related to a contract
  • It also does not concern itself with metadata that can be accessed on chain by other contracts

Implementation

Metadata Registry Smart-Contract

The first way to implement contract metadata is through a registry smart-contract. Basically, we could have a registry smart-contract store a big-map. The keys would be addresses of smart-contracts, and the values the actual metadata. This registry would assert that only SENDER with a matching address can update the value at a given key.

There are two problems with this approach:

  1. Developers have to add logic within the smart-contract to deal with the registry. Concretely, they would need to add an entrypoint to the contract, that would then query the registry contract, assert that the caller is the originator of the contract and possibly close this entrypoint some time after the origination of the contract (to avoid the creator of the contract unexpectedly changing this data). This makes the development process much harder than needed.
  2. Tools and developers must coordinate on using a particular metadata contract. This makes creating common knowledge much harder than needed.

Amendment

The other way, that I personally prefer (for now), is to make an amendment to Tezos. The idea is that, when originating a new smart-contract, one could simply attach metadata (a regular JSON object) to it. Some fields could be standardized on-chain (such as the ones mentioned in the intro), or standardized as we see more and more usage of some fields.

The advantages of this approach is that there is no need to add logic within the smart-contract to deal with metadata, and the common knowledge + agreement about the place where one should expect to get metadata comes straight from the governance process of Tezos.

Storage

An additional concern is whether the meta-data should be stored on chain or off chain. And if it is stored off chain, should the chain hold a hash, or/and a URI to the data.

I believe that right now, it is simply much easier to store things onchain. Once we have a resilient way to reliably link offchain data from the chain (e.g. having all the Tezos nodes participate on some IPFS realm dedicated to Tezos), I will likely change my mind and prefer to put things offchain. By then, putting stuff onchain would likely be an unnecessary burden.


As always, if you are interested in contributing to such an amendment, feel free to contact me! I’d gladly introduce you to the code base.

3 Likes

If you want this to work for contracts programmatically originated, the metadata should be a Michelson value (possibly packed into bytes) and not a JSON value.

Rather than store it in chain, you can treat it as an event. Archive nodes will keep it, some will choose to discard it.

1 Like

If you want this to work for contracts programmatically originated, the metadata should be a Michelson value (possibly packed into bytes) and not a JSON value.

Michelson values are not fit for such things. One can get away with not having variants, but not with not having records.

The concern is valid, and can be solved in a number of ways:

  • Extend Michelson with JSON
  • Use a regular string for the JSON
  • Extend Michelson interfaces with records

Rather than store it in chain, you can treat it as an event. Archive nodes will keep it, some will choose to discard it.

You are right, archive nodes are also a way to store data. To be honest, I am not clear on the trade-offs of the different alternatives (anarchy, IPFS, archive nodes, etc.). It might deserve its own post.

The first way to implement contract metadata is through a registry smart-contract.

The first way to implement contract metadata is to simply put the metadata in the contract’s own storage.

The most obvious problem with this is that the contract will end up uselessly paying for the metadata on every execution. (A side benefit is that the contract can update its own metadata if desired.)

This problem can be addressed by putting the metadata under big_map unit or by hypothetical “lazy storage” magic.

So, why do we need an amendment?