Blockchain Corda Application

Develop your first Decentralized Application using Corda Distributed Ledger

Read Recipe

Building A Blockchain Decentralized Application using Corda Distributed Ledger

Step-by-Step Recipe

Corda along with Hyperledger and Ethereum are 3 dominant platforms for building blockchain applications. Unlike Hyperledger and Ethereum, Corda is mainly focused on building distributed ledger applications. It uses Kotlin and Java programming languages.

In this tutorial, we will build our first Corda application. Specifically, we develop the following:

  • The CorDapp Template
  • Writing the state
  • Writing the flow
  • Running our CorDapp

This tutorial assumes that you already have setup Corda dev environment, you have run your first CorDapp (see Build and Run Sample Corda Decentralized App for a Distributed Ledger tutorial for details), and you are familiar with Corda’s key concepts.

If you’re a developer, the next step is to write your own CorDapp. CorDapps are applications that are installed on one or more Corda nodes, and that allow the node’s operator to instruct their node to perform some new process - anything from issuing a debt instrument to making a restaurant booking.
If you are not familiar with Corda or distributed ledger technology, here is a good article to get you started.

Our use-case

We will write a CorDapp to model IOUs on the blockchain. Each IOU – short for “I O(we) (yo)U” – will record the fact that one node owes another node a certain amount. This simple CorDapp will showcase several key benefits of Corda as a blockchain platform:

  • Privacy - Since IOUs represent sensitive information, we will be taking advantage of Corda’s ability to only share ledger updates with other nodes on a need-to-know basis, instead of using a gossip protocol to share this information with every node on the network as you would with a traditional blockchain platform
  • Well-known identities - Each Corda node has a well-known identity on the network. This allows us to write code in terms of real identities, rather than anonymous public keys
  • Re-use of existing, proven technologies - We will be writing our CorDapp using standard Java. It will run on a Corda node, which is simply a Java process and runs on a regular Java machine (e.g. on your local machine or in the cloud). The nodes will store their data in a standard SQL database

CorDapps usually define at least three things:

  • States - the (possibly shared) facts that are written to the ledger
  • Flows - the procedures for carrying out specific ledger updates
  • Contracts - the constraints governing how states of a given type can evolve over time

Our IOU CorDapp is no exception. It will define the following components:

The IOUState
Our state will be the IOUState, representing an IOU. It will contain the IOU’s value, its lender and its borrower. We can visualize IOUState as follows:

Corda blockchain development

The IOUFlow

Our flow will be the IOUFlow. This flow will completely automate the process of issuing a new IOU onto a ledger. It has the following steps:


Corda blockchain development

The IOUContract

For this tutorial, we will use the default TemplateContract. We will update it to create a fully-fledged IOUContract in the next step.
So far, we have designed a simple CorDapp that will allow nodes to agree new IOUs on the blockchain.
Next, we’ll take a look at the template project we’ll be using as the basis for our CorDapp.

The CorDapp Template

When writing a new CorDapp, you will generally want to start from one of the standard templates:

* The Java Cordapp Template =>

* The Kotlin Cordapp Template =>

The Cordapp templates provide the boilerplate for developing a new CorDapp. CorDapps can be written in either Java or Kotlin. We will be providing the code in both languages throughout this tutorial.

Note that there's no need to download and install Corda itself. The required libraries are automatically downloaded from an online Maven repository and cached locally.

Downloading the template
Open a terminal window in the directory where you want to download the CorDapp template, and run the following command:

.. container:: codeset

    .. code-block:: java

        git clone ; cd cordapp-template-java

    .. code-block:: kotlin

        git clone ; cd cordapp-template-kotlin

Opening the template in IntelliJ

Once the template is download, open it in IntelliJ by following the instructions here:

Template structure

For this tutorial, we will only be modifying the following files:

.. container:: codeset

    .. code-block:: java

        // 1. The state

        // 2. The flow

    .. code-block:: kotlin

        // 1. The state

        // 2. The flow

Step II- Writing the state

In Corda, shared facts on the blockchain are represented as states. Our first task will be to define a new state type to represent an IOU.

