BLOCKCHAIN: Poll - 分散投票システム [DAPP]

On the 22nd of October, 2018, we started working on developing a basic blockchain decentralized application in a three-day hackathon event. Me and my friend [Vince Millora](@Binsu) were partners, and we had come to a consensus that we'll make a "poll" web system. A back-end, and a front-end were required for it to be completed. And the day before the 28th, we prepared the slides and the script for the mini-pitch presentation. 

こんにちは、私はマルクス [Twitter: @markusveeyola](http://www.twitter.com/markusveeyola) です。


#Pollとは
A poll is a created event for implementing surveys from public opinions. This is done by choosing a candidate or a category for an independent topic. This is usually done to establish fair voting activities, such as an Election.

#なぜ Poll システム
We decided to make a poll system because we think that it suits well with the trust protocol that the blockchain offers for the internet. Blockchain is a technology that decentralizes information and makes the data immutable. All the data in the network cannot be tampered with because everyone has a copy, each copy has to verify whether or not the changes in the block is true. Hence, making your application's data secured. 

If you're curious about blockchain, here's a link to get you started:
[What is Blockchain Technology?](https://blockgeeks.com/guides/what-is-blockchain-technology/)

![poll3.PNG](https://qiita-image-store.s3.amazonaws.com/0/300940/b2b95d7d-b859-0661-0bb9-02e803e37905.png)

Since a poll system's fundamental function is to handle the votes of the people, any kind of tampering of a user's vote count must be safeguarded at all cost. With the help of the blockchain technology, we can safely deploy a voting system in the virtual world without worrying about the security of the users' data. This brings back the trust from the people to use the internet as a means of information transaction, which is why cryptocurrency finally became possible.




#何をすることができる
Here are the things the user can do in the application:

- The user can create a poll.
- The user can add candidates for the poll.
- The user can vote for a candidate in a poll.

Since, that's all clear, let's head on to the technologies we had used to make the application.

#使われる技術

###Solidity
To make a decentralized application, I first needed to make a smart contract that will write the functionalities of the poll system. And for that, I used the Solidity language. This language is specifically used for developing Blockchain applications, and the language itself is heavily based on Javascript. 

Also for compiling and deploying a solidity based smart contract, I had to use Remix. It is an online compiler that can deploy your smart contract into the blockchain network.

###GitHub

This tool is used simply to manage the project development properly, we created a repository to secure and track our code changes. It can be very handy if you're in a team and you have to develop a program concurrently. If you're not using this tool yet, you have to give it a try. 

###NPMとWebpack

To make our life even more easier, we used the Node Package Manager to handle the needed dependencies for our project. Instead of loading a lot of dependency links in your HTML script tags, we can bundle every single dependency into one by using the Webpack. And from there, we can just inject it directly. By standard, this method has become the normal way of implementing web applications.

###React JS

For the front-end of the application, I decided to use React JS as a personal preference. I'm inexperienced in using this technology, but I found it very useful in developing user interface in such a small time frame. The dynamic hotswapping changes was very handy in my realtime development. I never thought doing the front-end would be as fun as developing the back-end.


###Web3.js

This javascript file does everything for us to communicate to our contract in the blockchain network. All we had to do is to make an instance of our connection to the smart contract, using the contract ABI and its address. This is implemented in the front-end and from there, we can now call the functions from the smart contract. 

For more information about these technologies, check the the links below:
React.js : https://reactjs.org/docs/getting-started.html/
Web3.js : https://web3js.readthedocs.io/en/1.0/
NPM: https://docs.npmjs.com/getting-started/what-is-npm
Webpack: https://survivejs.com/webpack/what-is-webpack/
Solidity : https://solidity.readthedocs.io/en/v0.4.25/
Github: https://github.com/features

#スマトコントラクト

For the back-end of the application, this is entirely handled by the deployed smart contract in the blockchain. Although by standard practice, there should also be a local database to easily access the data information needed real time. The appropriate architecture is to sync the database and the contract's information, so the front-end can only communicate to the database. But, just to showcase how to make a decentralized application, and how it works when implemented, we opted to using the smart contract alone as the source of information. 

Now, let's walk you through our simple smart contract.

##Models
Now in the very beginning of the contract, we created 2 structs that makes up the data storing template for the poll system, the Poll and the PollCandidate structs.

First is the Poll struct, which contains the necessary information for a poll. A mapping variable was created for the Poll Candidate struct along with a counter, since each poll has its own candidates. Another mapping variable that tracks the address of the users that had already voted. Second is the Poll Candidate struct, we wanted to make it as simple as possible so it only contains the name of the candidate and the number of votes.


```javascript

contract PollSystem {
  
  // This is the data structure of the poll.
  struct Poll {
    string title;
    string description;
    uint dateCreated;
    uint endDate;
    address pollCreator;
    uint numberOfPollCandidates;

    mapping (uint => PollCandidate) pollCandidates; // storage for different candidates in the poll.
    mapping (address => bool) alreadyVoted; // storage for the users who already voted.
  }

  // This is the data structure of the poll candidate.
  struct PollCandidate {
    string candidate;
    uint numberOfVotes;
  }

  ...
}
```
##コンストラクターと変数

Next in the code is the declaration of varables, and the constructor. The constructor simply assigns the contractOwner variable with the msg.sender upon deployment. This is only done once since a constructor can only be run once. Next is the mapping variable of the Poll struct along with a counter variable. 

```javascript  
  mapping (uint => Poll) private polls; // storage for the polls
  uint private numberOfPolls;
  address private contractOwner;

  constructor () public {
    contractOwner=msg.sender;  
  }
```

##関数
Now that the variables and constructors are all set, we can now make functions.
###CreatePoll
Next in line is this main function. What it basically does is it creates a new poll by getting the necessary information in the parameters upon function call. It iterates the counter and uses it as index for adding a new poll, we set the number of candidates to 0 since we have yet to add any. 

A point to notice is we used an integer datatype for the dates since we can easily compare it once we want to verify if the poll event is already done or not based on the current date and the end date.

```javascript

  /* 
   * @details: Function for creating a poll.
   * @params: _title (title of the poll), _description (description about the poll)
   *          _dateCreated (the date when the poll is create), _endDate (date when the poll will end)
   */
  function createPoll(string _title, string _description, uint _dateCreated, uint _endDate) public {
    numberOfPolls++;
    polls[numberOfPolls]=Poll(_title, _description, _dateCreated, _endDate, msg.sender, 0);
  }
```

###CreatePollCandidate
Obviously, as we have foreshadowed just recently, the next main function is for creating candidates for the poll. So what it accepts in the parameters is the name of the candidate and the index to specify which poll will it be added. As a requirement, only the creator of the poll can add a new candidate in the poll.


```javascript

  /* 
   * @details: Create a candidate for a specific poll.
   * @params: _candidate (name of the candidate), pollIndex (the id of the poll where we add the candidate)
   */
  function createPollCandidate(string _candidate, uint pollIndex) public {
    require (polls[pollIndex].pollCreator==msg.sender);
    polls[pollIndex].numberOfPollCandidates++;
    polls[pollIndex].pollCandidates[polls[pollIndex].numberOfPollCandidates]=PollCandidate(_candidate, 0);
  }
```

###Vote
Given that we already added a poll and a few candidates, the last main function is for voting. This is where we can monitor if the voter has already voted since every vote stores the address of voter. Other than that, all it does is to increment a vote given index of the selected candidate and the index of the poll. 

```javascript

  /* 
   * @details: Vote a candidate in a specific a poll.
   * @params: pollIndex (the id of the poll where we vote), CandidateIndex (id of the candidate) 
   */
  function vote(uint pollIndex, uint candidateIndex) public {
    require (polls[pollIndex].alreadyVoted[msg.sender]!=true);
    polls[pollIndex].pollCandidates[candidateIndex].numberOfVotes++;
    polls[pollIndex].alreadyVoted[msg.sender]=true;
  }
```
###Others
The rest of the code functions are just for getting the information that was set by the main functions. Functions such as getting the number of votes, getting the candidate's name, checking if the user is the owner of the poll, and getting the poll details.  

You can go ahead and read through, the function definitions are very self explanatory.

```javascript

  /* 
   * @details: Get the number of votes of a candidate from a specific poll.
   * @params: pollIndex (the id of the poll), CandidateIndex (id of the candidate)
   * @return: uint (contains the number of votes of a candidate)
   */
  function getNumberOfVotes(uint pollIndex, uint candidateIndex) external constant returns (uint){
    return polls[pollIndex].pollCandidates[candidateIndex].numberOfVotes;
  }

  /* 
   * @details: Get the name of a candidate from a specific poll.
   * @params: pollIndex (the id of the poll), CandidateIndex (id of the candidate)
   * @return: string (contains the name of a candidate)
   */
  function getCandidateName(uint pollIndex, uint candidateIndex) external constant returns (string){
    return polls[pollIndex].pollCandidates[candidateIndex].candidate;
  }


  /* 
   * @details: Get the number of candidates in a specific poll.
   * @params: pollIndex (the id of the poll)
   * @return: uint (contains the number of candidates)
   */
  function getNumberOfCandidates(uint pollIndex) external constant returns (uint) {
    return polls[pollIndex].numberOfPollCandidates;
  }

  
  /* 
   * @details: Check if the user is the owner of the poll.
   * @params: pollIndex (the id of the poll)
   * @return: boolean (true if the user is the owner, else false)
   */
  function checkIfOwner(uint pollIndex) external constant returns (bool) {
    if(polls[pollIndex].pollCreator==msg.sender)
      return true;
    else
      return false;
  }

  /* 
   * @details: Get the details of a specific poll.
   * @params: pollIndex (the id of the poll)
   * @return: uint (contains the number of candidates)
   */
  function getPollDetails(uint pollIndex) external constant returns (string _title, string _description, uint _dateCreated, uint _endDate) {
    return (polls[pollIndex].title, polls[pollIndex].description, polls[pollIndex].dateCreated, polls[pollIndex].endDate);
  }
}
```

#アプリのスクリーンショット
After creating and deploying the smart contract, developing the front-end and establishing the connection from the smart contract using Web3. This is how it looks:


##Create Poll Page
We used MaterializeCSS to create the layout, its simple and clean just like we wanted. You can see the form where you can enter the information with a user friendly date picker. After filling it all up, you can then create a new poll.

You will need Metamask and an account to make a transaction, since creating new information costs gas.

![poll1.PNG](https://qiita-image-store.s3.amazonaws.com/0/300940/bcb935ad-f312-3f98-78b9-f98e4cfa67f1.png)

##Add Candidate & Vote Page 
In this page, you can add and vote for your candidate, however only the poll creator can add new candidates in the poll. So all you have to do is to put the name in the text field and just click add. 

![poll2.PNG](https://qiita-image-store.s3.amazonaws.com/0/300940/69eb5dae-145d-fae0-2dc8-6d5ef3d11516.png)

#必要な改善
Some features that you can add to improve the application:

- As you can see in the user interface, we only used the index as a means for searching, but you can make it more friendly to the user by letting them search the name of the poll and just set a password to secure the privacy and scope of the poll event.

- In our application, we check the dates in the front-end, but this is a bad practice as this can easily be manipulated in your own system unit. Checking of dates should be done in the smart contract to avoid time manipulation.

- Also, as I have mentioned earlier, you might want to use a database for real time interaction. Let your database sync into the smart contract and have your front-end communicate in your database. 

#結論
So that's it! We made a decentralized application for the blockchain that serves as a poll system. I'm sure there's still a lot of improvements to be done given that this is just a prototype. Now that we have given you an idea of the main functions and the technologies needed to make a decentralized application, why don't you give it a try and make something like this on your own and improve it!

I hope you learned a lot in this article. If you found it helpful, leave an [いいね!] for more contents like this!

ありがとうございました！