Writing a Lottery Smart Contract using Solidity

Dhruvjain
6 min readOct 21, 2022

--

Introduction

Smart contracts are simply programs stored on a blockchain that run when predetermined conditions are met. Ethereum is one of the most popular blockchain although other blockchains like Solana are catching up in terms of number of applications that are being built on them. Smart contracts on Ethereum are written in solidity. Solidity smart contracts are easy to understand and code as solidity is partly similar to the common programming languages. To develop applications on any blockchain, writing the smart contracts is the first step. Most blockchain developers start their journey by writing a few smart contracts in Solidity.

Objectives and End-Goal

The objective of this blog is to get you well-versed with the basic concepts of solidity and smart contract writing and get you started with your very first smart contract. At the end of this blog you will have your own Lottery smart contract up and running.

What are we building exactly?

We are building a lottery smart contract where we have two main entities, the creator and the contestants. The contestants pay an entry fees that will be stored in the smart contract and enter the lottery. The creator can set the fees, change the fees, and decide when to declare the result of the lottery. When the creator ends the lottery automatically the entire amount stored in the smart contract will be transferred to the winner of the lottery, who will be selected randomly from the list of contestants.Unlike in a traditional lottery system where the creator holds the money of the contestants, in a blockchain based lottery system the funds are held in the smart contract and can only be relieved from there on ending the election.

Environment Setup

For this tutorial we will have a very simple environment since we are only coding the smart contract and testing it manually and not writing automated tests. We will use a simple web IDE called Remix. It is one of the most used tools by early developers. It has a very intuitive UI and is very to use.

Coding

Finally the good part has arrived. First line of every solidity smart contract is a comment mentioning the standard and license used. The next line shows the version of solidity being used for this contract.Next we define the contract by using the key-word contract followed by name of the contract. All our code related to this contract will go here.

Solidity 0.6.8 introduces SPDX license identifiers so developers can specify the license the contract uses. (e.g. OpenZeppelin Contracts use MIT license).

Fig1. Creating the skeleton of the smart contract

Variable and Constructor Definition

Next we define the variables and the constructor that we will be using. In our scope, the only variables we have to define will be the owner, and the array of contestants. We also define the default fees of the lottery here which can be changed by the owner at any time. Now coming to the constructor, it is the piece of code that runs only once, that is when the contract is deployed. When we deploy the smart contract we want the person deploying the contract to be the creator of the lottery. The term msg.sender signifies the address from which the fees to deploy the contract was paid.

Fig2. Defining the variables and the constructor

The addresses of the contestants are of type payable which means that the smart contract will be able to pay these addresses. This is so because any address can win the lottery and the smart contract should be able to pay to that address.

Modifiers in Solidity

Next we write the functions that we will be using in this contract. Most of these functions can be called by anyone but a few functions like ending the election or changing\setting the fees should be called only by the creator. For ease of coding and not repeating the require condition again and again solidity has modifiers. They are used to add prerequisites to functions. As coding practice we generally put our modifiers at the end of the contracts.

Fig3. Function modifier for functions that can be called by creator only

Writing Functions

Next we write the basic functions like the get fees and set fees function. The logic for this is pretty straight forward, the get fees function calls the fees variable and returns the value of fees. Since the function only views the value and does not perform any transaction, no fees is charged and we add the view keyword. For set fees we change the value of fees variable and update it. Since only the creator can do this we add our modifier here.

Fig4. The fees getter and setter functions

Entering the contestant

Here any user that calls this function and sends the fees amount along with this call is registered for the lottery. We first check that the amount being sent(msg.value) is exactly equal to the fees and then we add the address of the function caller(msg.sender) into the contestants array. This function has the payable keyword since the smart contract is receiving funds in this function.

Fig5. The function to enroll participants

Checking the prize money

The get balance just like the getFees function gets us the amount of funds present in the smart contract. The this keyword is something to look at here and it always refers to the contract that is being used in. We typecast it into address type and return the balance.

Fig 6. The getBalance function

Declaring the result

The logic for this would be to generate a random range in the starting and ending index of the contestants array and declare him as the winner. However there is one problem. There is no true random number generator in solidity. Blockchain being a state complete machine does not support truly random numbers. Thus we have to use Pseudo random number generating algorithms. This problems can be solved by use of Oracles. In this implementation we will use a pseudo random number generating algorithm. We hash the block generation timestamp and the creator’s address and then modulo it with the length of the array. Solidity provides us with keecak256 hashing algorithm which we use for hashing. Keeping this function private or public does not make much of difference but since we are doing this for learning it has been kept public. Once the random number is generated we transfer the amount present in our contract to that address and then we reset the array as the lottery is now over and a new lottery can be started again.

Now we are done with the code and at the end of it your code should somewhat look like this.

Lottery Smart Contract

Conclusion

There we go we have our Lottery smart contract ready. Now what you need to do is try it and test it by yourself on remix. The IDE is very intuitive to use and by playing around and testing the features you will learn even more.A few common mistakes one could make are:-

  1. While entering the lottery make sure to set the value exactly equal to the fees and make sure the unit is set to Ether. By default it is set to Wei.
  2. Make sure to call the onlyOwner functions using the creator address. That will give you an error.
  3. While entering arguments like that of fees , again the default is set to Wei and you will have to add the required number of zeroes, remember (1ETH=10¹⁸Wei).

Explore Deeper

  1. You can try writing unit tests in JavaScript using truffle and chai libraries. I will write a blog on this later.
  2. Write and explore more smart contracts which are slightly more complex. Writing a smart contract for a shared wallet where one person adds funds into the smart contract and authorizes a few other users to use funds of that smart contract. For additional functionality, you can also add limits to the amount each authorized user can use.
  3. Explore deeper into the concepts of oracles and try building one using chainlink. A tutorial you can follow could be this.

--

--