How to Write an Ethereum Election Smart Contract https://blockgeeks.com
In this video we are going to learn how to code up an election contract. We want to hold a free and fair election for a specified amount of time and only allow authorized people to vote in it
We’ll start by defining a custom data type called a struct, which allows us to group together other data types, to define a Candidate struct. For a candidate in the election, we’ll keep track of their name and the number of votes they currently have.
Let’s also define a struct for the Voter, that will store whether or not the voter has already voted, and who they voted for.
We need to keep track of the owner of the contract as they will have special rights to authorize voters. We also keep a mapping to store voter information, as well as a dynamically-sized array of candidates that will be initialized on construction. The way to define an array is to simply use the square brackets after the data type of a variable. We’ll also keep track of the time when the election ends using an integer timestamp.
We’ll initialize our list of candidates in the constructor. We pass in a name for our election, the duration of the election in minutes, and an array of candidate names. But wait, when we try to pass in a string array, we get a compiler error saying ‘nested arrays not yet implemented’. Why is that? This is because functions in Solidity cannot accept or return 2-dimensional arrays. but you might say hey we’re not actually using a 2-dimensional array here we’re just using a 1-dimensional array of strings. And even though it appears that way, under the hood, the string data type is implemented as an array of the bytes32 data type. So when we add the square brackets after string, its actually a 2d array of bytes32, which is not yet supported.
As a workaround for now, we’ll just pass in 2 string arguments representing only two candidates in the election. If we wanted to support multiple candidates, we could just pass in an array of bytes32. We’ll define candidate objects using the provided names
We also set our auctionEnd variable to be from now plus the specified duration in minutes. Now is a global variable, which is an alias to another global variable called block.timestamp. It returns a unix timestamp indicating the current block’s creation time, not the actual current time. Solidity also supports many time units such as minute, days, months. For now we’ll just use minutes.
We’ll define an authorize function that allows the owner of the contract to give voting rights to any address. In this function, we initialize the Voter object for the address. Even though this looks like we are initializing an object in the voters mapping, that’s not actually what’s happening. Mappings can be thought of as hash tables which are virtually initialized such that every possible key exists and is mapped to a value whose byte-representation is all zeros, which is a type’s default value. So for bool it would be false, and for integer it would be 0.
So when we initialize this Voter struct with false and 0, we’re not actually doing anything since these are already the default values set in the mapping. The implication being that anybody would be able to participate in the election, not just the authorized voters, and thats not quite what we want. To solve this, we’ll add a weight field to the Voter struct which will specify the weight of a vote. This will allow us to only count votes from people we authorize with a weight of 1. So to give voting rights, we don’t need to create a Voter struct and pass in all the fields, we just need to set the one field that won’t default to 0, in this case we set the weight for the voter to 1.
Read more on Blockgeeks: https://blockgeeks.com