I'm developing a contract that stores multiple Games between two players.

struct Game {
  address player1;
  address player2;
  bool complete;

Game[] public games;

I would like to add functionality for the contract to randomly-ish assign player2 to a Game that is not yet complete.

function joinGame(bytes32 _commitment) public payable {
  uint256 gameId = notReallyRandomButBetterThanNothing(games.length);

  Game storage game = games[gameId];

  game.player2 = msg.sender;

function notReallyRandomButBetterThanNothing(uint256 _max) internal 
  pure returns(uint256) {

  return uint256(keccak256(block.timestamp)) % _max + 1;

In the example above, this will get a gameId to point to an index in the games array, but the issue is that that game might be complete.

I do not want to delete indexes from the games array when the game is complete because it will leave gaps and I do not want to shift and delete indexes because this will screw up the gameIds for other games in the array.

I also do not want to loop through the games array looking for a complete game because this could become costly.

What is the recommended storage pattern to deal with items that could be active or inactive?


Without more details is hard to recommend a concrete solution but.. You can have a mapping for the games

mapping (uint256 => Game) games;

And an array with incomplete games

uint256[] incompletes;
  • This is a simple and effective solution, thank you. I will be able to delete from the incompletes array without worrying about the order of the games. – stevenpslade Jul 29 '18 at 2:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.