Proj 10: Making a Blockchain Survey with Multichain (20 pts.)

What you Need

Purpose

To practice using Multichain for a simple practical application: a survey. This will give you some practice using PHP to control the Multichain via the API.

Concept

Right now, people vote by mail or in person, but they can't verify that their vote was correctly recorded. Then they wait till other people add up the votes, and tell them who won, and they can't verify the accuracy of that process either.

Here's how I propose to use Blockchains to create a better system.

Each voter has a computer connected to a blockchain, and each polling station does too, like this:

          

Voting works like this:

  1. The voter installs the blockchain software and joins the blockchain.
  2. The voter goes to a faucet and gets a token.
  3. The voter can vote online by sending the token to the account of the candidate they prefer. That voter can examine the blockchain to verify that the vote was correctly recorded, and also see the total votes for each candidate at any time.
  4. If a voter can't or won't vote online, the voter can go in person to a polling place and vote there.

In this project, we'll have one Voter and one Polling station, and the Polling station will be the only miner. We'll only implement the online voting method, for now.

Removing Old Multichains on the Poll Server

Pick one machine to be the Poll Server.

Execute this command:

ps aux | grep multi 
If any Multichain daemons are running, they will appear with command-lines on the right side starting with multichaind. Ignore the item beginning with "grep".

Find the process ID numbers in the second column of the multichaind processes. In the example below, there are two processes, with ID numbers 19066 and 51014.

          

For each multichaind process, execute this command to kill it, replacing the number with the correct process ID for your server.

kill 19066 
Execute this command to remove all old multichain data from your server:
rm -rf ~/.multichain 

Install Multichain on the Poll Server

Pick one machine to be the Poll Server.

If Multichain isn't already installed, execute these commands:

cd /tmp
wget http://www.multichain.com/download/multichain-1.0.1.tar.gz
tar -xvzf multichain-1.0.1.tar.gz
cd multichain-1.0.1
sudo mv multichaind multichain-cli multichain-util /usr/local/bin 

Creating a Blockchain on the Poll Server

First we will create a new blockchain named "survey". On the Poll Server, run this command:
multichain-util create survey

Adjusting Blockchain Settings

On the Poll Server, run this command:
nano ~/.multichain/survey/params.dat
In the "Global permissions" section, change these three parameters, as shown below.
anyone-can-connect = true 
anyone-can-send = true
anyone-can-receive = true
In the "Consensus requirements" section, change this parameter, as shown below.
setup-first-blocks = 10000

          

Save the file with Ctrl+X, Y, Enter.

Initialize the Blockchain

On the Poll Server, execute this command:
multichaind survey -daemon
The server starts, and you see the node address that others can use to connect to this chain, as shown below.

          

Getting an Address on the Poll Server

On the Poll Server, execute:
multichain-cli survey getnewaddress
An address appears. Make a note of it. In the example below, the address is

1ZW51sPdvVAbiXPfYdK83cgynoukYkmpXXqN5r

          

Issue the "token" Asset

Now we'll create an asset named "token" which cannot be subdivided, and place 10,000 of them on the Poll server.

On the Poll Server, execute these commands. Replace the address with the correct address for your Poll server.

multichain-cli survey issue 1ZW51sPdvVAbiXPfYdK83cgynoukYkmpXXqN5r token 10000 1
multichain-cli survey listassets
The commands succeed, so the Poll server now has 10,000 tokens, as shown below.

          

Install Apache on the Poll Server

On the Poll Server, execute this command. Enter your password when prompted to.
sudo apt-get update
On the Poll Server, execute these commands:
sudo apt-get install apache2 -y
sudo service apache2 start

Install PHP on the Poll Server

On the Poll Server, execute:
sudo apt-get install php libapache2-mod-php php-mcrypt php-mysql -y

Install Curl on the Poll Server

On the Poll Server, execute:
sudo apt install curl -y

Find your RPC Credentials

RPC (Remote Procedure Call) allows you to control your Multichain with HTTP requests.

On the Poll Server, execute:

cat ~/.multichain/survey/multichain.conf 
Your RPC username and password appear, as shown below. Make a note of them--you will need them later.

          

Find your RPC Port

On the Poll Server, execute:
grep rpc ~/.multichain/survey/params.dat 
Your RPC port appears, as shown below. Make a note of it--you will need it later.

          

Make the info.php Script

This script performs the "getinfo" method and prints the results three ways, to demonstrate how to excute a method and how to retrieve the results.

On the Poll Server, execute:

sudo nano /var/www/html/info.php
Enter or paste in this code. You will need to change two items:

1. Replace the password in the line beginning with "$a" with the correct password on your Poll Server
2. Replace the port number at the end of the line beginning with "$c" with the actual port number on your server.

