-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrps.sol
144 lines (124 loc) · 4.91 KB
/
rps.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
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.7.0 <0.9.0;
contract rps {
uint256 public startBlock = block.number;
address constant alice = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
address constant bob = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
bytes32 aliceHash;
bytes32 bobHash;
enum Choice {
Empty,
Rock,
Paper,
Scissor
}
Choice public aliceChoice = Choice.Empty;
Choice public bobChoice = Choice.Empty;
bool gameEnded = false;
mapping(address=>uint) public balances;
function resetAll() public {
require(gameEnded);
startBlock = block.number;
aliceHash = 0;
bobHash = 0;
aliceChoice = Choice.Empty;
bobChoice = Choice.Empty;
gameEnded = false;
}
// commit the choice (Rock / Paper / Scissor)
function commitChoice(bytes32 hash) public payable {
require(block.number < (startBlock + 100));
require((msg.sender == alice && aliceHash == 0) || (msg.sender == bob && bobHash == 0), "not Alice or Bob");
require(msg.value == 1 ether, "please pay to participate");
if(msg.sender == alice) {
aliceHash = hash;
} else {
bobHash = hash;
}
}
// reveal the choice (Rock / Paper / Scissor)
function revealChoice(Choice choice, uint nonce) public {
require(block.number >= (startBlock + 100) && block.number < (startBlock + 200));
require(msg.sender == alice || msg.sender == bob, "not Alice or Bob");
require(aliceHash != 0 && bobHash != 0, "someone did not submit hash");
require(choice != Choice.Empty, "have to choose Rock/Paper/Scissor");
if(msg.sender == alice) {
if (aliceHash == sha256(abi.encodePacked(choice, nonce))) {
aliceChoice = choice;
}
} else {
if (bobHash == sha256(abi.encodePacked(choice, nonce))) {
bobChoice = choice;
}
}
}
// check the result
function findResult() public {
require(block.number > (startBlock + 200));
require(!gameEnded, "can only compute result once");
require(aliceChoice != Choice.Empty && bobChoice != Choice.Empty, "someone did not reveal their choice");
// draw
if (aliceChoice == bobChoice) {
balances[alice] += 1 ether;
balances[bob] += 1 ether;
} else if (aliceChoice == Choice.Rock) {
if (bobChoice == Choice.Paper) {
// alice: rock, bob: paper, bob win
balances[bob] += 2 ether;
} else {
// alice: rock, bob: scissor, alice win
balances[alice] += 2 ether;
}
} else if (aliceChoice == Choice.Paper) {
if (bobChoice == Choice.Scissor) {
// alice: paper, bob: scissor, bob win
balances[bob] += 2 ether;
} else {
// alice: paper, bob: rock, alice win
balances[alice] += 2 ether;
}
} else if (aliceChoice == Choice.Scissor) {
if (bobChoice == Choice.Rock) {
// alice: scissor, bob: rock, bob win
balances[bob] += 2 ether;
} else {
// alice: scissor, bob: paper, alice win
balances[alice] += 2 ether;
}
}
gameEnded = true;
}
// in case either party did not participate
function refundDeposit() public {
bool didNotSubmitHash = block.number >= (startBlock + 100) && (aliceHash == 0 || bobHash == 0);
bool didNotRevealChoice = block.number >= (startBlock + 200) && (aliceChoice == Choice.Empty || bobChoice == Choice.Empty);
require(didNotSubmitHash || didNotRevealChoice);
require(address(this).balance >= 1 ether);
if (block.number >= (startBlock + 200)) {
if (aliceChoice == Choice.Empty && bobChoice != Choice.Empty) {
balances[bob] += 2 ether;
} else if (aliceChoice != Choice.Empty && bobChoice == Choice.Empty) {
balances[alice] += 2 ether;
} else {
balances[alice] += 1 ether;
balances[bob] += 1 ether;
}
} else if (block.number >= (startBlock + 100)) {
if (aliceHash == 0 && bobHash != 0) {
balances[bob] += 1 ether;
} else if (aliceHash != 0 && bobHash == 0) {
balances[alice] += 1 ether;
}
}
}
function claimMoney() public {
require(msg.sender == alice || msg.sender == bob, "not Alice or Bob");
require(balances[msg.sender] > 0);
uint amount = balances[msg.sender];
balances[msg.sender] = 0;
bool transferred = payable(msg.sender).send(amount);
if (transferred != true) {
balances[msg.sender] = amount;
}
}
}