From 1cc8df8d863cabdab5300c969d616ad0476990e8 Mon Sep 17 00:00:00 2001
From: mbraidot <mbraidot@buenosaires.gob.ar>
Date: Mon, 20 May 2019 11:05:15 -0300
Subject: [PATCH] =?UTF-8?q?El=20formulario=20de=20votaci=C3=B3n=20obtiene?=
 =?UTF-8?q?=20las=20proposals=20votadas=20y=20las=20muestra=20en=20el=20gr?=
 =?UTF-8?q?=C3=A1fico?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                   |   1 +
 solidity/Ballot.sol          |  29 +++--
 web/dist/js/vendor/abi.js    | 217 ++++++++++++++++++++---------------
 web/dist/js/vendor/ballot.js |  78 ++++++++++++-
 web/dist/smartVotar.html     |  74 +++---------
 5 files changed, 233 insertions(+), 166 deletions(-)
 create mode 100644 .gitignore

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..efa6632
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+bin/*
\ No newline at end of file
diff --git a/solidity/Ballot.sol b/solidity/Ballot.sol
index c3679fa..fce11ed 100644
--- a/solidity/Ballot.sol
+++ b/solidity/Ballot.sol
@@ -41,6 +41,9 @@ contract            Ballot
     /// @dev Short name (up to 32 bytes)
     bytes32[]           public      proposalList;
     uint                public      proposalListLength;
+    /// @dev Voting results tracking
+    mapping( uint => uint )
+                        public      votedProposalList;
     uint[]              private     emptyuintlist;
 
     /// @notice When the SC is being deployed, you must define initial conditions. When specifying percentages they are to have been multiplied with 100 million (5% is written as 5 million, since 5% is actially 0.05).
@@ -85,11 +88,13 @@ contract            Ballot
         /// @dev add it to the end of the proposalList
         uint        incoming                =   proposalNames.length;
         uint        i                       =   0;
+        uint        idp                     =   0;
         proposalListLength      =   0;
         while ( i < incoming )
         {
-            proposalList.push( proposalNames[i] );
+            idp = proposalList.push( proposalNames[i] );
             proposalListLength++;
+            votedProposalList[idp] = 0;
             i++;
         }
     }
@@ -160,26 +165,20 @@ contract            Ballot
             i--;
             if ( voterList[uidx].votedProposals[i] == proposal )
                 proposalCounter++;
+
         }
         require( proposalCounter < ballotMaxVotesPerProposal );
         voterList[uidx].votesLeft--;
         voterList[uidx].votedProposals.push( proposal );
+        votedProposalList[proposal]++;
     }
 
-    function getVotesCountByIdx( uint idx ) 
-        public 
-        view 
-        returns(int)
-    {
-        return int(voterList[idx].votedProposals.length);
-    }
-
-    function getVotedProposalByVoter( uint idx, uint idp )
-        public 
-        view 
-        returns ( int )
-    {
-        return int(voterList[idx].votedProposals[idp]);
+    function getTotalVoltes() public view returns(uint){
+        uint total = 0;
+        for(uint i = 0; i < proposalList.length; i++){
+            total += votedProposalList[i];
+        }
+        return total;
     }
 
     function uncreate()
diff --git a/web/dist/js/vendor/abi.js b/web/dist/js/vendor/abi.js
index 7a99718..1e5c383 100644
--- a/web/dist/js/vendor/abi.js
+++ b/web/dist/js/vendor/abi.js
@@ -6,90 +6,76 @@ var abiBallot = [
 		"constant": false,
 		"inputs": [
 			{
-				"name": "voters",
-				"type": "address[]"
+				"name": "proposal",
+				"type": "uint256"
 			}
 		],
-		"name": "giveRightToVote",
+		"name": "vote",
 		"outputs": [],
 		"payable": false,
 		"stateMutability": "nonpayable",
 		"type": "function"
 	},
 	{
-		"constant": false,
+		"constant": true,
 		"inputs": [],
-		"name": "uncreate",
-		"outputs": [],
+		"name": "ballotPercentOfRegisteredVotersReqToBeValid",
+		"outputs": [
+			{
+				"name": "",
+				"type": "uint256"
+			}
+		],
 		"payable": false,
-		"stateMutability": "nonpayable",
+		"stateMutability": "view",
 		"type": "function"
 	},
 	{
-		"constant": false,
-		"inputs": [
+		"constant": true,
+		"inputs": [],
+		"name": "proposalListLength",
+		"outputs": [
 			{
-				"name": "proposal",
+				"name": "",
 				"type": "uint256"
 			}
 		],
-		"name": "vote",
-		"outputs": [],
 		"payable": false,
-		"stateMutability": "nonpayable",
+		"stateMutability": "view",
 		"type": "function"
 	},
 	{
+		"constant": true,
 		"inputs": [
 			{
-				"name": "title",
-				"type": "string"
-			},
-			{
-				"name": "voteStarts",
-				"type": "uint256"
-			},
-			{
-				"name": "voteBefore",
-				"type": "uint256"
-			},
-			{
-				"name": "percentOfRegisteredVotersReqToBeValid",
-				"type": "uint256"
-			},
-			{
-				"name": "percentOfVotesCastToWin",
-				"type": "uint256"
-			},
-			{
-				"name": "countNonvotesAsBlanks",
-				"type": "bool"
-			},
-			{
-				"name": "maxVotesPerVoter",
-				"type": "uint256"
-			},
+				"name": "",
+				"type": "address"
+			}
+		],
+		"name": "voterMap",
+		"outputs": [
 			{
-				"name": "maxVotesPerProposal",
+				"name": "",
 				"type": "uint256"
-			},
-			{
-				"name": "proposalNames",
-				"type": "bytes32[]"
 			}
 		],
 		"payable": false,
-		"stateMutability": "nonpayable",
-		"type": "constructor"
+		"stateMutability": "view",
+		"type": "function"
 	},
 	{
 		"constant": true,
-		"inputs": [],
-		"name": "ballotChairman",
+		"inputs": [
+			{
+				"name": "voter",
+				"type": "address"
+			}
+		],
+		"name": "getVoterIdx",
 		"outputs": [
 			{
 				"name": "",
-				"type": "address"
+				"type": "int256"
 			}
 		],
 		"payable": false,
@@ -97,13 +83,31 @@ var abiBallot = [
 		"type": "function"
 	},
 	{
-		"constant": true,
+		"constant": false,
 		"inputs": [],
-		"name": "ballotCountNonvotesAsBlanks",
-		"outputs": [
+		"name": "uncreate",
+		"outputs": [],
+		"payable": false,
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"constant": true,
+		"inputs": [
 			{
 				"name": "",
-				"type": "bool"
+				"type": "uint256"
+			}
+		],
+		"name": "voterList",
+		"outputs": [
+			{
+				"name": "voter",
+				"type": "address"
+			},
+			{
+				"name": "votesLeft",
+				"type": "uint256"
 			}
 		],
 		"payable": false,
@@ -113,11 +117,11 @@ var abiBallot = [
 	{
 		"constant": true,
 		"inputs": [],
-		"name": "ballotMaxVotesPerProposal",
+		"name": "ballotCountNonvotesAsBlanks",
 		"outputs": [
 			{
 				"name": "",
-				"type": "uint256"
+				"type": "bool"
 			}
 		],
 		"payable": false,
@@ -127,7 +131,7 @@ var abiBallot = [
 	{
 		"constant": true,
 		"inputs": [],
-		"name": "ballotMaxVotesPerVoter",
+		"name": "ballotVoteBefore",
 		"outputs": [
 			{
 				"name": "",
@@ -139,23 +143,23 @@ var abiBallot = [
 		"type": "function"
 	},
 	{
-		"constant": true,
-		"inputs": [],
-		"name": "ballotPercentOfRegisteredVotersReqToBeValid",
-		"outputs": [
+		"constant": false,
+		"inputs": [
 			{
-				"name": "",
-				"type": "uint256"
+				"name": "voters",
+				"type": "address[]"
 			}
 		],
+		"name": "giveRightToVote",
+		"outputs": [],
 		"payable": false,
-		"stateMutability": "view",
+		"stateMutability": "nonpayable",
 		"type": "function"
 	},
 	{
 		"constant": true,
 		"inputs": [],
-		"name": "ballotPercentOfVotesCastToWin",
+		"name": "ballotVoteStarts",
 		"outputs": [
 			{
 				"name": "",
@@ -169,11 +173,11 @@ var abiBallot = [
 	{
 		"constant": true,
 		"inputs": [],
-		"name": "ballotTitle",
+		"name": "ballotMaxVotesPerProposal",
 		"outputs": [
 			{
 				"name": "",
-				"type": "string"
+				"type": "uint256"
 			}
 		],
 		"payable": false,
@@ -183,7 +187,7 @@ var abiBallot = [
 	{
 		"constant": true,
 		"inputs": [],
-		"name": "ballotVoteBefore",
+		"name": "ballotMaxVotesPerVoter",
 		"outputs": [
 			{
 				"name": "",
@@ -197,7 +201,7 @@ var abiBallot = [
 	{
 		"constant": true,
 		"inputs": [],
-		"name": "ballotVoteStarts",
+		"name": "getTotalVoltes",
 		"outputs": [
 			{
 				"name": "",
@@ -210,17 +214,12 @@ var abiBallot = [
 	},
 	{
 		"constant": true,
-		"inputs": [
-			{
-				"name": "voter",
-				"type": "address"
-			}
-		],
-		"name": "getVoterIdx",
+		"inputs": [],
+		"name": "ballotTitle",
 		"outputs": [
 			{
 				"name": "",
-				"type": "int256"
+				"type": "string"
 			}
 		],
 		"payable": false,
@@ -249,7 +248,7 @@ var abiBallot = [
 	{
 		"constant": true,
 		"inputs": [],
-		"name": "proposalListLength",
+		"name": "ballotPercentOfVotesCastToWin",
 		"outputs": [
 			{
 				"name": "",
@@ -262,21 +261,12 @@ var abiBallot = [
 	},
 	{
 		"constant": true,
-		"inputs": [
-			{
-				"name": "",
-				"type": "uint256"
-			}
-		],
-		"name": "voterList",
+		"inputs": [],
+		"name": "ballotChairman",
 		"outputs": [
 			{
-				"name": "voter",
+				"name": "",
 				"type": "address"
-			},
-			{
-				"name": "votesLeft",
-				"type": "uint256"
 			}
 		],
 		"payable": false,
@@ -288,10 +278,10 @@ var abiBallot = [
 		"inputs": [
 			{
 				"name": "",
-				"type": "address"
+				"type": "uint256"
 			}
 		],
-		"name": "voterMap",
+		"name": "votedProposalList",
 		"outputs": [
 			{
 				"name": "",
@@ -301,6 +291,49 @@ var abiBallot = [
 		"payable": false,
 		"stateMutability": "view",
 		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"name": "title",
+				"type": "string"
+			},
+			{
+				"name": "voteStarts",
+				"type": "uint256"
+			},
+			{
+				"name": "voteBefore",
+				"type": "uint256"
+			},
+			{
+				"name": "percentOfRegisteredVotersReqToBeValid",
+				"type": "uint256"
+			},
+			{
+				"name": "percentOfVotesCastToWin",
+				"type": "uint256"
+			},
+			{
+				"name": "countNonvotesAsBlanks",
+				"type": "bool"
+			},
+			{
+				"name": "maxVotesPerVoter",
+				"type": "uint256"
+			},
+			{
+				"name": "maxVotesPerProposal",
+				"type": "uint256"
+			},
+			{
+				"name": "proposalNames",
+				"type": "bytes32[]"
+			}
+		],
+		"payable": false,
+		"stateMutability": "nonpayable",
+		"type": "constructor"
 	}
 ];
 
diff --git a/web/dist/js/vendor/ballot.js b/web/dist/js/vendor/ballot.js
index 23d3b82..1ff997e 100644
--- a/web/dist/js/vendor/ballot.js
+++ b/web/dist/js/vendor/ballot.js
@@ -7,6 +7,7 @@ var netname;
 var blocknumber = -2;
 var nowblock;
 var proposalLength = 0;
+var totalVotes = 0;
 
 var netnames = {
     "1": 'Ethereum mainnet',
@@ -21,9 +22,11 @@ var netnames = {
 var mainaddr = {
     '5445': '0xe5bf7c3e8aa529e42fbd99428137b68db75d85f9',
     '47525974938': '0xe3e08934b6fa0b68972c08e0f545cee31ed039c6',
-    '5777':         '0xeAf032eaC758646E167916028F3abAbF0f33ae5d'
+    '5777':         '0x99845b94609F0285527ee11a0C9664532ddE0428'
 };
-var ballot_keccak3 = '0x20ab18e35a65929a015b8faf468469a21d2268ffce74a8888a12eb6b9d10bf43';
+/// Ballot address: 0x999d06fcc0a2380e0e0038b6d186275e754dd2b4
+
+var ballot_keccak3 = '0x27fdf9b1c0d27b6143d49147cf30b3f7f09ac1c2cb2b7115a1633e0b8551c6a9';
 var contract_event;
 
 window.addEventListener('load', page_loaded);
@@ -528,6 +531,32 @@ async function votar(addr, proposal){
 }
 
 
+async function resultados(addr){
+    var contract = setup_existing_instance(abiBallot, addr);
+    if (!contract)
+        return;
+    
+    try
+    {
+        let totalVotes = await getTotalVotes(contract);
+        let proposalLength = await getProposalListLength(contract);
+        var results = [];
+        for(var i=0;i<proposalLength;i++){
+            results[i] = await getProposalResults(contract, i);
+            /*contract.votedProposalList.call(i, { gas: 2111000 }, function(error, rcpt){
+                getProposalResults(error, rcpt, totalVotes, i);
+            });*/
+        }
+        showProposalResults(totalVotes, proposalLength, results);
+        //close_alertar();
+        
+    }
+    catch (error)
+    {
+        alertar(error);
+    }
+}
+
 
 ///////////////////////////////////////////////////////////
 // UTILS for ballot form creation
