0

The very last function of the code makeBet() is throwing an error when I want to deploy it on Remix. The error says that member status is not found or not visible when calling Game.status. That is very odd for me, as the struct Game clearly has member status defined in it as enum state. Where did I go wrong?

pragma solidity ^0.8.4

contract Bet {
    
    address payable owner;

    AggregatorV3Interface internal priceFeed;

    // Bet status
    enum BetStatus { LONG, SHORT, NGMI }

    //the game structure
    struct Game {
      uint256 betPrice;
      uint256 betAmount;
      BetStatus status;
      address maker;
      address taker;
      string deadline;
    }

    mapping (bytes32 => Game) public games;
    Game[] public activeGames;

    modifier onlyOwner() {
      require(msg.sender == owner);
      _;
    }

    receive() external payable {
    }

     /**
     * Network: Kovan
     * Aggregator: ETH/USD
     * Address: 0x9326BFA02ADD2366b30bacB125260Af641031331
     */
    constructor() public payable {
      priceFeed = AggregatorV3Interface(address(0x9326BFA02ADD2366b30bacB125260Af641031331));
    }

    function getThePrice() public view returns (int) {
      (
        uint80 roundID,
        int price,
        uint startedAt,
        uint timeStamp,
        uint80 answeredInRound
      ) = priceFeed.latestRoundData();

      return price;
    }

    function makeBet(uint _guess, string memory deadline) public payable {
      Game(msg.value, _guess, BetStatus(0), msg.sender, address(0), deadline);
      uint current_price = uint(getThePrice());

      if (_guess > current_price) {
        Game.status = BetStatus.LONG;
      } else if (_guess < current_price) {
        Game.status = BetStatus.SHORT;
      } else {
        Game.status = BetStatus.NGMI;
      }
}

function takeBet() public payable {
      //requires the taker to make the same bet amount
      
      require(msg.value == Games.betAmount);
      Game.taker = msg.sender;
    }

    function getBetOutcome() public payable {
      // TODO: remove game from activeGames map here

      uint current_price = uint(getThePrice());
      if (Game.status == BetStatus.LONG && current_price >= Game.betPrice) {
        (bool sent, bytes memory data) = Game.maker.call{value: address(this).balance}("");
        require(sent, "Failed to send Ether");
      } else if (Game.status == BetStatus.SHORT && current_price <= Game.betPrice) {
        (bool sent, bytes memory data) = Game.maker.call{value: address(this).balance}("");
        require(sent, "Failed to send Ether");
      } else {
        (bool sent, bytes memory data) = Game.taker.call{value: address(this).balance}("");
        require(sent, "Failed to send Ether");
      }
    }

1

Game is a type. You have defined the type as a struct.

In the makeBet() function you have not created a local variable of type Game. What you're doing is trying to assign a value to a type definition, not a variable.

You need something along the lines of:

function makeBet(uint _guess, string memory deadline) public payable {
  Game memory newGame = Game(msg.value, _guess, BetStatus(0), msg.sender, address(0), deadline);
  uint current_price = uint(getThePrice());

  if (_guess > current_price) {
    newGame.status = BetStatus.LONG;
  } else if (_guess < current_price) {
    newGame.status = BetStatus.SHORT;
  } else {
    newGame.status = BetStatus.NGMI;
  }

  activeGames.push(newGame);
}

Alternatively, you could push the new struct directly without creating a convenience variable:

function makeBet(uint _guess, string memory deadline) public payable {  
  BetStatus newStatus;
  uint current_price = uint(getThePrice());

  if (_guess > current_price) {
    newStatus = BetStatus.LONG;
  } else if (_guess < current_price) {
    newStatus = BetStatus.SHORT;
  } else {
    newStatus = BetStatus.NGMI;
  }

  activeGames.push(Game({
    betPrice: msg.value, 
    betAmount: _guess, 
    status: newStatus, 
    maker: msg.sender, 
    taker: address(0), 
    deadline: deadline}));
}
8
  • And what kind of an identifier could I assign to Game then? Because activeGames.push(newGame); throws an error of newGame - Undeclared identifier
    – Teo
    Jun 1 at 13:10
  • Already in the very beginning I tried assigning a local variable game = Game(msg.value, _guess, BetStatus(0), msg.sender, address(0), deadline); but couldn't figure out what kind of an identifier could a struct use, as it is a collection of different types.
    – Teo
    Jun 1 at 13:16
  • 1
    "throws an error of newGame - Undeclared identifier" <- You mean the first example doesn't compile? Jun 1 at 13:28
  • 1
    Okay, it compiles for me (Solidity v0.8.4). Can you copy+paste the whole function and replace the one in your code, and try again? Jun 1 at 13:36
  • 1
    For both of those functions you'll need to know the index of the bet in the activeGames[] array. Then you can create a local variable which points to that bet: Game storage activeBet = activeGames[index];. (Then you can do the rest of the function logic.) Jun 1 at 14:52

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.