Contract Metadata on Tezos

Introduction to TZIP-16

Developers on Tezos have increasingly been adopting and testing smart contracts based on the token standards FA1.2 (TZIP-7) and FA2 (TZIP-12). As more contracts are deployed, the importance of indexing and discoverability has increased as wallet integrators look for scalable ways to support tokens and contracts generally.

In this post, we briefly introduce TZIP-16: a standard for accessing contract metadata in JSON format in on-chain storage or off-chain using IPFS or HTTP(S).

The goal of TZIP-16 is to provide a standardized location and shape of contract metadata, easing the integration, discoverability and querying of Tezos smart contracts for applications, explorers, and wallets. It enables developers to focus more on product development and less on questions of how to integrate with wallets and external parties (e.g. wallets).

To enhance the experience, we also introduce TZComet, a still-in-development editor, validator, and explorer for contract metadata on Tezos.

And we’ve created this merge request to add sub-commands to display and use contract metadata in tezos-client according to the standard.

A special thanks to TZIP-16 reviewers: Baking Bad, Kukai, Spruce, SmartPy, Marigold/LIGO, Tezos Domains, Arthur Breitman, ECAD Labs, Serokell, Cryptonomic, Nomadic Labs, and Archetype for feedback on TZIP-16!

Key Resources

Standardizing Contract Metadata

Many smart contracts need to define metadata that is not included in the contract script, whether corresponding to the contract code itself (e.g. to reason about the contract’s behavior, interface, storage, etc.) or how it relates to off-chain data (e.g. a token representing artwork).

TZIP-16 proposes a method of finding specific metadata about the contract: provenance information (authorship), references to other implementation standards, off-chain views (Michelson functions or REST API calls to query the contract), and enables developers to create their own custom extensions (e.g. a multimedia metadata extension).

This metadata is described using a JSON format and a URI scheme is used to locate the metadata, whether on-chain (as in contract storage) data or off-chain (as in web-services or IPFS).

By adopting this standard, smart contract authors and wallet/indexer implementers can agree on both the location and contents of a contract’s metadata.

TZComet: A Playground for TZIP-16

Developers should be able to try out the TZIP-16 standard, which is why we are introducing TZComet, a contract metadata viewer for Tezos. As displayed below and on github, TZComet contains Metadata JSON Validation, URI Validation, and a Michelson PACK Parser. It will confirm whether the metadata/URI of a contract is valid and if a contract can be parsed by Michelson (the Tezos smart contract language).

Integration with Tezos-client

In order to make using TZIP-16 more fluid, we’ve created a draft merge request to integrate it directly into the tezos-client. It’s important to note that in its current state, this is not yet included in the main Tezos repository. The integration will enable a user to retrieve metadata for a contract and additionally call off-chain views.

The Future of TZIP-16

Next on the horizon, is a focus on applying TZIP-16 to popular smart contracts (especially in token API TZIPs such as TZIP-7 and TZIP-12) and extending TZIP-16 by specifying off-chain events (perhaps in its own TZIP) as well as multi-contract off-chain views, which are off-chain-views defined over more than one contract’s storage.

As noted, TZIP-16 provides a path forward on off-chain events, a common request from those indexing Tezos smart contracts and especially tokens. Such events include tracking all token transactions and providing token balance receipts, giving holders the ability to at any time a) queue balances and b) predetermine the outcome of a complicated transaction.

As with prior releases, we actively welcome feedback on TZIP-16, particularly as we and others in the community work to implement it for tokens and other popular applications. Reach out if you’d like to get involved!


Good work, it will be very useful.

I’m a little skeptical about the fact that we need to put a bytes encoded json variable for the on chain metadata usage. I’m not against the idea but I’d like an alternative: be allowed to reference storage data as a metadata without having to encode them in a different way that we would do if it were not a metadata.

For example, I would like to be able to manage the contract name or version on chain without having to encode/decode and still having those info indexed like other metadata.

1 Like

Once you decide to put the metadata on-chain, bytes is kinda the only type we can use; Michelson strings are too restrictive (only printable ASCII), see
Also note that BCD displays bytes when they are small enough (right now the threshold is pretty small though):

That’s why I proposed it as an alternative. If you need to use bytes you can use them. If your use case is simple enough - like updating a version number - it would perhaps be nice not having to deal with onchain concat and encoding.
The drawback is an increase complexity of the specification of the TZIP and its implementation for indexers but I think it is worth it because it simplifies smart contract developers life.

This is an excellent idea. One suggestion I’d make is to add an error map. This would be a registry of obtuse error IDs to human-readable error messages and potentially resolution suggestions. This would also make contract deployments nominally cheaper since you can simply index errors by number instead of attempting to abbreviate something vaguely detailed into as few characters as possible.

1 Like

Cool tracking there: