Running the example CorDapp

The example CorDapp allows nodes to agree IOUs with each other, as long as they obey the following contract rules:

  • The IOU’s value is strictly positive
  • A node is not trying to issue an IOU to itself

We will deploy and run the CorDapp on four test nodes:

  • Notary, which runs a notary service
  • PartyA
  • PartyB
  • PartyC

Because data is only propagated on a need-to-know basis, any IOUs agreed between PartyA and PartyB become “shared facts” between PartyA and PartyB only. PartyC won’t be aware of these IOUs.

Downloading the example CorDapp

Start by downloading the example CorDapp from GitHub:

  • Set up your machine by following the quickstart guide
  • Clone the samples repository from using the following command: git clone
  • Change directories to the cordapp-example folder: cd samples/cordapp-example

Opening the example CorDapp in IntelliJ

Let’s open the example CorDapp in IntelliJ IDEA:

  • Open IntelliJ
  • A splash screen will appear. Click open, navigate to and select the cordapp-example folder, and click OK
  • Once the project is open, click File, then Project Structure. Under Project SDK:, set the project SDK by clicking New..., clicking JDK, and navigating to C:\Program Files\Java\jdk1.8.0_XXX on Windows or Library/Java/JavaVirtualMachines/jdk1.8.XXX on MacOSX (where XXX is the latest minor version number). Click Apply followed by OK
  • Again under File then Project Structure, select Modules. Click +, then Import Module, then select the cordapp-example folder and click Open. Choose to Import module from external model, select Gradle, click Next then Finish (leaving the defaults) and OK
  • Gradle will now download all the project dependencies and perform some indexing. This usually takes a minute or so

Project structure

The example CorDapp has the following structure:

├── build.gradle
├── clients
│   ├── build.gradle
│   └── src
│       └── main
│           ├── kotlin
│           │   └── com
│           │       └── example
│           │           └── server
│           │               ├── MainController.kt
│           │               ├── NodeRPCConnection.kt
│           │               └── Server.kt
│           └── resources
│               ├──
│               └── public
│                   ├── index.html
│                   └── js
│                       └── angular-module.js
├── config
│   ├── dev
│   │   └── log4j2.xml
│   └── test
│       └── log4j2.xml
├── contracts-java
│   ├── build.gradle
│   └── src
│       └── main
│           └── java
│               └── com
│                   └── example
│                       ├── contract
│                       │   └──
│                       ├── schema
│                       │   ├──
│                       │   └──
│                       └── state
│                           └──
├── contracts-kotlin
│   ├── build.gradle
│   └── src
│       └── main
│           └── kotlin
│               └── com
│                   └── example
│                       ├── contract
│                       │   └── IOUContract.kt
│                       ├── schema
│                       │   └── IOUSchema.kt
│                       └── state
│                           └── IOUState.kt
├── cordapp-example.iml
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └──
├── gradlew
├── gradlew.bat
├── lib
│   ├── README.txt
│   └── quasar.jar
├── settings.gradle
├── workflows-java
│   ├── build.gradle
│   └── src
│       ├── integrationTest
│       │   └── java
│       │       └── com
│       │           └── example
│       │               └──
│       ├── main
│       │   └── java
│       │       └── com
│       │           └── example
│       │               └── flow
│       │                   └──
│       └── test
│           └── java
│               └── com
│                   └── example
│                       ├──
│                       ├── contract
│                       │   └──
│                       └── flow
│                           └──
└── workflows-kotlin
    ├── build.gradle
    └── src
        ├── integrationTest
        │   └── kotlin
        │       └── com
        │           └── example
        │               └── DriverBasedTests.kt
        ├── main
        │   └── kotlin
        │       └── com
        │           └── example
        │               └── flow
        │                   └── ExampleFlow.kt
        └── test
            └── kotlin
                └── com
                    └── example
                        ├── NodeDriver.kt
                        ├── contract
                        │   └── IOUContractTests.kt
                        └── flow
                            └── IOUFlowTests.kt

The key files and directories are as follows:

  • The root directory contains some gradle files, a README and a LICENSE
  • config contains log4j2 configs
  • gradle contains the gradle wrapper, which allows the use of Gradle without installing it yourself and worrying about which version is required
  • lib contains the Quasar jar which rewrites our CorDapp’s flows to be checkpointable
  • clients contains the source code for spring boot integration
  • contracts-java and workflows-java contain the source code for the example CorDapp written in Java
  • contracts-kotlin and workflows-kotlin contain the same source code, but written in Kotlin. CorDapps can be developed in either Java and Kotlin

Running the example CorDapp

There are two ways to run the example CorDapp:

  • Via the terminal
  • Via IntelliJ

Both approaches will create a set of test nodes, install the CorDapp on these nodes, and then run the nodes. You can read more about how we generate nodes here .

Running the example CorDapp from the terminal

