SHARE
TWEET

Untitled

a guest Apr 21st, 2019 104 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top