2

There are 2 contracts A and B.

A has a mapping which returns Struct:

mapping (bytes32 => Cup) public cups;

How can we read the cups mapping in contract B?

Following code doesn't work for sure:

interface CupsInteraface {
    function cups(bytes32 cup) external returns (Struct);
}
1
  • Providing more context will help to answer your question. Could you clarify the structure of both contracts, how they should interact? Oct 29, 2018 at 12:31

4 Answers 4

1

There is no way to do this in a stable version of solidity, but possible in experimental

pragma experimental ABIEncoderV2;

interface CupInteraface {
    struct S {
        bytes32 s;
    }
    function get(bytes32 cup) external returns (S memory);
}

contract Cup is CupInteraface {
    mapping(bytes32 => S) private _cups;

    constructor(bytes32 cup) public {
        _cups[cup] = S(cup);
    }

    function get(bytes32 cup) public returns (S memory) {
        return _cups[cup];
    }
}
0

As of right now, it's not possible to return structs in solidity. The most obvious workaround would be to make functions that return individual elements of a specific struct, like, assuming a cup has a title:

function cup_title(bytes32 cup) external returns (string){
   return cups[cup].title
}

And repeat that for every property.

Or, have just one function that returns multiple values from it (ie: all the attributes of the struct).

Or, use the Seriality library.

0

This can be achieved by using return type from Interface itself. While calling the function in contract B define the return type Interface.struct.

Consider below example:

// Main contract which have struct
contract A {
    struct cup{
        uint value1;
        uint value2;
    }

    mapping(uint=>cup) public cups;

    // Method to add cup struct in mapping.
    function addCup(uint _key, uint _value1, uint _value2) public{
        cups[_key] = cup(_value1, _value2);
    }
}

// Interface with struct and Mapping signature function
interface IA {
    // Struct of main contract A
    struct cup{
        uint value1;
        uint value2;
    }

    // Function signature for mapping
    function cups(uint key) view external returns (cup memory);
}

// Secondary contract to access data from main contract
contract B{
    function getCup(uint key, address _A) view public returns (IA.cup memory) {
        IA.cup memory _cup = IA(_A).cups(key);
        return _cup;
    }
}

Please check the attached screenshot of output from remix as well.

Note: This is for demo purpose only, The best implementation strategy is to implement Interface IA in contract A and use same struct of interface in contract A and contract B from Interface IA.

0

For the Interface, Don't create the struct in the interface instead use a library that way its abstracted and reusable

library StructLib {
    // Struct of main contract A
    struct cup{
        uint value1;
        uint value2;
    }
}
interface IA {
    // Function signature for mapping
    function cups(uint key) view external returns (StructLib.cup memory);
}

contract B{
    function getCup(uint key, address _A) view public returns (StructLib.cup memory) {
        StructLib.cup memory _cup = IA(_A).cups(key);
        return _cup;
    }
}

1
  • 1
    This only compiles since solc v0.8, the syntax isn't available in older versions.
    – Ismael
    Mar 4 at 4:36

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.