Building the example CorDapp

  • Open a terminal window in the cordapp-example directory
  • Run the deployNodes Gradle task to build four nodes with our CorDapp already installed on them:
    • Unix/Mac OSX: ./gradlew deployNodes
    • Windows: gradlew.bat deployNodes
  • After the build finishes, you will see the following output in the workflows-kotlin/build/nodes folder:

    • A folder for each generated node
    • A runnodes shell script for running all the nodes simultaneously on osX
    • A runnodes.bat batch file for running all the nodes simultaneously on Windows
  • Each node in the nodes folder will have the following structure:

. nodeName
├── additional-node-infos  //
├── certificates
├── corda.jar              // The Corda node runtime
├── cordapps               // The node's CorDapps
│   ├── corda-finance-contracts-4.2.jar
│   ├── corda-finance-workflows-4.2.jar
│   └── cordapp-example-0.1.jar
├── drivers
├── logs
├── network-parameters
├── node.conf              // The node's configuration file
├── nodeInfo-<HASH>        // The hash will be different each time you generate a node
└──      // The node's database

Running the example CorDapp

Start the nodes by running the following command from the root of the cordapp-example folder:

  • Unix/Mac OSX: workflows-kotlin/build/nodes/runnodes
  • Windows: call workflows-kotlin\build\nodes\runnodes.bat

Each Spring Boot server needs to be started in its own terminal/command prompt, replace X with A, B and C:

  • Unix/Mac OSX: ./gradlew runPartyXServer
  • Windows: gradlew.bat runPartyXServer

Look for the Started ServerKt in X seconds message, don’t rely on the % indicator.

