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-0048? | NFT metadata references and payloads #249

Closed
wants to merge 37 commits into from
Closed
Changes from 14 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
05f7c34
Introducing CIP-0048? Extended 721 metadata
Jack-0 Apr 21, 2022
01bce73
added forum post
Jack-0 Apr 21, 2022
a2fe0d4
amendments to specification reserved keywords
Jack-0 Apr 21, 2022
c476add
added pseudo code usage example
Jack-0 Apr 21, 2022
3d1b4f4
added external keyword
Jack-0 Apr 21, 2022
c41d545
added external char shortcut
Jack-0 Apr 21, 2022
56bcda6
added comment on references
Jack-0 Apr 21, 2022
07d87d1
proof read changes
Jack-0 Apr 21, 2022
c1988c3
updated CIP-0048.md
Jack-0 Apr 23, 2022
91ce437
updated CIP-0048.md to include fallback option
Jack-0 Apr 23, 2022
2706144
updated CIP-0048.md to include note on duplication
Jack-0 Apr 23, 2022
921e8eb
added a comment on references
Jack-0 Apr 23, 2022
fe506e1
updated CIP-0048.md to use policy and txhash
Jack-0 May 8, 2022
d8d5a30
updated CIP-0048.md grammar
Jack-0 May 8, 2022
2e7420a
Merge branch 'cardano-foundation:master' into master
Jack-0 Aug 27, 2022
827ca7b
refactored CIP48 into two CIPs
Sep 28, 2022
450812c
updated example
Sep 28, 2022
fc06058
CIP48 and CIP49 are seperate CIPs
Oct 2, 2022
6c9bada
reimplemented CIP48 -_-
Oct 2, 2022
2465815
updated CIP48
Oct 2, 2022
594400b
renamed CIP-0048/CIP-0048.md -> CIP-0048/README.md
Oct 2, 2022
aec50fc
updated README.md header
Oct 2, 2022
09b3b10
ammendments
Oct 2, 2022
54b0c63
ammendments
Oct 2, 2022
bc0906a
amendments
Oct 2, 2022
dc16d71
amendments to example
Oct 2, 2022
b7c36ac
merge
Oct 2, 2022
e4a6509
amendments
Oct 2, 2022
2364e8a
amendments
Oct 2, 2022
edf147b
amendments
Oct 2, 2022
4911949
amendments
Oct 2, 2022
b99a0aa
example update
Oct 2, 2022
c0d2aee
updates to handle image tag usage in CIP25
Oct 2, 2022
7bf0859
updates to handle files tag usage in CIP25
Oct 2, 2022
11eedf3
removed files in CIP48
Oct 2, 2022
404279a
behavior duplicated files in CIP25 if multiple refs are defined
Oct 2, 2022
7480cce
noticed txhashes should be an array
Oct 3, 2022
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
141 changes: 141 additions & 0 deletions CIP-0048/CIP-0048.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
CIP: 48?
Title: Extended 721 metadata
Authors: Jack (Pixel pool, https://forum.cardano.org/u/jack7e/, @pixel_pool twitter)
Comments-URI: https://forum.cardano.org/t/cip-extended-721/
Status: Draft
Type: Informational
Created: 2022-04-21
---

# Abstract
This standard proposes a fully on chain method to store and access metadata via the use of references or pointers to data.
This would allow users of 721 to increase or reduce the amount of data stored on chain.

# Motivation
- Large token mints that duplicated data could be dramatically reduced in size by pointing to one transaction payload that contains a ‘boilerplate’ structure.
- 16kB is the upper limit of data in each transaction but If a user wanted more there is no alternative than to store that data off-chain using an external service such as ipfs.
- The use of pointers to data is an extremely powerful tool. For example If a pointer, pointed to pointers you could soon minic something like the ext2 filesystem fully on chain.
- The aforementioned is all currently possible but there is no informational standard.
This CIP aims to describe is a standard so that if a user does want to reduce or increase there metadata size it can be queried by 3rd parties that look for the version 2 tag attached within the 721 metadatum transaction label


Specifically, this proposal aims to solve for the following:

* Provide a mechanism to reduce duplicated metadata into one or multiple transactions that can be referenced
* Provide a mechanism that allows on chain data to be referenced
* Provide a mechanism to reference on chain data in a set order
* Provide a mechanism to reference on chain data stored in a different policy

# Specification
Please note I offer optional single char names to allow futher reduction in metadata size if desired
Copy link
Member

Choose a reason for hiding this comment

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

Avoid first-person voice in CIPs.

Suggested change
Please note I offer optional single char names to allow futher reduction in metadata size if desired
Please note that some tags can be specified as single char names to allow further reduction in metadata size if desired.


*Inside the 721 metadata tag*
|reserved 721 metadata tag |description | example
|---|---| --- |
|references, refs, r | contains data tag and src tag | ```'r':{ "data:"text/plain","src":[0,1] }```|
|payload, p | contains raw data | ```'p':{ "0":["h","e","l","l","o"], "1":"world" }``` |
|version| this is described in 721 | not sure if it should be version 1.1? instead of 2|
Copy link
Member

Choose a reason for hiding this comment

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

Since this is an optional extension of the standard, it wouldn't make sense to use the same versioning scheme as CIP-0025 because there might be other proposed extensions which either conflict or are simply used in total separation from this one. Say we have two mutually exclusive extensions for CIP-0025 with versions 2.1 and 2.2. Now, shouldn't 2.2 implies that 2.1 is also used? What if, no, people just want to use 2.1?

I think CIP-0025 lacks extensibility mechanisms; something that can let new extensions be specified in an additive manner (e.g. an extra field extensions: ['CIP-0048']).


*inside the refences tag*
|tags that are reseved inside references |description | example
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
|tags that are reseved inside references |description | example
|tags that are reserved inside references |description | example

|---|---| --- |
|data| contains the data type MIME | for example if base 64, data:"text/plain;base64"|
|src|contains a list of poitners to payloads | ```"src":[0,1]``` or ``` "src":["payload0","payload1"]```|
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
|src|contains a list of poitners to payloads | ```"src":[0,1]``` or ``` "src":["payload0","payload1"]```|
|src|contains a list of pointers to payloads | ```"src":[0,1]``` or ``` "src":["payload0","payload1"]```|

|policy, p | references another policy. If none, assume current policy | ```'r':{"data:"text/plain","src":{[0,1]},"p":"<POLICY_ID>}"```|
|txhash, tx | references a specific tx hash (optional) | ```'r':{"data:"text/plain","src":{[0,1]},"tx":"<TX_HASH>}"```|
|type | the format/type of the data inside the payload |```'r':{"data:"image/jpeg","src":{[0,1]},"type":"ipfs"```|
Copy link
Member

Choose a reason for hiding this comment

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

What difference is made between data and type?

|b, back, backup | fallback, if a link to the data is used in the 'src' tag and is broken revert to a fallback link. | ```'r':{"src":{[0,1]},"b":{[2,3]}} ``` or for multiple fallbacks use ```'r':{"src":{[0,1]},"b":"{'0':{[2,3]}, '1'{[4,5]} }"``` |
Copy link
Member

Choose a reason for hiding this comment

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

How is a "broken" data defined?


*defintion of the different reference types*
| type | desciption |
|---| ---|
|ipfs|data is stored at ipfs|
|url|data is found a url|
|api|data is found at api get request|
|utf-8| data is directly in payload as utf-8 |
|b64 | data is in base 64 encoded in payload |
|reference? | advance feature, points to a reference |
|none| assume data is raw and using the defined media type |
Copy link
Member

Choose a reason for hiding this comment

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

It seems like each of those types has a precise semantic, what is it?


*?references in payloads could cause issues with circular dependencies, maybe this should be more like inode in ext2 or the depth defined*


```
{
"721":{
"<POLICY_ID>":{
"<NFT_NAME_B16>":{
"project":"<PROJECT>",
"name":"<NFT_NAME>",
"references":{
"type":"raw"
"data":"text/plain"
"src":[
0,
1
]
}
},
"payload":{
"0":["Hello"],"1":["World!"]
},
"version":"2"
}
}
}
```
# Retrieve payload information using references
1. Find all transactions with the 721 label
Copy link
Member

Choose a reason for hiding this comment

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

What is the scope of research here? A block? The whole chain? Should only payload under the same policy be considered?

2. Check the version tag
Copy link
Member

Choose a reason for hiding this comment

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

What should the version tag be?

3. If a payload is found append that to an map or some data structure
4. Given a nft find there references
5. Concatenate the data for all given references
Copy link
Member

Choose a reason for hiding this comment

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

How is "concatenate" defined here? What if the data isn't text or bytes?


### In example
```
nft 0 has the payload "p":{"0":""Hello","1":"World" } and the references "r":[0,1]
nft 0 == "HELLOWORLD"
```
```
nft 1 has no payload and the references [0]
nft 1 == "HELLO"
```
```
nft 2 has no payload and the references [1,0] (note the order)
nft 2 == "WORLDHELLO"
```

### Pseudo code

to get the metadata from payloads
```
for each transaction within the policy
if metadatum tag is '721'
if 'payload' or 'p' in json['721][<POLICY_ID>]
for payloads in ['721][<POLICY_ID>]['p']
for refrenceName, data in payload
add data with referencename to datastructure
```


to build the metadata for each nft
```
refs = json['721'][<POLICY_ID>][<NFT_NAME>]['references']['src']
dataType = json['721'][<POLICY_ID>][<NFT_NAME>]['references']['data']

for ref in refs
nft data += data from datastrucure indexed with ref
```

# Backwards compatibility
Used the version tag described in CIP 25.

# Further considerations
### References
If we wanted to add more powerful referencing we could allow for references to references
```"payload":{"r":{"src":{[98,99]},"policy":"<POLICY_ID>}"}}```
*Like a block of pointers in the ext2 filesystem*
### Duplicate data
There could be issues with duplicate payloads. The solution I propose is just to use
the latest version of that payload.