Ardor Lightweight Contracts Status Update
One of my colleagues at my previous job used to say that getting a software feature 99% done is just the beginning. The leap from 99% to 100% is the biggest step.
The development of the lightweight contracts feature is pretty much done but it is not yet at 100%. The remaining crucial step is the integration of this feature together with our strategic transaction pruning. This has surfaced some unforeseen problems which forced us to delay the release by a few weeks. While the technical details may not interest you, I’ll still explain them at the end of the article for the sake of transparency.
On top of that, we need to carefully review some design decisions and interfaces to make sure we won’t need to change them later, and by doing so break existing contracts. Once the interface is agreed, we need to adjust all the examples and provide documentation.
We hoped to release lightweight contracts on testnet by the end of Q2/2018 but there were several urgent tasks and we had to make some calculated decisions on what to prioritize first. We hired new developers, rented an office, attended conferences, and dealt with an endless stream of rather annoying (but essential nevertheless) bureaucratic tasks. However, last week in Lugano we ironed out most of the final details.
So, what’s next?
Our current due date for the lightweight contracts testnet release is August 17th just in time for the Blockchain Meets Purposeful Gaming Hackathon & Conference in Krems Austria, where we intend to make extensive use of these contracts. This release will be packed with additional goodies as well, but more on this in a separate article once we get closer to the release.
Warning — technical details below
So, what is left to develop? The current design of contract deployment in Ardor is a two-step process. First, the contract class or jar file is deployed to the blockchain as cloud data. Next, an account property transaction is submitted to reference the contract and provide the contract setup parameters. This indirection is very useful. It means that when deploying a new version of a contract, all you need to do is upload the new contract and update the property to point to the new version of the contract and voilà, the contract runner will automatically switch to executing the new contract. Our contracts are strategically designed to be stateless, which means no funds are locked and no data is lost when upgrading a contract. Therefore, there is no need for a painful migration process.
Another benefit of this design is that different accounts can use the same contract with different setup parameters. This means, for example, that if a contract is used to pay VAT tax from every transaction sent to it, different contract runner accounts will be able to specify different VAT percentage based on their specific jurisdiction and reuse the same contract.
The reference from the account property transaction which stores the contract setup parameters to the contract code stored as cloud data currently relies on a little-known feature of Ardor named “referenced transaction”. The problem we currently face is that given the name of the contract, there is no simple way to link from the account property value (which represents the contract setup) to the set property transaction itself which stores the reference to the cloud data transaction.
In fact, this requires loading the account properties transactions for this account and scanning them one by one for the correct transaction. The problem is that once we implement pruning, this property transaction might have been pruned so the contract runner will need to reload all these account properties transactions from an archival node and iterate over them until finding the right one. This is very inefficient.
The solution we devised is to implement a new “Contract Setup” transaction type (name not final), which combines an account property with a reference to the contract code, still stored as cloud data, as part of the transaction attachment. This way using the contract name alone we can load the reference to the contract code and solve the problem without having to load the referencing transaction itself.