How to Write an Ethereum Election Smart Contract


(bright sound)
– [Instructor] In this video,
we’re going to learn how to
code 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,
where a candidate in the election
will 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’ll 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
where 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 and pass in a string array,
we get the compiler error saying
nested array is not yet implemented.
Why is that?
This is because functions in Solidity
cannot accept or return
two dimensional arrays.
But, you might say hey,
we’re not actually using
a two dimensional array here.
We’re just using a one
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,
it’s actually a 2D array of bytes32,
which is not yet supported.
As a work around for now,
we’ll just pass in two 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 auction end 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 dot timestamp.
It returns a unix timestamp
indicating the current
blocks creation time,
not the actual current time.
Solidity also, supports many time units
such as minute, days, months,
but for now, we’ll just use minutes.
We’ll define an authorized
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’re initializing an object
in the voters mapping,
that’s not actually what’s happening here.
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 zero.
So, when we initialize this voter struct
with false and zero,
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 that’s 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 the weight of one.
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 zero.
In this case, we set the
weight for the voter to one.
And now, we define our vote function
that will allow any authorized
voter to submit a vote.
To vote for a candidate,
you need to submit an integer,
representing the zero based index
of the candidate in the list.
Anyone can access the list of candidates
since we have declared it public.
First, we’ll check that the time to vote
hasn’t already passed.
Then, we check that the sender
hasn’t already voted before.
We then, record the vote and set a flag
to make sure the voter
can no longer call vote
without getting an exception.
The last step is to
increase the vote count
for the specified candidate
by the amount of weight
given to the voter.
This function still allows
anyone who isn’t authorized
to call the vote function,
but only if the owner
gives their vote any weight
does it affect the result of the election
because by default
everyone’s voting weight
will be initialized to zero.
We could also, just
add a require statement
checking that the message sender has
a voting weight of at least one.
Now, let’s write the end function
that will allow the owner
to call the election.
We want to ensure that the owner cannot
end the election before time is up.
Then, we’ll announce the results
using a custom event
called election result,
in which we’ll put the candidate name
and how many votes they got.
And, we’ll do this for each
candidate in the election.
Now, let’s run a quick poll.
Let’s say that we wanted to vote on
what the best song was of
Drake’s More Life album.
Is it Passionfruit or is it Blem?
Let’s give ourselves as
the creator, voting rights
and we’ll also give
two other test accounts
voting rights.
Now, let’s vote for Passionfruit.
Since it was the first entry in the list,
we specify an index of zero for our vote
and then, we submit the vote.
If we try to vote again
using the same account,
you’ll see we get an exception
since we can only vote once.
We’ll give the remaining two votes to Blem
using other accounts.
Also, let’s try voting with an account
that hasn’t already been authorized
to see whether it affects the results.
We don’t throw an
exception when calling vote
as an unauthorized user
because it would consume
all the transaction gas
and we want to be nice.
If we try to end the election as someone
who isn’t the owner, we get an exception.
Now, let’s call the election
and announce the results as the owner.
We can see the transaction details
to look at any printed events.
In the result, we see that
Passionfruit got one vote
and Blem got two votes.
Note that the unauthorized
vote did not count
in the results.
And, now you’ve seen how to conduct
a transparent election or
a poll on the Blockchain.
To learn more about the features
Smart Contracts have to offer,
check out our online guides and courses
at blockgeeks.com.
Thanks for watching and see you next time.

Add a Comment

Your email address will not be published. Required fields are marked *