I have decided to build a re-usable Cordapp platform that will serve the need of multiple co-operates with minimal updates (per co-operate) when necessary.
I plan to achieve this by creating base classes for the States and Contracts which shall contain every possible common properties for each kind of Payment Instrument and will be extended by other regular States and Contracts. As for the flows, I can have all basic generic flows ready. Customized flows can then be written upon requirement and this (hopefully) would only be minimal additions to be made upfront.
In order to achieve the above plans, I recently tried it out with a test Cordapp.
For States, I observed that I could possibly have a base (Interface) State with all possible common parameters (for a particular Payment Instrument), which can then be extended by other regular States as planned.
For Contracts, I had a bit of challenge.
While having an Interface Contract IXContract being extended (by an open class) XContract, I got a transaction error “Contract verification failed: Required com.template.contracts.IXContract.Commands command, contract: com.template.contracts.XContract”. This seem to be caused by a conflict in contracts being used by a single XState.
I also modified the code to having IXContract as an open class and and XContract as abstract class. This returned a successful transaction, however the invalid rule in the IXContract was not caught and this is not the expected behavior of the project.
To avoid contract conflicts, I tried the usual programming style of simple classes. With base class IXContract, this time not extending the Contract interface (which makes it not a contract class), but contains a BaseContract method with contract rules. I then autowired this class in the regular XContract class (still extending the contract interface) and called the BaseContract method to apply the contract rule within it. This was tested successfully and the contract rules were caught as required. For more assurance, the flow was adjusted to align with the contract rules and the test transaction was then successful.
I however noted that this would obviously lead to us having a huge file of BaseContract class in future, but these have been our test trials so far.
This post contains attachment of the logs from the various results observed as explained in above.
The file ‘error.log’ is the result of a failed transaction due to conflict in double contracts (XContract and IXContract) used by a single state,
The file ‘expected_error’ is the result of a failed transaction when the IXContract file was declared as a (non-contract) class with methods containing a (deliberately) wrong contract rule.
The file ‘expected_success’ is the result of a successful transaction when the IXContract file was declared as a (non-contract) class with methods containing the correct contract rule.
Is this a good route towards implementing a reliable project with no possible risk upfront?
Kindly advice on a best way to achieve it if you can already foresee a disadvantage in our test trials.