¿Cómo puede compartir una definición de estructura entre contratos en archivos separados?

No puedo declarar una estructura independiente en su propio archivo, ¿qué ocurre?

Respuestas (3)

¡Puedes con una biblioteca! Aquí hay un ejemplo:

pragma solidity ^0.4.17;

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

contract A {
    SharedStructs.Thing thing;
}

contract B {
    SharedStructs.Thing thing;
}

Dos cosas importantes a tener en cuenta: 1) la biblioteca se implementa en la cadena y luego se hace referencia a ella por su dirección, y 2) la biblioteca actúa como un verdadero paso, lo que significa que msg.sender (y los valores relacionados) se refieren a la llamador original.

Más información y detalles aquí: http://solidity.readthedocs.io/en/develop/contracts.html#libraries

¿Está seguro de que es necesario implementar la biblioteca si desea compartir una definición de estructura ? Creo que en ese caso puedes usar una biblioteca sin tener que desplegarla y vincularla a los contratos.

Si no desea utilizar bibliotecas, puede crear un contrato abstracto que solo contenga las estructuras y herede de ellas. Es un poco feo si los contratos no están muy relacionados.

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);
    }
}
Precisamente porque es feo "abusar" de la herencia de esa manera, es más correcto usar esto desde una biblioteca en una forma de "interfaz de implementos" a través de una biblioteca.

Al menos en las versiones actuales de Solidity (^ 0.5.1), dependiendo de su necesidad, puede omitir la necesidad de una definición de estructura explícita mediante el desempaquetado de tuplas:

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;
    }
}

También puede encontrar útiles esta y estas publicaciones relacionadas.