Porting Chainstack’s `No Ticket Scalping` CorDapp to Daml for Corda

This article discusses the steps taken to port Chainstack’s ‘No Ticket Scalping’ CorDapp to a Daml application running on a Daml for Corda deployment. This article will concentrate on the technical steps required; for a more in-depth description of the application itself, see Chainstack’s write up. The ported application is available on GitHub.

Approach

The approach taken was first to fully understand the CorDapp, then to switch it to a Daml-based application runnable on a Daml for Corda deployment, following the steps below.

  • Port the CorDapp contracts to Daml
  • Drop the web application portion into a new project
  • Switch the web application to use a Daml Ledger API based client in place of the Corda RPC one.
  • Code-generate the Daml contract bindings
  • Implement the controller methods using the Daml ledger client/bindings
  • Test the Daml application using the Daml Sandbox
  • Deploy to Daml for Corda.

Steps

The CorDapp was not intended to be a fully featured application, more a minimal example of how the different components integrate together. The porting process continues this theme by primarily highlighting the techniques used to port rather than enhancing the capabilities of the app.

Porting the CordApp Contracts to Daml

The application only has one contract. This contract signifies one ticket distributor giving another distributor the right to sell a number of tickets for a particular event. This is shown in Daml below:

To see how this might fit into a broader business flow modeled in Daml, have a look at the ticket issuance Daml example. This demonstrates how Daml is used to construct a chain of obligation from promoters, to venues and artists, then to distributors, and finally the fans themselves.

Move Over the Web Application Code

As we are no longer constrained by CorDapp patterns, we opted to use a Kotlin DSL-based Gradle project. We need to add a dependency on Kotlin and Spring Boot, which are used by the web application. The Corda dependencies are replaced with a dependency on the Daml rxjava client.  With this done we just drop in the source code from the web application itself.

Connect to the Daml Ledger Client

This is simply a case of constructing a DamlLedgerClient in place of a CordaRPCClient:


The client connection is made following the construction of the spring boot application

Daml Contract bindings

With Corda, the smart contract state is represented as `ContractState` state classes. These are available to application Java code. Similarly with Daml, rather than using the generic data structures to construct and parse Daml commands and contracts, it is possible to generate Java bindings that make the Daml contracts available in Java. We instruct the Daml command line assistant to generate code for us:


Generation of java bindings for Daml contracts 

Implement the Controller Methods

The original application was well designed and had a clean web service based interface between the web application and the backend services. This meant that the only changes needed to the UI were a few name changes.  

The controller methods needed to be re-implemented in terms of Daml contracts rather than Corda state.


How the /api/noScalping/distributions web service endpoint is served

Testing

To debug the initial version of the ported application, we ran our Daml code in the Daml Sandbox, available in the Daml SDK. This quickly allowed problems to be identified and fixed. Once the model had been debugged (in other words, once the Daml code itself was internally consistent) the application was ready for deployment onto one of Chainstack’s on-demand Daml for Corda nodes. 


The ported web application

Deploying onto Chainstack’s on-demand Daml for Corda nodes

Now we have the application ported time to get it running on Daml for Corda.  Start by requesting for a Daml for Corda node to be provisioned.


Provisioning a Chainstack Daml for Corda Node

Once the node is set up it is possible to log into the Chainstack console and view the running nodes.  Once provisioned the Daml for Corda nodes will have the Daml for Corda CorDapps pre installed and a Daml Ledger API running in the background.


The Chainstack node will come with Daml CorDapps loaded

Daml for Corda nodes will have, in addition to Corda RPC port a Daml Ledger API port.  This is the port that should be used when issuing Daml ledger commands to upload DAR files or create users.  For more detailed instructions about the ledger initialization see the README for the ticket application.


The ticket.dar file being uploaded to the Daml for Corda node in the example above running on port 10000.

Conclusion

In this case starting with a well designed application and using the approaches below allowed this modest application to be ported from Kotlin Corda to Daml for Corda in around a day.

In doing so we have managed to replace the contracts and workflows sub-projects with a single Daml file which makes the application easier to reason about and maintain.

To see or run the ported application see the GitHub repository.