diff --git a/contracts/Arcadeum.sol b/contracts/Arcadeum.sol index 9f12187..b38e7db 100644 --- a/contracts/Arcadeum.sol +++ b/contracts/Arcadeum.sol @@ -12,6 +12,12 @@ contract Arcadeum { string private constant MESSAGE_PREFIX = 'Sign to play! This won\'t cost anything.\n'; string private constant PLAYER_PREFIX = '\nPlayer: 0x'; + // XXX: https://github.com/ethereum/solidity/issues/3270 + // *** THIS MUST MATCH DGame.sol *** + uint private constant PUBLIC_SEED_LENGTH = 1; + uint private constant META_STATE_DATA_LENGTH = 3; + uint private constant STATE_DATA_LENGTH = 1; + struct Match { DGame game; uint32 matchID; @@ -26,7 +32,8 @@ contract Arcadeum { SubkeySignature subkeySignature; TimestampSignature timestampSignature; uint32 seedRating; - bytes publicSeed; + // XXX: https://github.com/ethereum/solidity/issues/3270 + bytes32[PUBLIC_SEED_LENGTH] publicSeed; } struct Move { @@ -251,7 +258,8 @@ contract Arcadeum { aMatch.game.registerWin(msg.sender, aMatch.game.secretSeedRating(msg.sender, winnerSecretSeed), aMatch.opponent.seedRating, metaState.state, 1 - aMatch.opponent.playerID); } - function canReportCheater(Match aMatch, uint32 reporterSeedRating, bytes reporterPublicSeed, DGame.MetaState metaState, Move cheaterMove) public view returns (bool) { + // XXX: https://github.com/ethereum/solidity/issues/3270 + function canReportCheater(Match aMatch, uint32 reporterSeedRating, bytes32[PUBLIC_SEED_LENGTH] reporterPublicSeed, DGame.MetaState metaState, Move cheaterMove) public view returns (bool) { bytes24 gameMatchID; address opponent; @@ -278,7 +286,8 @@ contract Arcadeum { return true; } - function reportCheater(Match aMatch, uint32 reporterSeedRating, bytes reporterPublicSeed, DGame.MetaState metaState, Move cheaterMove) external { + // XXX: https://github.com/ethereum/solidity/issues/3270 + function reportCheater(Match aMatch, uint32 reporterSeedRating, bytes32[PUBLIC_SEED_LENGTH] reporterPublicSeed, DGame.MetaState metaState, Move cheaterMove) external { bytes24 gameMatchID; address opponent; uint value; @@ -353,11 +362,13 @@ contract Arcadeum { return subkeyParent(subkey, subkeySignature); } - function matchHash(DGame game, uint32 matchID, uint timestamp, address[2] accounts, uint32[2] seedRatings, bytes[2] publicSeeds) public pure returns (bytes32) { + // XXX: https://github.com/ethereum/solidity/issues/3270 + function matchHash(DGame game, uint32 matchID, uint timestamp, address[2] accounts, uint32[2] seedRatings, bytes32[PUBLIC_SEED_LENGTH][2] publicSeeds) public pure returns (bytes32) { return keccak256(game, matchID, timestamp, accounts[0], accounts[1], seedRatings[0], seedRatings[1], publicSeeds[0], publicSeeds[1]); } - function matchMaker(Match aMatch, address sender, uint32 senderSeedRating, bytes senderPublicSeed) private pure returns (address) { + // XXX: https://github.com/ethereum/solidity/issues/3270 + function matchMaker(Match aMatch, address sender, uint32 senderSeedRating, bytes32[PUBLIC_SEED_LENGTH] senderPublicSeed) private pure returns (address) { address opponent; bytes32 hash; diff --git a/contracts/DGame.sol b/contracts/DGame.sol index b5cbfa6..2544c58 100644 --- a/contracts/DGame.sol +++ b/contracts/DGame.sol @@ -2,6 +2,12 @@ pragma solidity ^0.4.19; pragma experimental ABIEncoderV2; contract DGame { + // XXX: https://github.com/ethereum/solidity/issues/3270 + // *** THIS MUST MATCH Arcadeum.sol *** + uint private constant PUBLIC_SEED_LENGTH = 1; + uint private constant META_STATE_DATA_LENGTH = 3; + uint private constant STATE_DATA_LENGTH = 1; + enum Winner { NONE, PLAYER_0, @@ -26,13 +32,15 @@ contract DGame { struct MetaState { uint32 nonce; MetaTag tag; - bytes data; + // XXX: https://github.com/ethereum/solidity/issues/3270 + bytes32[META_STATE_DATA_LENGTH] data; State state; } struct State { uint32 tag; - bytes data; + // XXX: https://github.com/ethereum/solidity/issues/3270 + bytes32[STATE_DATA_LENGTH] data; } struct Move { @@ -56,8 +64,9 @@ contract DGame { return 0; } - function publicSeed(address /* account */, bytes /* secretSeed */) public view returns (bytes) { - return new bytes(0); + // XXX: https://github.com/ethereum/solidity/issues/3270 + function publicSeed(address /* account */, bytes /* secretSeed */) public view returns (bytes32[PUBLIC_SEED_LENGTH]) { + return [bytes32(0)]; } function winner(MetaState metaState) public pure returns (Winner) { @@ -99,8 +108,6 @@ contract DGame { function isMoveLegal(MetaState metaState, Move move) public pure returns (bool) { NextPlayers next; bytes32 hash; - uint offset; - uint i; next = nextPlayers(metaState); @@ -130,12 +137,10 @@ contract DGame { } hash = keccak256(move.data); - offset = 1 + 32 * move.playerID; - for (i = 0; i < 32; i++) { - if (hash[i] != metaState.data[offset + i]) { - return false; - } + // XXX: https://github.com/ethereum/solidity/issues/3270 + if (hash != metaState.data[1 + move.playerID]) { + return false; } } else if (metaState.tag == MetaTag.COMMITTING_SECRET) { @@ -143,12 +148,10 @@ contract DGame { } else if (metaState.tag == MetaTag.REVEALING_SECRET) { hash = keccak256(move.data); - offset = 32 * move.playerID; - for (i = 0; i < 32; i++) { - if (hash[i] != metaState.data[offset + i]) { - return false; - } + // XXX: https://github.com/ethereum/solidity/issues/3270 + if (hash != metaState.data[move.playerID]) { + return false; } } @@ -193,12 +196,12 @@ contract DGame { } else if (metaState.tag == MetaTag.COMMITTING_RANDOM) { next.tag = MetaTag.REVEALING_RANDOM; - next.data = new bytes(65); next.data[0] = metaState.data[0]; + // XXX: https://github.com/ethereum/solidity/issues/3270 for (i = 0; i < 32; i++) { - next.data[1 + i] = moves[0].data[i]; - next.data[33 + i] = moves[1].data[i]; + next.data[1] |= bytes32(moves[0].data[i]) << ((31 - i) * 8); + next.data[2] |= bytes32(moves[1].data[i]) << ((31 - i) * 8); } next.state = metaState.state; @@ -214,11 +217,11 @@ contract DGame { } else if (metaState.tag == MetaTag.COMMITTING_SECRET) { next.tag = MetaTag.REVEALING_SECRET; - next.data = new bytes(64); + // XXX: https://github.com/ethereum/solidity/issues/3270 for (i = 0; i < 32; i++) { - next.data[0 + i] = moves[0].data[i]; - next.data[32 + i] = moves[1].data[i]; + next.data[0] |= bytes32(moves[0].data[i]) << ((31 - i) * 8); + next.data[1] |= bytes32(moves[1].data[i]) << ((31 - i) * 8); } next.state = metaState.state; @@ -275,8 +278,7 @@ contract DGame { require(nBytes >= 8); metaState.tag = MetaTag.COMMITTING_RANDOM; - metaState.data = new bytes(1); - metaState.data[0] = byte(nBytes); + metaState.data[0] = bytes32(nBytes); metaState.state = state; return metaState;