<?php
echo "<h1>Information About the Survey Blockchain</h1>";

$a = 'curl -s --user multichainrpc:8EC2qNiyoyAVj6dQE6Sf5VuyVJF2zSewrsixnEMdoh7t --data-binary \'';
$b = '{"jsonrpc": "1.0", "id":"", "method": "getinfo", "params": [';
$c = '] }\' -H "content-type: text/plain;" http://127.0.0.1:9706/';
$cmd = $a . $b . $c;

echo "\n<h2>Raw Output</h2><pre>\n";
$ret=system($cmd);

echo "\n<h2>Decoded Output</h2>\n";
$rets = json_decode($ret, true);
print_r($rets);

echo "\n<h2>Single-Item Output</h2>\n";
echo $rets['result']['version'];
?>

          

Save the file with Ctrl+X, Y, Enter.

Testing the info.php Script

php /var/www/html/info.php
Scroll back to the start of the output. You should see a "result" section showing the version of multichain and other information, as shown below.

Saving a Screen Image

Make sure the version number is visible, as shown above.

Capture a full-screen image.

YOU MUST SUBMIT A FULL-SCREEN IMAGE FOR FULL CREDIT!

Save the image with the filename "YOUR NAME Proj 10a", replacing "YOUR NAME" with your real name.

Make a pay.php Script

Now that you know how to control the Multichain from PHP, you can make a script that pays out a token.

This script will send 1 token to a specific address.

On the Poll Server, execute:

sudo nano /var/www/html/pay.php
Enter or paste in this code.

Enter or paste in this code. You will need to change two items:

1. Replace the password in the line beginning with "$a" with the correct password on your Poll Server
2. Replace the port number at the end of the line beginning with "$d" with the actual port number on your server.

<?php

echo "<h1>Sending you a Survey Token!</h1>";
$addr = $_POST["address"];

$a = 'curl -s --user multichainrpc:8EC2qNiyoyAVj6dQE6Sf5VuyVJF2zSewrsixnEMdoh7t --data-binary \'';
$b = '{"jsonrpc": "1.0", "id":"", "method": "sendassettoaddress", "params": ["';
$c = '", "token", 1';
$d = '] }\' -H "content-type: text/plain;" http://127.0.0.1:9706/';
$cmd = $a . $b . $addr . $c . $d;

$ret=system($cmd);
?>
          

Save the file with Ctrl+X, Y, Enter.

Make a faucet.htm Page

On the Poll Server, execute:
sudo nano /var/www/html/faucet.htm
Enter or paste in this code.
<html><head><title>Survey Token Faucet</title></head>
<body bgcolor="#cccccc">
<h1 align="center">Survey Token Faucet</h1>

<form method="post" action="pay.php">
<p align="center"><b>Enter your address</b></p>
<p align="center"><input type="text" name="address" size="90"></textarea></p>
<p align="center">
<button type="submit" name="submitButton" value="">Get Token</button>
</form> 

</body></html>
          

Save the file with Ctrl+X, Y, Enter.

Removing Old Multichains on the Voter

Your other machine is the Voter. On the Voter, execute this command:
ps aux | grep multi 
If any Multichain daemons are running, they will appear with command-lines on the right side starting with multichaind. Ignore the item beginning with "grep".

Find the process ID numbers in the second column of the multichaind processes. In the example below, there are two processes, with ID numbers 19066 and 51014.

          

For each multichaind process, execute this command to kill it, replacing the number with the correct process ID for your server.

kill 19066 
Execute this command to remove all old multichain data from the Voter:
rm -rf ~/.multichain 

Install Multichain on the Voter

On the Voter, if Multichain isn't already installed, execute these commands:
cd /tmp
wget http://www.multichain.com/download/multichain-1.0.1.tar.gz
tar -xvzf multichain-1.0.1.tar.gz
cd multichain-1.0.1
sudo mv multichaind multichain-cli multichain-util /usr/local/bin 

Finding the IP Address of your Poll Server

On the Poll Server, execute:
ifconfig
Find the IP address of your Ethernet interface, as shown below.

Finding the Network Port

On the Poll Server, execute:
grep network-port ~/.multichain/survey/params.dat
Find the port number, as shown below.

Connecting the Voter to the Blockchain

On the Voter, run the following command, replacing the node address and port number with the correct values for your Poll server, which you found just a few steps above.
multichaind survey@172.16.1.135:9707 -daemon
Your node connects, and shows a "Node started" message, as shown below.

          

Getting an Address

On the Voter, run the following command:
multichain-cli survey getnewaddress
An address appears. Make a note of it. In the example below, the address is

