7

I can't declare a stand-alone struct in its own file, what gives?

9

You can with a library! Here's an example:

pragma solidity ^0.4.17;

library SharedStructs {
    struct Thing {
        address[] people;
    }    
}

contract A {
    SharedStructs.Thing thing;
}

contract B {
    SharedStructs.Thing thing;
}

Two important things to keep in mind: 1) the library gets deployed to the chain and then is referenced by its address, and 2) the library acts as a true pass-through, meaning msg.sender (and related values) refer to the original caller.

More info and details here: http://solidity.readthedocs.io/en/develop/contracts.html#libraries

1
  • Are you sure that it's necessary to deploy the library if you want to share a struct definition? I think that in that case you can use a library without having to deploy it and link it to the contracts. – Franco Victorio Sep 17 '18 at 17:32
5

If you do not want to use libraries you can create an abstract contract that only contains the structs an inherit from them. It is kinda ugly if the contracts are not quite related.

contract GeometryShapesData {
    struct Point {
        uint x;
        uint y;
    }
}

contract A is GeometryShapesData {
    mapping (bytes32 => Point) public points;
    function addPoint(bytes32 idx, uint x, uint y) public { 
        points[idx] = Point(x, y);
    }
    function getPoint(bytes32 idx) constant public returns (uint x, uint y) {
        return (points[idx].x, points[idx].y);
    }
}

contract B is GeometryShapesData {
    Point[4] public vertexes;
    function addVertex(uint pos, uint x, uint y) public { 
        vertexes[pos] = Point(x, y);
    }
    function getVertex(uint pos) constant public returns (uint x, uint y) {
        return (vertexes[pos].x, vertexes[pos].y);
    }
}
1
  • Precisely because its ugly to "abuse" inheritance in such manner, it's more correct to use this from a library in a "implements interface" fashion through a library. – Leon Aug 31 '18 at 11:52
0

At least in current Solidity versions (^0.5.1), depending on your need, you could bypass the need for the explicit struct definition via tuple unpacking:

contract A {
    struct Thing {
        uint x;
        uint y;
        uint z;
    }
    mapping(uint => Thing) public foo;
    ...
}

import { A } from "./A.sol";
contract B {
    A a;
    constructor(A _a) public { a = _a; }
    function getY(uint id) public returns(uint) {
        (,uint ans,) = a.foo(id);
        return ans;
    }
}

You may also find this and this related posts helpful too.

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.