For each node, the runnodes script creates a node tab/window:

   ______               __
  / ____/     _________/ /___ _
 / /     __  / ___/ __  / __ `/         Top tip: never say "oops", instead
/ /___  /_/ / /  / /_/ / /_/ /          always say "Ah, Interesting!"
\____/     /_/   \__,_/\__,_/

--- Corda Open Source corda-4.2 (4157c25) -----------------------------------------------

Logs can be found in                    : /Users/joeldudley/Desktop/cordapp-example/workflows-kotlin/build/nodes/PartyA/logs
Database connection url is              : jdbc:h2:tcp://localhost:59472/node
Incoming connection address             : localhost:10005
Listening on port                       : 10005
Loaded CorDapps                         : corda-finance-corda-4.2, cordapp-example-0.1, corda-core-corda-4.2
Node for "PartyA" started up and registered in 38.59 sec

Welcome to the Corda interactive shell.
Useful commands include 'help' to see what is available, and 'bye' to shut down the node.

Fri Mar 02 17:34:02 GMT 2018>>>

It usually takes around 60 seconds for the nodes to finish starting up. To ensure that all the nodes are running, you can query the ‘status’ end-point located at http://localhost:[port]/api/status (e.g. http://localhost:50005/api/status for PartyA).

Running the example CorDapp from IntelliJ

  • Select the Run Example CorDapp - Kotlin run configuration from the drop-down menu at the top right-hand side of the IDE

  • Click the green arrow to start the nodes:run config drop down

  • To stop the nodes, press the red square button at the top right-hand side of the IDE, next to the run configurations

Interacting with the example CorDapp


The Spring Boot servers run locally on the following ports:

  • PartyA: localhost:50005
  • PartyB: localhost:50006
  • PartyC: localhost:50007

These ports are defined in clients/build.gradle.

Each Spring Boot server exposes the following endpoints:

  • /api/example/me
  • /api/example/peers
  • /api/example/ious
  • /api/example/create-iou with parameters iouValue and partyName which is CN name of a node

There is also a web front-end served from the home web page e.g. localhost:50005.

Creating an IOU via the endpoint

An IOU can be created by sending a PUT request to the /api/example/create-iou endpoint directly, or by using the the web form served from the home directory.

To create an IOU between PartyA and PartyB, run the following command from the command line:

curl -X PUT 'http://localhost:50005/api/example/create-iou?iouValue=1&partyName=O=PartyB,L=New%20York,C=US'

Note that both PartyA’s port number (50005) and PartyB are referenced in the PUT request path. This command instructs PartyA to agree an IOU with PartyB. Once the process is complete, both nodes will have a signed, notarised copy of the IOU. PartyC will not.

Submitting an IOU via the web front-end

To create an IOU between PartyA and PartyB, navigate to the home directory for the node, click the “create IOU” button at the top-left of the page, and enter the IOU details into the web-form. The IOU must have a positive value. For example:

Counterparty: Select from list
Value (Int):   5

And click submit. Upon clicking submit, the modal dialogue will close, and the nodes will agree the IOU.

Checking the output

Assuming all went well, you can view the newly-created IOU by accessing the vault of PartyA or PartyB:

Via the HTTP API:

Via home page:

The vault and web front-end of PartyC (at localhost:50007) will not display any IOUs. This is because PartyC was not involved in this transaction.

Via the interactive shell (terminal only)

Nodes started via the terminal will display an interactive shell:

Welcome to the Corda interactive shell.
Useful commands include 'help' to see what is available, and 'bye' to shut down the node.

Fri Jul 07 16:36:29 BST 2017>>>

Type flow list in the shell to see a list of the flows that your node can run. In our case, this will return the following list:


Creating an IOU via the interactive shell

We can create a new IOU using the ExampleFlow$Initiator flow. For example, from the interactive shell of PartyA, you can agree an IOU of 50 with PartyB by running flow start ExampleFlow$Initiator iouValue: 50, otherParty: "O=PartyB,L=New York,C=US".

This will print out the following progress steps:

✅   Generating transaction based on new IOU.
✅   Verifying contract constraints.
✅   Signing transaction with our private key.
✅   Gathering the counterparty's signature.
    ✅   Collecting signatures from counterparties.
    ✅   Verifying collected signatures.
✅   Obtaining notary signature and recording transaction.
    ✅   Requesting signature by notary service
            Requesting signature by Notary service
            Validating response from Notary service
    ✅   Broadcasting transaction to participants
✅   Done

Checking the output

We can also issue RPC operations to the node via the interactive shell. Type run to see the full list of available operations.

You can see the newly-created IOU by running run vaultQuery contractStateType: com.example.state.IOUState.

As before, the interactive shell of PartyC will not display any IOUs.

Via the h2 web console

You can connect directly to your node’s database to see its stored states, transactions and attachments. To do so, please follow the instructions in Node database .

Running nodes across machines

The nodes can be configured to communicate as a network even when distributed across several machines:

  • Deploy the nodes as usual:

    • Unix/Mac OSX: ./gradlew deployNodes
    • Windows: gradlew.bat deployNodes
  • Navigate to the build folder (workflows-kotlin/build/nodes)

  • For each node, open its node.conf file and change localhost in its p2pAddress to the IP address of the machine where the node will be run (e.g. p2pAddress="")

  • These changes require new node-info files to be distributed amongst the nodes. Use the network bootstrapper tool (see Network Bootstrapper ) to update the files and have them distributed locally:java -jar network-bootstrapper.jar workflows-kotlin/build/nodes

  • Move the node folders to their individual machines (e.g. using a USB key). It is important that none of the nodes - including the notary - end up on more than one machine. Each computer should also have a copy of runnodes and runnodes.bat.For example, you may end up with the following layout:

    • Machine 1: Notary, PartyA, runnodes, runnodes.bat
    • Machine 2: PartyB, PartyC, runnodes, runnodes.bat
  • After starting each node, the nodes will be able to see one another and agree IOUs among themselves

Testing your CorDapp

Corda provides several frameworks for writing unit and integration tests for CorDapps.

Contract tests

You can run the CorDapp’s contract tests by running the Run Contract Tests - Kotlin run configuration.

Flow tests

You can run the CorDapp’s flow tests by running the Run Flow Tests - Kotlin run configuration.

Integration tests

You can run the CorDapp’s integration tests by running the Run Integration Tests - Kotlin run configuration.

Running tests in IntelliJ

We recommend editing your IntelliJ preferences so that you use the Gradle runner - this means that the quasar utils plugin will make sure that some flags (like -javaagent - see below ) are set for you.

To switch to using the Gradle runner:

  • Navigate to Build, Execution, Deployment -> Build Tools -> Gradle -> Runner (or search for runner)

    • Windows: this is in “Settings”
    • MacOS: this is in “Preferences”
  • Set “Delegate IDE build/run actions to gradle” to true

  • Set “Run test using:” to “Gradle Test Runner”

If you would prefer to use the built in IntelliJ JUnit test runner, you can add some code to your build.gradle file and it will copy your quasar JAR file to the lib directory. You will also need to specify -javaagent:lib/quasar.jar and set the run directory to the project root directory for each test.

Add the following to your build.gradle file - ideally to a build.gradle that already contains the quasar-utils plugin line:

apply plugin: 'net.corda.plugins.quasar-utils'

task installQuasar(type: Copy) {
    destinationDir rootProject.file("lib")
    from(configurations.quasar) {
        rename 'quasar-core(.*).jar', 'quasar.jar'

and then you can run gradlew installQuasar.

Debugging your CorDapp

See Debugging a CorDapp .

Was this page helpful?

Thanks for your feedback!

Chat with us

Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.

Propose documentation improvements directly

Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.

We're sorry this page wasn't helpful. Let us know how we can make it better!

Chat with us

Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.

Create an issue

Create a new GitHub issue in this repository - submit technical feedback, draw attention to a potential documentation bug, or share ideas for improvement and general feedback.

Propose documentation improvements directly

Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.