# Simple voting on the Waves blockchain
The head of the HOA (homeowners association) asks the tenants of the building: "Dear residents, do you agree with the construction of the kids' playground in the yard of your building?".
Objective: implement such voting among tenants on the Waves blockchain.
# Roadmap
- Create an account of the head of the HOA.
- Create accounts of tenants.
- Create dApp script with the
vote
method. - Attach dApp script to the account of the head of the HOA, thus creating a dApp.
- Vote from the accounts of tenants by invoking the
vote
method of the dApp. - View the results of the voting.
# 1. Creation of the account of the head of the HOA
Go to the Waves IDE settings.
Make sure that the test network is selected.
Create an account of the head of HOA by selecting Generate New Account.
Rename created account to "Head of HOA".
Copy the address of the head of HOA and top up its balance by 10 WAVES using the Faucet. The head of HOA will need tokens to pay the fee for the set script transaction when he will be attaching dApp script to his account.
# 2. Creation of accounts of tenants
Similarly, create accounts of tenants Aleksei and Anna and top up their balances by 10 WAVES. They will need tokens to pay a fee for the invoke script transaction when they will vote by calling the vote
method of the dApp.
# 3. Creation of a dApp script
Create a dApp script by selecting DApp in the drop-down list.
Rename the script to the "Head of the HOA voting".
Replace automatically generated code with the following:
{-# STDLIB_VERSION 8 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
func voterIsAllowedToVote(voterPublicKey: ByteVector) = {
let alekseiPubKey = base58'8QvKvspfNF6cUv2DFMCfvT8SrbraERqXpNMEMqBfJZ3e'
let annaPubKey = base58'AtYwJTqWNfwYrPnWVvfmnPTSTEioiLFzUTcZVttgDj1x'
if (voterPublicKey != alekseiPubKey && voterPublicKey != annaPubKey)
then
false
else
true
}
@Callable(i)
func vote(theVote: Int) = {
if (!voterIsAllowedToVote(i.callerPublicKey))
then
throw("You can not vote because you are not in the list of voters!")
else
let dataFromStorage = this.getInteger(i.callerPublicKey.toBase58String())
if (dataFromStorage.isDefined())
then
throw("You have already voted! Voting the second time is not allowed.")
else
(
[
IntegerEntry(i.callerPublicKey.toBase58String(), theVote)
],
unit
)
}
# Explanation of the code of the dApp script
# The vote
function
The vote
function performs the IntegerEntry
script action that records the vote to the account data storage of the head of the HOA.
In front of the vote
function, there is a @Callable
annotation which makes the dApp function callable. The i
is the variable that contains the information about the invocation. In the code we use variable i
to get public key of the account which invoked the vote
function.
To keep things simple, there are no checks of the value of the theVote
variable in the code.
# The voterIsAllowedToVote
function
The voterIsAllowedToVote
function checks if the account that invoked the script has rights to vote.
In the current example the values of public keys are hardcoded in the script. In the real world example, it will be better to read public keys, for example, from the data storage of the account of the head of the HOA (after saving them there beforehand).
Get the values of alekseiPubKey
and annaPubKey
from the accounts' cards of Aleksei and Anna.
# The getInteger
function
The getInteger
function gets values of the account data storage by key:
let dataFromStorage = this.getInteger(i.callerPublicKey.toBase58String())
The size and the complexity of the script is displayed in the panel underneath the script editor.
# 4. Attaching dApp script to the account of the head of the HOA
Press the Deploy dAppscript button.
In the opened window, in the Account combo box, select the "Head of the HOA" value. Sign the transaction by pressing Add sign.
Note that you can also sign a transaction with a seed phrase or using Keeper Wallet.
Send a set script transaction from the account of the head of the HOA by pressing Publish. By doing so, you just created a dApp.
In the Waves Explorer for Testnet, find the information about the activity on the account of the head of the HOA. Enter the address of the head of the HOA in the search bar and press Enter.
There are two transactions on the head of the HOA's address: the transfer transaction (balance top up by 10 WAVES using the Faucet) and the set script transaction. Note that the commission of 0.01 WAVES was charged from the head of the HOA's balance for the set script transaction.
# 5. Voting
In order to vote a resident must send an invoke script transaction from his account. In the transaction he must specify the address of the dApp, the name of the method to call, and the passed parameters. Send an invoke script transaction from Aleksei's account using Console. First, select Aleksei's account in the Waves IDE.
Then, on the Console tab, execute the following command:
broadcast(invokeScript({dApp: "3Mw2J9yxS8ftQ8FZuD6hsE3fCu494qJqB5r", call: {function: "vote", args: [{type: "integer", value: 7}]} }))
Here 3Mw2J9yxS8ftQ8FZuD6hsE3fCu494qJqB5r
is the address of the account of the head of the HOA.
If everything went right, you will see the following result (expand the Promise
object in the console):
Similarly, vote from Anna's account, after selecting Anna's account in the Wave IDE:
broadcast(invokeScript({dApp: "3Mw2J9yxS8ftQ8FZuD6hsE3fCu494qJqB5r", call: {function: "vote", args: [{type: "integer", value: 25}]} }))
If you will try to vote again from Aleksei's or Anna's accounts, you will see the error:
If you will try to vote from the account of the head of the HOA, you will see the error:
# 6. Viewing the results of the voting
Take a look at the contents of the head of the HOA's account data storage on the Data tab in the Waves Explorer — there are two records in the account data storage.