Simple: deploy the contract, register your ACTIONS of your other contracts with times when they should be executed and they will be repeatably called automatically. Just like a cronjob...
How it works: Using recursive deferred transactions.
Note: The tutorial and code is written for eosio-cpp version 1.4.1. Make sure you have the right version when compiling. You will also require cleos on a Linux environment.
Thanks: If you use this code or learn something please thank Obolus in your code and also on twitter.
This requires some basic knowledge about setting up accounts and deploying a contract. See a tutorial here for example:
first steps with eos or first contract.
In the following we use 2 accounts. jobservice which is where the cronjob service is deployed and mycontract which is where the contract with the actions sits.
First we need to build the contract with EOS CDT.
eosio-cpp -abigen cronjob.cpp -o cronjob.wasm && cleos set contract jobservice ../cronjob/
Next we need to give permissions to the jobservice to run functions on mycontract.
cleos set account permission mycontract active '{"threshold": 1,"keys": [{"key": "EOS5bUj...YOUR.PUBLIC.KEY.HERE...AQq","weight": 1}], "accounts": [{"permission":{"actor":"jobservice","permission":"eosio.code"},"weight":1}]}' owner -p mycontract@owner
Now it's time to think about when the functions should run. We define an ID that identifies the job testjob1 and let this job call the action testprint. The last arguments defines that it should repeat the action every 60 seconds with the first time running on UTC 2018-08-15 10:01.
export sched=`date --date "2018-08-15 10:01" %s`;
export arg="[mycontract, testjob1, testprint, ${sched}, 60]";
echo $arg;
cleos push action jobservice insertjob "${arg}" -p mycontract@active
This requires permissions of mycontract or jobservice. For changing, remove the old job which also kill the current pending deferred tx. Then reinsert you modified job with the same id. You can only have one job per (owner,id).
cleos push action jobservice rmalljobs '["mycontract"]' -p mycontract@active
With rmjob
you can also delete a specific job by jobid.
In the .hpp file, please switch the flag for DEBUG if you want to do your own development within the license requirements on this.
Tested with multiple thousand recursions but there might be a limit to the recursions. Be careful.
It is difficult to store arguments of your ACTION in a table due to unknown type and number. There is a way to do it though, I leave this as an exercise for the user. It means that now you can call ACTIONS that do not require an argument. Just make a wrapper around that function and store the arguments yourself. Then it's also easy to change.
Currently you can register a starttime and repeat time [s]. You cannot schedule the 1 day of the month or year. Also there might be an upper limit on deffered transactions. Be careful.
Feedback is tricky. As mentioned in this issue. In the jobservice you can check against the last executed flag and periodically make sure that everything is ok. The mycontract needs to provide resources for the called ACTIONS.
cleos get table jobservice mycontract cronjobs