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