@@ -589,9 +618,54 @@ async function getProposalList(err, rcpt){
         </div>';
         $('#proposals').append(element);
 
+        var results = '<div class="res_op"><span class="lab">'+hex2ascii(rcpt)+'</span> \
+        <div class="progress"> \
+            <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" \
+                aria-valuemax="100" style="width: 0%;" id="result_'+num+'"> \
+                0% \
+            </div> \
+        </div></div>';
+        $('#results').append(results);
+
     }
 }
 
+function getTotalVotes (contract) {
+    return new Promise (function (resolve, reject) {
+        contract.getTotalVoltes.call({ gas: 2111000 }, function (error, result) {
+            if (error) {
+                reject(error);
+            } else {
+                resolve(result);
+            }
+        });
+    });
+}
+
+function getProposalResults(contract, option){
+
+    return new Promise (function (resolve, reject) {
+        contract.votedProposalList.call(option, { gas: 2111000 }, function (error, result) {
+            if (error) {
+                reject(error);
+            } else {
+                resolve(result);
+            }
+        });
+    });
+}
+
+async function showProposalResults(totalVotes, proposalLength, results){
+    for(var i = 0; i<proposalLength; i++){
+        var percentage = (totalVotes.toString(10) > 0) ? results[i].toString(10) / totalVotes.toString(10) * 100 : 0;
+        console.log(i, percentage);
+
+        $('#result_'+i).text(percentage.toFixed(2));
+        $('#result_'+i).attr('aria-valuenow', percentage).css('width', percentage+'%');
+    }
+}
+
+
 function hex2ascii(hexx) {
     var hex = hexx.toString();
     var str = '';
diff --git a/web/dist/smartVotar.html b/web/dist/smartVotar.html
index 0b5729d..2b5b0c2 100644
--- a/web/dist/smartVotar.html
+++ b/web/dist/smartVotar.html
@@ -42,45 +42,10 @@
                     <b>Comienza:</b> <span id="comienza_votacion"></span><br />
                     <b>Termina:</b> <span id="termina_votacion"></span>
                 </p>
-                <div class="resultados" style="display: none;">
+                <div class="resultados" style="display: none;" id="results">
                     <h2>Resultados</h2>
-                    <div class="res_op">
-                        <span class="lab">Opción 1</span>
-                        <div class="progress">
-                            <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0"
-                                aria-valuemax="100" style="width: 60%;">
-                                60%
-                            </div>
-                        </div>
-                    </div>
-                    <div class="res_op">
-                        <span class="lab">Opción 2</span>
-                        <div class="progress">
-                            <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0"
-                                aria-valuemax="100" style="width: 20%;">
-                                20%
-                            </div>
-                        </div>
-                    </div>
-                    <div class="res_op">
-                        <span class="lab">Opción 3</span>
-                        <div class="progress">
-                            <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0"
-                                aria-valuemax="100" style="width: 15%;">
-                                15%
-                            </div>
-                        </div>
-                    </div>
-                    <div class="res_op">
-                        <span class="lab">Opción 4</span>
-                        <div class="progress">
-                            <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0"
-                                aria-valuemax="100" style="width: 5%;">
-                                5%
-                            </div>
-                        </div>
-                    </div>
-                    <h2>Detalle de la votación</h2>
+                    
+                    <!--<h2>Detalle de la votación</h2>
                     <table class="table table-hover">
                         <thead>
                             <tr>
@@ -111,7 +76,7 @@
                             </tr>
                         </tbody>
 
-                    </table>
+                    </table>-->
 
                 </div>
                 <form action="" id="form_votacion">
@@ -178,6 +143,18 @@
         if(typeof input_address != "undefined" && input_address != ""){
             $("#contract_address").text(input_address);
             ver_votacion(input_address);
+
+            //TEST
+            /*$("form").hide();
+            $(".resultados").show();
+            resultados(input_address);*/
+        }
+
+        function viewVotacion(){
+            $("form").hide();
+            $(".resultados").show();
+            
+            resultados(input_address);
         }
 
         async function sendVotacion(){
@@ -194,9 +171,7 @@
                     console.log(resultado.toString(10));
                     
                     alertarSuccess('¡Votaste con éxito!');
-                    $("form").hide();
-                    $(".resultados").show();
-                    $(".votar legend").text('Tu voto');
+                    viewVotacion();
 
                 }else{
                     alertar('Ocurrió un error');
@@ -239,21 +214,6 @@
                     }, 200)
                 
                 sendVotacion();
-                /*$("#voterow :input").attr("disabled", true);
-                $("#voterow .btn").hide();
-                
-                var result = sendVotacion();
-                console.log(result);
-                if (result === true){
-                    alertarSuccess('¡Votaste con éxito!');
-                    $("form").hide();
-                    $(".resultados").show();
-                    $(".votar legend").text('Tu voto');
-                }else{
-                    alertar('Ocurrió un error');
-                    $("#voterow :input").attr("disabled", false);
-                    $("#voterow .btn").show();
-                }*/
                 
             },
             messages: {
-- 
GitLab