Menu

Blogchain

A blog about Blockchain technology

Event Sourcing and CQRS in Blockchain Transactions

Microservices and blockchain smart contracts have a lot in common. They’re both expected to run in isolation (on-chain) and communicate with the outside (off-chain) via a message-based channel. They should both be small in size, developed to run autonomously and independently, and perform better when they are deployed on a decentralized network.
Event Sourcing and the Command Query Responsibility Segregation (CQRS) patterns are commonly applied to the design of microservice architectures, and thus can be implemented also when building blockchain smart contracts.

Event Sourcing
While single capability-oriented design is a crucial technique for isolation of smart contracts, it’s not sufficient to ensure independent deployability. Smart contracts may operate on a common data model within the domain of the system, despite being isolated in execution. For example, in an application there may be a smart contract for managing bets and another for managing sporting events to bet on. The smart contract for betting may reference a sporting event, creating a dependency between the two smart contracts (betting cannot happen if an event does not exist). Is there a way to model data that can help avoid data sharing among smart contracts?
Whatever format and storage (SQL, NoSQL, JSON) we use, we generally model databases according to objects and CRUD (Create, Read, Update, Delete) operations. Instead of storing structures that model the state of the domain, we can store events that lead to the current state of our world. This modelling approach is called event sourcing (https://martinfowler.com/eaaDev/EventSourcing.html).
Event sourcing is all about storing facts. A fact is a representative value of an event occurrence. Just as in life, we can’t go back in time and change the past--we can only do something in the present to compensate for earlier actions. Data is immutable; so we always issue a new command or event to compensate for, rather than update, the state of an entity. This approach operates under the acronym of CRAB – Create, Retrieve, Append and Burn (https://blog.bigchaindb.com/crab-create-retrieve-append-burn-b9f6d111f460), which is exactly what a blockchain allows to execute: no data updates or deletions, but only appends to the chain. Deleting something from a blockchain conflicts with its immutability, but you can stop asset transfer by “burning” the recipient address.
An immediate concern of this approach is performance. If any state value is a function of events, you may assume that every access to the value would require recalculation of the current state from the source events. Obviously, that would be extremely slow. In event sourcing, you can avoid such expensive operations by using a so-called rolling snapshot: a projection of the entity state at a given point in time. For instance, banks pre-calculate your bank account balance on the last day of every month, so you don’t need to sum all debits and credits operations since the day you opened your bank account to obtain your current balance.
The following figure shows a structural data model for a betting application. This is sometimes called the snowflake model, because each entity (a database table) is different from any other.


 
Structural Data Model

 

Command Query Responsibility Segregation
The structural data model saves only the current state of the system, while the event sourcing approach saves individual facts. State, in event sourcing, is a function of all the pertinent facts that occurred. Not only does this give full auditability, but it also allows us to build state projections towards any time in the past.
To push this further in terms of isolation of responsibilities, Command Query Responsibility Segregation (CQRS) complements event sourcing as a design pattern for data storage. CQRS encourages effective single responsibility and deployability of microservices, and by extension, smart contracts. It states that you can, and should, separate data update from data query capabilities into separate models. 
When using CQRS, the need to access data across multiple contexts can be eliminated. A smart contract can own and encapsulate any update to the model’s state and raise events on change of this state. By subscribing to notifications of these events, a separate smart contract can build a completely independent and query optimized model that doesn’t need to be shared with any other contract or external service. You can learn more about CQRS from Martin Fowler’s post at https://martinfowler.com/bliki/CQRS.html.
The figure below describes a typical data model for a betting application using event sourcing. This simple model employs a similar structure irrespective of the event handled. It’s not necessary to know the current state of the bet to read the sequence of events. The event’s data structure depends on the event itself. Although a sequence of states exists as defined in the workflow, it’s irrelevant from a data model perspective. Think bigger: in a supply chain scenario, multiple workflows and events exist, with different entities and attributes. Your structural data model may grow complex, whereas the event-based model, bar a few different attributes for each event, remains constant.


 
Event Sourcing Data Model

 

Go Back

Comment