If you’ve written a Solidity smart contract, then you’re familiar with the benefits of decentralization. You’re also probably aware of its limitations. One such limitation is the smart contract’s inability to execute on a schedule. In order to execute a method on the contract, it would have to be triggered from the outside. In order to demonstrate this weakness, I shall build an Ethereum Lottery smart contract.

Let’s spec it out:

– 1 ETH per entry

– Unlimited entries are allowed

– Minimum of 5 entries per drawing is required

– One winner is randomly selected. He/she wins the entire pot.

– The winner must withdraw his winnings

– Upon drawing, the lottery is reset and a new pool begins

This is what I whipped up:

Disclaimer: This solidity contract is imperfect. I do not recommend uploading this contract and running your own lottery. This is for demonstration purposes only!

Now that we’ve got the disclaimer out of the way, let’s focus on the drawWinner() function.

We assert that there are at least 5 entries. We calculate the final hash based on each of the entrant transaction block hashes and derive a random integer with a max equal to the number of entrants. We pick our winner and log their winnings in a map. We then reset our lottery.

Unfortunately, we can’t simply annotate it with a @Scheduled(cron = “0 0 0 15 * *”) nor @Scheduled(fixedDelay = 2592000000) and call it done. In this contract, drawWinner() has to be triggered from the outside by the proper owner at the proper time every time, or a winner isn’t drawn.

Now that requires a lot of trust for a system designed around trustlessness. How do we automate execution? Let’s ask Google for a solution here:

It looks like Solidity developers have been asking for a solution:

search result 1

search result 2

search result 3

search result 4

search result 5

You’ll notice mentions of a service known as Ethereum Alarm Clock which is currently dormant (or dead?).



In many cases, contracts can (and should) be written/re-written to follow a lazy evaluation pattern. However, in other cases, an eager approach is desired and necessary.

Let’s discuss the “other case” and see how we can eagerly execute our lottery picker.

Ping Chain is a service that was built to solve this very problem.

Full Disclosure: I am part of the team that built the Ping Chain service.

Let’s see how we can refactor our lottery smart contract and have it trigger reliably on a schedule.

By converting the drawWinner() method into an internal method, implementing pingchainTriggerCallback, and adding some boilerplate pingchain code, I’ve made this contract ready for eager execution.

Now all we have to do is follow the quickstart instructions; set up triggers, fill our account with gas and PNG, and our contract is ready to go!

Source code available at github.com/cranklin/crankys-lottery.

Before I conclude, there are a few things to note:

– Ping chain is not fully decentralized. It can’t be. Ethereum smart contracts must be triggered from the outside.

– This sample lottery contract should not be uploaded. I cooked this up really quick for educational purposes. You’ll find that it costs a lot of gas to run, the random number picker isn’t perfect, and some features are missing.

– (Pseudo)Random number generators in smart contracts are not a simple task. Deterministic generation of a pseudorandom number on a public blockchain while preventing it from being manipulated or guessed is obviously difficult to secure. Current block hashes are unknown (the miner hasn’t mined the block yet). Block hashes are only known for block heights: n-256 to n-1 where n is the current block height. The rest are 0. In this system, I stored the contract construction block height for its hash to be determined at a later transaction (state change). Each transaction (state change) stores that transaction’s block height and keccak256 hashes the concatenation of the previously stored block height’s hash with the latest concatenation. The final transaction (drawWinner) concatenates its n-1 block hash and performs a final keccak256 hash before calculating its modulo to the number of entries. It’s a quick/naive approach to a complicated problem.

– And you probably should not actually run a lottery… it’s probably illegal where you live