No puedo declarar una estructura independiente en su propio archivo, ¿qué ocurre?
¡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
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);
}
}
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.
Franco Victorio