# Work proposal - Decentralized NFT Metadata Validation using Holochain ## Problem Statement Metadata for NFTs is stored off-chain and typically referenced in the NFT itself as a URL. A URL contining the hash of the data can be used to ensure that if the data returned from the URL is changed at a later date this can be detected. It is reasonable to enforce some constraints on the Metadata of NFTs and the artwork file they point to in a collection. An example of this would be enforcing that images are of a particular size/format or that the metadata json matches a particular schema. Furthermore the validation should be a function of the account performing the minting so that certain minter specific constraints can be enforced (e.g. metadata.minter field is set correctly). Since the meta/image data is too large to submit on-chain the only way to perform this kind of validation is using a centralized web service as an intermediary in the minting process. It would be preferable to have a decentralized way to obtain the same result. ## Background Holochain is an IPFS-like hash addressed storage with the distinction that the data is namespaced into applications and types. Data of a specific type must pass an application specific validation rule or storage nodes must reject it. Rules are encoded as arbitrary WASM code the hash of which is the identifier for an application. Data also has an associated author which is an ECDSA keypair. An identifier of the form `<app hash>/<data hash>` can be used to retrieve a piece of data with the guarantee that the data is correct (pre-image of the hash), and the promise that the data was authored by a valid account and has passed the validation check. Honest nodes will not store or provide data that does not passed these conditions. ## Proposed Solution Create a Holochain app, accessible via the Holochain launcher, that will allow a user to mint and view NFTs on a specific Rain NFT contract, using Walletconnect for connecting a supported EVM wallet. The hApp will be open to anyone to join, however to mint, an agent must first submit a proof-of-ownership for an Ethereum account. The minting of an NFT with validated data would work as follows: 0. A Holochain application exists that validates NFT metadata and artwork files according to the required rules (**appHash**) 1. The author joins the Holochain application, then if they wish, submits a proof-of-ownership of an Ethereum account (**authorEvmAddress**). 2. The author then submits their NFT Metadata to the Holochain application. The metadata and the artwork file are both validated and if valid will be stored in the network. The metadata hash is returned (**dataHash**) and can be used to retrieve the data. This data is associated with a link with the base `keccak(authorEvmAddress|dataHash)`. 3. An NFT is minted on Ethereum using a Rain contract that accepts the `dataHash`. A Rain expression creates an NFT with `ID = keccak(authorEvmAddress|dataHash)` and a catch-all URI (that says something to the effect of "View this NFT on Holochain app XYZ") 4. Minted NFTs would only be viewable inside the hApp, which will use the cryptographic binding between the tokenId and the data stored on Holochain to display the artwork. Previous versions of this proposal explored the possibility of a gateway for compatibility with existing NFT marketplaces. However for this POC, the goal is to show cryptographic binding between an on-chain token ID and validated data on Holochain. So, the NFTs will be both minted and viewable only within the hApp. ## Scope of Work - Detailed specification document - Detail minting process on both Holochain and Ethereum **[3 days]** - Contract and NFT data specification **[1 day]** - PoC Implementation - Holochain application **[5 days]**) - Setting up contract and Rain expression **[1 day]** - Integration testing and unit testing **[3 days]** - Example Holochain Launcher Application for minting and viewing NFTs (TBD, validated POAPs?) **[6 days]** - Communication - Blog post/article about the process/benefits **[1 day]** - Documentation for how to use **[1 day]**