Transaction Processor and Python Egg for Hyperledger Sawtooth


Transaction Processor and Python Egg for Hyperledger Sawtooth

Recipe ID: hsts-r20


Recipe Overview

Sawtooth simplifies the development of applications by separating the core system from the application domain. Application developers only need to focus on implementing their business logic for the enterprise using the transaction processor, with the language of their choice, without needing to know the underlying details of the Sawtooth core system.
In our previous recipe, we build transaction handler and processor for Hyperledger Sawtooth. As next steps we build transaction processor service and Python Egg. We accomplish this recipe by covering 4 topics: i- Building the command-line script, ii- Setting up the transaction processor as a service, iii- Building a Python egg and installing your python package, and iv- Starting the transaction processor service
For those who are not familiar with Hyperledger project Intro to Hyperledger Family and Hyperledger Blockchain Ecosystem and Hyperledger Design Philosophy and Framework Architecture articles are strongly recommended.
To better follow and understand this recipe, it is advisable to read Essential Hyperledger Sawtooth Features for Enterprise Blockchain Developers, Blockchain Developer Guide- How to Install and work with Hyperledger Sawtooth , Configuring Hyperledger Sawtooth Validator and REST API as well as Designing namespace and address for Hyperledger Sawtooth transaction family articles in advance.

I- Building Command-line Script

After the transaction handler is implemented, the transaction processor can be started to connect to the validator and serve the request for your transaction family. We can take advantage of Python Setuptools to create a command line, which makes it easy to run your transaction processor.
Setuptools allows modules to register python functions as console script entry points. When the package has been installed, Setuptools will generate a command-line script that imports your module and calls the registered function. To generate the command line for your transaction processor, enter the following code in setup.py:

entry_points={

'console_scripts': [

'mkt-tp-python = sawtooth_mkt.processor.main:main',

]

})

After your package is installed, the transaction processor can be started simply by using the command line:

ubuntu@ip-172-31-90-67:~$ mkt-tp-python --help usage: mkt-tp-python [-h] [-C CONNECT] [-v] [-V] optional arguments:

-h, --help show this help message and exit -C CONNECT, --connect CONNECT

Endpoint for the validator connection

-v, --verbose Increase output sent to stderr -V, --version print version information

II- Setting up Transaction Processor as a Service

systemd is an init system that provides many features for starting, stopping, and managing processes on the Linux platform. To run a process as a service, a unit file is defined for the process; this is the configuration file that describes how to run the process as a service.

The exec start command is the command line generated in the previous section: mkt-tp-
python (sawtooth_mkt/packaging/systemd/sawtooth-mkt-tp-python.service):

[Unit]

Description=Sawtooth MKT TP Python

After=network.target

[Service]

User=sawtooth

Group=sawtooth

EnvironmentFile=-/etc/default/sawtooth-mkt-tp-python

ExecStart=/usr/bin/mkt-tp-python $SAWTOOTH_MKT_TP_PYTHON_ARGS

Restart=on-failure

[Install]

WantedBy=multi-user.target

The EnvironmentFile specified in the preceding unit file is used to define environment variables for the service. The environment file for the example marketplace service is at
sawtooth_mkt/packaging/systemd/sawtooth-mkt-tp-python. Its content is as follows:

SAWTOOTH_MKT_TP_PYTHON_ARGS=-v -C tcp://localhost:4004

To install both files in the etc directory during the installation of the Python package, the following code needs to be added in setup.py:

if os.path.exists("/etc/default"):

data_files.append(

('/etc/default', ['sawtooth_mkt/packaging/systemd/sawtooth-mkt-tp-python']))

if os.path.exists("/lib/systemd/system"):

