Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CIP-???? | On-Chain Token Metadata Standard #137

Closed
wants to merge 8 commits into from
Closed
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 218 additions & 0 deletions CIP-0031/CIP-0031.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
---
CIP: 31
Title: On-Chain Token Metadata Standard
Authors: Matt Ho <matt.ho@gmail.com>
Comments-URI: https://github.com/cardano-foundation/CIPs/pull/137
Status: Draft
Type: Standards
Created: 2020-10-12
License: CC-BY-4.0
---

# Abstract

This specification defines a new transaction metadata label (i.e. `20`) and entry for [CIP-0031] to associate token metadata
during a minting transaction. Unlike CIP-28, this proposal is intended to define a specific schema to allow basic information
about fungible tokens to be provided On-Chain.

`20` is proposed as the metadata label in homage to the `ERC20` standard on Ethereum.

# Motivation

The (Cardano Token Registry)[https://github.com/cardano-foundation/cardano-token-registry] is a centralized Off-Chain governance system to manage token
metadata. This proposal aims to provide an On-Chain solution to the same problems that will afford users a much higher degree of trust than the existing
system.

Specifically, this proposal aims to solve for the following:

* Provide a standardized way to associate an icon and a ticker with a token
* Provide a mechanism that allows the viewer to evaluate the trustworthiness and/or authenticity of a token

# Specification

Minters of tokens on the Cardano blockchain main optionally choose to associate the following transaction metadata to facilitate off-chain labeling of tokens.
When doing so, transaction metadata MUST be included in the same transaction that mints the asset id.

> <sub>NOTE</sub>
>
> The following provides an example of the proposed on-chain metadata:
```json
{
"20": {
"<policy-id>": {
"<asset-name>": {
"ticker": "SUNDAE",
"url": "https://dex.sundaeswap.finance/assets/{policy-id}.{asset-name}",
"desc": "SUNDAE",
"icon": "ipfs://ipfs/<ipfs-hash>",
"icon-<size>": "ipfs://ipfs/<ipfs-hash>",
"decimals": 6,
"version": "1.0"
}
}
}
}
```

Field | | Description |
:--- | :---- | :---- |
policy-id | | token policy id |
asset-name | | hex encoded asset name |
ticker | OPTIONAL | when present, field and overrides default ticker which is the asset-name |
url | OPTIONAL | https only url that refers to metadata stored offchain. The URL SHOULD use the project domain and MUST return authenticity metadata in either html or json format (see below) |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would define the project domain 🤔 ? Or more exactly, how a consuming client like a wallet would know what the domain is for a particular metadata. This echoes to the "authenticity metadata" below.

desc | OPTIONAL | additional description that defines the usage of the token |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably it's good to highlight that desc and logo are different form the CF registry

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I accidentally pressed "approve" instead of comment, but I don't oppose this CIP anyway

logo | REQUIRED | MUST be either https, ipfs, or data. logo MUST be a browser supported image format.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mismatch in this table to the examples. Table uses "logo", but examples use "icon".

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed to icon in latest

logo-&lt;size&gt; | OPTIONAL | allows teams to provide icon in different sizes. the recommended values of size are 16, 32, 64, 96, 128. logos are assumed to be square so that logo-64 would refer to a 64x64 logo
decimals | OPTIONAL | how many decimal places should the token support? For ADA, this would be 6 e.g. 1 ADA is 10^6 Lovelace
version | OPTIONAL | when not specified, version will default to `1.0`

> <sub>NOTE</sub>
>
> The following provides an example of the alternate proposed on-chain metadata reference:

```json
{
"20": {
"<policy-id>": {
"<asset-name>": {
"ref": "https://assets.sundaeswap.finance",
}
}
}
}
```

In some cases, it is not practical or desirable to have embed the metadata on-chain. In these cases, this proposal allows the on-chain


Field | | Description |
:--- | :---- | :---- |
policy-id | | token policy id |
asset-name | | hex encoded asset name |
ref | REQUIRED | https only url that holds the metadata in the onchain format (see above). The URL SHOULD use the project domain and MUST return the token metadata as described above


### Authenticity Metadata

To help prevent adversaries from creating fake tokens with the intent to defraud users, projects may authenticate tokens using domains they control. This
mechanism provides users a better understanding of where their tokens came from.

The url provided in the token metadata should return content in either html or JSON format.

* In JSON format, the url should return a JSON block of the same shape as the on-chain token metadata that includes both the policy-id and asset-name to be verified.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a silly question but, if it is required for downstream consumers to query the url provided in the token metadata ... why do we require to include all metadata on-chain in the first place? Wouldn't it be more efficient (space-wise) to only include: (a) a URL, (b) a hash of the expected metadata on-chain, and let client gather other metadata off-chain?

Also, how does one whether a given URL is valid? Do we expect wallets to whitelist some URLs for known tokens?

* In HTML format, the url should contain the a `meta` tag with `name` of `cip-31:authenticate` and a value of a comma separate list of tokens to declare as authenticate where tokens are formatted as `{policy id}{hex-encoded asset name}` with no space in between

## Example 1 - On-Chain Metadata

In this example, we describe a transaction that contains the first minting of an asset, `12345678901234567890123456789012345678901234567890123456.EXAMPLE/P`.
The metadata attached to this transaction is as follows:

```json
{
"20": {
"12345678901234567890123456789012345678901234567890123456": {
"4558414D504C452F50": {
"ticker": "EXP",
"url": "https://example.com/",
"desc": "Example Publisher Token",
"icon": "ipfs://ipfs/1234567890123456789012345678901234567890123456",
"icon-16": "ipfs://ipfs/1234567890123456789012345678901234567890123456",
"decimals": 4
}
}
}
}
```

* `4558414D504C452F50` is the hex encoded form of `EXAMPLE/P`

When I visit, the url, `https://example.com/`, I am returned HTML which includes the following tag:

```html
<meta name="cip-31:authenticate" value="123456789012345678901234567890123456789012345678901234564558414D504C452F50"/>
```

## Example 2 - On-Chain Reference

In this example, we use the same data, but instead construct the metadata as an off-chain reference.

```json
{
"20": {
"12345678901234567890123456789012345678901234567890123456": {
"4558414D504C452F50": {
"ref": "https://assets.example.com/"
}
}
}
}
```

In this example, the `ref` url returns the following JSON encoded content. Note that this URL also contains data for other tokens, but because we know the policy id and the hex encoded asset name of the `EXP`, we can uniquely identify from this list.

```json
{
"20": {
"12345678901234567890123456789012345678901234567890123456": {
"4558414D504C452F50": {
"ticker": "EXP",
"url": "https://example.com/asset.json",
"desc": "Example Publisher Token",
"icon": "ipfs://ipfs/1234567890123456789012345678901234567890123456",
"icon-16": "ipfs://ipfs/1234567890123456789012345678901234567890123456",
"decimals": 4
}
},
"12345678901234567890123456789012345678901234567890123456": {
"123456789012345678": {
"ticker": "OTHER-TOKEN",
"url": "https://other-token.com/",
"desc": "other token included for example purposes",
"icon": "ipfs://ipfs/1234567890123456789012345678901234567890123457",
"decimals": 2
}
}
}
}
```

Unlike the previous example, this example returns a JSON encoded authenticity data as follows:

```json
{
"20": {
"12345678901234567890123456789012345678901234567890123456": {
"4558414D504C452F50": {
"ticker": "EXP",
"url": "https://example.com/asset.json",
"desc": "Example Publisher Token",
"icon": "ipfs://ipfs/1234567890123456789012345678901234567890123456",
"icon-16": "ipfs://ipfs/1234567890123456789012345678901234567890123456",
"decimals": 4
}
},
"12345678901234567890123456789012345678901234567890123456": {
"123456789012345678": {
"ticker": "OTHER-TOKEN",
"url": "https://other-token.com/",
"desc": "other token included for example purposes",
"icon": "ipfs://ipfs/1234567890123456789012345678901234567890123457",
"decimals": 2
}
}
}
}
```

Notice this data is the same data as returned by the `ref` for the on-chain reference. This is intentionally designed to reduce the amount of
boilerplate required to satisfy this CIP.

## Notes

This CIP is intended to handle the common use faced primarily by exchanges as wallets that need to display tokens to their users.
Other standards, like `CIP-25`, the NFT metadata standard, will be more appropriate for handling specialized use cases.

It is not expected nor desired for all tokens to contain `CIP-31` metadata.