Wie können Sie eine Strukturdefinition zwischen Verträgen in separaten Dateien teilen?

Ich kann eine eigenständige Struktur nicht in einer eigenen Datei deklarieren, was gibt das?

Antworten (3)

Mit einer Bibliothek ist das möglich! Hier ist ein Beispiel:

pragma solidity ^0.4.17;

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

contract A {
    SharedStructs.Thing thing;
}

contract B {
    SharedStructs.Thing thing;
}

Zwei wichtige Dinge, die Sie beachten sollten: 1) Die Bibliothek wird in der Kette bereitgestellt und dann über ihre Adresse referenziert, und 2) Die Bibliothek fungiert als echter Pass-Through, was bedeutet, dass msg.sender (und zugehörige Werte) auf die verweisen ursprünglicher Anrufer.

Weitere Informationen und Details hier: http://solidity.readthedocs.io/en/develop/contracts.html#libraries

Sind Sie sicher, dass die Bibliothek bereitgestellt werden muss, wenn Sie eine Strukturdefinition freigeben möchten ? Ich denke, dass Sie in diesem Fall eine Bibliothek verwenden können, ohne sie bereitstellen und mit den Verträgen verknüpfen zu müssen.

Wenn Sie keine Bibliotheken verwenden möchten, können Sie einen abstrakten Vertrag erstellen, der nur die Strukturen enthält, von denen Sie erben. Es ist irgendwie hässlich, wenn die Verträge nicht ganz zusammenhängen.

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);
    }
}
Gerade weil es hässlich ist, die Vererbung auf diese Weise zu „missbrauchen“, ist es richtiger, dies aus einer Bibliothek in einer Art „Implementierungsschnittstelle“ über eine Bibliothek zu verwenden.

Zumindest in aktuellen Solidity-Versionen (^0.5.1) könnten Sie je nach Bedarf die Notwendigkeit der expliziten Struct-Definition durch Tupel-Entpacken umgehen:

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

Möglicherweise finden Sie auch diesen und diesen verwandten Beitrag hilfreich.