Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.89 KB | None | 0 0
  1. pragma solidity 0.5.6;
  2.  
  3. contract RPSs {
  4. address payable private _player1;
  5. address payable private _player2;
  6. uint _stake;
  7. bytes32 _p1Move;
  8. string _p2Move;
  9. uint _p1Timer;
  10. uint _p2Timer;
  11.  
  12. function RPS() public payable {
  13. // 1 (a) Constructor that sets creator as player 1.
  14. _player1 = msg.sender;
  15. }
  16.  
  17. function p1_commit(bytes32 _commitment) public payable {
  18. // (b) only callable by player 1
  19. require(msg.sender == _player1);
  20.  
  21. // (d) amount must be strictly greater than 0.
  22. require(msg.value > 0 ether);
  23.  
  24. _p1Move = _commitment;
  25. _p1Timer = block.timestamp;
  26.  
  27. // (c) the amount of ethereum sent by player 1 defines the stake of the game
  28. _stake = msg.value;
  29. }
  30.  
  31. function p2_join(string calldata _play) external payable {
  32. // (a) should do nothing if there are already two players
  33. if(_player2 == address(0) && _player1 != msg.sender) {
  34. // (b) play is either “Rock”, “Paper”, or “Scissors”
  35. require(valid_play(_play));
  36.  
  37. // (c) must be at least enough ethereum as the stake of the game.
  38. require(msg.value >= _stake);
  39.  
  40. // (d) whoever sends the message is player 2, assuming all the above hold
  41. _player2 = msg.sender;
  42. _p2Move = _play;
  43. _p2Timer = block.timestamp;
  44. }
  45. }
  46.  
  47. function p1_reveal(string calldata _play, string calldata _salt) external {
  48. // (c) called by player 1 only
  49. require(msg.sender == _player1);
  50.  
  51. // (a) play must be either “Rock”, “Paper”, or “Scissors”
  52. require(valid_play(_play));
  53.  
  54. // (b) keccak256( play, salt) should be equal to the commitment provided when the contract was created
  55. require(salt_string(_play, _salt) == _p1Move);
  56.  
  57. // (d) if no other player has joined, cancel the contract, refunding the stored ether to player 1.
  58. if(_player2 == address(0)) {
  59. selfdestruct(_player1);
  60. } else {
  61. uint8 winner = check_moves(_play, _p2Move);
  62.  
  63. // (e) if the game is a tie, erase both players’ moves (but not player identities!)
  64. if(winner == 0) {
  65. _p1Move = "";
  66. _p2Move = "";
  67. } else {
  68. // (f) If not a tie, kill the contract and give the balance to player that won.
  69. if(winner == 1) selfdestruct(_player1);
  70. else selfdestruct(_player2);
  71. }
  72. }
  73.  
  74. // (g) if player 2 has not made a move in 30 seconds, cancel the contract, giving all stored ether to player 1.
  75. if((block.timestamp - _p2Timer) > 30) selfdestruct(_player2);
  76. }
  77.  
  78. function p2_payout() external {
  79. // (a) if it’s been at least 30 seconds since player 1 has made a move, kill the contract and send the balance to player 2
  80. if((block.timestamp - _p1Timer) > 30) selfdestruct(_player2);
  81. }
  82.  
  83. function p1_replay(bytes32 _commitment) external {
  84. // (a) player 1 only
  85. require(msg.sender == _player1);
  86.  
  87. // (b) only if player 1 has no valid play stored (because a tie was declared)
  88. require(_p1Move == "");
  89.  
  90. // (c) sets player 1’s commitment to commitment
  91. _p1Move = _commitment;
  92. _p1Timer = block.timestamp;
  93. }
  94.  
  95. function p2_replay(string calldata _play) external {
  96. // (a) player 2 only
  97. require(msg.sender == _player2);
  98.  
  99. // (b) only if player 2 has no valid play stored (because a tie was declared)
  100. require(str_eq(_p2Move, ""));
  101.  
  102. // (c) stores play as player 2’s play (should be “Rock”, “Paper”, or “Scissors”)
  103. require(valid_play(_play));
  104. _p2Move = _play;
  105. _p2Timer = block.timestamp;
  106. }
  107.  
  108. function salt_string(string memory _str, string memory _salt) public pure returns (bytes32){
  109. return keccak256(abi.encodePacked(_str, _salt));
  110. }
  111.  
  112. function str_eq (string memory a, string memory b) private pure returns(bool) {
  113. return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));
  114. }
  115.  
  116. function valid_play(string memory _play) private pure returns (bool) {
  117. return str_eq(_play, "Rock") || str_eq(_play, "Paper") || str_eq(_play, "Scissors");
  118. }
  119.  
  120. function check_moves(string memory _p1, string memory _p2) private pure returns (uint8) {
  121. if(str_eq(_p1, _p2)) {
  122. return 0;
  123. } else if(str_eq(_p1, "Rock")) {
  124. if (str_eq(_p2, "Scissors")) return 1;
  125. else return 2;
  126. } else if(str_eq(_p1, "Paper")) {
  127. if (str_eq(_p2, "Rock")) return 1;
  128. else return 2;
  129. } else if(str_eq(_p1, "Scissors")) {
  130. if (str_eq(_p2, "Paper")) return 1;
  131. else return 2;
  132. }
  133. }
  134. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement