Code Reusability via CordaService— Engineering Principles on Corda
January 04, 2021
Most developers have learned Best Engineering Principles but it’s not always straightforward to follow these rules on Distributed Ledger Technology (DLT) platforms. Let’s have a quick dive in and see how we can achieve one of the main engineering principles — Code Reusability — on the Corda platform.
Corda is a DLT Platform that was created specifically for businesses, offering privacy, scalability, and interoperability. It was designed to meet one of the most highly regulated and complex industries in the world — finance, but it can be applied to other types of enterprises as well. Corda is used primarily to reduce reconciliation efforts for its participants while increasing the speed of business.
What is the problem?
While writing CorDapps we need a place to store common functionalities (for example, vault queries or calls to external services) that can be used by flows to achieve code reusability.
This is where Service classes come in. Services classes are long-lived classes that provide a place to store reusable functionalities that can be accessed by flows within a node. While flows are short-lived classes, functions can be decoupled from flows into Service classes, and these functions can be called from other services or flows.
How to write a CordaService
Service classes are long-lived instances that can be triggered by flows from within a node or can trigger a flow by listening on a specific type of state update/creation. A Service class is limited to a single instance per node. During startup, the node handles the creation of the service.
Writing a CordaService
class is very easy — just follow these steps:
- Annotate a class with
@CordaService
. - Extend the class from
SingletonSerializeAsToken
. - Create a constructor with a single parameter
AppServiceHub
type.
In the example above, the CordaService
is triggered by trackBy
, which listens on a completed transaction that contains a specified state and executes CordaService
functionality in response to it (read more about that here). If there are calls to other flows inside trackBy
then those flows must be annotated with @StartableByService
.
Another way to trigger a CordaService
is by calling it explicitly from a flow class inside any function except a constructor (you get an error message if a flow instance is not initiated before you make a call to Services):
To sum up
Corda Services allow you to separate functionalities from flow to external classes allowing for code reusability and access of shared resources between flows — you put your code inside the Service class.
To create a Service class simply annotate a class with @CordaService,
extend it from SingletonSerializeAsToken
and add a constructor with a single argument of type AppServiceHub
. If you use trackBy
in your service where you call other flows, don’t forget to annotate those flows with @StartableByService
. Now your Corda Service is ready to be used from any function of flow, except a constructor. Enjoy!
The link to the sample is here.
—Dr. Iryna Tsimashenka is a Developer Evangelist at R3, an enterprise blockchain software firm working with a global ecosystem of more than 350 participants across multiple industries from both the private and public sectors to develop on Corda, its open-source blockchain platform, and Corda Enterprise, a commercial version of Corda for enterprise usage.
Follow Iryna on Twitter here.