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.

Image for post

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:

  1. Annotate a class with @CordaService.
  2. Extend the class from SingletonSerializeAsToken.
  3. 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 AppServiceHubIf 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.