Writing a lottery contract is a great way to learn important Smart Contract concepts such as State, Event and Visibility. In this 3 part series, I will describe the logic and codes behind a Lottery Smart Contract. In developing my Lottery Contract, I used Oraclize, a data carrier service that executes external JSON web services.
We know how lotteries work. Bets for some numbers are placed. The lottery closes and a set of random numbers are announced. Winners receive their windfall. This is a perfect candidate to be implemented as a Smart Contract because:
- The business case is trustless. Punters are worried that the lottery company may run away when they run out of money to pay out. The lottery companies need to verify if punters really betted the numbers.
- Punters are never too sure if the random numbers are really random. In my Lottery Contract, I have not really solved this problem. I will explain why.
- Punters needs to queue to receive their prize money. This is a hassle.
The Challenge of Randomness
The challenge in developing Lottery as a smart contract is randomness. To understand why, it is important to understand that random numbers generated by computers are never truly random. Computers are deterministic - meaning that the same inputs always generates the same outputs. Think about the CPU. When you feed a set of instructions into the CPU, say, 1+1, it always says 2. You will be truly worried if it doesn't sometimes. So how do you get a deterministic system like a computer to generate random numbers if the same input always produces the same output? The way that computers today do this is a technique called Pseudo Random Number Generator (PRNG). PRNG is an algorithm to generate random numbers based on seed values that is high in entropy - which is essentially actions within a computing environment that has some good amount of randomness. So what generates entropy in a computing environment?
- Movement of the mouse - you move your mouse all over the mouse pad, occasionally clicking it. Chances are you won't be clicking at the same rate and moving to the same place twice very often.
- Typing on the keyboard - you are likely to type as you think, thus you probably don't type at the same rate all the time since there are so many keys and so many different things you type.
- Time - Time flows in a single direction - forward. You computer's clock keeps running. Since it never stays the same, using time as a seed will give your random number algorithm a different number each time.
Why is this consider Pseudo (as opposed to True Random Number Generator - TRNG). Numbers generated through PRNG WILL produce the same "random" number if the circumstance that generates this number is repeated. i.e. if time reverses and goes back to the same time you used as seed to generate that previous number, you will get the same random number again.
Sounds like Time is a good seed for our Lottery contract right? No, because you can't tell time in a Blockchain. You can set a clock in your computer, in a server and on your mobile phone. But as a distributed system, the Blockchain follows nobody's clock, so time is not a feasible seed to generate numbers on the Blockchain. There has been many discussions on what can be used as a seed to generate random numbers on the blockchain. Here's one, another, and another. They mostly involve using block numbers, time stamps or any numbers that is derived from a new block. This works as a decent PRNG solution since the characteristic of a new block is highly unlikely to be the same as any previous blocks.
A Less Optimum Approach
I took an approach that is very much less optimum. I wrote a simple JSON web service that generates a random number between 5 and 15 and hosted it online here. My lottery smart contract will make an external call to this web service to generate a random number. This is not optimum because while punters trust that a lottery smart contract is immutable on the Blockchain, they wouldn't trust me as a developer of my random number generate running on my own server. Nobody can verify that I didn't cheat since I am the sole person with rights to edit the codes behind my random number generator. Who's to say that I didn't code the random number generator to keep trying until it gets a number that none of the punters betted on? So really, as a punter, you won't be betting with me anytime soon if this is how my real Lottery contract works.
For my lottery smart contract to make this external web service call, I used Oraclize which is an easy way to execute external web services from a Smart Contract. Oraclize has been used to develop some clever smart contracts such as a "travel insurance" that pays out if your flight is late.
Here's the logic behind my Lottery Smart Contract. For simplicity, and since the purpose of developing it is to learn about States, Visibility and usage of Oraclize, I decided to keep this first version simple.
Icons made by Smashicons from www.flaticon.com is licensed by CC 3.0 BY
Icons made by Freepik from www.flaticon.com is licensed by CC 3.0 BY
In part 2 of this series, I will explain how Lottery Smart Contract is executed. In part 3, I will walk through its codes.