diff --git a/contracts/Puzzle.go b/contracts/Puzzle.go index 2a67f6158..2b58d7382 100644 --- a/contracts/Puzzle.go +++ b/contracts/Puzzle.go @@ -28,10 +28,10 @@ var ( ) // PuzzleABI is the input ABI used to generate the binding from. -const PuzzleABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"manager\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"sessionID\",\"type\":\"uint256\"}],\"name\":\"play\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"player\",\"type\":\"address\"},{\"name\":\"level\",\"type\":\"uint256\"}],\"name\":\"setLevel\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getPlayers\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"player\",\"type\":\"address\"},{\"name\":\"level\",\"type\":\"uint256\"},{\"name\":\"session\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"string\"}],\"name\":\"payout\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"player\",\"type\":\"address\"}],\"name\":\"resetPlayer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"players\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]" +const PuzzleABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"player\",\"type\":\"address\"}],\"name\":\"endGame\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"manager\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"player\",\"type\":\"address\"},{\"name\":\"level\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"string\"}],\"name\":\"payout\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"player\",\"type\":\"address\"},{\"name\":\"level\",\"type\":\"uint256\"}],\"name\":\"setLevel\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getPlayers\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"play\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"player\",\"type\":\"address\"}],\"name\":\"resetPlayer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"players\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]" // PuzzleBin is the compiled bytecode used for deploying new contracts. -const PuzzleBin = `0x608060405234801561001057600080fd5b50600380546001600160a01b0319163317905561087f806100326000396000f3fe60806040526004361061007b5760003560e01c80638f3a7d8b1161004e5780638f3a7d8b1461016e578063c95e090914610230578063d826f88f14610263578063f71d96cb146102785761007b565b8063481c6a75146100805780636898f82b146100b1578063722dcd8f146100d05780638b5b9ccc14610109575b600080fd5b34801561008c57600080fd5b506100956102a2565b604080516001600160a01b039092168252519081900360200190f35b6100ce600480360360208110156100c757600080fd5b50356102b1565b005b3480156100dc57600080fd5b506100ce600480360360408110156100f357600080fd5b506001600160a01b0381351690602001356103ff565b34801561011557600080fd5b5061011e61041b565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561015a578181015183820152602001610142565b505050509050019250505060405180910390f35b6100ce6004803603608081101561018457600080fd5b6001600160a01b0382351691602081013591604082013591908101906080810160608201356401000000008111156101bb57600080fd5b8201836020820111156101cd57600080fd5b803590602001918460018302840111640100000000831117156101ef57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061047e945050505050565b34801561023c57600080fd5b506100ce6004803603602081101561025357600080fd5b50356001600160a01b0316610616565b34801561026f57600080fd5b506100ce6106d2565b34801561028457600080fd5b506100956004803603602081101561029b57600080fd5b50356107b8565b6003546001600160a01b031681565b60408051808201909152601181527f496e73756666696369656e742046756e6400000000000000000000000000000060208201526801158e460913d0000034101561037d57604051600160e51b62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561034257818101518382015260200161032a565b50505050905090810190601f16801561036f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b503360009081526020819052604090205415156103d757600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b031916331790555b3360009081526020818152604080832093909355600181528282208290556002905220349055565b6001600160a01b03909116600090815260016020526040902055565b6060600480548060200260200160405190810160405280929190818152602001828054801561047357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610455575b505050505090505b90565b6003546040805180820190915260138152600160681b72556e617574686f72697a656420416363657373026020820152906001600160a01b0316331461050957604051600160e51b62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561034257818101518382015260200161032a565b5081600080866001600160a01b03166001600160a01b0316815260200190815260200160002054146040518060600160405280602c8152602001610828602c913990151561059c57604051600160e51b62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561034257818101518382015260200161032a565b506001600160a01b03841660009081526001602052604090205483036105c285856103ff565b6001600160a01b03851660008181526002602052604080822054905160059091048402929183156108fc02918491818181858888f1935050505015801561060d573d6000803e3d6000fd5b50505050505050565b6003546040805180820190915260138152600160681b72556e617574686f72697a656420416363657373026020820152906001600160a01b031633146106a157604051600160e51b62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561034257818101518382015260200161032a565b506001600160a01b031660009081526001602090815260408083208390558282528083208390556002909152812055565b6003546040805180820190915260138152600160681b72556e617574686f72697a656420416363657373026020820152906001600160a01b0316331461075d57604051600160e51b62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561034257818101518382015260200161032a565b5060045460005b818110156107a657600060048281548110151561077d57fe5b6000918252602090912001546001600160a01b0316905061079d81610616565b50600101610764565b5060006107b46004826107e0565b5050565b60048054829081106107c657fe5b6000918252602090912001546001600160a01b0316905081565b81548183558181111561080457600083815260209020610804918101908301610809565b505050565b61047b91905b80821115610823576000815560010161080f565b509056fe506c617965722072657175657374696e67207061796f757420666f7220756e6b6e6f776e2073657373696f6ea165627a7a72305820565023c31d341faf87f17e3031d315462faab38087fb5c7191bc471c812bf5680029` +const PuzzleBin = `0x608060405234801561001057600080fd5b50600480546001600160a01b03191633179055610977806100326000396000f3fe6080604052600436106100865760003560e01c80638b5b9ccc116100595780638b5b9ccc146101e557806393e84cd91461024a578063c95e090914610252578063d826f88f14610285578063f71d96cb1461029a57610086565b80632a035b6c1461008b578063481c6a75146100c057806352bcd7c8146100f1578063722dcd8f146101ac575b600080fd5b34801561009757600080fd5b506100be600480360360208110156100ae57600080fd5b50356001600160a01b03166102c4565b005b3480156100cc57600080fd5b506100d56103ad565b604080516001600160a01b039092168252519081900360200190f35b6100be6004803603606081101561010757600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561013757600080fd5b82018360208201111561014957600080fd5b8035906020019184600183028401116401000000008311171561016b57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103bc945050505050565b3480156101b857600080fd5b506100be600480360360408110156101cf57600080fd5b506001600160a01b038135169060200135610569565b3480156101f157600080fd5b506101fa610585565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561023657818101518382015260200161021e565b505050509050019250505060405180910390f35b6100be6105e8565b34801561025e57600080fd5b506100be6004803603602081101561027557600080fd5b50356001600160a01b0316610722565b34801561029157600080fd5b506100be6107f6565b3480156102a657600080fd5b506100d5600480360360208110156102bd57600080fd5b50356108dc565b6004546040805180820190915260138152600160681b72556e617574686f72697a656420416363657373026020820152906001600160a01b0316331461038b57604051600160e51b62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610350578181015183820152602001610338565b50505050905090810190601f16801561037d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506001600160a01b03166000908152600260205260409020805460ff19169055565b6004546001600160a01b031681565b6004546040805180820190915260138152600160681b72556e617574686f72697a656420416363657373026020820152906001600160a01b0316331461044757604051600160e51b62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610350578181015183820152602001610338565b506001600160a01b038316600090815260026020908152604091829020548251808401909352601f83527f506c61796572206973206e6f7420696e20616e206163746976652067616d65009183019190915260ff1615156001146104f057604051600160e51b62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610350578181015183820152602001610338565b506001600160a01b03831660009081526020819052604090205482036105168484610569565b6001600160a01b03841660008181526001602052604080822054905160059091048402929183156108fc02918491818181858888f19350505050158015610561573d6000803e3d6000fd5b505050505050565b6001600160a01b03909116600090815260208190526040902055565b606060058054806020026020016040519081016040528092919081815260200182805480156105dd57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116105bf575b505050505090505b90565b60408051808201909152601181527f496e73756666696369656e742046756e6400000000000000000000000000000060208201526801158e460913d0000034101561067857604051600160e51b62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610350578181015183820152602001610338565b503360009081526003602052604090205460ff1615156106ef57336000818152600360205260408120805460ff191660019081179091556005805491820181559091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b03191690911790555b3360009081526020818152604080832083905560018083528184203490556002909252909120805460ff19169091179055565b6004546040805180820190915260138152600160681b72556e617574686f72697a656420416363657373026020820152906001600160a01b031633146107ad57604051600160e51b62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610350578181015183820152602001610338565b506001600160a01b031660009081526020818152604080832083905560028252808320805460ff1990811690915560018352818420849055600390925290912080549091169055565b6004546040805180820190915260138152600160681b72556e617574686f72697a656420416363657373026020820152906001600160a01b0316331461088157604051600160e51b62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610350578181015183820152602001610338565b5060055460005b818110156108ca5760006005828154811015156108a157fe5b6000918252602090912001546001600160a01b031690506108c181610722565b50600101610888565b5060006108d8600582610904565b5050565b60058054829081106108ea57fe5b6000918252602090912001546001600160a01b0316905081565b8154818355818111156109285760008381526020902061092891810190830161092d565b505050565b6105e591905b808211156109475760008155600101610933565b509056fea165627a7a72305820d77629ee8b56472dfdca022f06934c4f4dfcf700ce46dccd736c4eef81d380bc0029` // DeployPuzzle deploys a new Ethereum contract, binding an instance of Puzzle to it. func DeployPuzzle(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Puzzle, error) { @@ -266,46 +266,67 @@ func (_Puzzle *PuzzleCallerSession) Players(arg0 *big.Int) (common.Address, erro return _Puzzle.Contract.Players(&_Puzzle.CallOpts, arg0) } -// Payout is a paid mutator transaction binding the contract method 0x8f3a7d8b. +// EndGame is a paid mutator transaction binding the contract method 0x2a035b6c. // -// Solidity: function payout(address player, uint256 level, uint256 session, string ) returns() -func (_Puzzle *PuzzleTransactor) Payout(opts *bind.TransactOpts, player common.Address, level *big.Int, session *big.Int, arg3 string) (*types.Transaction, error) { - return _Puzzle.contract.Transact(opts, "payout", player, level, session, arg3) +// Solidity: function endGame(address player) returns() +func (_Puzzle *PuzzleTransactor) EndGame(opts *bind.TransactOpts, player common.Address) (*types.Transaction, error) { + return _Puzzle.contract.Transact(opts, "endGame", player) } -// Payout is a paid mutator transaction binding the contract method 0x8f3a7d8b. +// EndGame is a paid mutator transaction binding the contract method 0x2a035b6c. // -// Solidity: function payout(address player, uint256 level, uint256 session, string ) returns() -func (_Puzzle *PuzzleSession) Payout(player common.Address, level *big.Int, session *big.Int, arg3 string) (*types.Transaction, error) { - return _Puzzle.Contract.Payout(&_Puzzle.TransactOpts, player, level, session, arg3) +// Solidity: function endGame(address player) returns() +func (_Puzzle *PuzzleSession) EndGame(player common.Address) (*types.Transaction, error) { + return _Puzzle.Contract.EndGame(&_Puzzle.TransactOpts, player) } -// Payout is a paid mutator transaction binding the contract method 0x8f3a7d8b. +// EndGame is a paid mutator transaction binding the contract method 0x2a035b6c. // -// Solidity: function payout(address player, uint256 level, uint256 session, string ) returns() -func (_Puzzle *PuzzleTransactorSession) Payout(player common.Address, level *big.Int, session *big.Int, arg3 string) (*types.Transaction, error) { - return _Puzzle.Contract.Payout(&_Puzzle.TransactOpts, player, level, session, arg3) +// Solidity: function endGame(address player) returns() +func (_Puzzle *PuzzleTransactorSession) EndGame(player common.Address) (*types.Transaction, error) { + return _Puzzle.Contract.EndGame(&_Puzzle.TransactOpts, player) } -// Play is a paid mutator transaction binding the contract method 0x6898f82b. +// Payout is a paid mutator transaction binding the contract method 0x52bcd7c8. // -// Solidity: function play(uint256 sessionID) returns() -func (_Puzzle *PuzzleTransactor) Play(opts *bind.TransactOpts, sessionID *big.Int) (*types.Transaction, error) { - return _Puzzle.contract.Transact(opts, "play", sessionID) +// Solidity: function payout(address player, uint256 level, string ) returns() +func (_Puzzle *PuzzleTransactor) Payout(opts *bind.TransactOpts, player common.Address, level *big.Int, arg2 string) (*types.Transaction, error) { + return _Puzzle.contract.Transact(opts, "payout", player, level, arg2) } -// Play is a paid mutator transaction binding the contract method 0x6898f82b. +// Payout is a paid mutator transaction binding the contract method 0x52bcd7c8. // -// Solidity: function play(uint256 sessionID) returns() -func (_Puzzle *PuzzleSession) Play(sessionID *big.Int) (*types.Transaction, error) { - return _Puzzle.Contract.Play(&_Puzzle.TransactOpts, sessionID) +// Solidity: function payout(address player, uint256 level, string ) returns() +func (_Puzzle *PuzzleSession) Payout(player common.Address, level *big.Int, arg2 string) (*types.Transaction, error) { + return _Puzzle.Contract.Payout(&_Puzzle.TransactOpts, player, level, arg2) } -// Play is a paid mutator transaction binding the contract method 0x6898f82b. +// Payout is a paid mutator transaction binding the contract method 0x52bcd7c8. // -// Solidity: function play(uint256 sessionID) returns() -func (_Puzzle *PuzzleTransactorSession) Play(sessionID *big.Int) (*types.Transaction, error) { - return _Puzzle.Contract.Play(&_Puzzle.TransactOpts, sessionID) +// Solidity: function payout(address player, uint256 level, string ) returns() +func (_Puzzle *PuzzleTransactorSession) Payout(player common.Address, level *big.Int, arg2 string) (*types.Transaction, error) { + return _Puzzle.Contract.Payout(&_Puzzle.TransactOpts, player, level, arg2) +} + +// Play is a paid mutator transaction binding the contract method 0x93e84cd9. +// +// Solidity: function play() returns() +func (_Puzzle *PuzzleTransactor) Play(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Puzzle.contract.Transact(opts, "play") +} + +// Play is a paid mutator transaction binding the contract method 0x93e84cd9. +// +// Solidity: function play() returns() +func (_Puzzle *PuzzleSession) Play() (*types.Transaction, error) { + return _Puzzle.Contract.Play(&_Puzzle.TransactOpts) +} + +// Play is a paid mutator transaction binding the contract method 0x93e84cd9. +// +// Solidity: function play() returns() +func (_Puzzle *PuzzleTransactorSession) Play() (*types.Transaction, error) { + return _Puzzle.Contract.Play(&_Puzzle.TransactOpts) } // Reset is a paid mutator transaction binding the contract method 0xd826f88f. diff --git a/contracts/Puzzle.sol b/contracts/Puzzle.sol index 76baf45ba..ac0512e88 100644 --- a/contracts/Puzzle.sol +++ b/contracts/Puzzle.sol @@ -3,13 +3,14 @@ pragma solidity >=0.4.22; contract Puzzle { string internal constant INSUFFICIENT_FUND_MESSAGE = "Insufficient Fund"; string internal constant RESTRICTED_MESSAGE = "Unauthorized Access"; - string internal constant INCORRECT_SESSION = "Player requesting payout for unknown session"; + string internal constant NOT_IN_GAME = "Player is not in an active game"; string internal constant INCORRECT_LEVEL = "Player requesting payout for earlier level"; uint constant thresholdLevel = 5; - mapping(address => uint) playerSession; mapping(address => uint) playerLevel; mapping(address => uint) playerStake; + mapping(address => bool) playerInGame; // Whether the player is in a active game or not. Payout won't work if not in game. + mapping(address => bool) playerSet; address public manager; // The adress of the owner of this contract address payable[] public players; // all players @@ -19,19 +20,20 @@ contract Puzzle { } /** - * @dev The player enters into the current game session by + * @dev The player enters into a new game by * paying at least 20 token. */ - function play(uint sessionID) public payable { + function play() public payable { require(msg.value >= 20 ether, INSUFFICIENT_FUND_MESSAGE); - if (playerSession[msg.sender] == 0) { - // New player + if (playerSet[msg.sender] == false) { + // New player, never staked before + playerSet[msg.sender] = true; players.push(msg.sender); } - playerSession[msg.sender] = sessionID; playerLevel[msg.sender] = 0; playerStake[msg.sender] = msg.value; + playerInGame[msg.sender] = true; } /** @@ -44,8 +46,8 @@ contract Puzzle { /** * @dev pay the player if they have crossed their last best level. */ - function payout(address payable player, uint level, uint session, string memory /*sequence*/) public payable restricted { - require(playerSession[player] == session, INCORRECT_SESSION); + function payout(address payable player, uint level, string memory /*sequence*/) public payable restricted { + require(playerInGame[player] == true, NOT_IN_GAME); uint progress = level - playerLevel[player]; //if a later transaction for a higher level comes earlier. setLevel(player,level); @@ -53,18 +55,26 @@ contract Puzzle { player.transfer(amount); } + /** + * @dev set the player's game state to inactive. + */ + function endGame(address player) public restricted { + delete playerInGame[player]; + } + modifier restricted() { require(msg.sender == manager, RESTRICTED_MESSAGE); _; } - + /** * @dev Resets the current session of one player */ function resetPlayer(address player) public restricted { delete playerLevel[player]; - delete playerSession[player]; - delete playerStake[player]; + delete playerInGame[player]; + delete playerStake[player]; + delete playerSet[player]; } /**