CIP extended 721
Hello, I have been working on a new extended standard for the informational CIP 25. I would love to get some feedback!
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
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 |
inside the refences tag
tags that are reseved 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"]
|
policy, p | references another policy (optional). Default (if none) is 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" |
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]} }"
|
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 |
?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
- Find all transactions with the 721 label
- Check the version tag
- If a payload is found append that to an map or some data structure
- Given a nft find there references
- Concatenate the data for all given references
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]},"p":"<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.