As discussed in the introduction to Corda apps we need to build the nodes and run them. but which nodes? and how can we change that?
If we open the main build.gradle from our project we will find the following task.
We can easily identify three nodes, the notary, PartyA and PartyB.
We already know what the notary does. Party A and B are simply the interested parties of our network in development mode.
To build all three nodes we need to execute this task, which we can easily do by calling gradlew:
Unix/Mac OS: ./gradlew deployNodes
Windows: gradlew.bat deployNodes
Next step is get the nodes up and running, for that we call:
Unix/Mac OS: build/nodes/runnodes
After running and waiting a few seconds for Corda to setup everything, three terminal windows will be opened, each representing a distinct node in your Corda network.
We can identify them by their name. how? looking at the logs, it’s easy to identify as corda prints the node name (see image below).
How to run commands?
Running commands on the node shell is pretty straightforward if you have experience with terminal:
For instance we can run flow list command to list all available flows on that node. As we can see all the flows we created previously are listed and are available to be executed on demand.
Creating Wallets and Accounts
Let’s create a new wallet for each of our nodes, A and B. We can do that by running
> flow start com.marcus.flows.CreateWalletFlow accountCurrencies [“EUR”]
let’s destruct this command to be easy to understand.
- flow start — is the corda shell command to initiate a new flow
- com.marcus.flows.CreateWalletFlow — is the flow we want to initiate
- accountCurrencies [“EUR”] — we know that CreateWalletFlow requires arguments to be passed to it. In this case we passing a set of currencies [“EUR”] on accountCurrencies argument.
CreateWalletFlow returns a WalletState as a result, which we can see being printed after running the flow
Let’s verify that we can add a new currency to our wallet by running:
> flow start com.marcus.flows.CreateAccountFlow currency: “USD”
As expected there is a new AccountState created for our wallet.
We can quickly verify that our WalletState now contains two accounts
> run vaultQuery contractStateType: com.marcus.states.AccountState
As expected we can see that in our node we have two AccountState — one for EUR and USD — we can also notice that they both belong to the same WalletState as we can see from the walletStateId
If we query the vault for the wallet state on the same shell, we will verify that the only wallet in that vault has the above id
> run vaultQuery contractStateType: com.marcus.states.WalletState
Making our first transfer
To make a transfer is very simple we just need to call MakeTransferflow
> flow start com.marcus.flows.MakeTransferFlow destination: "O=PartyB, L=New York, C=US", amount: 1 EUR
In this case we are transferring 1 Euro to party B, for obvious reasons, this command should be ran on Party A shell — Party B cannot transfer to itself.
We can see in the result that this transfer was a success. 🚀 and if we want to check the transfer states we can use
> run vaultQuery contractStateType: com.marcus.states.TransferState
In this state we can see that both participants are listed under participants, which means that this transfer state is also persisted into Party B vault.
If we want to sell all movements for a certain node, we can run
> run vaultQuery contractStateType: com.marcus.states.MovementState
And we can see that there is a movement associated with the previous transfer, and that this is a DEBIT movement — meaning money left this account.
If we execute the same command on PartyB shell, we expect to see a similar movement but with status CREDIT.
Requesting a transfer
Requesting a transfer is very similar to making a transfer in the first place, but with one more step.
Let’s start by requesting 10 Euros from Party A, in this case the following command should be executed on Party B’s shell
> flow start com.marcus.flows.RequestTransferFlow origin: “O=PartyA, L=London, C=GB”, amount: 10 EUR
Ff we query Party A’s vault for Transfer states we will find that there is a new TransferState created with status Requested, which Party A can then execute and make the transfer to Party B.
To execute the transfer Party A can execute the following command:
> flow start com.marcus.flows.ExecuteRequestedTransferFlow linearId: “6e6e763f-d2a3-49c6-8eae-713a2c42b55d”
We need to specify which requested transfer are we executing, and for that we use the transfer linearId, in this 6e6e763f-d2a3–49c6–8eae-713a2c42b55d.
Finally, you may find all code in this series on my github account, feel free to download it and change as much as you want.