[Ethereum] Unable to retrieve struct from mapping

librarymappingsoliditystruct

I have a mapping like this:

pragma solidity 0.4.24;
pragma experimental ABIEncoderV2;
pragma experimental "v0.5.0";

...


mapping(bytes32 => LibMarket.Market) public hashToMarket;

where each Market is defined as:

struct Market {
    address a;
    uint256 b;
    uint256 c;
    string d;
    string e;
}

in a library file LibMarket.

In another contract, I'm trying to access this mapping using the hash like so:

    LibMarket.Market memory market = registry.hashToMarket(marketHash);

However, I'm receiving the error

Exchange.sol:139:9: TypeError: Different number of components on the
left hand side (1) than on the right hand side (5).
LibMarket.Market memory market = registry.hashToMarket(marketHash);
^—————————————————————-^

Why am I getting this error?

EDIT:

Although this doesn't answer this exact question. A simple workaround is to define a different getter function in the contract that has the hashToMarket mapping like so and it will work as intended:

function getMarket(bytes32 marketHash) public view returns(LibMarket.Market) {
    return hashToMarket[marketHash];
}

Best Answer

Since the error message is saying there are 5 results coming from the right-hand side of the assignment, that implies that the function hashToMarket() is not returning a Market object, but it's actually returning the five pieces of a Market object together (a, b, c, d, and e).

EDIT: That function is the default getter for a public mapping, which does indeed return the component pieces of the object rather than the assembled one. If you want to use that default getter, you can get the individual pieces, and then re-cast them into the known struct like:

pragma solidity ^0.4.24;
contract MultiReturns {
    struct MyThing {
        uint256 a;
        uint256 b;
        uint256 c;
    }

    function getPieces() internal pure returns(uint256 a, uint256 b, uint256 c) {
        return (123, 456, 789);
    }

    function doWork() public {
        (uint256 a, uint256 b, uint256 c) = getPieces();
        MyThing memory t = MyThing(a, b, c);
    }
}

Here the getPieces function is a sample function that returns multiple values (like the default getter in the original question was using). Note how the doWork method first gets the three pieces returned in one return statement from the getPieces function, and then uses them to construct the desired struct.

Related Topic