Welcome to the second part of the Corda Accounts technical deep dive. In this post, we will continue our discussion and have a look at the accounts-workflows CorDapp in greater detail. If you landed here directly, you might want to take a look at Part 1 of this blog here.
Account Workflow Cordapp
The accounts-workflows CorDapp could be a bit overwhelming when you look at the number of files, but it isn’t all that difficult. Let’s try and find out more.
Just like any workflow CorDapp, the accounts-workflows CorDapp contains certain flows and services, so let’s concentrate on them and see what they do.
Creating an Account
As we saw in the previous blog, accounts are Corda States, so in order to create one we need to run a transaction that would require a flow. This is where the CreateAccount flow comes into play.
Sharing an Account
Since accounts are created locally, all you pass to the CreateAccount flow is a name parameter; it isn’t shared with other nodes in the Corda network. This means other participants in the network are not aware of the existence of the account. In order for them to know about the account, it (AccountInfo) must be shared with them.
ShareAccountInfo flow helps us with that. You should see 2 pairs of ShareAccountInfo flows: ShareAccountInfo — ShareAccountInfoHandler andShareAccountInfoFlow — ShareAccountInfoHandlerFlow. The handlers are the responders in each pair. They are the initiating and non-initiating versions of the same flow, respectively.
Initiating Flows can be started via RPC and services, and when they are used as subflows, a new flow session is created. To know more about initiating flows, read more here.
Thus the ShareAccountInfo flow takes a StateAndRef and recipient parameter and shares the StateAndRef object (AccountInfo in this case) with the recipient.
Requesting an Account from another Node
Nodes can request information for accounts hosted in another node. This is achieved using the RequestAccountInfoFlow. This flow also has two pairs RequestAccountInfoFlow — RequestAccountInfoHandlerFlow and RequestAccountInfo — RequestAccountInfoHandler, the latter being the initiating version.
Where is the account’s Party?
In order for an account to be able to participate in a transaction, it needs to be a Party. But you’ve probably noticed, all that we know at this point is that an account is a ContractState.
Accounts also need key pairs to sign transactions. If you have a look at the CreateAccount flow, all we do there is create the AccountInfo state — so what about the key pair?
Let’s try to clear away all this confusion.
Key pair for Account
A new key pair should be created with each transaction in which an account participates. This is to avoid the possibility of the private key being compromised, rendering the account useless. You could, however, work with a single key pair if you wished. In order to generate a key pair, theRequestKeyForAccount flow is used.
The RequestKeyForAccount flow takes an AccountInfo as a parameter, generates a key pair, and returns the public key wrapped in an AnonymousParty.
So now you have a key pair as well as a Party to work with.
The flow pairs areRequestKeyForAccount — SendKeyForAccount and RequestKeyForAccountFlow and SendKeyForAccountFlow. RequestKeyForAccount — SendKeyForAccount is the initiating flow pair.
There are a number of flows available to query accounts using different parameters. They are pretty self-explanatory:
- AccountInfoByKey: Returns an account for a specified public key.
- AccountInfoByName: Returns an account for a specified name.
- AccountInfoByUUID: Returns an account for a specified identified.
- AccountsForHost: Returns an account for a specified host (Party).
- AllAccounts: Returns all known accounts.
- OurAccounts: Returns all accounts hosted by the node.
So that almost covers all the flows — we will come back to the other flows in the package soon. But before that, let’s see what we have in the AccountService.
As the name suggests AccountService is a CordaService. The AccountService itself is an interface with an implementation in the form of KeyManagementBackedAccountService.
AccountService provides a convenient way of handling various operations that involve accounts. For example, in order to create an account, you could either call the CreateAccount flow or use the AccountService’s createAccount method, and it will take care of the other details internally.
This service helps with certain common operations such as creating, sharing, and querying accounts.
Syncing Accounts Across Nodes
You will also find another flow pair while investigating this CorDapp — it’s called ShareStateAndSyncAccounts — ReceiveStateAndSyncAccounts. As the name suggests, it has something to do with the syncing of accounts.
Each account works by having multiple public keys that they use to transact. Remember that the State doesn’t contain any information about an account; it contains an AnonymousParty which has the public key. Thus a public key to account id relationship is maintained separately, which helps to identify an account’s state ownership.
This mapping needs to be synced across nodes whenever a new key is requested from a counterparty. This is done using the ShareStateAndSyncAccounts flow.
Account as Observer
We learned that an account can participate in a state by using a public key. However, can an account also be an observer? In other words, can an account not participate in a state, but still be able to see the state?
Yes, that’s what is achieved using theShareStateWithAccount — ReceiveStateForAccount flow.
If you look carefully at the accounts-workflows CorDapp, you will also find a schema available there. This schema exists for that exact purpose. It is used to maintain a mapping of the account id to StateAndRef for state-observed by an account.
For an owned state however, as mentioned previously, the public key mapping to the account id is used.
So that brings us to the end of this blog. This two-part deep dive should give you a comprehensive understanding of how Corda Accounts work internally.
Thank you so much for reading.
Want to learn more about building awesome blockchain applications on Corda? Be sure to visit corda.net, check out our community page to learn how to connect with other Corda developers, and sign up for one of our newsletters for the latest updates.
— Ashutosh Meher is a Developer Evangelist at R3, an enterprise blockchain software firm working with a global ecosystem of more than 350 participants across multiple industries from both the private and public sectors to develop on Corda, its open-source blockchain platform, and Corda Enterprise, a commercial version of Corda for enterprise usage.
Follow Ashutosh on Twitter here.