Test Your CorDapp
This tutorial guides you through the steps required to execute the flows Communication between participants in an application network is peer-to-peer using flows. you have previously created, to confirm the CorDapp Corda Distributed Application. A Java (or any JVM targeting language) application built using the Corda build toolchain and CorDapp API to solve some problem that is best solved in a decentralized manner. works as expected.
Learning Objectives
Once you have completed this tutorial, you will know how to execute flows and analyse the results of these flows to confirm correct behaviour of your CorDapp.
Before You Start
Before you run your flows, you must install the CorDapp template. The CorDapp template will automatically provision a notary virtual node The combination of the context of a user and the ephemeral compute instances created to progress a transaction on that identity's behalf. , in addition to virtual nodes for four participants – Alice, Bob, Charlie, and Dave. You will use the Bob and Dave virtual nodes for your flows. They represent the farmer and the customer referenced in the earlier tutorials.
Follow the CorDapp template instructions to start the Corda combined worker and to deploy the static network.
Once done, confirm that the nodes are available by running the
listVNodes
gradle task. It should return something like the following:CPI Name Holding identity short hash X500 Name MyCorDapp E18496F580F4 CN=Bob, OU=Test Dept, O=R3, L=London, C=GB MyCorDapp 19F285FA7192 CN=Alice, OU=Test Dept, O=R3, L=London, C=GB MyCorDapp 943300F6BD04 CN=Charlie, OU=Test Dept, O=R3, L=London, C=GB NotaryServer 82E04CE54296 CN=NotaryRep1, OU=Test Dept, O=R3, L=London, C=GB MyCorDapp 715E366736B2 CN=Dave, OU=Test Dept, O=R3, L=London, C=GB
Optional: You may need to run this a few times following network setup, to give the system chance to update the data being broadcast following registration.
Take note of the holding ID short hash for both Bob and Dave. You will need these when running flows.
Running Flows
Now that you have created virtual nodes and your CorDapp has been installed on these, you can test the code that you have written in the previous tutorials.
Verify the Flow Installation
To ensure that your flows are available on the virtual nodes you will be using, perform a sanity check:
- Following the CorDapp template documentation steps, open the Swagger UI and log in.
- Use the
GET flowclass/{holdingidentityshorthash}
endpoint to list the flows available. You should do this specifying the holding identities that you noted down earlier for both Bob and Dave. The returned classes should contain the flow classes that you wrote in earlier tutorials.
Issue an AppleStamp
First, Bob the farmer will issue Dave the customer an AppleStamp
which Dave can exchange for a basket of applies
at a future time.
use the
POST /flow/{holdingidentityshorthash}
endpoint, specifying Bob’s holding ID and the following request body with Dave’s name as the holder:{ "clientRequestId": "create-stamp-1", "flowClassName": "com.r3.developers.apples.workflows.CreateAndIssueAppleStampFlow", "requestBody": { "stampDescription": "Can be exchanged for a single basket of apples", "holder": "CN=Dave, OU=Test Dept, O=R3, L=London, C=GB" } }
To confirm successful issuance of the stamp, run the
GET /flow/{holdingidentityshorthash}/{clientrequestid}
endpoint, specifying Bob’s holding ID again, and the client request ID used in the previous step.You should observe that the
flowStatus
in the response is completed, andflowResult
contains a UUID.Make a note of the UUID, as this is the ID of the newly issued stamp, which you will use again later.
Create BasketOfApples
Farmer Bob now has a BasketOfApples
which he wishes to put on the ledger so that it can be redeemed for an AppleStamp
.
Repeat the instructions from the previous section, but use the following request body, which invokes a different flow:
{ "clientRequestId": "package-apples-1", "flowClassName": "com.r3.developers.apples.workflows.PackageApplesFlow", "requestBody": { "appleDescription": "Golden delicious apples, picked on 11th May 2023", "weight": 214 } }
Check the result of this flow.
The
flowStatus
in the response should be completed. In this case, we do not care about the flow result as this is not required to redeem theAppleStamp
.
Redeem the AppleStamp
for a BasketOfApples
Finally, Dave can redeem his AppleStamp
.
Start a new flow against Bob’s virtual node. The request body in this case should be:
{ "clientRequestId": "redeem-apples-1", "flowClassName": "com.r3.developers.apples.workflows.RedeemApplesFlow", "requestBody": { "buyer": "CN=Dave, OU=Test Dept, O=R3, L=London, C=GB", "stampId": "<The stamp id noted earlier>" } }
The flowStatus
in the response should also be completed. Following this step, the AppleStamp
has been spent, and Dave is now the owner of a basket of apples.
Error Scenarios
The above steps show the “happy path”. However, you may wish to execute some further flows to ensure that your contract validation works as expected. Some additional scenarios to try are:
- Try redeeming the original
AppleStamp
again. You can do this by entering a new flow as you did when following the steps for redeeming theAppleStamp
, but with a new client request ID. The transaction A transaction is a proposal to update the ledger. should fail with an error indicating that anAppleStamp
with the specified ID could not be found. - Repeat all the steps for issuing an
AppleStamp
, but get another virtual node (for example, Charlie) to issue anAppleStamp
to Dave, rather than Bob doing this. On redemption, the transaction should fail because Bob does not recognise theAppleStamp
ID provided. - Repeat all the steps for redeeming the
AppleStamp
, but on redemption, Bob tries to redeem Dave’sAppleStamp
by specifying himself as the buyer. This should be rejected. Similarly, attempting to specify a different entity An organization or individual that participates in one or more application networks that can provide attestation that they are whom they claim to be. altogether (for example, Charlie) should also be rejected.
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.