On-chain Data Storage
Summary
A smart contract that allows for easy storage and retrieval of data on-chain
Motivation
Currently in Solana there is no standard for data storage on-chain. By data, I mean anything that can be stored as bytes like a text file, a HTML document, a PNG image, NFT JSON Metadata etc. This RFC proposes a solution for storing data on-chain and having it be retrieved easily.
Implementation
To solve this issue, I have developed the Solana Data Program. This is a Solana smart contract that allows users to initialize a Data Account to store any data as bytes and have its metadata be stored in a separate PDA
Flow Diagram
Here’s a flow diagram to describe how the accounts are linked:
Accounts
Metadata Account:
In the Metadata PDA Account, we store the metadata regarding the data in the Data Account. A few important fields stored in it are:
-
authority
: The authority needs to be a signer in any instruction that involves the Data Account - updating the data and/or data type, finalizing the data, transferring the authority, and/or closing the account -
data_type
andserialization_status
: Currently the supported data types are:
i. CUSTOM: To store custom data or a currently unsupported data type
ii. IMG: To store image data as raw bytes
iii. HTML: To store a HTML file as raw bytes
iv. JSON: To store minified JSON as raw bytesThe motivation behind having set
data_type
s is that it helps the client application determine how to display the data. It also opens doors for data verification (denoted byserialization_status
). Currently when JSON data being updated, the user could optionally verify to ensure it is valid JSON. -
dynamic
: A dynamic Data Account can realloc (up or down) while a static account will always stay a fixed size. This could be useful when users want to pay a fixed amount for the storage space (static) in the Data Account rather than a only-pay-how-much-is-needed approach (dynamic)
Data Account:
A Data Account is any Solana account that is owned by the Data Program and has an associated Metadata PDA Account. The data is stored directly as raw bytes so one could easily retrieve it using a single getAccountInfo
RPC call as such:
const data = (await connection.getAccountInfo(dataKey, commitment)).data;
The data account need not be created by the Data Program. You can also pass in a previously created Data Account to the Initialize instruction and it will assign it to the Data Program
Instructions
-
InitializeDataAccount
: This instruction creates and initializes the Metadata Account and optionally creates a Data Account. -
UpdateDataAccount
: This instruction updates thedata_type
field in the Metadata Account and the data in the Data Account. -
UpdateDataAccountAuthority
: This instruction updates theauthority
of the Data Account by updating the value in the Metadata Account. It requires both the old and new authority to be signers to prevent accidental transfers. -
FinalizeDataAccount
: This instruction finalizes the data in the Data Account by setting thedata_status
in the Metadata Account to beFINALIZED
. Finalized data can no longer be updated. -
CloseDataAccount
: This instruction closes the Data Account and the Metadata Account and transfers the lamports to theauthority
.
Usage
SolD Website
SolD is a website that acts as an editor for the Data Program:
- It allows users to view the metadata and data associated with a Data Account via the
/<datakey>?cluster=<cluster>
route - It allows users to connect with their wallet and upload files directly to the Data Program by going to the
/upload
route - If the user is logged in as the
authority
, it allows the user to edit the data, finalize it and/or close the metadata and data accounts. - Users can also view all data accounts they “own” via the
/authority/<authority>
route and perform group actions on them
Typescript SDK
solana-data-program
is a Typescript SDK that exposes APIs to interact with the Data Program and helper methods to parse the data, metadata etc. of a Data Account
NFTs
One potential use case of the Data Program are fully on-chain dynamic NFTs. By this I mean an NFT with:
- JSON metadata stored on-chain
- Image data stored on-chain
- JSON metadata that can be updated via an on-chain crank
- Image data that can be updated via an on-chain crank
Here’s a link to such an NFT: Quine NFT
On clicking View original you will see the original HTML file that was pulled from on-chain. You can also inspect the Metadata and Image data on SolD separately:
Image: HoyEJgwKhQG1TPRB2ziBU9uGziwy4f25kDcnKDNgsCkg
Metadata JSON: Hb9vkWax5AeLWvCtYSjSvWrN6gTw324gKMa28kcBsgT3
P.S. The NFT image is a quine. The code on the surface of the rotating sphere is the code used to generate the sphere with code on its surface
Composability
An important consideration went into making sure that the Data Program is easy to use and composable. To demonstrate that, I have also made example smart contracts (two of which involve minting NFTs including the Quine NFT ) that CPI into the Data Program: solana-data-program/examples at main · nvsriram/solana-data-program · GitHub
URI Standard for Data Retrieval
Currently, to have the data be pulled from on-chain I have an API route /data/<dataKey>?cluster=<cluster>&ext=<ext>
that just returns the data as is (or in the extension format specified by ext
). It would be more handy to have a URI standard which might look something of the sort:
sol://<datakey>?ext=<ext>
to get the data stored in datakey
in the format specified by ext
OR
sol://meta/<datakey>
to get the metadata associated with the datakey
Conclusion
This RFC discusses the features of the Data Program and how it can be used to store data on-chain. It presents the SolD website editor and Typescript SDK that make it easy to interact with the Data Program. It showcases potential use cases in fully on-chain dynamic NFTs and proposes a URI standard for data retrieval.
References
Data Program Smart Contract: GitHub - nvsriram/solana-data-program: Solana smart contract that handles on-chain data storage
SolD Website Editor: https://sold-website.vercel.app/
Typescript SDK: solana-data-program - npm
Quine NFT: Solscan
Quine NFT Image: https://sold-website.vercel.app/HoyEJgwKhQG1TPRB2ziBU9uGziwy4f25kDcnKDNgsCkg?cluster=Devnet
Quine NFT Metadata: https://sold-website.vercel.app/Hb9vkWax5AeLWvCtYSjSvWrN6gTw324gKMa28kcBsgT3?cluster=Devnet
Examples: solana-data-program/examples at main · nvsriram/solana-data-program · GitHub