The EIP proposes an standard on a Cron system as an attempt to deterministically schedule state changes from the EVM, simmilar in as many points as possible with existing cron standards and with complete Cron verbosity. The problem is divided into two different modules: The Crontab, a compiler of cron expressions
State scheduling has always been a tough task in the EVM. Depending on the use case, we see implementations today developing their own lazy calculations on intervals. Scheduled meta transactions also create a time interval, and manage logic offchain.
Using modular arithmetics it is possible to generically calculate the number of times a generic event has occurred from the time it was scheduled, with O(1)
complexity. This means it is possible to create a fully verbose clock function, which pasively calculates the number of occurrences of the event. This number, which we will call height, can be used to define time epochs.
Once clock instances are in place, it is possible to link it to EVM code, and make its execution deterministic by providing the right incentives to external accounts to execute it. Executors have a very simple payoff matrix, where they only need to check that the reward will be higher than the gas costs of executing it. As a result, any Smart Contract is able to create the following code, and have:
CronTab ct = CronTab.new('*','*', '*', '1', '*')
bytes32 ct_id = ct.getID();
crono.schedule(ct_id, bytes4(sha3("setN(uint256)")), _n)
This EIP proposes a Cron implementation as a general tool for Ethereum, accessible by any Smart Contract, or external account simmilar to other general purpose services like ENS.
An interface simmilar to Cron in Ethereum would have the following benefits:
- Interoperability: By decoupling the scheduling logic, Smart Contracts and external services (oracles) can easily sync their clocks.
- Programability: Most Smart Contracts develop their own arithmetic rules every time they want to schedule periodic changes. The complexity of coding an arbitrarily complex rule may prevent the developer to include it
- Security: As having a robust library externalizes the development
The Ethereum Cron is comprised by two different modules:
- Crontab: Registry storing all Crontab expressions created from any account. For each one of this entries, provides a function, height, which returns the number of occurrences the of a given crontab expression since its creation To get more details about how this calculation is done, go to Annexe 2.
- Scheduler: Mapping from a crontab entry id to a target transaction, and the mechanism design to enforce and prove the execution of the defined recurring transaction.
The specs for each one of these modules are attached below.
A CRON expression is a string representing the schedule for a particular command to execute. The parts of a CRON schedule are as follows:
* * * * * *
- - - - - -
| | | | | |
| | | | | + year [optional]
| | | | +----- day of week (0 - 7) (Sunday=0 or 7)
| | | +---------- month (1 - 12)
| | +--------------- day of month (1 - 31)
| +-------------------- hour (0 - 23)
+------------------------- min (0 - 59)
Each of the parts supports wildcards (*), ranges (2-5) and lists (2,5,6,11).
Creates a new contract entry mapped to msg.sender
function schedule(bytes2 ct_second, bytes2 ct_minute,bytes2 ct_hour, bytes2 ct_day, bytes2 ct_weekday, bytes4 ct_year) public returns(bool);
Timestamp(in seconds) where the counter starts.
function initTimestamp() public view returns (uint256);
Return the number of occurrences of the stored crontab expression from initialTimestamp()
to block.timestamp
function height(bytes32 _id) public view returns (uint256);
Return the number of occurrences of the stored crontab expression from initTimestamp()
to a given _timestamp
function heightOf(bytes32 _id, uint256 _timestamp) public view returns (uint256);
Return the next timestamp where height will be changed, 2^256-1
if no new event is expected
function next(bytes32 _id) public view returns (uint256);
function getExpression(bytes32 _id) public view returns(bytes2 ct_second, bytes2 ct_minute,bytes2 ct_hour, bytes2 ct_day, bytes2 ct_weekday, bytes4 ct_year);
The scheduler creates a mapping between Crontab instances and EVM code to be executed and the mechanisms to ensure that every transaction is executed whenever the scheduler has enough balance to pay a transaction executor.
Creates a to
function schedule(bytes32 _id, address _target, bytes32 _data) public payable returns (uint256);
function bid(bytes32 _id, _price) public view returns (uint256);
- ISO 8601
- NTP
Field | Required | Allowed values | Allowed special characters | Remarks |
---|---|---|---|---|
ct_minutes | Yes | 0–59 | * | |
ct_hours | Yes | 0–23 | * | |
ct_weekday | Yes | 1–31 | * | ? L W only in some implementations |
ct_month | Yes | 1–12 | * , - | |
ct_weekday | Yes | 0–6 | * , - ? L # | ? L W only in some implementations |
ct_day | No | 1970–2099 | * , - | This field is not supported in standard/default implementations. |
The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion.-->
While an Smart Contract with recurring or scheduled events can easi
Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable.
The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details.
Copyright and related rights waived via CC0.