└── Readme.md /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # InterPlanetary NFT Extensions (IPNFTX) 4 | 5 | 6 | ## Simple Summary 7 | 8 | A standard interface for non-fungible token _overlay_ data, expressed as a set of statements in form of `(entity, attribute, value)` tuples. 9 | 10 | ## Abstract 11 | 12 | The following standard allows for the implementation of a standard API for providing _overlay data_ for NFTs within smart contracts. This standard provides a basic functionality for publishing, tracking and indexing information associated with NFTs. 13 | 14 | > Just as anyone can make statements about things in the physical world we aim to enable any actor on the network to make statements about specific NFTs on blockchain, regardless of their owner or contract origin. Just as in physical world individuals choose who's statements to consider any actors can choose which sources (contracts) and on what subject (attribute) to track / index. 15 | 16 | We consider use case for NFTs in which they are entities that anyone on the network (regardless of their ownership) can publish statements about in form of (entity, attribute, value) forming open informational graph of [entity, attribute, values][EAV] similar to [RDF][]. Of course, the contract/owner of an NFT can use this protocol to provide data about their own NFT's, but the system is not limited to this in the same way that anyone on the Web can link to any website. 17 | 18 | We aim at enable additional layers of functionality on top NFTs in an open ended, yet interoperable manner with little to no coordination. 19 | 20 | ## Motivation 21 | 22 | A standard interface for overlay data for NFTs allows extending NFTs in manner which: 23 | 24 | 1. Upholds NFTs immutablity guarantees. 25 | 2. Allow arbitrary actors to extend NFTs. 26 | 3. Protocol Extensions require little or no coordination (multiformats). 27 | 4. Protocol Extensions are interoperable (multiformats) / conflict-free (append-only onchain events). 28 | 29 | 30 | This standard is inspired by [Datomic Data Model][] and [Resource Description Framework (RDF)][RDF]. 31 | 32 | #### Examples 33 | 34 | ##### Associating CID with NFT 35 | 36 | https://nft.storage service archives NFT assets on IPFS & filecoin, yet there is no good way to associate those [CID][]s to corresponding tokens. 37 | 38 | ##### Preview images 39 | 40 | TODO: Scaled preview images for NFTs. 41 | 42 | ##### IPNS 43 | 44 | TODO: Map NFT to a CID to represent mutable content 45 | 46 | ## Specification 47 | 48 | The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119. 49 | 50 | **Every NFT-AV contract must implement the NFTAV interface** 51 | 52 | ```solidity 53 | interface ERC721 { 54 | /// Event adds or retracts relation between 55 | /// - entity (NFT identified by `contract address`, 56 | /// `uint256 tokenId` pair) 57 | /// - attribute (multiformat value describing a 58 | /// relation) 59 | /// - value (value for the attribute) 60 | /// 61 | /// A boolean `op` indicates whether relation is 62 | /// added or retracted 63 | event IPNFT( 64 | uint256 source_id, // NFT tokenId 65 | bytes entity, // multiformat MF(token_contract, token_id, net, chain) 66 | bytes attribute, // multiformat MF(cardinality, type, ...rest:MF) 67 | bytes value // multiformat CID or MF(RETRACT_OR_APPEND, CID) 68 | ); 69 | } 70 | ``` 71 | 72 | The `IPNFT` events are associate with a source NFT in their contract. This event describes 73 | information about `entities`. When describeing information about *this* NFT the `entity` will be an empty (null) binary. 74 | 75 | 76 | IPNFT can be used to publish and interlink metadata about entities represented as NFTs. 77 | 78 | TODO 79 | 80 | ## Indexing 81 | 82 | We can create secure per-chain indexes of these events and roll all chains into a master index 83 | for all of Web3. The events would look something like: 84 | 85 | ``` 86 | { chainNamespace: 'eth', 87 | chainReference: 'mainnet', 88 | contractAddress: Binary, 89 | transaction: Binary, 90 | tokenId: 12987189739812, 91 | source: 89879798, 92 | entity: Binary, 93 | attribute: Binary, 94 | value: Binary 95 | } 96 | ``` 97 | 98 | Note that every event has a `transaction` id provided by the chain. 99 | 100 | You can then imagine a REST interface that caches access to this information to make it easily 101 | available to web developers. 102 | 103 | ``` 104 | /ipnft/eth/mainnet/{contractAddress}/{tokenId}/{entity}/{attribute} 105 | ``` 106 | 107 | When the values are CID's we can do everything we do from gateways using these mutable identifiers. 108 | 109 | ``` 110 | /ipnft/eth/mainnet/{contractAddress}/{tokenId}/{entity}/{attribute}/_latest?format=jpeg 111 | /ipnft/eth/mainnet/{contractAddress}/{tokenId}/{entity}/{attribute}/_latest?format=car 112 | ``` 113 | 114 | We can put the last transaction in a header so that you can query its history since a previous state. 115 | 116 | ``` 117 | /nftx/eth/mainnet/{contractAddress}/{tokenId}/{entity}/{attribute}/_since?transaction={transaction} 118 | ``` 119 | 120 | This would allow any number of new database to be written since this effectively globalizes a 121 | cache of the change feed of any database written to this protocol, without these gateways 122 | even needing to be aware of the underlying database protocol. 123 | 124 | ## Rationale 125 | 126 | TODO 127 | 128 | ## The OPTIONAL description protocol extension 129 | 130 | Each `IPNFT` event is a fact / statement that represent addition or retraction of a relation between an **entity**, an **attribute** and a **value**. This forms triples graph where `entity` denotes the resource (usually NFT in some chain), and the `attribute` denotes traits or aspects of the _entity_, and expresses a relation between the `entity` and a the `value`. 131 | 132 | > While some indexes can choose to unify set of statements across (some or all) sources _(that are globally identifiable by `contract`, `source_id` pair)_, others may choose to namespace by a `contract` or `source_id` or both. 133 | > 134 | > This allows both interoperability before standardisation and extensiblity without breaking compatiblity. 135 | 136 | ### Entity 137 | 138 | An entity denotes the subject about which statement are made. 139 | 140 | When `subject` is empty (0 bytes) it is considered to refec to the `source` token itself (as in `(emitting_contract, source)` pair). This is convinient when contract want to make statements about its own tokens. 141 | 142 | However `subject` may encode information about other tokens, even in other chains. It is adviced to encode this information in [multiformat][]: 143 | 144 | - **chain** - blockchain identifier 145 | - **network** - network identifier, mainnet, testnet, etc... 146 | - **contract** - contract address that issued token 147 | - **token_id** - token identifier 148 | 149 | // TODO: this should be a generic multiformat for identifying NFT's, similar to what ceramic and did do. 150 | 151 | ### Attributes 152 | 153 | Every attribute is identified by a [multiformat][] value that follows (TCS+) (cardinality, type, subject) encodes it's semantics: 154 | 155 | - **Cardinality**, specifying whether NFTs can have one or a set of values for the attribute. 156 | - **Type**, the type allowed for an attribute's value. That is one of the following types: 157 | - boolean 158 | - integer 159 | - float 160 | - string 161 | - bytes 162 | - link 163 | - **Predicate**, specifying rest of relation semantics. This can be just an arbitrary name or multiformat encoding more domain semantics. 164 | 165 | 166 | 167 | ### Attribute Values 168 | 169 | NFT Attribute Values MUST be [multiformat][] 170 | that encode following: 171 | 172 | - **OP** - Retraction or Addtion 173 | - **Data** - Value that MUST correspond to the an attribute type. If attribute type is _link_ data MUST be a valid [CID][]. 174 | 175 | ### References 176 | 177 | - [Datoms][] from datomic 178 | - [Resource Description Framework (RDF)][rdf] 179 | - [InterPlanetary Name System (IPNS)][IPNS] 180 | - [ERC-721] 181 | - [multiformat] 182 | - [did:key] 183 | - [IPLD] 184 | - [EAV] 185 | - [CID] 186 | 187 | ### Notes 188 | 189 | 190 | 191 | [did:key]:https://w3c-ccg.github.io/did-method-key/ 192 | [datoms]:https://docs.datomic.com/cloud/whatis/data-model.html#datoms 193 | [rdf]:https://en.wikipedia.org/wiki/Resource_Description_Framework 194 | [IPNS]:https://docs.ipfs.io/concepts/ipns/ 195 | [ERC-721]:https://eips.ethereum.org/EIPS/eip-721 196 | [multiformat]:https://multiformats.io/ 197 | [UCAN]:https://whitepaper.fission.codes/access-control/cap-authz 198 | [IPLD]:https://github.com/ipld/specs/blob/master/data-model-layer/data-model.md 199 | [EAV]:https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model 200 | [CID]:https://docs.ipfs.io/concepts/content-addressing/ 201 | [Datomic Data Model]:https://docs.datomic.com/cloud/whatis/data-model.html 202 | --------------------------------------------------------------------------------