0

I want to add elements in moneyLineData of a Bet instance.

pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;

contract Betting {

    struct Bet{
        uint betId;
        string question;
        mapping(uint => MoneyLineData) moneyLineData;
        uint lengthMoneyLineData;
    }

    struct MoneyLineData{
        string option;
        int value; 
    }

    mapping(uint => Bet) public bets;
    uint public lengthBets = 0;

    constructor() public{
        MoneyLineData[2] memory moneyLineData = [MoneyLineData("Gator", 200), MoneyLineData("Miami", -100)];
        Bet memory bet;
        bet.betId = 1;
        bet.question = "Gator vs Miami";
        bet.lengthMoneyLineData = 0;
        bet.moneyLineData[bet.lengthMoneyLineData] = moneyLineData[0];
        bet.moneyLineData[bet.lengthMoneyLineData] = moneyLineData[1];
        bet.lengthMoneyLineData += moneyLineData.length;
        bets[lengthBets] = bet;
        lengthBets += 1;
    }
}

But I get this error.

Error: CompileError: /D/Workspace/Nodejs/ethereum-sports-betting/contracts/Betting.sol:32:3: TypeError: Member "moneyLineData" is not available in struct Betting.Bet memory outside of storage.
                bet.moneyLineData[bet.lengthMoneyLineData] = moneyLineData[0];
                ^---------------^

Any help would be greatly appreciated. Thank you!

Stuxen
  • 125
  • 6

1 Answers1

1

I got a little lost in it so I thought I'd show a few patterns instead of fixing it. I think you get in trouble with a questionable data layout. Here are some patterns to help with your original question:

pragma solidity ^0.5.8;

contract MappingInStruct {

    struct Parent {
        mapping(bytes32 => Child) childrenOfTheMapping;
        Child[] childrenOfTheArray;
    }

    struct Child {
        uint value;
        string name;
    }

    Parent[] parents;

    function newParent() public {
        Parent memory p;
        parents.push(p);
        // It will get very awkward to parse inputs and map to storage here, so let's do it separately.
    }

    // As child mapping

    function newChildOfTheMapping(uint parent, bytes32 key, uint value, string memory name) public {
        Parent storage p = parents[parent]; // this will revert if out of bounds. 
        Child storage c = p.childrenOfTheMapping[key]; // overwrites existing, not sequencial, every possible key "exists" (but most default to 0).
        c.value = value;
        c.name = name;
    }

    function getChildOfTheMapping(uint parent, bytes32 key) public view returns(uint value, string memory name) {
        Child storage c = parents[parent].childrenOfTheMapping[key];
        return (c.value, c.name);
    }

    // As child array

    function newChildOfTheArray(uint parent, uint value, string memory name) public {
        Child memory c = Child({
            value: value,
            name: name
        });
        Parent storage p = parents[parent];
        p.childrenOfTheArray.push(c);
    }

    function getChildOfTheArray(uint parent, uint child) public view returns(uint value, string memory name) {
        Child storage c = parents[parent].childrenOfTheArray[child];
        return (c.value, c.name);
    }

    // array.length is a property of a dynamic array. Mapping doesn't have it. 
    function parentChildrenOfTheArrayCount(uint parent) public view returns(uint count) {
        count = parents[parent].childrenOfTheArray.length;
    }
}

This might help with the storage pointers. https://blog.b9lab.com/storage-pointers-in-solidity-7dcfaa536089

It's super important to realize that arrays, dynamic arrays and mappings are quite different. Only the [] looks the same. Make sure you know which one or combination to use so things go smoothly. Some hints over here: Are there well-solved and simple storage patterns for Solidity?

Related objects are tricky to get right. I fear this is skipping ahead much too fast, but it might save you a ton of time. https://medium.com/robhitchens/solidity-crud-epilogue-e563e794fde

Hope it helps.

Rob Hitchens
  • 55,151
  • 11
  • 89
  • 145
  • Thank you very much! You are GOD! Looking at your example I found my mistake. – Stuxen Oct 27 '19 at 03:21
  • lol. No, just a humble spirit in the bitstream. Thanks for accepting my answer. – Rob Hitchens Oct 27 '19 at 03:45
  • I know I shouldn't be asking this. But only you seem to have an immense knowledge on Ethereum. Can you answer my other question if you get time? – Stuxen Oct 29 '19 at 00:25