Run a sample CorDapp
Get started with Corda by running a sample CorDapp. Learn how to download, deploy, launch, interact with, and test a CorDapp before you try modifying a [Java]((https://github.com/corda/cordapp-template-java/tree/release/4.12) or Kotlin template, building your own, or using a community CorDapp.
The local Corda network in the sample includes one notary and two nodes, each representing a party in the network. A Corda node is an individual instance of Corda representing one party in a network. For more information on nodes, see the node documentation.
The sample CorDapp allows nodes to reach loan agreements with each other, as long as they obey the following contract rules:
- The loan agreement’s value is strictly positive.
- A node is not trying to issue a loan agreement to itself.
You will deploy and run the sample CorDapp on the following test nodes:
- Notary, which runs a notary service
- PartyA
- PartyB
Before you start
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
- Learn what a CorDapp is.
- Set up your development environment.
Step 1: Download the sample CorDapp
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
- Choose a directory to store the sample CorDapp.
- Open the command line from that directory.
- Run the following command to clone the sample repository:
git clone https://github.com/corda/samples-java/tree/release/4.12
git clone https://github.com/corda/samples-kotlin/tree/release/4.12
The sample project folders will appear in your chosen directory.
The samples-java
and samples-kotlin
repositories each contain a number of sample CorDapps. For details of all the sample CorDapps and their features and usage, see the README file in the samples-java
or samples-kotlin
folder. The sample CorDapp that you are going to run and deploy is the Basic CorDapp in the Basic\cordapp-example
sub-folder.
You can see the project structure in Appendix A.
Step 2: Open the sample CorDapp in IntelliJ IDEA
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
- Open IntelliJ.
- Choose Open from the top menu.
- Navigate to the
Basic\cordapp-example
sub-folder and click OK.
The project containing the sample CorDapp opens.
Step 3: Deploy the CorDapp locally
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
Open the command line from the
cordapp-example
directory.Run the
deployNodes
Gradle task:- Unix/macOS:
./gradlew deployNodes
- Windows:
gradlew.bat deployNodes
This builds three nodes with the CorDapp installed on them.
- Unix/macOS:
When the build finishes, go to the
build/nodes
folder.You will see the following output:
- A folder for each generated node
- A
runnodes
shell script for running all the nodes simultaneously on macOS - A
runnodes.bat
batch file for running all the nodes simultaneously on Windows
See Appendix B for the node structure.
deployNodes
is a utility task that can be used in a development environment to create a new set of nodes for testing a CorDapp. In a production environment, you would create a single node as described in Creating nodes locally instead, and build your CorDapp JARs as described
in Building and installing a CorDapp.Step 4: Launch the sample CorDapp
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
To start the nodes and the sample CorDapp:
- Run the command that corresponds to your operating system:
- Unix/macOS:
./build/nodes/runnodes
- Windows:
.\build\nodes\runnodes.bat
- Start a Spring Boot server for Party A. Run the command:
- Unix/macOS:
./gradlew runPartyAServer
- Windows:
gradlew.bat runPartyAServer
Look for the Started Server in X seconds
message — don’t rely on the % indicator.
- Repeat the command to start the server for Party B:
- Unix/macOS:
./gradlew runPartyBServer
- Windows:
gradlew.bat runPartyBServer
build/nodes/runnodes --headless
to prevent each server from opening in a new terminal window. To interact with the nodes, you will need to use ssh, see Node shell.The runnodes
script creates a node tab/window for each node. It usually takes about 60 seconds for all the nodes to start. Each node displays “Welcome to the Corda interactive shell” along with a prompt. Whilst the runnodes
script terminates, the two commands to start Party A and B do not and should be run in separate terminal windows.
- Optional: If not all the nodes start successfully the first time, close the terminals and run the script again.
______ __
/ ____/ _________/ /___ _
/ / __ / ___/ __ / __ `/ I won $3M on the lottery so I donated a quarter
/ /___ /_/ / / / /_/ / /_/ / of it to charity. Now I have $2,999,999.75.
\____/ /_/ \__,_/\__,_/
--- Corda Open Source Edition 4.12 (fa98aa7) -------------------------------------------------------------
Logs can be found in : /Users/cordauser/src/samples-kotlin/Basic/cordapp-example/build/nodes/PartyA/logs
⚠️ ATTENTION: This node is running in development mode! 👩💻 This is not safe for production deployment.
Advertised P2P messaging addresses : localhost:10005
RPC connection address : localhost:10006
RPC admin connection address : localhost:10046
Loaded 2 CorDapp(s) : Contract CorDapp: Example-Cordapp Contracts version 1 by vendor Corda Open Source with licence Apache License, Version 2.0, Workflow CorDapp: Example-Cordapp Flows version 1 by vendor Corda Open Source with licence Apache License, Version 2.0
Node for "PartyA" started up and registered in 8.07 sec
Welcome to the Corda interactive shell.
You can see the available commands by typing 'help'.
Tue Jan 24 16:30:32 GMT 2023>>> Running P2PMessaging loop
Step 5: Interact with the sample CorDapp
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
You can interact with the sample CorDapp:
- Via HTTP
- Via the interactive shell (terminal only)
- Via the h2 web console
Via HTTP
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
The Spring Boot servers run locally on the following ports:
- PartyA:
localhost:50005
- PartyB:
localhost:50006
These ports are defined in clients/build.gradle
.
Each Spring Boot server exposes the following endpoints:
/me
/peers
/ious
/create-iou
with parametersiouValue
andpartyName
which is CN name of a node
There is also a web front-end served from the home web page (for example, localhost:50005
).
Create an IOU via the endpoint
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
You can create an IOU by sending a POST
request to the /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:
curl -i -X POST 'http://localhost:50005/create-iou?iouValue=12&partyName=O=PartyB,L=New%20York,C=US' -H 'Content-Type: application/x-www-form-urlencoded'
Note that both PartyA’s port number (50005
) and PartyB are referenced in the POST 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.
Via the interactive shell (command line only)
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
Nodes started via the command line 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.
Mon May 10 16:36:29 BST 2021>>>
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:
net.corda.samples.example.flows.ExampleFlow$Initiator
net.corda.core.flows.ContractUpgradeFlow$Authorise
net.corda.core.flows.ContractUpgradeFlow$Deauthorise
net.corda.core.flows.ContractUpgradeFlow$Initiate
Create an IOU via the interactive shell
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
You can create a new IOU using the ExampleFlow$Initiator
flow. For example, from the interactive shell of Party A,
you can agree an IOU of 50 with Party B 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
Check the output
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
You 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: net.corda.samples.example.states.IOUState
.
Via the h2 web console
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
You can connect directly to your node’s database to see its stored states, transactions, and attachments. Follow the instructions in Node database.
Step 6: Test the CorDapp
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
Corda provides several frameworks for writing unit and integration tests for CorDapps. To access test flows in IntelliJ, select an option from the ‘Run Configurations’ dropdown next to the hammer icon. For a general guide, see Running tests in IntelliJ.
Integration tests
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
First, run an integration test to calibrate your environment.
Go to:
- Kotlin:
workflows > src > integrationTest > kotlin > net.corda.samples.example > DriverBasedTest
- Java:
workflows > src > integrationTest > java > net.corda.samples.example > DriverBasedTest
- Kotlin:
Select the green arrow next to the test code. This will open the
Run Terminal
.
Contract tests
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
You can run the CorDapp’s contract tests by running the Run Contract Tests - Java
run configuration.
Go to:
- Kotlin:
contracts > src > test > kotlin > net.corda.samples.example.contracts > ContractTests
- Java:
contracts > src > test > java > net.corda.samples.example.contracts > ContractTests
- Kotlin:
Select the arrow next to the test code. Choose the arrow at the top to run all the tests at once, or select the arrow next to a particular section to test it individually.
Flow tests
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
You can run the CorDapp’s flow tests by running the Run Flow Tests - Java
run configuration.
Go to:
- Kotlin:
workflows > src > test > kotlin > net.corda.samples.example > FlowTests.kt
- Java:
workflows > src > test> java > net.corda.samples.example > FlowTests
- Kotlin:
Select the arrow next to the test code. Choose the arrow at the top to run all the tests at once, or select the arrow next to a particular section to test it individually.
Debug a test
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
If your test fails, run a Gradle test instead of a unit test.
- Open the Gradle tab on the right-hand side of your IntelliJ window.
- Open Build Tool Settings (wrench icon) and select Gradle Settings.
- Set Gradle as the default in your Build and Run settings and click Apply.
- Go to Run Configurations (next to the hammer icon) and select Edit Configurations.
- Delete the unit test driver and click Apply.
- Return to your test code. You will see the Gradle icon (an elephant).
- Select the Gradle icon to run your test.
Related Content
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
Appendix A: Projects’ structure
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
The cordapp-example
Java folder is structured as follows:
.
├── clients
│ ├── build.gradle
│ └── src
│ └── main
│ ├── java
│ │ └── net
│ │ └── corda
│ │ └── samples
│ │ └── example
│ │ ├── webserver
│ │ │ ├── Controller.java
│ │ │ ├── NodeRPCConnection.java
│ │ │ └── Starter.java
│ │ │
│ │ └── Client.java
│ │
│ └── resources
│ └── static
│ ├── index.html
│ └── app.js
│
├── config
│ ├── dev
│ │ └── log4j2.xml
│ └── test
│ └── log4j2.xml
│
│
├── contracts
│ ├── build.gradle
│ └── src
│ ├── main
│ │ └── java
│ │ └── net
│ │ └── corda
│ │ └── samples
│ │ └── example
│ │ ├── contract
│ │ │ └── IOUContract.java
│ │ ├── schema
│ │ │ ├── IOUSchema.java
│ │ │ └── IOUSchemaV1.java
│ │ └── states
│ │ └── IOUState.java
│ └── test
│ └── java
│ └── net
│ └── corda
│ └── samples
│ └── example
│ └── contracts
│ ├── ContractTests.java
│ └── StateTests.java
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
│
├── lib
│ ├── README.txt
│ └── quasar.jar
│
├── workflows
│ ├── build.gradle
│ └── src
│ ├── integrationTest
│ │ └── java
│ │ └── net
│ │ └── corda
│ │ └── samples
│ │ └── example
│ │ └── DriverBasedTests.java
│ ├── main
│ │ ├── java
│ │ │ └── net
│ │ │ └── corda
│ │ │ └── samples
│ │ │ └── example
│ │ │ └── flows
│ │ │ └── ExampleFlow.java
│ │ └── resources
│ │ └── migration
│ │ ├── iou.changelog-master.xml
│ │ └── iou.changelog-v1.xml
│ │
│ └── test
│ └── java
│ └── net
│ └── corda
│ └── samples
│ └── example
│ └── FlowTests.java
│
├── LICENCE
├── README.md
├── TRADEMARK
├── build.gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── repositories.gradle
└── settings.gradle
The cordapp-example
Kotlin folder is structured as follows:
.
├── clients
│ ├── build.gradle
│ └── src
│ └── main
│ ├── kotlin
│ │ └── net
│ │ └── corda
│ │ └── samples
│ │ └── example
│ │ ├── webserver
│ │ │ ├── Controller.kt
│ │ │ ├── NodeRPCConnection.kt
│ │ │ └── Server.kt
│ │ │
│ │ └── Client.kt
│ │
│ └── resources
│ └── static
│ ├── index.html
│ └── app.js
├── config
│ ├── dev
│ │ └── log4j2.xml
│ └──test
│ └── log4j2.xml
│
│
├── contracts
│ ├── build.gradle
│ └── src
│ ├── main
│ │ └── kotlin
│ │ └── net
│ │ └── corda
│ │ └── samples
│ │ └── example
│ │ ├── contract
│ │ │ └── IOUContract.kt
│ │ ├── schema
│ │ │ └── IOUSchema.kt
│ │ └── states
│ │ └── IOUState.kt
│ └── test
│ └── kotlin
│ └── net
│ └── corda
│ └── samples
│ └── example
│ └── contracts
│ ├── ContractTests.kt
│ └── StateTests.kt
│
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
│
│
├── workflows
│ ├── build.gradle
│ └── src
│ ├── integrationTest
│ │ └── kotlin
│ │ └── net
│ │ └── corda
│ │ └── samples
│ │ └── example
│ │ └── DriverBasedTests.kt
│ ├── main
│ │ ├── kotlin
│ │ │ └── net
│ │ │ └── corda
│ │ │ └── samples
│ │ │ └── example
│ │ │ └── flows
│ │ │ └── ExampleFlow.kt
│ │ └── resources
│ │ └── migration
│ │ ├── iou.changelog-master.xml
│ │ └── iou.changelog-v1.xml
│ │
│ └── test
│ └── kotlin
│ └── net
│ └── corda
│ └── samples
│ └── example
│ └── FlowTests.kt
├── LICENCE
├── README.md
├── TRADEMARK
├── build.gradle
├── constans.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── repositories.gradle
└── settings.gradle
The key files and directories are as follows:
- The root directory contains some gradle files, a
README
, aLICENSE
, and aTRADEMARK
statement. - clients contains the source code for Spring Boot integration.
- config contains the Log4j 2 configuration.
- contracts and workflows contain the source code for the sample CorDapp. CorDapps can be developed in either Java or Kotlin.
- 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 your CorDapp’s flows to be checkpointable.
Appendix B: Node structure
![Click to copy the section link. heading-link-icon](/icons/chain-icon.png)
Each node in the nodes
folder is structured as follows:
. nodeName
├── additional-node-infos //
├── certificates
├── corda.jar // The Corda node runtime
├── cordapps // The node's CorDapps
│ ├── config
│ ├── corda-example-contracts-0.1.jar
│ └── corda-example-workflows-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
├── persistence.mv.db // The node's database
└── persistence.trace.db // The node's database
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.