Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pragma solidity 0.5.6;
- contract RPSs {
- address payable private _player1;
- address payable private _player2;
- uint _stake;
- bytes32 _p1Move;
- string _p2Move;
- uint _p1Timer;
- uint _p2Timer;
- function RPS() public payable {
- // 1 (a) Constructor that sets creator as player 1.
- _player1 = msg.sender;
- }
- function p1_commit(bytes32 _commitment) public payable {
- // (b) only callable by player 1
- require(msg.sender == _player1);
- // (d) amount must be strictly greater than 0.
- require(msg.value > 0 ether);
- _p1Move = _commitment;
- _p1Timer = block.timestamp;
- // (c) the amount of ethereum sent by player 1 defines the stake of the game
- _stake = msg.value;
- }
- function p2_join(string calldata _play) external payable {
- // (a) should do nothing if there are already two players
- if(_player2 == address(0) && _player1 != msg.sender) {
- // (b) play is either “Rock”, “Paper”, or “Scissors”
- require(valid_play(_play));
- // (c) must be at least enough ethereum as the stake of the game.
- require(msg.value >= _stake);
- // (d) whoever sends the message is player 2, assuming all the above hold
- _player2 = msg.sender;
- _p2Move = _play;
- _p2Timer = block.timestamp;
- }
- }
- function p1_reveal(string calldata _play, string calldata _salt) external {
- // (c) called by player 1 only
- require(msg.sender == _player1);
- // (a) play must be either “Rock”, “Paper”, or “Scissors”
- require(valid_play(_play));
- // (b) keccak256( play, salt) should be equal to the commitment provided when the contract was created
- require(salt_string(_play, _salt) == _p1Move);
- // (d) if no other player has joined, cancel the contract, refunding the stored ether to player 1.
- if(_player2 == address(0)) {
- selfdestruct(_player1);
- } else {
- uint8 winner = check_moves(_play, _p2Move);
- // (e) if the game is a tie, erase both players’ moves (but not player identities!)
- if(winner == 0) {
- _p1Move = "";
- _p2Move = "";
- } else {
- // (f) If not a tie, kill the contract and give the balance to player that won.
- if(winner == 1) selfdestruct(_player1);
- else selfdestruct(_player2);
- }
- }
- // (g) if player 2 has not made a move in 30 seconds, cancel the contract, giving all stored ether to player 1.
- if((block.timestamp - _p2Timer) > 30) selfdestruct(_player2);
- }
- function p2_payout() external {
- // (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
- if((block.timestamp - _p1Timer) > 30) selfdestruct(_player2);
- }
- function p1_replay(bytes32 _commitment) external {
- // (a) player 1 only
- require(msg.sender == _player1);
- // (b) only if player 1 has no valid play stored (because a tie was declared)
- require(_p1Move == "");
- // (c) sets player 1’s commitment to commitment
- _p1Move = _commitment;
- _p1Timer = block.timestamp;
- }
- function p2_replay(string calldata _play) external {
- // (a) player 2 only
- require(msg.sender == _player2);
- // (b) only if player 2 has no valid play stored (because a tie was declared)
- require(str_eq(_p2Move, ""));
- // (c) stores play as player 2’s play (should be “Rock”, “Paper”, or “Scissors”)
- require(valid_play(_play));
- _p2Move = _play;
- _p2Timer = block.timestamp;
- }
- function salt_string(string memory _str, string memory _salt) public pure returns (bytes32){
- return keccak256(abi.encodePacked(_str, _salt));
- }
- function str_eq (string memory a, string memory b) private pure returns(bool) {
- return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));
- }
- function valid_play(string memory _play) private pure returns (bool) {
- return str_eq(_play, "Rock") || str_eq(_play, "Paper") || str_eq(_play, "Scissors");
- }
- function check_moves(string memory _p1, string memory _p2) private pure returns (uint8) {
- if(str_eq(_p1, _p2)) {
- return 0;
- } else if(str_eq(_p1, "Rock")) {
- if (str_eq(_p2, "Scissors")) return 1;
- else return 2;
- } else if(str_eq(_p1, "Paper")) {
- if (str_eq(_p2, "Rock")) return 1;
- else return 2;
- } else if(str_eq(_p1, "Scissors")) {
- if (str_eq(_p2, "Paper")) return 1;
- else return 2;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement