Contract Source Code:
File 1 of 1 : Lotthereum
pragma solidity ^0.4.11;
contract SafeMath {
function add(uint x, uint y) internal constant returns (uint z) {
assert((z = x + y) >= x);
}
function subtract(uint x, uint y) internal constant returns (uint z) {
assert((z = x - y) <= x);
}
function multiply(uint x, uint y) internal constant returns (uint z) {
z = x * y;
assert(x == 0 || z / x == y);
return z;
}
function divide(uint x, uint y) internal constant returns (uint z) {
z = x / y;
assert(x == ( (y * z) + (x % y) ));
return z;
}
function min64(uint64 x, uint64 y) internal constant returns (uint64) {
return x < y ? x: y;
}
function max64(uint64 x, uint64 y) internal constant returns (uint64) {
return x >= y ? x : y;
}
function min(uint x, uint y) internal constant returns (uint) {
return (x <= y) ? x : y;
}
function max(uint x, uint y) internal constant returns (uint) {
return (x >= y) ? x : y;
}
function assert(bool assertion) internal {
if (!assertion) {
revert();
}
}
}
contract Owned {
address owner;
modifier onlyowner() {
if (msg.sender == owner) {
_;
}
}
function Owned() {
owner = msg.sender;
}
}
contract Mortal is Owned {
function kill() {
if (msg.sender == owner)
selfdestruct(owner);
}
}
contract Lotthereum is Mortal, SafeMath {
Game[] private games;
mapping (address => uint) private balances; // balances per address
struct Game {
uint id;
uint pointer;
uint maxNumberOfBets;
uint minAmountByBet;
uint prize;
uint currentRound;
Round[] rounds;
}
struct Round {
uint id;
uint pointer;
bytes32 hash;
bool open;
uint8 number;
Bet[] bets;
address[] winners;
}
struct Bet {
uint id;
address origin;
uint amount;
uint8 bet;
uint round;
}
event RoundOpen(
uint indexed gameId,
uint indexed roundId
);
event RoundClose(
uint indexed gameId,
uint indexed roundId,
uint8 number
);
event MaxNumberOfBetsChanged(
uint maxNumberOfBets
);
event MinAmountByBetChanged(
uint minAmountByBet
);
event BetPlaced(
uint indexed gameId,
uint indexed roundId,
address indexed origin,
uint betId
);
event RoundWinner(
uint indexed gameId,
uint indexed roundId,
address indexed winnerAddress,
uint amount
);
function createGame(
uint pointer,
uint maxNumberOfBets,
uint minAmountByBet,
uint prize
) onlyowner returns (uint id) {
id = games.length;
games.length += 1;
games[id].id = id;
games[id].pointer = pointer;
games[id].maxNumberOfBets = maxNumberOfBets;
games[id].minAmountByBet = minAmountByBet;
games[id].prize = prize;
games[id].currentRound = createGameRound(id);
}
function createGameRound(uint gameId) internal returns (uint id) {
Game game = games[gameId];
id = games[gameId].rounds.length;
game.rounds.length += 1;
game.rounds[id].id = id;
game.rounds[id].open = true;
RoundOpen(gameId, id);
}
function payout(uint gameId) internal {
Game game = games[gameId];
Round round = game.rounds[game.currentRound];
Bet[] bets = round.bets;
address[] winners = round.winners;
for (uint i = 0; i < bets.length; i++) {
if (bets[i].bet == round.number) {
uint id = winners.length;
winners.length += 1;
winners[id] = bets[i].origin;
}
}
if (winners.length > 0) {
uint prize = divide(game.prize, winners.length);
for (i = 0; i < winners.length; i++) {
balances[winners[i]] = add(balances[winners[i]], prize);
RoundWinner(game.id, game.currentRound, winners[i], prize);
}
}
}
function closeRound(uint gameId) constant internal {
Game game = games[gameId];
Round round = game.rounds[game.currentRound];
round.open = false;
round.hash = getBlockHash(game.pointer);
round.number = getNumber(game.rounds[game.currentRound].hash);
game.pointer = game.rounds[game.currentRound].number;
payout(gameId);
RoundClose(game.id, round.id, round.number);
game.currentRound = createGameRound(game.id);
}
function getBlockHash(uint i) constant returns (bytes32 blockHash) {
if (i > 255) {
i = 255;
}
uint blockNumber = block.number - i;
blockHash = block.blockhash(blockNumber);
}
function getNumber(bytes32 _a) constant returns (uint8) {
uint8 _b = 1;
uint8 mint = 0;
bool decimals = false;
for (uint i = _a.length - 1; i >= 0; i--) {
if ((_a[i] >= 48) && (_a[i] <= 57)) {
if (decimals) {
if (_b == 0) {
break;
} else {
_b--;
}
}
mint *= 10;
mint += uint8(_a[i]) - 48;
return mint;
} else if (_a[i] == 46) {
decimals = true;
}
}
return mint;
}
function placeBet(uint gameId, uint8 bet) public payable returns (bool) {
Game game = games[gameId];
Round round = game.rounds[game.currentRound];
Bet[] bets = round.bets;
if (!round.open) {
return false;
}
if (msg.value < game.minAmountByBet) {
return false;
}
uint id = bets.length;
bets.length += 1;
bets[id].id = id;
bets[id].round = round.id;
bets[id].bet = bet;
bets[id].origin = msg.sender;
bets[id].amount = msg.value;
BetPlaced(game.id, round.id, msg.sender, id);
if (bets.length == game.maxNumberOfBets) {
closeRound(game.id);
}
return true;
}
function withdraw() public returns (uint) {
uint amount = getBalance();
if (amount > 0) {
balances[msg.sender] = 0;
msg.sender.transfer(amount);
return amount;
}
return 0;
}
function getBalance() constant returns (uint) {
uint amount = balances[msg.sender];
if ((amount > 0) && (amount < this.balance)) {
return amount;
}
return 0;
}
function getGames() constant returns(uint[] memory ids) {
ids = new uint[](games.length);
for (uint i = 0; i < games.length; i++) {
ids[i] = games[i].id;
}
}
function getGameCurrentRoundId(uint gameId) constant returns(uint) {
return games[gameId].currentRound;
}
function getGameRoundOpen(uint gameId, uint roundId) constant returns(bool) {
return games[gameId].rounds[roundId].open;
}
function getGameMaxNumberOfBets(uint gameId) constant returns(uint) {
return games[gameId].maxNumberOfBets;
}
function getGameMinAmountByBet(uint gameId) constant returns(uint) {
return games[gameId].minAmountByBet;
}
function getGamePrize(uint gameId) constant returns(uint) {
return games[gameId].prize;
}
function getRoundNumberOfBets(uint gameId, uint roundId) constant returns(uint) {
return games[gameId].rounds[roundId].bets.length;
}
function getRoundBetOrigin(uint gameId, uint roundId, uint betId) constant returns(address) {
return games[gameId].rounds[roundId].bets[betId].origin;
}
function getRoundBetAmount(uint gameId, uint roundId, uint betId) constant returns(uint) {
return games[gameId].rounds[roundId].bets[betId].amount;
}
function getRoundBetNumber(uint gameId, uint roundId, uint betId) constant returns(uint) {
return games[gameId].rounds[roundId].bets[betId].bet;
}
function getRoundNumber(uint gameId, uint roundId) constant returns(uint8) {
return games[gameId].rounds[roundId].number;
}
function getRoundPointer(uint gameId, uint roundId) constant returns(uint) {
return games[gameId].rounds[roundId].pointer;
}
function getPointer(uint gameId) constant returns(uint) {
return games[gameId].pointer;
}
function () payable {
}
}