Page 35 - MSDN Magazine, September 2018
P. 35

Figure 5 Functions in the Betting Smart Contract
cannot happen if an event doesn’t 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 Create, Read, Update, Delete (CRUD) 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 modeling approach is called event sourcing (bit.ly/2O68nrt).
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 (bit.ly/2MbpUOb), which is exactly what a blockchain allows to execute: no data updates or deletions, it 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.
Figure 6 shows the structural data model for the betting appli- cation. This is sometimes called the snowflake model, because each entity (a database table) is different from any other.
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 toward any time in the past.
To push this further in terms of isolation of responsibilities, Command Query Responsibility Segregation (CQRS) comple- ments 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 con- texts can be eliminated. A smart contract can own and encapsulate
constructor() public { Gambler = msg.sender;
}
function Bet(uint amount) public payable {
require(msg.sender == Gambler, "Only a gambler can place a bet."); require(amount > 0, "Amount should be greater than zero.");
BetAmount = amount; address(this).transfer(amount);
State = BetType.Placed; }
function Won(uint amount) public payable {
require(msg.sender != Gambler, "Only the bookmaker can mark a bet as won."); require(amount > 0, "Amount should be greater than zero.");
Gambler.transfer(amount);
Close(BetType.Won); }
function Lost() public payable {
require(msg.sender != Gambler, "Only the bookmaker can mark a bet as won.");
Bookmaker = msg.sender; Bookmaker.transfer(BetAmount); Close(BetType.Lost);
}
function Close(BetType state) internal { Gambler = 0x0;
BetAmount = 0;
State = state;
}
Event Sourcing and CQRS
As discussed in the previous section, I recommend building smart contracts with responsibility for one capability only. While capability- oriented design is a crucial technique for isolation of smart con- tracts, 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 on which to bet. The smart contract for betting may reference a sporting event, creating a dependency between the two smart contracts (betting
Sports Event
ID
Name Location DateTime
User
ID Name Role Balance
<<Enumeration>> RoleType
Gambler Bookmaker
Bet
ID
EventID GamblerID BookmakerID PlacedOn BetAmount WonAmount State
Bet Placed
Message Sender Address Amount
State
Bet Won
Message Sender Address Amount
State
Bet Lost
Message Sender Address Amount
State
<<Enumeration>> BetType
Placed Won Lost
Figure 6 Structural Data Model msdnmagazine.com
Figure 7 Event-Sourcing Data Model
September 2018 27


































































































   33   34   35   36   37