data_files.append(('/lib/systemd/system',

['sawtooth_mkt/packaging/systemd/sawtooth-mkt-tp-

python.service']))

 

III- Building a Python Egg and Installing Python Package

Your transaction processor package is now ready to be distributed. It could either be built as a python egg file or you could directly install it from the source on the host:

1. To build a Python egg, enter the following command:

sudo python3 setup.py bdist_egg

2. To install it from source, enter the following command:

sudo python3 setup.py install

3. Your transaction family deployment is done. Your Python package for your transaction family should be installed in the following location if you are installing it from the source on the local host, or in the python default distribute package folder if you are installing it from the built egg files:
ubuntu@ip-172-31-90-67:~/examples$ ls -li /usr/local/lib/python3.5/dist-packages/sawtooth_mkt-1.0.4-py3.5.egg 2157 -rw-r--r-- 1 root staff 31390 Sep 16 17:07 /usr/local/lib/python3.5/dist-packages/sawtooth_mkt-1.0.4-py3.5.egg

4. The command line for your transaction processor is as follows:
ubuntu@ip-172-31-90-67:~/examples$ which mkt-tp-python /usr/local/bin/mkt-tp-python

5. The system service for your transaction processor is as follows:
systemctl list-units|grep -i sawtooth-mkt|less sawtooth-mkt-tp-python.service loaded active running Sawtooth MKT TP Python

IV- Starting Transaction Processor Service
You are now ready to start your transaction processor and process clients request for your business:

1. To enable and start the transaction processor service, enter the following:
sudo systemctl enable sawtooth-mkt-tp-python.service sudo systemctl start sawtooth-mkt-tp-python.service

2. Check the service status:
sudo systemctl status sawtooth-mkt-tp-python.service

3. Check the log of your transaction processor in /var/log/sawtooth:

[04:36:15.955 [MainThread] core INFO] register attempt: OK

[05:42:59.182 [MainThread] core DEBUG] received message of type:

PING_REQUEST

[06:34:54.718 [MainThread] core DEBUG] received message of type:

TP_PROCESS_REQUEST

 

Putting Things Together

The transaction processor includes two components: a general implemented transaction processor class and one or multiple transaction handler classes. The general-purpose transaction processor connects to the validator, receives the transaction processing request, and dispatches the request to the transaction handler class to be processed.
The general transaction processor is created and started during the start of the transaction processor, the main routine.
The transaction handler class is application-dependent and contains the business logic for a particular family of transactions. The transaction handler class is the real implementation of smart contracts for your applications.
The following diagram shows the relationships between each component:

 

 

hyperledger sawtooth processor as a service and Python egg

The transaction handler is the smart contract in the Sawtooth blockchain. The main focus of our application development is on implementing the business logic for your enterprise. The transaction handler class interacts with the general transaction processor using two methods:

The metadata methods for the marketplace example are as follows:

@property

def family_name(self):

return 'mkt'

@property

def family_versions(self):

return ['1.0']

@property

def namespaces(self):

return [self._namespace_prefix]

 

def apply(self, transaction, context):

The apply method has two arguments: the transaction and the context. It is very important to understand these two arguments in order to write smart contracts. The argument transaction is the object that is created from the message on the wire based on the protobuf definition. It contains a header and a payload, and its protobuf definition is as follows:
message Transaction {

 

}

The header in the preceding transaction contains the family name, the version, and the public key of the client that signs this transaction, such as signer_public_key. Its protobuf definition is as follows:

message TransactionHeader {

//Public key for the client who added this transaction to a batch
string batcher_public_key = 1;

//A list of transaction signatures that describe the transactions that must be processed before this transaction can be valid
repeated string dependencies = 2;

//The family name correlates to the transaction processor's family name that this transaction can be processed on, for example 'intkey'

string family_name = 3;

//The family version correlates to the transaction processor's family version that this transaction can be processed on, for example

"1.0"

string family_version = 4;

//A list of addresses that are given to the context manager and control what addresses the transaction processor is allowed to read from.

repeated string inputs = 5;

//A random string that provides uniqueness for transactions with otherwise identical fields.

string nonce = 6;

//A list of addresses that are given to the context manager and control what addresses the transaction processor is allowed to write to.

repeated string outputs = 7;

//The sha512 hash of the encoded payload string payload_sha512 = 9;

//Public key for the client that signed the TransactionHeader string signer_public_key = 10;

}
The payload in the preceding transaction is in the form of bytes and the payload is opaque to the core system, which means that the Sawtooth core will not process the transaction payload; the payload is specific and is handled only by the transaction family. How to encode and decode the payload depends on the approach that you choose for your smart contract. The second argument, context, is an instance of the Context class from the Python SDK. The context allows the API to access the current state in the global state on a validator. All validator interactions by the transaction handler should be made through the Context.

The APIs in the Context are get_state, set_state, and delete_state. Based on the address in the global state, they are defined as follows:
class Context:

def get_state(self, addresses, timeout=None):

def set_state(self, entries, timeout=None):

def delete_state(self, addresses, timeout=None):

Here is a link to the source files of this recipe.

To recap, so far you learned how to configure Hyperledger Sawtooth (Validator and REST API), design namespace and address for Hyperledger Sawtooth transaction family, build transaction handler and processor for Hyperledger Sawtooth, and build transaction processor service and python egg for Hyperledger Sawtooth.

The following recipes are excellent resources for installing other Hyperledger tools:

Blockchain Developer Guide- How to Install and work with Hyperledger Sawtooth
Blockchain Developer Guide- How to Install Hyperledger Fabric on AWS
Blockchain Hyperledger Composer Business Network Modeling and Environment Setup
Blockchain Developer Guide- How to Install Hyperledger Burrow on AWS
Blockchain Developer Guide- How to Install Hyperledger Seth and Docker on AWS
Blockchain Developer Guide- How to Install Hyperledger Indy and Indy CLI on AWS

To conclude this recipe, we like to recommend our Blockchain Hyperledger Development in 30 hours course to those interested in pursuing a blockchain development career. Indeed, as of this writing, Hyperledger Foundation offers the following two Hyperledger certifications: The Certified Hyperledger Fabric Administrator (CHFA) and The Certified Hyperledger Sawtooth Administrator (CHSA), both of which are highly regarded in the industry. Hyperledger Foundation is in the process of creating Hyperledger Developer certification program, which may be released in early or middle of 2020. In short, by taking our hands-on online Hyperledger class, you would be able to obtain CHFA certification.

This tutorial is written by Brian Wu who is our senior Hyperledger instructor in Washington DC. His Hyperledger Cookbook with 40+ hands-on recipes is highly recommended.

Related Training Courses

Hands-on Node.JS, MongoDB and Express.js Training
Advance JavaScript, jQuery Using JSON and Ajax
Learn Hands-on Blockchain Ethereum Development & Get Certified in 30 Hrs
Learn Blockchain Hyperledger Development & Get Certified in 30 Hrs
Become Blockchain Certified Security Architect in 30 hours
Blockchain Certified Solution Architect in 30 hours
Introduction to Python Programming
Object Oriented Programming with UML


Private and Custom Tutoring

We provide private tutoring classes online and offline (at our DC site or your preferred location) with custom curriculum for almost all of our classes for $50 per hour online or $75 per hour in DC. Give us a call or submit our private tutoring registration form to discuss your needs.


View Other Classes!