The Next Generation Protocol for Decentralized Scheduling on Ethereum.

This article aims to describe the research our team has done regarding conditional scheduling and why we decided to make it the main point of our next generation scheduling protocol.

For a few months now, we’ve been working on the Ethereum Alarm Clock protocol, tooling, DApp and integrations. The Ethereum Alarm Clock is an on-chain, time-based protocol for scheduling transactions. Created by Piper Merriam in 2015, it is currently maintained by the ChronoLogic team. Time-based scheduling is a very powerful idea, but it’s not capable of handling if-this-then-that type of scheduling. The idea to explore this type of scheduling was sparked by discussions with teams and projects in the Ethereum space about potential use-cases for the Ethereum Alarm Clock. Some of them were based on a state change, rather than a specific time period.

Let’s take a closer look at the example on how we could implement decentralized stop-loss functionality using the Ethereum Alarm Clock. One of the possible solutions for the problem that could be implemented can be defined as follows:

Create a smart contact called StopLoss with execute function that is going to check a decentralized exchange for your current position and will place the sell order if certain conditions are met

with function that is going to check a decentralized exchange for your current position and will place the sell order if certain conditions are met Use the Ethereum Alarm Clock protocol to create a scheduled transaction with recurring execution for execute for e.g every 5min

While this solution works, it would generate an enormously high cost for users (~500 000 gas per trigger x 12 (times per hour) x 24 (hours) ~= 225 USD daily given 2Gwei gas price) making this it not feasible.

In general, the problem with this approach is that every trigger costs gas regardless of whether it succeeds or not. A much more efficient solution for this problem would be to have a scheduler that allows one to store conditions directly in the contract and allows the execution only when these conditions are met.

Looking through that lens we came to the conclusion that time-based scheduling is just a special case of conditional scheduling. The conditions are: if time then or if block then . TimeNodes (the off-chain executors) are checking time and block conditions before the execution (by reading them from the smart contract) which means that they attempt the sending of transactions only when those conditions are met. Instead of defining time or block we delegate this check to external contracts that for e.g has method inExecutionWindow(uint windowStart, uint windowSize) returns (bool) which check whether block.number if within the given window.

Generalizing this approach, we can set any arbitrary pair of address and bytes that can be used as a guarding expression before the execution. Find below the implementation on how to call arbitrary callData and get the returned value (❤️ to Gonçalo Sá for optimizations done during micro-hacking session at DappDev in Kiev)

callData.sol

In general the execution flow for a scheduled transaction can be depicted as follows

Conditional execution flow

Translating this to Solidity code, we check the conditions before execution

Where canExecute deserializes and invokes callWithData

And since canExecute is declared with modifier view it can be “tested” without using gas by the off-chain nodes before attempting execution.

This approach to scheduling enables a much broader spectrum of use-cases than simple time-based executions. We can efficiently implement any Ethereum state-based scheduling, Plasma chain observers, state-channel challenges etc.

If you’re interested in the work we’re doing on the Chronos protocol, follow the progress on our public GitHub. Connect with us directly on our Gitter channel to discuss our latest development.