Guest User

Untitled

a guest
Apr 21st, 2019
116
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. pragma solidity ^0.5.6;
  2.  
  3. contract RPS {
  4. address payable p1;
  5. address payable p2;
  6. uint stake;
  7. bytes32 p1Commitment;
  8. bytes32 p2Commitment;
  9. uint timeSinceP1;
  10. uint timeSinceP2;
  11.  
  12.  
  13. // 1. function RPS() public payable
  14. // Constructor that sets creator as player 1.
  15. constructor() public payable {
  16. p1 = msg.sender;
  17. }
  18. modifier onlyP1() {
  19. require(msg.sender == p1);
  20. _;
  21. }
  22. modifier onlyP2() {
  23. require(msg.sender == p2);
  24. _;
  25. }
  26. modifier notP1() {
  27. require(msg.sender != p1);
  28. _;
  29. }
  30. modifier notTwoPlayers() {
  31. require(!(p1 != address(0) && p2 != address(0)));
  32. _;
  33. }
  34. function p1_commit(bytes32 _commitment) public onlyP1 payable {
  35. // _commitment is the output of a keccak256 hash of "Rock", "Paper", or "Scissors" and a salt value
  36. // only callable by player 1
  37. // the amount of ethereum sent by player 1 defines the stake of the game
  38. // amount must be strictly greater than 0
  39. require(msg.value > 0 ether);
  40. stake = msg.value;
  41. p1Commitment = _commitment;
  42. timeSinceP1 = block.timestamp;
  43. }
  44. function p2_join(string calldata _play) external notP1 notTwoPlayers payable {
  45. // if two players: do nothing
  46. // else _play is either rock paper scissors
  47. if ((keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Rock")) ||
  48. keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Paper")) ||
  49. keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Scissors"))) &&
  50. msg.value >= stake) {
  51. p2 = msg.sender;
  52. p2Commitment = keccak256(abi.encodePacked(_play));
  53. timeSinceP2 = block.timestamp;
  54. }
  55. // must be at least enough ethereum as the stake of the game
  56. // whoever sends the message is player 2 if all these are True
  57.  
  58. }
  59. function p1_reveal(string calldata _play, string calldata _salt) onlyP1 external {
  60. // _play must be "Rock" "Paper" or "Scissors"
  61. if (keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Rock")) ||
  62. keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Paper")) ||
  63. keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Scissors"))) {
  64. // keccak256(_play, _salt) should be equal to the commitment provident when the contract was created
  65. // called by player 1 only
  66. require(p1Commitment == keccak256(abi.encodePacked(_play, _salt)));
  67. // if no other player has joined, cancel the contract, refunding the stored ether to player 1
  68. if (p2 == address(0)) {
  69. selfdestruct(p1);
  70. }
  71. // if the game is a tie, erase both players' moves (but not player identities!)
  72. if (keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked(p2Commitment))) {
  73. p1Commitment = bytes32(0);
  74. p2Commitment = bytes32(0);
  75. }
  76. else {
  77. // if not a tie, kill the contract and give the balance to player that won
  78. if (keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Paper")) && p2Commitment == keccak256(abi.encodePacked("Rock")) ||
  79. keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Rock")) && p2Commitment == keccak256(abi.encodePacked("Scissors")) ||
  80. keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Scissors")) && p2Commitment == keccak256(abi.encodePacked("Paper"))) {
  81. selfdestruct(p1);
  82. }
  83. else {
  84. selfdestruct(p2);
  85. }
  86. }
  87. // if player 2 has not made a move in 30 seconds, cancel the contract,
  88. // giving all stored ether to player 1
  89. if (block.timestamp - timeSinceP1 >= 30) {
  90. selfdestruct(p2);
  91. }
  92. }
  93. }
  94. function p2_payout() external {
  95. // if it's been at least 30 seconds since player 1 has made a move, kill the contract,
  96. // and send the balance to player 2
  97. if (block.timestamp - timeSinceP1 >= 30) {
  98. selfdestruct(p2);
  99. }
  100. }
  101. function p1_replay(bytes32 _commitment) onlyP1 external {
  102. // player 1 only
  103. // only if player 1 has no valid play stored (because a tie was declared)
  104. // sets player 1's commitment to _commitment
  105. if (p1Commitment == bytes32(0)) {
  106. p1Commitment = _commitment;
  107. }
  108. }
  109. function p2_replay(string calldata _play) onlyP2 external {
  110. // player 2 only
  111. // only if player 2 has no valid play stored (because a tie was declared)
  112. // stores play as player 2's play (should be "Rock", "Paper", or "Scissors")
  113. if (p2Commitment == bytes32(0)) {
  114. p2Commitment = keccak256(abi.encodePacked(_play));
  115. }
  116. }
  117. }
RAW Paste Data