Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Livecoding: Blockchain-Redux Now Shares Blocks Real-Time

DZone's Guide to

Livecoding: Blockchain-Redux Now Shares Blocks Real-Time

We continue our look at building a blockchain framework using React and Redux by implementing functionality where blocks can be shared between clients in real-time.

· Security Zone ·
Free Resource

Mobile is increasingly becoming a part of every consumers’ identity, but the increasing use of this digital channel is escalating the security risks faced by consumers and institutions.

Sunday was fun. We built a thing!

Well... we added a thing to the You Can Use Blockchain To Store And Share UI State proof of concept I've been livecoding on. I'd share a live link with you, but... err... the app broke.

It was working, you see. Then it wasn't. Infinite loop on page load.

Next time! I promise.

We did get something working, however. When you dispatch an action on blockchain-redux, the generated block is shared live with all other clients. That sharing still happens via Firebase, so it's not that impressive, but it's a step in the right direction.

You create new benchmark measurements in one browser window, and the other window reacts. Magic!

Here's how it works.

How Blockchain-Redux Shares Blocks Between Clients in Real-Timeat

Long validation times got you down? Blockchain-redux is all real-time with the firebaseMiddleware. Soon with the WebRTC middleware too, I hope.

In part, that's because there's no real consensus algorithm. Any valid block is accepted to the chain. The longest chain wins by default.

You may have seen how blockchain initialization works before. We read the whole chain from Firebase and replace the local chain stub.

Image title

Initializing the blockchain from Firebase

You can read more details about this code in a previous blog post.

The part that's new is calling listenForNextBlock after replacing the local chain.

Image title

Listen for the next block

We have a local chain and want to make sure we catch the next block that shows up. So we fetch the latest index with store.getLastBlock().index, increment by 1, and listen for changes on blockchain/${nextIndex}.

When that block shows up, we call valueHandler.

valueHandler then parses the value and calls store.addBlock(), which validates that the block fits our chain, and if it does fit, it gets added. If the block makes it to our local chain, then the redux-y stuff kicks in, wakes up all subscribed components, and re-renders happen.

Completely Transparent to Your App

All this real-time sharing is completely invisible to your app. You build your code just like it was any other Redux-based app.

To initialize the blockchain and render a live count of nodes, you'd do something like this:

// App.js

class App extends Component {
    blockchain = { } ;

    componentDidMount = async ( ) => {
        const FirebaseApp = firebase.initializeApp ( {
            apiKey: "" ,
            databaseURL: "https://thing.firebaseio.com" ,
            projectId: "thing"
        } ) ;

        this.blockchain = await createStore(
            benchmarkReducer,
            firebaseMiddleware(FirebaseApp)
        ) ;

        this.unsubscribe = this.blockchain.subscribe ( ( ) => {
            console.log ( "Hello" ) ;
            this.forceUpdate ( ) ;
        } ) ;
        this.forceUpdate ( ) ;
    } ;

    componentWillUnmount( ) {
        this.unsubscribe ( ) ;
    }

   render( ) {
        console.log ( "in render" , this.blockchain ) ;

        if ( this.blockchain.getState ) {
            console.log ( "Current state" , this.blockchain.getState ( ) ) ;
        }

        return (
        <div className= "App" >
            <BlockchainContext.Provider value= { this.blockchain } >
                <IntroCopy />

                <BlockchainContext.Consumer >
                    {blockchain => (
                        <Benchmarks blockchain= {blockchain} />
                    ) }
                </BlockchainContext.Consumer >

                <div style= { { padding: "3vh" } } />
            </BlockchainContext.Provider >
        </div>       
         ) ;
    }
}

Initialize the store in componentDidMount, subscribe to changes, run forceUpdate to get around async issues, unsubscribe on unmount.

The best way to make this store available to the rest of your app is via the new context API using <Context.Provider value={this.blockchain}>.

Then inside <IntroCopy />, where you display the node count, you do something like this:

// IntroCopy.js

// functional component boilerplate ...
// ... render stuff

<BlockchainContext.Consumer >
    { ( { getWholeChain = ( ) => [ ] } ) => (
        There are {getWholeChain( ).length } nodes on the chain
    ) }
</BlockchainContext.Consumer >

// ... more other render stuff

The value passed into the render prop is the whole blockchain store. Take out getWholeChain and show the length. You could use getState() to get the latest block value, for example.

Lots of stuff you can do.

And to add a new block? Just call dispatch and have a reducer. Blockchain-redux handles the rest!

Next Steps

I still have to resolve a few TODO comments around block conflicts. What happens if your network is slow and you add blocks locally that other clients haven't seen and you get blocks from the outside world that conflict? Which do you pick?

I'm not sure yet.

Plus I really want to move away from Firebase. That's gonna be fun.

Explore the authentication advancements that are designed to secure accounts and payments—without overburdening consumers with a friction-laden experience.

Topics:
security ,blockchain ,react ,redux

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}