From f7985fb57c15f469f1be5115fd3112267cdbc4f3 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Tue, 26 Jun 2018 16:34:28 -0400 Subject: [PATCH] Added quadratic voting --- contracts/polls/SingleChoice.sol | 24 ++++++++++++++++++++++++ test/votingdapp.js | 25 ++++++++++++++++--------- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/contracts/polls/SingleChoice.sol b/contracts/polls/SingleChoice.sol index ab5b250..3ba2230 100644 --- a/contracts/polls/SingleChoice.sol +++ b/contracts/polls/SingleChoice.sol @@ -27,7 +27,10 @@ contract SingleChoice is Controlled { string public question; string[] public choices; + int[] public result; + int[] public qvResult; + bytes32 uid; function SingleChoice(address _controller, bytes _rlpDefinition, uint salt) { @@ -55,6 +58,7 @@ contract SingleChoice is Controlled { } result.length = choices.length; + qvResult.length = choices.length; } function pollType() public constant returns (bytes32) { @@ -71,7 +75,18 @@ contract SingleChoice is Controlled { function deltaVote(int _amount, bytes32 _ballot) onlyController returns (bool _succes) { if (!isValid(_ballot)) return false; uint v = uint(_ballot) / (2**248); + result[v] += _amount; + + int qv; + if (_amount < 0) { + qv = -sqrt(-_amount); + } else { + qv = sqrt(_amount); + } + + qvResult[v] += qv; + return true; } @@ -82,6 +97,15 @@ contract SingleChoice is Controlled { function getBallot(uint _option) constant returns(bytes32) { return bytes32((_option * (2**248)) + (uint(keccak256(uid, _option)) & (2**248 -1))); } + + function sqrt(int256 x) public pure returns (int256 y) { + int256 z = (x + 1) / 2; + y = x; + while (z < y) { + y = z; + z = (x / z + z) / 2; + } + } } diff --git a/test/votingdapp.js b/test/votingdapp.js index 04e79b7..e9105e3 100644 --- a/test/votingdapp.js +++ b/test/votingdapp.js @@ -59,13 +59,13 @@ describe("VotingDapp", function () { web3.eth.getAccounts().then((acc) => { accounts = acc; - return SNT.methods.generateTokens(accounts[0], 123456).send() + return SNT.methods.generateTokens(accounts[0], 6).send() }).then((receipt) => { - return SNT.methods.generateTokens(accounts[1], 789012).send() + return SNT.methods.generateTokens(accounts[1], 12).send() }).then((receipt) => { - return SNT.methods.generateTokens(accounts[2], 345678).send() + return SNT.methods.generateTokens(accounts[2], 10).send() }).then((receipt) => { - return SNT.methods.generateTokens(accounts[3], 901234).send() + return SNT.methods.generateTokens(accounts[3], 7).send() }).then((receipt) => { done(); }); @@ -148,18 +148,25 @@ describe("VotingDapp", function () { poll = await PollManager.methods.poll(pollId).call(); let votersByBallotYES = await PollManager.methods.getVotesByBallot(pollId, Yes).call(); let tokenVotesByBallotYES = await pollContract.methods.result(0).call(); // 0 == Yes (because it is the initial option ) - - // console.dir(poll); // Will contain state of the poll - // console.log(tokenVotesByBallotYES); // Contains how many votes has a ballot - // console.log(votersByBallotYES); // Contains how many voters voted for that option + let quadraticVotesByBallotYES = await pollContract.methods.qvResult(0).call(); // 0 == Yes (because it is the initial option ) + // Will contain state of the poll + // console.dir(poll); + + // Contains how many votes has a ballot + // console.log(tokenVotesByBallotYES); + + // Contains how many votes has a ballot using quadratic voting + //console.log(quadraticVotesByBallotYES); + + // Contains how many voters voted for that option + // console.log(votersByBallotYES); // =================================================== // Unvote receipt = await PollManager.methods.unvote(pollId).send({from: accounts[0]}); assert.equal(!!receipt.events.Unvote, true, "Unvote not triggered"); - }); });