Application State Storage on IPFS

Dennison Bertram
Sep 6, 2018 · 7 min read

Recently I have become more interested in IPFS and the possible use cases for web deployments of applications and decentralization of state. Mostly I’ve been thinking on how we can use IPFS on the backend of servers to allow for application developers to create bifurcated state storage for decentralized apps in a hybrid environment. (IE: how can we easily let backend developers serve private distributed data)

What if the users application state was separated from the data a company traditionally had access to? We could encrypt user’s private data and store it directly in IPFS using immutable data-structures. This gives us a ready-made immutable document data store addressable by hashes that has the incredible advantage of simultaneously being accessible from anywhere.

Curious about IPFS? Learn more: https://ipfs.io/

The Global State Object

What if all users for all applications had all their state stored in the same place? A global state object. Users could hydrate their application state from anywhere and always have access to immutable persistent state. When encrypted it would be impossible to tell the who was requesting what content. Indeed in many ways this is the idea behind blockchain. No matter where you are, your Ethereum, Bitcoin, (or any other blockchain) application has access to the same global state which is stored in the blockchain, and reading it is free. This has plenty of security advantages, but it’s not necessarily the most efficient use of storage for application state for web applications.

So what if we built use-specific mini-blockchains? Blockchains designed only to store application state in a distributed way, but building on an existing protocol to remove the necessity of dealing with complicated problems like consensus protocols, attack-resistance, etc? A blockchain that keeps track only of user state, but carries with it the security of immutability? Using basic data-structures such as linked-lists (a very apropos data structure) we can build up our application state from linked node’s, each representing a version of state.

To test the idea I’ve built an implementation of a basic data-structure: the Linked List, using IPFS, Express, and React.

EXPRESS:

The Express server using IPFS. Next step is to use IPFS as middleware.

Express works as the backend server and routes GET/POST requests to and from IPFS. Normally the idea of merging Express, a server application on NODE with IPFS would probably seem pretty strange, but it serves a practical purpose. In thinking about building an app that might store some state-data in IPFS there is a huge performance boost by running your own local IPFS node. Both server and client side code are connected directly to the same instance which means for performance it’s relatively fast (and reliable). Additionally it allows the client to access IPFS without needing any sort of 3rd party browser extension. People who are comfortable building on Node+Express based systems keep their regular habits, while power users are free to hydrate their state from any IPFS provider of their choosing.

Additionally it seems to me that hybrid solutions of merging traditional tech-structure and distributed technologies might be useful in smoothing the transition to distributed technologies for wide-spread adoption. Creating systems that leverage distributed technologies with no additional perceivable load on end users (plugins like Metamask or Scatter for example) is critical for the early stages of consumer adoption.

As for the security of data passing through the express server, it’s easy enough to protect client state data as well. Although in my example I’m not using encryption, client side encryption (perhaps via metamask signatures?) can easily keep user data protected while still flowing through a traditional backend with flags on state objects that allow for reading of non-private data.

Power users can bookmark their state objects in the Ethereum blockchain, or use encryption to share state with trusted parties.

CODE:

The React State

As you can imagine, the state required to represent a node in a linked list is fairly minimal. In this example the user-data is kept in value (an empty string) while the data for keeping track of the nodes orientation with respect to the other nodes is contained in nonce, pointerStart, pointerEnd, previousHash and demoHistory.

DemoHistory is entirely just for demo purposes, as by using it in any production setting means each state object becomes the size of all previous state objects, and being that we can’t actually delete our state objects as they are immutable, It’s not always necessarily practical. For demonstration purposes however, it’s quite nice.

PointerStart, PointerEnd are optional features that allow us to use our linked list like a queue or a a stack with reduced functionality but without requiring a full copy of the state history to be made.

Nonce is a convenience value in this case and we increment it every time our state is submitted to the server. This gives us an idea of how long our block-chain/linked-list goes back without requiring us to follow each previousHash back to the start (at the start previousHash is empty).

PreviousHash of course is the magic. If we were building a real blockchain we would need to build a hashing function to secure our previous ‘blocks’, but by using IPFS this a feature we get for free. Every file when saved into IPFS is represented by a hash of it’s contents. It does double duty in this case by both being the hash of the previous node and the pointer to the previous node. How convenient!

If we really wanted to keep things simple, we only need two variables in our object to make our mini-block chain linked-list work:

Previous Hash gives us a pointer AND a hash function in one!

With just these two values we can keep our state and, as long as we have the ‘head’ of the list, we can retrace our state, (securely mind you!) back to the start. Of course this means you can’t lose track of the “head” of your linked-list as the design is uni-directional. You can find your way back to the beginning but you can’t go the other way. It would be trivial to add a cookie tracking feature on the Express server that allows users to rehydrate state from where they last left off, or let users bookmark their state into an Ethereum SideChain.

The complete React Application

DEMO:

The demo code is available here: https://github.com/crazyrabbitLTC/IPFS-EXPRESS-LinkedListDemo

The backend when you startup.
Okay so my styling could use some work….

The code assumes you have IPFS daemon installed and running and have installed the dependencies from package.json.

Once it’s running you can experiment by entering different values into the form and clicking submit. On each submit the form value will be hashed and stored in IPFS.

The history links in this example aren’t using the GET route from the EXPRESS app, rather they point to Infura’s IPFS endpoint to demonstrate that your form value is now saved in the IPFS network.

If you’re curious: https://ipfs.io/ipfs/Qmb9eGe8gk8kNiKcCXN9CoLvuWxPf2ofZbSiaXm48ZCkKH

This example is fairly simple, and should be enough to get anyone curious in hacking around with it a head-start on thinking about how we could potentially take the state out of applications and store it in a global state object.

Building upon the idea, we could use immutable nodes which then also track other immutable nodes, opening the door to more complicated data-structures like trees, or application specific queue’s or stacks.

Use-Case

It most certainly is still “early days” for thinking of use cases, but in my mind I can imagine companies that serve their application state and non-private business logic directly from IPFS, from anywhere. Applications where privacy is critical or where regimes censor the internet could benefit highly from the plausible deniability of a global state object.

What about Redux?

If you were thinking, “Hmm all this immutable state makes me think of redux” well you aren’t wrong! One of the first things I came across when I started thinking about this implementation of a global state was this great post:

https://swizec.com/blog/blockchain-redux-experiment-part-2/swizec/8055

Next Steps:

Next steps would probably be to enhance the abilities of the Express server backend connection. This is a pretty basic implementation of IPFS and there are plenty of ways to improve performance. After that, I would perhaps try to build out a handshake protocol to enable collective data-sharing agreements between client and server (allow the client to authorize server access to state-copies), implement a binary search tree, queue and stack, perhaps turn it all into a standalone library, and finally of course- build a demo app!

…..to be continued

Dennison Bertram

Written by

Professional Revolutionary and Blockchain.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade