Skip to content

Instantly share code, notes, and snippets.

@tarassh
Last active May 20, 2018 10:23
Show Gist options
  • Save tarassh/1c57b6a5af5a217bbf679f6d54484e41 to your computer and use it in GitHub Desktop.
Save tarassh/1c57b6a5af5a217bbf679f6d54484e41 to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.23;
contract RandomVote {
event ParticipantIndex(address indexed participant, uint indexed index, uint indexed stepsToNextRound);
event ParticipantNumber(address indexed participants, uint indexed number, uint indexed stepsToChoosingTheWinner);
event TheWinner(address indexed participant, uint indexed number);
address public winner;
uint public numberOfParticipants = 0;
uint public digestIndex = 0;
uint public numberIndex = 0;
mapping(address => bytes32) public digests;
mapping(address => uint) public numbers;
mapping(uint => address) public indexes;
bool public generationEnded = false;
uint public seed;
constructor(uint number) public {
require(number > 0);
numberOfParticipants = number;
}
modifier isRound1 {
require(digestIndex >= 0 && digestIndex < numberOfParticipants);
_;
}
modifier isRound2 {
require(digestIndex == numberOfParticipants && numberIndex < numberOfParticipants);
_;
}
function setDigest(string digestStr) public isRound1 {
require(digests[msg.sender] == 0x0);
bytes32 digest = fromHex(digestStr);
digests[msg.sender] = digest;
indexes[digestIndex] = msg.sender;
emit ParticipantIndex(msg.sender, digestIndex++, numberOfParticipants - digestIndex);
}
function setNumber(string numberStr) public isRound2 {
bytes memory temp = bytes(numberStr);
bytes32 digest = sha256(temp);
require(digests[msg.sender] == digest);
require(numbers[msg.sender] == 0);
uint number = parseInt(numberStr, temp.length);
numbers[msg.sender] = number;
seed += number;
emit ParticipantNumber(msg.sender, number, numberOfParticipants - (++numberIndex));
if (numberIndex == numberOfParticipants) {
calculateRandom();
}
}
function calculateRandom() internal {
uint256 random = seed % numberOfParticipants;
winner = indexes[random];
generationEnded = true;
emit TheWinner(winner, random);
}
// Convert an hexadecimal character to their value
function fromHexChar(uint c) public pure returns (uint) {
if (byte(c) >= byte('0') && byte(c) <= byte('9')) {
return c - uint(byte('0'));
}
if (byte(c) >= byte('a') && byte(c) <= byte('f')) {
return 10 + c - uint(byte('a'));
}
if (byte(c) >= byte('A') && byte(c) <= byte('F')) {
return 10 + c - uint(byte('A'));
}
}
// Convert an hexadecimal string to raw bytes
function fromHex(string s) public pure returns (bytes32) {
require(bytes(s).length == 64);
bytes memory ss = bytes(s);
require(ss.length%2 == 0); // length must be even
bytes32 r;
for (uint i=0; i<32; ++i) {
bytes32 oneByte = byte(fromHexChar(uint(ss[2*i])) * 16 +
fromHexChar(uint(ss[2*i+1])));
r |= oneByte >> 8 * i;
}
return r;
}
function parseInt(string _a, uint _b) internal pure returns (uint) {
bytes memory bresult = bytes(_a);
uint mint = 0;
bool decimals = false;
for (uint i = 0; i < bresult.length; i++) {
if ((bresult[i] >= 48) && (bresult[i] <= 57)) {
if (decimals) {
if (_b == 0) break;
else _b--;
}
mint *= 10;
mint += uint(bresult[i]) - 48;
} else if (bresult[i] == 46) decimals = true;
}
return mint;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment