Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pragma solidity ^0.5.6;
- contract RPS {
- address payable p1;
- address payable p2;
- uint stake;
- bytes32 p1Commitment;
- bytes32 p2Commitment;
- uint timeSinceP1;
- uint timeSinceP2;
- // 1. function RPS() public payable
- // Constructor that sets creator as player 1.
- constructor() public payable {
- p1 = msg.sender;
- }
- modifier onlyP1() {
- require(msg.sender == p1);
- _;
- }
- modifier onlyP2() {
- require(msg.sender == p2);
- _;
- }
- modifier notP1() {
- require(msg.sender != p1);
- _;
- }
- modifier notTwoPlayers() {
- require(!(p1 != address(0) && p2 != address(0)));
- _;
- }
- function p1_commit(bytes32 _commitment) public onlyP1 payable {
- // _commitment is the output of a keccak256 hash of "Rock", "Paper", or "Scissors" and a salt value
- // only callable by player 1
- // the amount of ethereum sent by player 1 defines the stake of the game
- // amount must be strictly greater than 0
- require(msg.value > 0 ether);
- stake = msg.value;
- p1Commitment = _commitment;
- timeSinceP1 = block.timestamp;
- }
- function p2_join(string calldata _play) external notP1 notTwoPlayers payable {
- // if two players: do nothing
- // else _play is either rock paper scissors
- if ((keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Rock")) ||
- keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Paper")) ||
- keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Scissors"))) &&
- msg.value >= stake) {
- p2 = msg.sender;
- p2Commitment = keccak256(abi.encodePacked(_play));
- timeSinceP2 = block.timestamp;
- }
- // must be at least enough ethereum as the stake of the game
- // whoever sends the message is player 2 if all these are True
- }
- function p1_reveal(string calldata _play, string calldata _salt) onlyP1 external {
- // _play must be "Rock" "Paper" or "Scissors"
- if (keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Rock")) ||
- keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Paper")) ||
- keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Scissors"))) {
- // keccak256(_play, _salt) should be equal to the commitment provident when the contract was created
- // called by player 1 only
- require(p1Commitment == keccak256(abi.encodePacked(_play, _salt)));
- // if no other player has joined, cancel the contract, refunding the stored ether to player 1
- if (p2 == address(0)) {
- selfdestruct(p1);
- }
- // if the game is a tie, erase both players' moves (but not player identities!)
- if (keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked(p2Commitment))) {
- p1Commitment = bytes32(0);
- p2Commitment = bytes32(0);
- }
- else {
- // if not a tie, kill the contract and give the balance to player that won
- if (keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Paper")) && p2Commitment == keccak256(abi.encodePacked("Rock")) ||
- keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Rock")) && p2Commitment == keccak256(abi.encodePacked("Scissors")) ||
- keccak256(abi.encodePacked(_play)) == keccak256(abi.encodePacked("Scissors")) && p2Commitment == keccak256(abi.encodePacked("Paper"))) {
- selfdestruct(p1);
- }
- else {
- selfdestruct(p2);
- }
- }
- // if player 2 has not made a move in 30 seconds, cancel the contract,
- // giving all stored ether to player 1
- if (block.timestamp - timeSinceP1 >= 30) {
- selfdestruct(p2);
- }
- }
- }
- function p2_payout() external {
- // 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 - timeSinceP1 >= 30) {
- selfdestruct(p2);
- }
- }
- function p1_replay(bytes32 _commitment) onlyP1 external {
- // player 1 only
- // only if player 1 has no valid play stored (because a tie was declared)
- // sets player 1's commitment to _commitment
- if (p1Commitment == bytes32(0)) {
- p1Commitment = _commitment;
- }
- }
- function p2_replay(string calldata _play) onlyP2 external {
- // player 2 only
- // only if player 2 has no valid play stored (because a tie was declared)
- // stores play as player 2's play (should be "Rock", "Paper", or "Scissors")
- if (p2Commitment == bytes32(0)) {
- p2Commitment = keccak256(abi.encodePacked(_play));
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement