Hey everyone!
I’m trying to form a metadata standard for NFTs with this proposal. Let me know your thoughts about this approach.
Motivation
Tokens on Cardano are a part of the ledger. Unlike on Ethereum, where metadata can be attached to a token through a smart contract, this isn’t possible on Cardano because tokens are native and Cardano uses an UTxO ledger, which makes it hard to directly attach metadata to a token.
So the link to the metadata needs to be established differently.
Cardano has the ability to send metadata in a transaction, that’s the way we can create a link between a token and the metadata. To make the metadata unique to the token, they should be appended to the same transaction, where the token forge happens:
Given a token in a EUTXOma ledger, we can ask “where did this token come from?” Since tokens
are always created in specific forging operations, we can always trace them back through their
transaction graph to their origin.
(Section 4.1 in the paper: https://hydra.iohk.io/build/5400786/download/1/eutxoma.pdf)
Considerations
That being said, we have an unique metadata link to a token and can always prove that with 100% certainty.
My assumption is now that, with the upcoming explorer APIs for multi assets it should be possible to find the forging transaction of a token by simply providing the Policy ID and the token name, in order to get the right metadata.
EDIT:
I just found the SQL DB Schema in the db-sync repository, it has a table, that confirms my idea actually works:
CREATE TABLE public.ma_tx_mint (
id bigint NOT NULL,
policy public.hash28type NOT NULL,
name public.asset32type NOT NULL,
quantity public.int65type NOT NULL,
tx_id bigint NOT NULL
);
With SELECT tx_id FROM ma_tx_mint where ma_tx_mint.policy = <“policy”> AND ma_tx_mint.name = <“name”>
I can get the forging transaction by only providing the Policy-ID and the token name.
Specification
This is the registered transaction_metadatum_label
value
transaction_metadatum_label | description |
---|---|
721 | NFT Metadata |
There are two different ways, how the metadata structure can be defined. One makes more use of the Cardano blockchain and the other is a more offchain approach. For both approaches we mint the example NFTs with:
Policy-ID: cbc34df5cb851e6fe5035a438d534ffffc87af012f3ff2d4db94288b
Names: nft0, nft1, …
On-Chain Approach:
{
"721": {
"cbc34df5cb851e6fe5035a438d534ffffc87af012f3ff2d4db94288b": {
"nft0": {
"id": 0,
"name": "NFT 0",
"image": "ipfs://ipfs/<IPFS_HASH>",
<other properties>
},
"nft1": {
"id": 1,
"name": "NFT 1",
"image": "ipfs://ipfs/<IPFS_HASH>",
<other properties>
}
...
}
}
}
Off-Chain Approach:
This could be useful, when creating a lot of NFTs or the metadata entries for a single token are big in size, were it would be too expensive to do everything on-chain.
{
"721": {
"cbc34df5cb851e6fe5035a438d534ffffc87af012f3ff2d4db94288b": {
"offchain": "ipfs://ipfs/<IPFS_HASH>"
}
}
}
Fetching the link from the offchain property will give you back a json file of this format:
{
"nft0": {
"id": 0,
"name": "NFT 0",
"image": "ipfs://ipfs/<IPFS_HASH>",
<other properties>
},
"nft1": {
"id": 1,
"name": "NFT 1",
"image": "ipfs://ipfs/<IPFS_HASH>",
<other properties>
}
}
Since we have the policy and the token name, it is a quick and exact lookup in the metadata map for a specific token to get all the properties needed.
Ipfs is the preferred way to where fetch data from. Reason one is to keep everything decentralized/immutable and reason two is, that the hash is always fix in size and you can be assured that you always stay below the maximum of 64 bytes for a string (http/https is of course also an option).
These approaches also work with batch transactions, where tokens are not only forged in a single transaction, but in multiple.