The ContractState interface
A Corda state is any instance of a class that implements the ContractState interface. The ContractState interface is defined as follows:
.. container:: codeset
    .. code-block:: kotlin
        interface ContractState {
            // The list of entities considered to have a stake in this state.
            val participants: List<AbstractParty>
We can see that the ContractState interface has a single field, participants. participants is a list of the entities for which this state is relevant.
Beyond this, our state is free to define any fields, methods, helpers or inner classes it requires to accurately represent a given type of shared fact on the blockchain.
.. note::
    The first thing you'll probably notice about the declaration of ContractState is that it is not written in Java or another common language. The core Corda platform, including the interface declaration above, is entirely written in Kotlin.
    Learning some Kotlin will be very useful for understanding how Corda works internally, and usually only takes an experienced Java developer a day or so to pick up. However, learning Kotlin isn't essential. Because Kotlin code compiles to JVM bytecode, CorDapps written in other JVM languages such as Java can interoperate with Corda.
Modeling IOUs
How should we define the IOUState representing IOUs on the blockchain? Beyond implementing the ContractState interface, our IOUState will also need properties to track the relevant features of the IOU:
* The value of the IOU
* The lender of the IOU
* The borrower of the IOU
There are many more fields you could include, such as the IOU's currency, but let's ignore those for now. Adding them later is often as simple as adding an additional property to your class definition.

Defining IOUState
Let's get started by opening (for Java) or StatesAndContracts.kt (for Kotlin) and updating TemplateState to define an IOUState:
.. container:: codeset
    .. literalinclude:: example-code/src/main/kotlin/net/corda/docs/kotlin/tutorial/helloworld/IOUState.kt
        :language: kotlin
        :start-after: DOCSTART 01
        :end-before: DOCEND 01
    .. literalinclude:: example-code/src/main/java/net/corda/docs/java/tutorial/helloworld/
        :language: java
        :start-after: DOCSTART 01
        :end-before: DOCEND 01
If you're following along in Java, you'll also need to rename to
To define IOUState, we've made the following changes:
We've renamed the TemplateState class to IOUState
We've added properties for value, lender and borrower, along with the required getters and setters in Java: value is of type int (in Java)/Int (in Kotlin) and lender and borrower are of type Party
Party is a built-in Corda type that represents an entity on the network
We've overridden participants to return a list of the lender and borrower
participants is a list of all the parties who should be notified of the creation or consumption of this state
The IOUs that we issue onto a ledger will simply be instances of this class.

Progress so far
We've defined an IOUState that can be used to represent IOUs as shared facts on a ledger. As we've seen, states in Corda are simply classes that implement the ContractState interface. They can have any additional properties and methods you like.
All that is left to do is write the IOUFlow that will allow a node to orchestrate the creation of a new IOUState on the blockchain, while only sharing information on a need-to-know basis.
What about the contract?
Each state has an associated contract that imposes invariants on how the state evolves over time. Including a contract isn't crucial for our first CorDapp, so we'll just use the empty TemplateContract and TemplateContract.Commands.Action command defined by the template for now. In the next step, we'll implement our own contract and command.
Writing the flow
A flow encodes a sequence of steps that a node can perform to achieve a specific ledger update. By installing new flows on a node, we allow the node to handle new business processes. The flow we define will allow a node to issue an IOUState onto the ledger.

Flow outline
The goal of our flow will be to orchestrate an IOU issuance transaction. Transactions in Corda are the atomic units of change that update the ledger. Each transaction is a proposal to mark zero or more existing states as historic (the inputs), while creating zero or more new states (the outputs).
The process of creating and applying this transaction to a ledger will be conducted by the IOU's lender, and will require the following steps:
  1. Building the transaction proposal for the issuance of a new IOU onto a ledger
  2. Signing the transaction proposal
  3. Recording the transaction and sending it to the IOU's borrower so that they can record it too
We also need the borrower to receive the transaction and record it for itself. At this stage, we do not require the borrower to approve and sign IOU issuance transactions. We will be able to impose this requirement when we look at contracts in the next tutorial.
.. warning:: The execution of a flow is distributed in space and time, as the flow crosses node boundaries and each participant may have to wait for other participants to respond before it can complete its part of the overall work. While a node is waiting, the state of its flow may be persistently recorded to disk as a restorable checkpoint, enabling it to carry on where it left off when a counterparty responds. However,             before a node can be upgraded to a newer version of Corda, or of your Cordapp, all flows must have completed, as there is no mechanism to upgrade a persisted flow checkpoint. It is therefore undesirable to model a long-running business process as a single flow: it should rather be broken up into a series of transactions, with flows used only to orchestrate the completion of each transaction.
Tasks like recording a transaction or sending a transaction to a counterparty are very common in Corda. Instead of forcing each developer to reimplement their own logic to handle these tasks, Corda provides a number of library flows to handle these tasks. We call these flows that are invoked in the context of a larger flow to handle a repeatable task *subflows*.
All flows must subclass FlowLogic. You then define the steps taken by the flow by overriding
Let's define our IOUFlow. Replace the definition of Initiator with the following:
.. container:: codeset
    .. literalinclude:: example-code/src/main/kotlin/net/corda/docs/kotlin/tutorial/helloworld/IOUFlow.kt
        :language: kotlin
        :start-after: DOCSTART 01
        :end-before: DOCEND 01
    .. literalinclude:: example-code/src/main/java/net/corda/docs/java/tutorial/helloworld/
        :language: java
        :start-after: DOCSTART 01
        :end-before: DOCEND 01
If you're following along in Java, you'll also need to rename to
Let's walk through this code step-by-step.
We've defined our own FlowLogic subclass that overrides has a return type that must match the type parameter passed to FlowLogic - this is type returned by running the flow.
FlowLogic subclasses can optionally have constructor parameters, which can be used as arguments to In our case, we have two:
iouValue, which is the value of the IOU being issued
otherParty, the IOU's borrower (the node running the flow is the lender) is annotated @Suspendable - this allows the flow to be check-pointed and serialised to disk when it encounters a long-running operation, allowing your node to move on to running other flows. Forgetting this annotation out will lead to some very weird error messages!
There are also a few more annotations, on the FlowLogic subclass itself:
@InitiatingFlow means that this flow is part of a flow pair and that it triggers the other side to run the counterpart flow (which in our case is the IOUFlowResponder defined below).
@StartableByRPC allows the node owner to start this flow via an RPC call
Let's walk through the steps of itself. This is where we actually describe the procedure for issuing the IOUState onto a ledger.
Choosing a notary
Every transaction requires a notary to prevent double-spends and serve as a timestamping authority. The first thing we do in our flow is retrieve a notary from the node's ServiceHub. 
ServiceHub.networkMapCache provides information about the other nodes on the network and the services that they offer.
.. note::
    Whenever we need information within a flow - whether it's about our own node's identity, the node's local storage, or the rest of the network - we generally obtain it via the node's ServiceHub.
Building the transaction
We'll build our transaction proposal in two steps:
Creating the transaction's components
Adding these components to a transaction builder
Transaction items
Our transaction will have the following structure:

Corda blockchain development

     :scale: 15%
     :align: center
* The output IOUState on the right represents the state we will be adding to the ledger. As you can see, there are no inputs - we are not consuming any existing ledger states in the creation of our IOU
* An Action command listing the IOU's lender as a signer
We've already talked about the IOUState, but we haven't looked at commands yet. Commands serve two functions:
They indicate the intent of a transaction - issuance, transfer, redemption, revocation. This will be crucial when we discuss contracts in the next step.
They allow us to define the required signers for the transaction. For example, IOU creation might require signatures from the lender only, whereas the transfer of an IOU might require signatures from both the IOU’s borrower and lender
Each Command contains a command type plus a list of public keys. For now, we use the pre-defined TemplateContract.Action as our command type, and we list the lender as the only public key. This means that for the transaction to be valid, the lender is required to sign the transaction.

Creating a transaction builder
To actually build the proposed transaction, we need a TransactionBuilder. This is a mutable transaction class to which we can add inputs, outputs, commands, and any other items the transaction needs. We create a TransactionBuilder that uses the notary we retrieved earlier.
Once we have the TransactionBuilder, we add our components:
The command is added directly using TransactionBuilder.addCommand
The output IOUState is added using TransactionBuilder.addOutputState. 
As well as the output state itself, this method takes a reference to the contract that will govern the evolution of the state over time. Here, we are passing in a reference to the TemplateContract, which imposes no constraints. We will define a contract imposing real constraints in the next tutorial

Signing the transaction
Now that we have a valid transaction proposal, we need to sign it. Once the transaction is signed, no-one will be able to modify the transaction without invalidating this signature. This effectively makes the transaction immutable.
We sign the transaction using ServiceHub.signInitialTransaction, which returns a SignedTransaction. A SignedTransaction is an object that pairs a transaction with a list of signatures over that transaction.

Finalizing the transaction
We now have a valid signed transaction. All that's left to do is to get the notary to sign it, have that recorded locally and then send it to all the relevant parties. Once that happens, the transaction will become a permanent part of the ledger. We use FinalityFlow which does all of this for the lender.
For the borrower to receive the transaction they just need a flow that responds to the seller's.

Creating the borrower's flow
The borrower has to use ReceiveFinalityFlow in order to receive and record the transaction; it needs to respond to the lender's flow. Let's do that by replacing Responder from the template with the following:
.. container:: codeset
    .. literalinclude:: example-code/src/main/kotlin/net/corda/docs/kotlin/tutorial/helloworld/IOUFlowResponder.kt
        :language: kotlin
        :start-after: DOCSTART 01
        :end-before: DOCEND 01
    .. literalinclude:: example-code/src/main/java/net/corda/docs/java/tutorial/helloworld/
        :language: java
        :start-after: DOCSTART 01
        :end-before: DOCEND 01
As with the IOUFlow, our IOUFlowResponder flow is a FlowLogic subclass where we've overridden
The flow is annotated with InitiatedBy(IOUFlow.class), which means that your node will invoke when it receives a message from a instance of Initiator running on another node. This message will be the finalized transaction which will be recorded in the borrower's vault.

Progress so far
Our flow and our CorDapp are now ready! We have now defined a flow that we can start on our node to completely automate the process of issuing an IOU onto the ledger. All that's left is to spin up some nodes and test our CorDapp.
Running our CorDapp

Now that we've written a CorDapp, it's time to test it by running it on some real Corda nodes.

Deploying our CorDapp
Let's take a look at the nodes we're going to deploy. Open the project's build.gradle file and scroll down to the task deployNodes section. This section defines three nodes. There are two standard nodes (PartyA and PartyB), plus a special network map/notary node that is running the network map service and advertises a validating notary service.
.. code:: bash
    task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
        nodeDefaults {
                cordapps = [
        directory "./build/nodes"
        node {
            name "O=Notary,L=London,C=GB"
            notary = [validating : true]
            p2pPort 10002
            rpcPort 10003
        node {
            name "O=PartyA,L=London,C=GB"
            p2pPort 10005
            rpcPort 10006
            webPort 10007
            rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL]]]
        node {
            name "O=PartyB,L=New York,C=US"
            p2pPort 10008
            rpcPort 10009
            webPort 10010
            sshdPort 10024
            rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
We can run this deployNodes task using Gradle. For each node definition, Gradle will:
Package the project's source files into a CorDapp jar
Create a new node in build/nodes with our CorDapp already installed
We can do that now by running the following commands from the root of the project:
.. code:: bash
    // On Windows
    gradlew clean deployNodes
    // On Mac
    ./gradlew clean deployNodes
Running the nodes
Running deployNodes will build the nodes under build/nodes. If we navigate to one of these folders, we'll see the three node folders. Each node folder has the following structure:
    .. code:: bash
        |____corda.jar                     // The runnable node
        |____corda-webserver.jar           // The node's webserver (The notary doesn't need a web server)
        |____node.conf                     // The node's configuration file
        |____java/kotlin-source-0.1.jar  // Our IOU CorDapp

Let's start the nodes by running the following commands from the root of the project:
.. code:: bash
    // On Windows
    // On Mac
This will start a terminal window for each node, and an additional terminal window for each node's webserver – five terminal windows in all. Give each node a moment to start - you'll know it's ready when its terminal windows displays the message, "Welcome to the Corda interactive shell".

Corda blockchain development

     :scale: 25%
     :align: center

Interacting with the nodes
Now that our nodes are running, let's order one of them to create an IOU by kicking off our IOUFlow. In a larger app, we'd generally provide a web API sitting on top of our node. Here, for simplicity, we'll be interacting with the node via its built-in CRaSH shell.
Go to the terminal window displaying the CRaSH shell of PartyA. Typing help will display a list of the available commands.
.. note:: Local terminal shell is available only in a development mode. In production environment SSH server can be enabled.
    More about SSH and how to connect can be found on the :doc:`shell` page.
We want to create an IOU of 99 with PartyB. We start the IOUFlow by typing:
.. code-block:: bash
    start IOUFlow iouValue: 99, otherParty: "O=PartyB,L=New York,C=US"
This single command will cause PartyA and PartyB to automatically agree an IOU. This is one of the great advantages of the flow framework - it allows you to reduce complex negotiation and update processes into a single function call.
If the flow worked, it should have recorded a new IOU in the vaults of both PartyA and PartyB. Let's check.
We can check the contents of each node's vault by running:
.. code-block:: bash
    run vaultQuery contractStateType: com.template.IOUState
The vaults of PartyA and PartyB should both display the following output:
.. code:: bash
    - state:
          value: 99
          lender: "C=GB,L=London,O=PartyA"
          borrower: "C=US,L=New York,O=PartyB"
          - "C=GB,L=London,O=PartyA"
          - "C=US,L=New York,O=PartyB"
        contract: "com.template.contract.IOUContract"
        notary: "C=GB,L=London,O=Notary"
        encumbrance: null
          attachmentId: "F578320232CAB87BB1E919F3E5DB9D81B7346F9D7EA6D9155DC0F7BA8E472552"
        txhash: "5CED068E790A347B0DD1C6BB5B2B463406807F95E080037208627565E6A2103B"
        index: 0
    - ref:
        txhash: "5CED068E790A347B0DD1C6BB5B2B463406807F95E080037208627565E6A2103B"
        index: 0
      contractStateClassName: "com.template.state.IOUState"
      recordedTime: 1506415268.875000000
      consumedTime: null
      status: "UNCONSUMED"
      notary: "C=GB,L=London,O=Notary"
      lockId: null
      lockUpdateTime: 1506415269.548000000
    totalStatesAvailable: -1
    stateTypes: "UNCONSUMED"
    otherResults: []
This is the transaction issuing our IOUState onto a ledger.
However, if we run the same command on the other node (the notary), we will see the following:
.. code:: bash
      "states" : [ ],
      "statesMetadata" : [ ],
      "totalStatesAvailable" : -1,
      "stateTypes" : "UNCONSUMED",
      "otherResults" : [ ]
This is the result of Corda's privacy model. Because the notary was not involved in the transaction and had no need to see the data, the transaction was not distributed to them.
We have written a simple CorDapp that allows IOUs to be issued onto the ledger. Our CorDapp is made up of two key parts:
The IOUState, representing IOUs on the blockchain
The IOUFlow, orchestrating the process of agreeing the creation of an IOU on-ledger
After completing this step, your CorDapp should look like this:
Next steps
There are a number of improvements we could make to this CorDapp:
We could add unit tests, using the contract-test and flow-test frameworks
We could change IOUState.value from an integer to a proper amount of a given currency
We could add an API, to make it easier to interact with the CorDapp
But for now, the biggest priority is to add an IOUContract imposing constraints on the evolution of each IOUState over time. We do this in the next step. 
Hello, World! Pt.2 - Contract constraints
.. note:: This tutorial extends the CorDapp built during the :doc:Hello, World tutorial <hello-world-introduction>.
In the Hello, World tutorial, we built a CorDapp allowing us to model IOUs on ledger. Our CorDapp was made up of two elements:
An IOUState, representing IOUs on the blockchain
An IOUFlow and IOUFlowResponder flow pair, orchestrating the process of agreeing the creation of an IOU on-ledger
However, our CorDapp did not impose any constraints on the evolution of IOUs on the blockchain over time. Anyone was free to create IOUs of any value, between any party.
In this step, we'll write a contract to imposes rules on how an IOUState can change over time. In turn, this will require some small changes to the flow we defined in the previous steps.
We'll start by writing the contract.
.. toctree::
   :maxdepth: 1
Writing the contract
It's easy to imagine that most CorDapps will want to impose some constraints on how their states evolve over time:
A cash CorDapp will not want to allow users to create transactions that generate money out of thin air (at least without the involvement of a central bank or commercial bank)
A loan CorDapp might not want to allow the creation of negative-valued loans
An asset-trading CorDapp will not want to allow users to finalise a trade without the agreement of their counterparty
In Corda, we impose constraints on how states can evolve using contracts.
.. note::
    Contracts in Corda are very different to the smart contracts of other distributed ledger platforms. They are not stateful objects representing the current state of the world. Instead, like a real-world contract, they simply impose rules on what kinds of transactions are allowed.
Every state has an associated contract. A transaction is invalid if it does not satisfy the contract of every input and output state in the transaction.

The Contract interface
Just as every Corda state must implement the ContractState interface, every contract must implement the
Contract interface:
.. container:: codeset
    .. code-block:: kotlin
        interface Contract {
            // Implements the contract constraints in code.
            fun verify(tx: LedgerTransaction)
We can see that Contract expresses its constraints through a verify function that takes a transaction as input,and:
Throws an IllegalArgumentException if it rejects the transaction proposal
Returns silently if it accepts the transaction proposal
Controlling IOU evolution
What would a good contract for an IOUState look like? There is no right or wrong answer - it depends on how you want your CorDapp to behave.
For our CorDapp, let's impose the constraint that we only want to allow the creation of IOUs. We don't want nodes to transfer them or redeem them for cash. One way to enforce this behavior would be by imposing the following constraints:
A transaction involving IOUs must consume zero inputs, and create one output of type IOUState
The transaction should also include a Create command, indicating the transaction's intent (more on commands  shortly)
We might also want to impose some constraints on the properties of the issued IOUState:
Its value must be non-negative
The lender and the borrower cannot be the same entity
And finally, we'll want to impose constraints on who is required to sign the transaction:
The IOU's lender must sign
The IOU's borrower must sign
We can picture this transaction as follows: 

Corda blockchain development

    :scale: 15%
    :align: center
Defining IOUContract
Let's write a contract that enforces these constraints. We'll do this by modifying either or TemplateContract.kt and updating to define an IOUContract:
.. container:: codeset
    .. literalinclude:: example-code/src/main/kotlin/net/corda/docs/kotlin/tutorial/twoparty/IOUContract.kt
        :language: kotlin
        :start-after: DOCSTART 01
        :end-before: DOCEND 01
    .. literalinclude:: example-code/src/main/java/net/corda/docs/java/tutorial/twoparty/
        :language: java
        :start-after: DOCSTART 01
        :end-before: DOCEND 01
If you're following along in Java, you'll also need to rename to
Let's walk through this code step by step.
The Create command
The first thing we add to our contract is a *command*. Commands serve two functions:
They indicate the transaction's intent, allowing us to perform different verification for different types of  transaction. For example, a transaction proposing the creation of an IOU could have to meet different constraints to one redeeming an IOU
They allow us to define the required signers for the transaction. For example, IOU creation might require signatures  from the lender only, whereas the transfer of an IOU might require signatures from both the IOU's borrower and lender
Our contract has one command, a Create command. All commands must implement the CommandData interface.
The CommandData interface is a simple marker interface for commands. In fact, its declaration is only two words long (Kotlin interfaces do not require a body):
.. container:: codeset
    .. code-block:: kotlin
        interface CommandData

The verify logic
Our contract also needs to define the actual contract constraints by implementing verify. Our goal in writing the verify function is to write a function that, given a transaction:
Throws an IllegalArgumentException if the transaction is considered invalid
Does **not** throw an exception if the transaction is considered valid
In deciding whether the transaction is valid, the verify function only has access to the contents of the transaction:
tx.inputs, which lists the inputs
tx.outputs, which lists the outputs
tx.commands, which lists the commands and their associated signers
As well as to the transaction's attachments and time-window, which we won't use here.
Based on the constraints enumerated above, we need to write a verify function that rejects a transaction if any of the following are true:
The transaction doesn't include a Create command
The transaction has inputs
The transaction doesn't have exactly one output
The IOU itself is invalid
The transaction doesn't require the lender's signature

Command constraints
Our first constraint is around the transaction's commands. We use Corda's requireSingleCommand function to test for the presence of a single Create command.
If the Create command isn't present, or if the transaction has multiple Create commands, an exception will be thrown and contract verification will fail.

Transaction constraints
We also want our transaction to have no inputs and only a single output - an issuance transaction.
In Kotlin, we impose these and the subsequent constraints using Corda's built-in requireThat block. requireThat provides a terse way to write the following:
If the condition on the right-hand side doesn't evaluate to true...
...throw an IllegalArgumentException with the message on the left-hand side

As before, the act of throwing this exception causes the transaction to be considered invalid.
In Java, we simply throw an IllegalArgumentException manually instead.

IOU constraints
We want to impose two constraints on the IOUState itself:
Its value must be non-negative
The lender and the borrower cannot be the same entity
You can see that we're not restricted to only writing constraints inside verify. We can also write other statements - in this case, extracting the transaction's single IOUState and assigning it to a variable.

Signer constraints
Finally, we require both the lender and the borrower to be required signers on the transaction. A transaction's required signers is equal to the union of all the signers listed on the commands. We therefore extract the signers from the Create command we retrieved earlier.
This is an absolutely essential constraint - it ensures that no IOUState can ever be created on the blockchain without the express agreement of both the lender and borrower nodes.
Progress so far
We've now written an IOUContract constraining the evolution of each IOUState over time:
An IOUState can only be created, not transferred or redeemed
Creating an IOUState requires an issuance transaction with no inputs, a single IOUState output, and a  Create command
The IOUState created by the issuance transaction must have a non-negative value, and the lender and borrower must be different entities
Next, we'll update the IOUFlow so that it obeys these contract constraints when issuing an IOUState onto the ledger.
Updating the flow
We now need to update our flow to achieve three things:
Verifying that the transaction proposal we build fulfills the IOUContract constraints
Updating the lender's side of the flow to request the borrower's signature
Creating a response flow for the borrower that responds to the signature request from the lender
We'll do this by modifying the flow we wrote in the previous tutorial.

Verifying the transaction
In, change the imports block to the following:
.. container:: codeset
    .. literalinclude:: example-code/src/main/kotlin/net/corda/docs/kotlin/tutorial/twoparty/IOUFlow.kt
        :language: kotlin
        :start-after: DOCSTART 01
        :end-before: DOCEND 01
    .. literalinclude:: example-code/src/main/java/net/corda/docs/java/tutorial/twoparty/
        :language: java
        :start-after: DOCSTART 01
        :end-before: DOCEND 01
And update to the following:
.. container:: codeset
    .. literalinclude:: example-code/src/main/kotlin/net/corda/docs/kotlin/tutorial/twoparty/IOUFlow.kt
        :language: kotlin
        :start-after: DOCSTART 02
        :end-before: DOCEND 02
        :dedent: 8
    .. literalinclude:: example-code/src/main/java/net/corda/docs/java/tutorial/twoparty/
        :language: java
        :start-after: DOCSTART 02
        :end-before: DOCEND 02
        :dedent: 8
In the original CorDapp, we automated the process of notarising a transaction and recording it in every party's vault by invoking a built-in flow called FinalityFlow as a subflow. We're going to use another pre-defined flow, CollectSignaturesFlow, to gather the borrower's signature.
First, we need to update the command. We are now using IOUContract.Create, rather than TemplateContract.Commands.Action. We also want to make the borrower a required signer, as per the contract constraints. This is as simple as adding the borrower's public key to the transaction's command.
We also need to add the output state to the transaction using a reference to the IOUContract, instead of to the old TemplateContract.
Now that our state is governed by a real contract, we'll want to check that our transaction proposal satisfies these requirements before kicking off the signing process. We do this by calling TransactionBuilder.verify on our transaction proposal before finalising it by adding our signature.

Requesting the borrower's signature
Previously we wrote a responder flow for the borrower in order to receive the finalized transaction from the lender. We use this same flow to first request their signature over the transaction.
We gather the borrower's signature using CollectSignaturesFlow, which takes:
A transaction signed by the flow initiator
A list of flow-sessions between the flow initiator and the required signers
And returns a transaction signed by all the required signers.
We can then pass this fully-signed transaction into FinalityFlow.

Updating the borrower's flow
On the lender's side, we used CollectSignaturesFlow to automate the collection of signatures. To allow the borrower to respond, we need to update its responder flow to first receive the partially signed transaction for signing. Update to be the following:
.. container:: codeset
    .. literalinclude:: example-code/src/main/kotlin/net/corda/docs/kotlin/tutorial/twoparty/IOUFlowResponder.kt
        :language: kotlin
        :start-after: DOCSTART 1
        :end-before: DOCEND 1
        :dedent: 4
    .. literalinclude:: example-code/src/main/java/net/corda/docs/java/tutorial/twoparty/
        :language: java
        :start-after: DOCSTART 1
        :end-before: DOCEND 1
        :dedent: 4
We could write our own flow to handle this process. However, there is also a pre-defined flow called
SignTransactionFlow that can handle the process automatically. The only catch is that SignTransactionFlow is an
abstract class - we must subclass it and override SignTransactionFlow.checkTransaction.
SignTransactionFlow will automatically verify the transaction and its signatures before signing it. However, just because a transaction is contractually valid doesn't mean we necessarily want to sign. What if we don't want to deal with the counterparty in question or the value is too high, or we're not happy with the transaction's structure?
Overriding SignTransactionFlow.checkTransaction allows us to define these additional checks. In our case, we are checking that:
The transaction involves an IOUState - this ensures that IOUContract will be run to verify the transaction
The IOU's value is less than some amount (100 in this case)
If either of these conditions are not met, we will not sign the transaction - even if the transaction and its signatures are contractually valid.
Once we've defined the SignTransactionFlow subclass, we invoke it using FlowLogic.subFlow, and the communication with the borrower's and the lender's flow is conducted automatically.
SignedTransactionFlow returns the newly signed transaction. We pass in the transaction's ID to ReceiveFinalityFlow to ensure we are recording the correct notarised transaction from the lender.
Tutorial Conclusion
We have now updated our flow to verify the transaction and gather the lender's signature, in line with the constraints defined in IOUContract. We can now re-run our updated CorDapp, using the:doc: same instructions as before <hello-world-running>.
Our CorDapp now imposes restrictions on the issuance of IOUs. Most importantly, IOU issuance now requires agreement from both the lender and the borrower before an IOU can be created on the blockchain. This prevents either the lender or the borrower from unilaterally updating the ledger in a way that only benefits themselves.
After completing this tutorial, your CorDapp should look like this:

You should now be ready to develop your own CorDapps. If you want to learn more advance topics on Corda or other blockchain development platforms, the following classes are recommended:

Blockchain Hyperledger Fabric and Composer development- 30 hour course
Blockchain Ethereum development with Solidity- 30 hour course
Blockchain Corda R3 distributed ledger development- 30 hour course  
Become Blockchain Certified Security Architect in 30 hours

Private and Custom Training!

Private and Custom Tutoring

Through High School Technology Services or HSTS, we offer private custom tutoring classes both online and in DC for almost all of our courses or bootcamps starting from $60 per hour. Give us a call or email us to discuss your needs.

Program Terms and Policies

You can go to HSTS Terms and Policies page to review the terms and policies for cancellation, rescheduling, and refunds.

Let's Get In Touch!

Are you ready to invest in yourself, reinvent your career and earn a high income? That's great! Give us a call or stop by at 3165 Mt Pleasant St NW, DC


Attend our DC community events!

We organize community, free workshop, and networking events at our DC office, so check out our next event via below groups:

JavaScript DC Meetup Group
Coding & Technology Training Meetup Group
Coding Bootcamps Meetup Group

Coding Bootcamps and High School Technology Services are among brands of WEG2G Group