Now that we have our states created with all the fields that matter to us, it’s time to create the contracts that bind our states.
In Corda R3 we need to create a contract class that is responsible for all possible changes related to the state it is binded. We saw that on the previous post about states, that each state class has an annotation @BelongsToContract that receives a contract class as parameter.
First we start by creating a BaseContract that implements the Contract interface, this way we let the framework know that his class is a contract.
The Contract class has only one function to implement, verify, this function is called by the framework whilst it is verifying the transaction. the way we let the framework know that this verification failed is by throwing an exception, and for that we will be using the require functions provided by the framework.
Because every state is associated with a contract we need to provide a set of commands, a command will indicate that this contract will perform this actions on this state. example: AccountContract will perform a CreateAccountCommand (action create) on a new AccountState.
We start the verification by checking if this transaction is associated with a notary and reject any transaction that does not have one, this way we are certain that every time the ledge is updated, the transaction was verified by a notary.
We might have more than one command associated with a transaction and we need to make sure that every command is verified. For this reason we loop over all the commands in this transaction and verify it.
On DBanking we created our own command class MyCommand that extends the functionality of CommandData — Corda R3 command interface — with a set of abstract verification functions that our commands must implement.
- verifiySignatures — A transaction is valid only if the stakeholders of this transaction has signed it with his private key. Ff the signature is missing we assume this transaction is not valid and won’t update the ledger with the states in it.
- verifyContractShape — This function is responsible for the verification of the shape of this transaction. for example, how many states are there on this transaction? does it match to the ones we expect? how many inputs and which states are they? how many outputs?
- verifyContractSpecifics — This function is always called after the verifyContractShape, which help us avoid verifying the shape again on this function and assume the shape is correct when getting the states to be verified.
Below you may find the several contracts in DBanking dapp:
Next article we will cover DBanking flows, and bind everything together.