Lightweight Contracts — The Ardor answer to smart contracts. Image credit: Hudson Hintze, Unplash.

Lightweight Contracts

The Ardor answer to smart contracts

See all lightweight contracts articles

One of the main bottlenecks of existing smart contract technology is that it requires every node in the blockchain to process every contract to reach the same state. But is this really necessary?

For example, when you transfer an obscure ERC20 token on the Ethereum blockchain from one address to another, is it really important that all 15306 Ethereum nodes execute this contract? Wouldn’t it be enough that the sender, recipient, and perhaps some independent validator execute the contract? What about CryptoKitties breeding? You see where I’m going?

Surely, if the contract ends up updating some state, such as account balances for example, these updates must be processed by the whole network, but why do all nodes need to re-process the whole contract if they don’t care about its outcome?

In Ardor, we implemented a different approach which is more flexible and scalable. Instead of requiring every node to process every contract invocation, we ask only the parties interested in the contract to process it and verify that they reach the same state.

With this approach, the “contract” code itself is a simple Java class uploaded to the blockchain and therefore digitally signed and time stamped. However, the execution of the “contract” is only performed by nodes who selected to run the ‘ContractRunner’ addon.

The input to the contract is typically a transaction with an attached message, which identifies the contract to execute, and supplies optional parameters. The output of the contract are one or more transactions submitted to the network to update the blockchain state. The transactions submitted by the contract are normal transactions which have to comply with all the existing protocol rules.

In other words, the lightweight contract, is Java code which implements a certain interface, stored on the blockchain. The contract code is executed by anyone who wants to run it, not by every node, and is triggered by a blockchain transaction (or by each new block). The result of the calculation made by the contract is submitted as one or more normal transactions of any type supported by Ardor.

What can it be used for? Lightweight contracts provide essentially everything Ethereum smart contracts are used for, integrated with everything Ardor already provides out of the box. Such as automation of repetitive tasks, Financial calculations, Predictable random numbers, Oracles to register information from external sources, and more. All this is integrated with the existing built in Ardor Coin Exchange, Asset Exchange, Voting Tools, Marketplace, Account Properties, Messages, etc. This provides a powerful tool for developing decentralized applications by relying on existing built in API features.

But, how do we make sure that whoever executes the smart contract does not cheat? Since the Java class file is stored on the blockchain, anyone interested can execute the same contract based on the same input, either in production mode, in order to submit the output as a transaction or in approval mode to verify that a transaction submitted by a contract indeed followed the correct calculations.

Lightweight contracts support different levels of trust.

Peer Review — the contract author can publish the Java source code for peer review, anyone can compile the source code and generate the exact same class file stored in the blockchain. Even if the source code is not published by the author, anyone can download the contract class from the blockchain, decompile it, and review the source code to make sure it has no bugs or back doors.

Result Validation — given a transaction executed by a contract, any node can execute the same contract and confirm that the transactions submitted by the contract, represent the correct contract output according to the input provided and the executed code. This allows nodes to identify and flag cheaters but does not prevent their transactions from being included in the blockchain. For simple contracts which do not represent significant value transfer, this should be good enough.

Account Control — the account running the contract can be placed under account control with multi signature of another account, or two out of three accounts. Whenever the contract account submits a transaction, the controlling accounts will repeat the calculation. Only if they reach the same results they’ll submit an approval transaction.

Example: a simple Hello World contract

Ardor Hello World Lightweight Contract

The contract, first performs validation then composes a sendMessage transaction for sending a response to the sender account of the message which triggered the contract.

Note that this contract is executed only by nodes who choose to execute it, so even if it enters an infinite loop, or runs out of memory, or causes a stack overflow, it will only affect these nodes. It will not cause a network wide systematic problem. In the worst case, these nodes will need a restart after disabling this contract execution. This means that we do not need to measure the execution of the contract and require an, Ethereum like, pay per instruction approach. The contract account will only pay the transaction fees of the transactions it submitted.

Also note that our lightweight contracts are stateless, they can only rely on input provided by the trigger transaction, stored on the blockchain or extracted from external sources. Therefore there is no problem with “killing” these contracts. As long as the passphrase of the account running the contract is still available, funds can be manually recovered in case of a disaster (Note that they are still subject to account control rules)

Hacking of lightweight contracts is still an issue. For example, if someone is able to exploit a DAO style bug, and cause the contract to send funds to their account using a valid transaction, this will still work. Therefore for very sensitive high value contracts, a manual verification step can be added as account control.

Since our lightweight contracts are developed in Java they can be developed using the best, standard, development tools available (IntelliJ, Eclipse, Netbeans) and they can be debugged on a testnet, unit tested with JUnit, and in general use the best programming tools available. Our contracts can use limitless repositories of 3rd party Java based libraries used for mathematical, economics, or physics calculations to interface with any external system using almost any technology. Of course, the more external code you rely on, the less trust you have, so it’s a trade-off that application developers will need to consider.

To summarize, building on top of dozens of development man years already invested into the Ardor built in functionality, our lightweight contracts provide a layer of flexibility and automation which enables building much more sophisticated server side blockchain applications.