Hyperledger Sawtooth as a development framework: architecture overview
Following a significant amount of research and tests, REMME has decided to choose Hyperledger Sawtooth as its blockchain framework. It provides out-the-box mechanisms so developers don’t need to write the entire blockchain software from scratch.
The Hyperledger Sawtooth framework is being developed by Intel under the hood of the Hyperledger foundation. It is a blockchain framework highly focused on agility. Basically, the framework itself provides basic things like communication between nodes in a network, storing data onto the blockchain and the architecture for plugging smart contracts and consensus algorithms. Everything besides that can be easily swapped in and out.
Let’s dive deeper into the architecture of the framework. Here are some important statements to keep in mind:
1. Any data needing to be persisted is stored in the on-chain key-value storage distributed among the network of validators.
2. This storage allows any binary data to be stored in it.
3. Data is modified with transactions.
4. Every transaction has an associated transaction family and is processed by a corresponding handler.
5. A transaction family handler take the transaction payload, parses it and performs the required business logic and writes out corresponding changes to the storage.
6. Data in storage is addressed with 35 byte addresses, where the first 3 bytes are the prefix, which is by convention unique for every transaction family, and the rest of an address is any data specified by the transaction family (it may be a hash of any data, some number etc).
Unlike Ethereum and some other platforms, the code of handlers (smart contracts) can be written in any language (basically you need only support for protobuf and ZMQ; Sawtooth has SDKs for most of the major languages) and or stored off-chain. Instead of distributing a smart contract on the blockchain, every validator node needs to install the software performing those smart contracts in order to verify transactions. Also there is no such thing as “gas”.
Let’s a take a closer look at the architecture of the framework to see how smart contracts interact with blockchain. The following statements represent the architecture of the framework on an application level:
1. Validator is the central entity in this system performing all network and storage operations.
2. When the validator receives a new transaction it is passed to one of the connected transaction processors.
3. Transaction processor is an entity which is communicating to the validator and contains a bunch of transaction handlers.
4. When the transaction processor receives a transaction it is passed to the corresponding transaction handler.
One of the most notable features of the transaction processing mechanism is parallel scheduling. On top of payload, every transaction should define inputs and outputs. They define what a transaction handler can read and write respectively during a transaction. This data is used to schedule parallel execution of transactions which can drastically improve the overall performance
Sawtooth currently supports DevMode and PoET consensus implementations.
The framework has a built-in implementation of consensus called DevMode. This algorithm just collects transactions into blocks and does not perform any additional logic. However, it is a perfect fit for testing purposes.
Hyperledger Sawtooth also uses proof-of-elapsed-time (PoET), a lottery-like algorithm. At a high level, proof-of-elapsed-time follows this strategy:
- Each participant in the blockchain network waits a random amount of time.
- The first participant to finish waiting gets to be leader for the new block.
The following transaction families for production use are included out of the box:
1. Settings is used for storing any settings on the blockchain. It is by Hyperledger Sawtooth itself for switching consensus algorithms and for including consensus algorithms to define parameters like timings, list of allowed validators, number of transactions per block and so on. This family also contains the list of allowed keys: users who own those keys should approve of any changes to on-chain settings before they commence action. The number of required approvals can also be set so this family works like an m-of-n multisignature contract.
2. Identity allows for specific permissions for different user roles. For example, it allows for permitting or forbidding a certain user from sending transactions for all transaction families or even for a specific transaction family, as well as allowing them to join the network of validators and so on.
3. BlockInfo allows other transaction families to access block metadata.
All of those families are optional and can be disabled. For the setting they are responsible for, default values will be used.
It’s recommended to use Docker to manage interactions between components as the easiest way.
This example launches the intkey transaction family which allows for storing integer values mapped to some key. In the next chapter we will test this when we try to send some test transactions to the system.
Transactions and blocks monitoring
After downloading this file to docker-compose.yml and running docker-compose you will see something like this:
That means that everything is up and running and your basic system is ready to use. In this log you will be able to monitor every single transaction and block (and also via the provided REST API of which we will talk later)
Here you can clearly see that:
1) Interactions between everything in the system is tied to the validator.
2) 4004 port is being used for communications between components (on the application level ZMQ is used)
3) Validators communicate via 8800 port.
To sum up, now we have a brief insight of what the Hyperledger Sawtooth framework is, what the components are and how they interact with each other. By looking into the structure of the Dockerfile you can see that the only mandatory component in the system is the validator, and it does exactly what its name says: validates blocks and performs all of the network activities. Any other component can be easily swapped in and out or replaced with your own. Moreover, the way interaction is built (communication between executables via ZMQ sockets) gives you free choice of platform to use for development.
In the next post we will see the structure of a transaction, learn how the transactions are processed in the framework, write our own transaction family implementing an ERC20-like token and learn how to interact with the system via the provided REST API.