-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLottery.sol
214 lines (167 loc) · 8.1 KB
/
Lottery.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
pragma solidity ^0.4.24;
contract Lottery{
uint public ticketPrice;
uint public submissionDeadline;
uint public revealDeadline;
uint[] public winnerTicketNumbers;
uint [] rewardPrices=[50000 ether,10000 ether,400 ether,400 ether,200 ether,200 ether,200 ether,200 ether,200 ether,200 ether,200 ether,200 ether,200 ether,200 ether,200 ether,100 ether,100 ether,100 ether,100 ether,100 ether,40 ether,10 ether,4 ether];
struct intIndex{
bool isExist;
uint index;
}
mapping (uint => intIndex) public isWinnerTicketNumbers;
bool public isAvailable;
uint public periodno;
uint[] public revealRandomNumbers;
uint[] public allTicketNumbers;
bytes32[] public commitmentAll;//all hash number
mapping (uint => bool) public isExistTicket;
mapping (uint => bool) public isWithdrawed;
mapping (bytes32 => bool) public isSavedRandomNumber;
uint public totalCost;
//participent struct
struct participent{
uint[] ticketNumbers;
mapping ( uint => bool) hasTicketNumber;
bytes32[] commitment;
mapping ( bytes32 => bool) commitmentVerify;
}
mapping (address=>participent) personalInfo;
constructor() public payable {
//constants
periodno = 1;
ticketPrice = 2 ether;
submissionDeadline = block.timestamp + 5 days;
revealDeadline = block.timestamp + 7 days;
// we calculated: 68900 is sum of max prizes amount
totalCost=68900 ether;
}
function purchase(uint ticketNumber, bytes32 _hash) public payable returns(bool){
//checking the time for period. refreshing the new week.
if( revealDeadline<block.timestamp){
periodno=periodno+1;
submissionDeadline = block.timestamp + 5 days;
revealDeadline = block.timestamp + 7 days;
}
//checking if sender has enough money and entered suitable lottery number
require(msg.value==ticketPrice && ticketNumber<99999 && ticketNumber>=0);
//checking is ticketNumber unique or not , and time for
if(block.timestamp<submissionDeadline && isExistTicket[ticketNumber]==false &&msg.value==ticketPrice){
// in purchase/submission period
personalInfo[msg.sender].ticketNumbers.push(ticketNumber);
personalInfo[msg.sender].hasTicketNumber[ticketNumber]=true;
//adding person ticket and hashes
personalInfo[msg.sender].commitment.push(_hash);
personalInfo[msg.sender].commitmentVerify[_hash]=true;
allTicketNumbers.push(ticketNumber);
commitmentAll.push(_hash);
isExistTicket[ticketNumber]=true;
}
return true;
}
function reveal(uint randomnumber) public returns (bool) {
//checking the time of beetween last 2 days in week.
require (block.timestamp>submissionDeadline && block.timestamp<revealDeadline);
//checking same user doesnt reveal the same number more than once
require(isSavedRandomNumber[sha256(abi.encodePacked(randomnumber,msg.sender))]==false);
if(personalInfo[msg.sender].commitmentVerify[sha256(abi.encodePacked(randomnumber,msg.sender))]==false){
//checking
revert();
return false;
}
else{
revealRandomNumbers.push(randomnumber);
//adding the user reval number is used
isSavedRandomNumber[sha256(abi.encodePacked(randomnumber,msg.sender))]=true;
return true;
}
}
function result() public returns (bool){
// generating 23 luckly winner number
uint total=0;
for(uint i=0;i<revealRandomNumbers.length;i++){
total=total+revealRandomNumbers[i];
}
//we summed all randomnumbers and used sha256 for hashing then converted to int
//this prosedure used for all 23 winner number
for(uint a=0;a<20;a++){
winnerTicketNumbers.push((uint(sha256(abi.encodePacked(total)))) %100000);
isWinnerTicketNumbers[(uint(sha256(abi.encodePacked(total)))%100000)].isExist=true;
isWinnerTicketNumbers[(uint(sha256(abi.encodePacked(total)))%100000)].index=a;
total=uint(sha256(abi.encodePacked(total)));
}
//XXXX 4 digits
winnerTicketNumbers.push(uint(sha256(abi.encodePacked(total))) %10000);
isWinnerTicketNumbers[(uint(sha256(abi.encodePacked(total)))%10000)].isExist=true;
isWinnerTicketNumbers[(uint(sha256(abi.encodePacked(total)))%10000)].index=20;
total=uint(sha256(abi.encodePacked(total)));
// XXX 3 digits
winnerTicketNumbers.push(uint(sha256(abi.encodePacked(total))) %1000);
isWinnerTicketNumbers[(uint(sha256(abi.encodePacked(total)))%1000)].isExist=true;
isWinnerTicketNumbers[(uint(sha256(abi.encodePacked(total)))%1000)].index=21;
total=uint(sha256(abi.encodePacked(total)));
//XX 2 digits
winnerTicketNumbers.push(uint(sha256(abi.encodePacked(total))) %100);
isWinnerTicketNumbers[(uint(sha256(abi.encodePacked(total)))%100)].isExist=true;
isWinnerTicketNumbers[(uint(sha256(abi.encodePacked(total)))%100)].index=22;
total=uint(sha256(abi.encodePacked(total)));
if(totalCost<=allTicketNumbers.length*ticketPrice){
//pay the participent the prizes because we have enough money to share
isAvailable=true;
return true;
//DONATION ADDRESS OF UNESCO :D
//we send the extra money
0xdD870fA1b7C4700F2BD7f44238821C26f7392148.transfer((allTicketNumbers.length*ticketPrice)-totalCost);
}
else{
//not enough ethers collected so we should refund. :(
isAvailable=false;
return false;
}
}
function withdrawMoney (uint ticket) public returns (uint){
uint status=0;
//for checking sender has really the ticket
require(personalInfo[msg.sender].hasTicketNumber[ticket]=true);
bool isWin=false;
//checking,if we have enought ether to share the prizes
if (isAvailable){
//checking user didnt withdrawed before
require(isWithdrawed[ticket]==false);
if(isWinnerTicketNumbers[ticket].isExist==true){
//for the first 20 prizes
msg.sender.transfer(rewardPrices[isWinnerTicketNumbers[ticket].index]);
isWin=true;
}
if(isWinnerTicketNumbers[ticket%10000].isExist==true){
//last 4 digits
msg.sender.transfer(rewardPrices[isWinnerTicketNumbers[ticket%10000].index]);
isWin=true;
}
if(isWinnerTicketNumbers[ticket%1000].isExist==true){
//last 3 digits
msg.sender.transfer(rewardPrices[isWinnerTicketNumbers[ticket%1000].index]);
isWin=true;
}
if(isWinnerTicketNumbers[ticket%100].isExist==true){
//last 2 digits
msg.sender.transfer(rewardPrices[isWinnerTicketNumbers[ticket%100].index]);
isWin=true;
}
if(isWin){
//a user must get the prizes only once.
isWithdrawed[ticket]=true;
status=1;
}
}
else{
// refunding the money and sending the 2 ether
if(isWithdrawed[ticket]==false){
msg.sender.transfer(ticketPrice);
isWithdrawed[ticket]=true;
status=2;
}
}
return status;
}
}