mirror of
https://github.com/status-im/visual-identity.git
synced 2025-02-12 20:46:35 +00:00
Created test case to demonstrate how to use contracts
This commit is contained in:
parent
a712cece85
commit
3759522633
7
config/namesystem.js
Normal file
7
config/namesystem.js
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
default: {
|
||||
enabled: false,
|
||||
available_providers: ["ens"],
|
||||
provider: "ens"
|
||||
}
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.11;
|
||||
pragma solidity ^0.4.23;
|
||||
|
||||
import "../common/Controlled.sol";
|
||||
import "./LowLevelStringManipulator.sol";
|
||||
@ -27,6 +27,8 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
||||
address token;
|
||||
address pollContract;
|
||||
bool canceled;
|
||||
uint voters;
|
||||
mapping(bytes32 => uint) votersPerBallot;
|
||||
mapping(address => VoteLog) votes;
|
||||
}
|
||||
|
||||
@ -62,10 +64,10 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
||||
Poll p = _polls[ _idPoll ];
|
||||
p.startBlock = _startBlock;
|
||||
p.endBlock = _endBlock;
|
||||
p.voters = 0;
|
||||
|
||||
|
||||
var (name,symbol) = getTokenNameSymbol(address(token));
|
||||
string memory proposalName = strConcat(name , "_", uint2str(_idPoll));
|
||||
var (name, symbol) = getTokenNameSymbol(address(token));
|
||||
string memory proposalName = strConcat(name, "_", uint2str(_idPoll));
|
||||
string memory proposalSymbol = strConcat(symbol, "_", uint2str(_idPoll));
|
||||
|
||||
p.token = tokenFactory.createCloneToken(
|
||||
@ -80,6 +82,8 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
||||
p.pollContract = IPollFactory(_pollFactory).create(_description);
|
||||
|
||||
if (p.pollContract == 0) throw;
|
||||
|
||||
emit PollCreated(_idPoll);
|
||||
}
|
||||
|
||||
function cancelPoll(uint _idPoll) onlyController {
|
||||
@ -90,6 +94,18 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
||||
PollCanceled(_idPoll);
|
||||
}
|
||||
|
||||
function canVote(uint _idPoll) public view returns(bool) {
|
||||
if(_idPoll >= _polls.length) return false;
|
||||
|
||||
Poll storage p = _polls[_idPoll];
|
||||
uint balance = MiniMeToken(p.token).balanceOf(msg.sender);
|
||||
|
||||
return block.number >= p.startBlock &&
|
||||
block.number <= p.endBlock &&
|
||||
!p.canceled &&
|
||||
balance != 0;
|
||||
}
|
||||
|
||||
function vote(uint _idPoll, bytes32 _ballot) {
|
||||
if (_idPoll >= _polls.length) throw;
|
||||
Poll p = _polls[_idPoll];
|
||||
@ -110,6 +126,10 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
||||
|
||||
p.votes[msg.sender].ballot = _ballot;
|
||||
p.votes[msg.sender].amount = amount;
|
||||
|
||||
p.voters++;
|
||||
|
||||
p.votersPerBallot[_ballot]++;
|
||||
|
||||
if (!IPollContract(p.pollContract).deltaVote(int(amount), _ballot)) throw;
|
||||
|
||||
@ -129,9 +149,11 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
||||
|
||||
if (!IPollContract(p.pollContract).deltaVote(-int(amount), ballot)) throw;
|
||||
|
||||
|
||||
p.votes[msg.sender].ballot = 0;
|
||||
p.votes[msg.sender].amount = 0;
|
||||
p.votersPerBallot[ballot]--;
|
||||
|
||||
p.voters--;
|
||||
|
||||
// enableTransfers = true;
|
||||
if (!MiniMeToken(p.token).transferFrom(address(this), msg.sender, amount)) throw;
|
||||
@ -155,7 +177,8 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
||||
bytes32 _pollType,
|
||||
string _question,
|
||||
bool _finalized,
|
||||
uint _totalCensus
|
||||
uint _totalCensus,
|
||||
uint _voters
|
||||
) {
|
||||
if (_idPoll >= _polls.length) throw;
|
||||
Poll p = _polls[_idPoll];
|
||||
@ -168,6 +191,7 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
||||
_question = getString(p.pollContract, bytes4(sha3("question()")));
|
||||
_finalized = (!p.canceled) && (getBlockNumber() >= _endBlock);
|
||||
_totalCensus = MiniMeToken(p.token).totalSupply();
|
||||
_voters = p.voters;
|
||||
}
|
||||
|
||||
function getVote(uint _idPoll, address _voter) constant returns (bytes32 _ballot, uint _amount) {
|
||||
@ -178,6 +202,16 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
||||
_amount = p.votes[_voter].amount;
|
||||
}
|
||||
|
||||
function getVotesByBallot(uint _idPoll, bytes32 _ballot)
|
||||
public view returns(uint voters, uint votes) {
|
||||
if (_idPoll >= _polls.length) throw;
|
||||
Poll storage p = _polls[_idPoll];
|
||||
|
||||
voters = p.votersPerBallot[_ballot];
|
||||
votes = p.votersPerBallot[_ballot];
|
||||
|
||||
}
|
||||
|
||||
function proxyPayment(address ) payable returns(bool) {
|
||||
return false;
|
||||
}
|
||||
@ -199,6 +233,7 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
||||
event Vote(uint indexed idPoll, address indexed _voter, bytes32 ballot, uint amount);
|
||||
event Unvote(uint indexed idPoll, address indexed _voter, bytes32 ballot, uint amount);
|
||||
event PollCanceled(uint indexed idPoll);
|
||||
event PollCreated(uint indexed idPoll);
|
||||
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ contract SingleChoice is Controlled {
|
||||
using RLP for bytes;
|
||||
|
||||
string public question;
|
||||
string[] public options;
|
||||
string[] public choices;
|
||||
int[] public result;
|
||||
bytes32 uid;
|
||||
|
||||
@ -50,11 +50,11 @@ contract SingleChoice is Controlled {
|
||||
var itrOptions = itmOptions.iterator();
|
||||
|
||||
while(itrOptions.hasNext()) {
|
||||
options.length++;
|
||||
options[options.length-1] = itrOptions.next().toAscii();
|
||||
choices.length++;
|
||||
choices[choices.length-1] = itrOptions.next().toAscii();
|
||||
}
|
||||
|
||||
result.length = options.length;
|
||||
result.length = choices.length;
|
||||
}
|
||||
|
||||
function pollType() constant returns (bytes32) {
|
||||
@ -63,7 +63,7 @@ contract SingleChoice is Controlled {
|
||||
|
||||
function isValid(bytes32 _ballot) constant returns(bool) {
|
||||
uint v = uint(_ballot) / (2**248);
|
||||
if (v>=options.length) return false;
|
||||
if (v>=choices.length) return false;
|
||||
if (getBallot(v) != _ballot) return false;
|
||||
return true;
|
||||
}
|
||||
@ -76,7 +76,7 @@ contract SingleChoice is Controlled {
|
||||
}
|
||||
|
||||
function nOptions() constant returns(uint) {
|
||||
return options.length;
|
||||
return choices.length;
|
||||
}
|
||||
|
||||
function getBallot(uint _option) constant returns(bytes32) {
|
||||
|
@ -1,8 +1,9 @@
|
||||
pragma solidity ^0.4.6;
|
||||
|
||||
import "./SingleChoice.sol";
|
||||
import "./PollManager.sol";
|
||||
|
||||
contract SingleChoiceFactory {
|
||||
contract SingleChoiceFactory is IPollFactory {
|
||||
uint salt;
|
||||
function create(bytes _description) returns(address) {
|
||||
salt++;
|
||||
|
@ -22,10 +22,12 @@
|
||||
"bignumber.js": "^5.0.0",
|
||||
"formik": "^0.11.11",
|
||||
"jquery": "^3.3.1",
|
||||
"lodash": "^4.17.10",
|
||||
"react": "^16.3.2",
|
||||
"react-blockies": "^1.3.0",
|
||||
"react-bootstrap": "^0.32.1",
|
||||
"react-dom": "^16.3.2",
|
||||
"react-toggle": "^4.0.2"
|
||||
"react-toggle": "^4.0.2",
|
||||
"rlp": "^2.0.0"
|
||||
}
|
||||
}
|
||||
|
168
test/votingdapp.js
Normal file
168
test/votingdapp.js
Normal file
@ -0,0 +1,168 @@
|
||||
const utils = require('../utils/testUtils')
|
||||
const assert = require('assert');
|
||||
const SingleChoice = require('Embark/contracts/SingleChoice');
|
||||
const BN = web3.utils.BN;
|
||||
var _ = require('lodash');
|
||||
var rlp = require('rlp');
|
||||
|
||||
config({
|
||||
contracts: {
|
||||
"MiniMeTokenFactory": {
|
||||
"gasLimit": 4000000
|
||||
},
|
||||
"MiniMeToken": {
|
||||
"deploy": false,
|
||||
},
|
||||
"SNT":{
|
||||
"instanceOf": "MiniMeToken",
|
||||
"args": [
|
||||
"$MiniMeTokenFactory",
|
||||
utils.zeroAddress,
|
||||
0,
|
||||
"TestMiniMeToken",
|
||||
18,
|
||||
"TST",
|
||||
true
|
||||
],
|
||||
"gasLimit": 4000000
|
||||
},
|
||||
"PollManager": {
|
||||
"deploy": true,
|
||||
"args": ["$MiniMeTokenFactory", "$SNT"]
|
||||
},
|
||||
"SingleChoiceFactory": {
|
||||
"deploy": true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
singleChoiceDef = (question, options) => {
|
||||
var d = [
|
||||
new Buffer(question),
|
||||
_.map(options, function(o) {
|
||||
return new Buffer(o);
|
||||
})
|
||||
];
|
||||
|
||||
var b= rlp.encode(d);
|
||||
var rlpDefinition = '0x' + b.toString('hex');
|
||||
|
||||
return rlpDefinition;
|
||||
}
|
||||
|
||||
describe("VotingDapp", function () {
|
||||
this.timeout(0);
|
||||
|
||||
let accounts;
|
||||
|
||||
before(function(done) {
|
||||
|
||||
web3.eth.getAccounts().then((acc) => {
|
||||
accounts = acc;
|
||||
return SNT.methods.generateTokens(accounts[0], 123456).send()
|
||||
}).then((receipt) => {
|
||||
return SNT.methods.generateTokens(accounts[1], 789012).send()
|
||||
}).then((receipt) => {
|
||||
return SNT.methods.generateTokens(accounts[2], 345678).send()
|
||||
}).then((receipt) => {
|
||||
return SNT.methods.generateTokens(accounts[3], 901234).send()
|
||||
}).then((receipt) => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("Test", async () => {
|
||||
|
||||
const blockNumber = await web3.eth.getBlockNumber();
|
||||
const question = singleChoiceDef("Move from Slack to Status Desktop", [ "Yes", "No" ]);
|
||||
let receipt;
|
||||
|
||||
|
||||
// ===================================================
|
||||
// Creating a proposal without holding SNT SHOULD FAIL!
|
||||
try {
|
||||
receipt = await PollManager.methods.addPoll(
|
||||
blockNumber,
|
||||
blockNumber + 10,
|
||||
SingleChoiceFactory.options.address,
|
||||
question)
|
||||
.send({from: accounts[8]});
|
||||
assert.fail('should have reverted before');
|
||||
} catch(error) {
|
||||
utils.assertJump(error);
|
||||
}
|
||||
|
||||
|
||||
// ===================================================
|
||||
// Creating a proposal as a SNT holder
|
||||
|
||||
receipt = await PollManager.methods.addPoll(
|
||||
blockNumber,
|
||||
blockNumber + 10,
|
||||
SingleChoiceFactory.options.address,
|
||||
question)
|
||||
.send({from: accounts[0]});
|
||||
|
||||
assert.equal(!!receipt.events.PollCreated, true, "PollCreated not triggered");
|
||||
|
||||
const pollId = receipt.events.PollCreated.returnValues.idPoll;
|
||||
let poll = await PollManager.methods.poll(pollId).call();
|
||||
|
||||
SingleChoice.options.address = poll._pollContract;
|
||||
const pollContract = SingleChoice;
|
||||
|
||||
// Options are represented as a hex value
|
||||
const Yes = await SingleChoice.methods.getBallot(0).call();
|
||||
const No = await SingleChoice.methods.getBallot(1).call();
|
||||
|
||||
|
||||
// ===================================================
|
||||
// Determining if I can vote por a proposal
|
||||
let canVote = await PollManager.methods.canVote(pollId).call({from: accounts[0]});
|
||||
assert.equal(canVote, true, "User should be able to vote");
|
||||
|
||||
|
||||
// ===================================================
|
||||
// Voting
|
||||
receipt = await PollManager.methods.vote(pollId, Yes).send({from: accounts[0]});
|
||||
assert.equal(!!receipt.events.Vote, true, "Vote not triggered");
|
||||
|
||||
|
||||
// ===================================================
|
||||
// Getting what option the voter selected
|
||||
let myVote = await PollManager.methods.getVote(pollId, accounts[0]).call();
|
||||
assert.equal(myVote._ballot, Yes, "Vote is different from selected");
|
||||
|
||||
|
||||
// ===================================================
|
||||
// Voting when you're not a SNT holder SHOULD FAIL!
|
||||
try {
|
||||
receipt = await PollManager.methods.vote(pollId, Yes)
|
||||
.send({from: accounts[8]});
|
||||
assert.fail('should have reverted before');
|
||||
} catch(error) {
|
||||
utils.assertJump(error);
|
||||
}
|
||||
|
||||
|
||||
// ===================================================
|
||||
// Getting proposal information
|
||||
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
|
||||
|
||||
|
||||
// ===================================================
|
||||
// Unvote
|
||||
receipt = await PollManager.methods.unvote(pollId).send({from: accounts[0]});
|
||||
assert.equal(!!receipt.events.Unvote, true, "Unvote not triggered");
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user