Now that we have implemented all states and contracts the only missing bit is implementing flows.
What is a workflow?
In Corda R3, every operation is associated with a flow, a flow is basically an operation that the client can perform on the application developed.
The flow responsibility is to create new states or fetch from the ledger an existing state and create a new one, evolving the state this way, and what do we do with this states? We need to persist them, or add it to the ledge and request every other node that is interested in these new states to validate them. Said validation is based on the contracts that we have written on previous post.
Which operations do we have?
The main goal is to allow each node to be able to transfer a given amount between two nodes.
So we need the following operations:
- Create a Wallet — this operation will associate the caller node with a wallet that will allow it to create accounts.
- Create an Account — This operation will associate the caller node with an account that is associated with a currency, allowing it to receive/make transfers from/to other nodes for that currency.
- Make Transfer — This operation allows the caller node to transfer a given amount for a given currency to another node in the system.
- Request Transfer — This operation allows the caller node to request a transfer from another node for a given amount and currency.
- Execute Requested Transfer — This operation allows a node that received a requested transfer, to execute the transfer.
You will find out that many flows requires us to perform some repetitive operations, like build a transaction or collect signatures and update the ledger. For that reason we will take advantage of inheritance and create a generic BaseFlow class that is abstract and all other flows should extend.
There are some operations that are useful for a lot of flows but are not used in every flow we have, for those function we create an extension function utilities class.
Create a Wallet
Previously we said that each node represents a bank in our system, but how do we know how much of a given currency does a bank owns in our network? We first need to have a place to store money, The purpose of a wallet is exactly that.
So the first operation we need to create is the wallet creation. To create a wallet we need to give a set of currencies that this wallet is allowed to receive/send in our network.
Create an Account
Even though we can create a wallet with a set of currencies, we need to allow the user to create a new account any time in the future.
The main operation on our network is the ability to transfer a given amount of an asset/currency from a party another party. This operation we require the client to give us the destination party that will be receiving and how much are we transfering. (Notice that we do not require the client to give us who the origin is, as we assume it’s always the node that initiate the transaction.
A transfer is persisted into our ledger as a TransferState which contains the origin and destination with a given amount transferred between them, date and status. It’s important to note that TransferState contains a list of parties that wants to know about that state, the origin and destination. Corda will handle all the hard work for us and persist this state in both ledgers.
For every transfer we will always create two movements, one for the origin party and one for the destination party with different movement types. The origin will always have a Debit direction, as this account is the one transferring the assets.
Request and Execute Transfer
Finally we have two operations the compliment each other, we allow a party to request some assets from another party, obviously we need to have a second operation that the former party will call to accept or reject the request. For simplicity our execute operation will always try to accept the request, we will later create a job that runs on every node to verify if a requested transaction was not executed after some interval of time, and then reject it.