1PZQYZoKrTmHABFkNTJtPZbavKeuQHxiwGQgF5

          

Using the Faucet

On any machine in your network, open a Web browser and go to this address, replacing the IP address with the IP address of your Poll Server. You used this address just a few steps above to connect to the blockchain.
172.16.1.135/faucet.htm
Paste your address into the Faucet page, as shown below.

          

Click the "Get Token" button.

The response shows "error": null, as shown below--it worked!

          

Checking your Balance

On the Voter, execute:
multichain-cli survey gettotalbalances
You now have 1 token, as shown below. You may have to wait 15-30 seconds for the token to appear.

          

Getting an Account for Candidate #1

On the Poll Server, execute these commands (the same command twice):
multichain-cli survey getnewaddress
multichain-cli survey getnewaddress
Two addresses appears, as shown below.

          

Making a Voting Page

On the Poll Server, execute:
sudo nano /var/www/html/vote.htm
Paste in this code. Replace the addresses with the two addresses you just made.
<html>
<head><title>Candidates</title></head>
<body>

<h2>Vote for Candidate #1</h2>
multichain-cli survey sendassettoaddress 1VRxsr8G1oe9WApAXUEXT6BJ9BEjJeHJhGKTkP token 1

<h2>Vote for Candidate #2</h2>
multichain-cli survey sendassettoaddress 1M3p1VDLSfZZBERkLkERf77vZ24tf1nNhJdmYm token 1

</body>
</html>

          

Save the file with Ctrl+X, Y, Enter.

Voting

In a Web browser, go to this address, replacing the IP address with the IP address of your Poll Server.
172.16.1.135/vote.htm
You see the voting commands, as shown below.

          

To vote, on your Voter Machine, execute one of those commands, as shown below.

          

Make the results.php Script

This script reports the voting results--that is, the total tokens received by each candidate.

On the Poll Server, execute:

sudo nano /var/www/html/results.php
Enter or paste in this code. You will need to change four items:

1. Replace the $can1 value with the address for Candidate #1
2. Replace the $can2 value with the address for Candidate #2
3. Replace the password in the line beginning with "$a" with the correct password on your Poll Server
4. Replace the port number at the end of the line beginning with "$d" with the actual port number on your server.

<?php

$can1 = "1VRxsr8G1oe9WApAXUEXT6BJ9BEjJeHJhGKTkP";
$can2 = "1M3p1VDLSfZZBERkLkERf77vZ24tf1nNhJdmYm";

$a = 'curl -s --user multichainrpc:8EC2qNiyoyAVj6dQE6Sf5VuyVJF2zSewrsixnEMdoh7t --data-binary \'';
$b = '{"jsonrpc": "1.0", "id":"", "method": "getaddressbalances", "params": ["';
$c = '"';
$d = '] }\' -H "content-type: text/plain;" http://127.0.0.1:9706/';

echo "\n<h2>Candidate #1 Total</h2><pre>\n";
$cmd = $a . $b . $can1 . $c . $d;
$ret=system($cmd);

echo "\n<h2>Candidate #2 Total</h2><pre>\n";
$cmd = $a . $b . $can2 . $c . $d;
$ret=system($cmd);

?>

          

Save the file with Ctrl+X, Y, Enter.

Viewing the Results

In a Web browser, go to this address, replacing the IP address with the IP address of your Poll Server.
172.16.1.135/results.php

          

Saving a Screen Image

Make sure you can see at least one vote recorded, with a qty of one or more, as shown above.

Capture a full-screen image.

YOU MUST SUBMIT A FULL-SCREEN IMAGE FOR FULL CREDIT!

Save the image with the filename "YOUR NAME Proj 10b", replacing "YOUR NAME" with your real name.

Turning in your Project

Email the images to cnit.141@gmail.com with the subject line: Proj 10 from YOUR NAME.

Limitations

This system doesn't allow the Voters to independently view the results now. When I tried it, I got an error because those accounts were not in my wallet. It also has no protection against a person voting multiple times right now. Those are improvements that could be made in a later version.

Sources

Customizing blockchain parameters
API reference (JSON-RPC)
Step by step tutorial for leveraging JSON-RPC API?
Bitcoin JSON-RPC Tutorial 5 - Your First Calls - YouTube
EasyBitcoin-PHP GitHub
Unofficial PHP library for interacting with the Multichain JsonRPC interface
How To Install and Use Composer on Ubuntu 14.04
composer-cache file permissions #19
How To Install Linux, Apache, MySQL, PHP (LAMP) stack on Ubuntu 14.04
MultiChain JSON-RPC API commands

Posted 6-18-16 by Sam Bowne
Revised 10-16-17