It’s used for applications built on the EOSIO blockchain to sourcing to event blockchain events to update queryable datastores and trigger deterministically side effects on the blockchain or external services.
Likewise, the pattern in question was born considering the following:
- Separate the concern of how the state exists on the blockchain and how the client frontend queries it.
- The client frontend is not the only one responsible for determining the derived, reduced, and/or accumulated state.
- The capacity for blockchain events to trigger new transactions, as well as other side effects outside of the blockchain.
- The blockchain is the single source of truth for all application state.
In general, demux allows you to get the benefits of blockchain and traditional databases, for one hand, properties such as immutability, traceability, and trust of blockchain, and on the other hand the facility, velocity, and flexibility to query databases. It’s because how to make complex queries on the blockchain has high costs and is taken advantage of thanks to different optimizations of databases the number of resources needed is lower.
Separated Persistence Layer
The storage of data in an indexed state on the blockchain could be useful for the next three reasons:
- The decentralized consensus of the computational results.
- The use of state within other blockchain computations.
- The retrieve of the state for use in client interfaces.
However, when more complex frontends are built some problems start to appear when directly querying the blockchain, is because of this that demux addresses the scaling problem by off-loading queries to any persistence layer that is defined according to the needs, for this reason, the data are preprocessed and indexed in a traditional database.
This avoids adding more endpoints nodes when you need to scale the load of queries and also omits having to perform an excessive number of queries to the blockchain and process the extremely costly data. The previous is useful when complex applications need to retrieve data from the blockchain.
Thus, as the blockchain events are produced, the chosen database is updated by update functions (
Updaters) that deterministically process the
Actions object array. Then, the database is kept updated concerning the blockchain state and the DAPP frontend queries the database through the appropriate
Single Source of Truth
- If the database is deleted or lost it can be recovered by reproducing the actions of the blockchain.
- If the application is open-source and the blockchain is public, the state of the application could be audited.
- It’s not necessary to keep multiple ways of updating the state.
Since you have a system for acting on specific blockchain events deterministically, you can use this system to handle non-deterministic events as well.
These effect functions (
Effects) work almost the same as update functions, except that they run asynchronously, do not run during replays, and modification of the deterministic data store is out of bounds.
Some examples of side effects are:
- Signing and broadcasting a transaction.
- Sending an email.
- Begin a traditional fiat payment.
Like Flux and Redux, the data flow in demux is unidirectional. Starting from the DAPP frontend, it can write to the data string through
Transactions, which will be read by an observer (
Action Watcher) to notify that they should be handled which can cause side effects, after that through the update functions the event will be recorded in the database which will be queried through an
API by the DAPP.
Demux Data Flow Diagram
Sequence of Demux Data Flow
- The client sends a transaction to the blockchain.
Action Readerto check for new blocks.
Action Readersees transactions in the new block and parses actions.
Action Watchersends actions to
Action Handlerprocesses actions through
Actionsrun their corresponding
Updaters, updating the state of the Datastore.
Actionsrun their corresponding
Effects, triggering external events.
- The client queries
APIfor updated data.
Implementation at EOS Costa Rica
We use our solution inspired by the demux architectural pattern, which use the nodeos State History Plugin as
Some of our open source projects implemented the solution based on the demux pattern: