Solidity-Funktion, um eine Datenstruktur zurückzugeben

Wenn Sie versuchen, eine Struktur mit Solidity wie folgt zurückzugeben:

function getAssetStructById(uint256 assetId) constant returns (asst _asset) {
    return (assetsById[assetId]);
}

Dies ist der Kompilierungsfehler, der ausgelöst wird:

Error: Internal type is not allowed for public or external functions.

Wie kann ich also die Daten der Struktur zurückgeben? Ich habe versucht, jedes Feld der Struktur zurückzugeben, aber das funktioniert nicht mehr, sobald Sie 9 Datenfelder erreichen und den Fehler erhalten:

'Stack too deep' compiler error.

Ref.: Gibt es eine Begrenzung für die Anzahl der Rückgabewerte von Solidity-Funktionen?

Dies ist die Struktur, die die Funktion zurückgeben soll:

struct asst {
    uint256 assetId;
    uint256 next;
    uint256 prev;
    uint256 timestampCreation;
    address assetOwner;
    address issuer;
    string content;
    uint256 sellPrice;
    assetState state;
}

Irgendeine Idee, wie man das auf Solidity macht? Danke!

Ref.: Gibt eine Struktur aus einem Solidity Contract zurück

Antworten (3)

Aktualisieren:

Siehe hier. Wir können Strukturen zurückgeben, aber nur für interne Aufrufe.

Zurückgeben von Strukturen in der neuen Version in Solidity

In diesem Codeausschnitt wird function tryIt()nach erfolgreicher Kompilierung „true“ zurückgegeben. Es wird nur ein interner Anruf getätigt (Erfolg). getAssetStructById()schlägt fehl, wenn von außen angerufen wird.

pragma solidity 0.4.17;

contract Test {

    enum assetState{something}

    mapping(uint256 => asst) assetsById;

    struct asst {
        uint256 assetId;
        uint256 next;
        uint256 prev;
        uint256 timestampCreation;
        address assetOwner;
        address issuer;
        string content;
        uint256 sellPrice;
        assetState state;
    }

    function getAssetStructById(uint256 assetId) public view returns (asst _asset) {
        return (assetsById[assetId]);
    }

    function tryIt(uint id) public view returns(bool success) {
        asst memory a = getAssetStructById(id); 
        return true;
    }
}

Ich hoffe es hilft.

Das ist nicht mehr ganz korrekt. Können Sie Ihre Antwort aktualisieren, um widerzuspiegeln, dass ab Solidity Version 0.4.17 Strukturen zurückgegeben werden können, jedoch nur von internen Funktionen ?

Sie können derzeit keine Strukturen in Soldity zurückgeben, da die Antwort auf die von Ihnen verknüpfte Frage korrekt umreißt. Aber Sie können Ihre Struktur auseinandernehmen und die einzelnen Elemente zurückgeben (Solidity unterstützt mehrere Rückgabewerte):

function getAssetStructById(uint256 assetId) constant returns (
uint256 assetId,
uint256 next,
uint256 prev,
uint256 timestampCreation,
address assetOwner,
address issuer,
string content,
uint256 sellPrice,
assetState state
) {
    return (assetsById[assetId].assetId, /*add other fields here*/);
}

Wir sind derzeit in der Anzahl der gesamten lokalen Variablen, Parameter und Rückgabewerte begrenzt. Das können Sie nur teilweise durch eine Umstrukturierung umgehen. Oftmals führt dies zu der Frage: Braucht man wirklich all diese Daten auf der Blockchain? Es kann ausreichen, zB einen Hash eines größeren Datensatzes zu speichern. Bedenken Sie auch, dass jeder Anruf ziemlich viel Benzin kostet, wenn Sie eine Menge Parameter übergeben.

hatte vor über einem Jahr das gleiche Problem. Musste tun, was diese Antwort bespricht. Eine andere Möglichkeit ist die Protokollierung über Ereignisse, um Unit-Tests zu schreiben. (z. B. um den Zustand einer Reihe von Zählern nach jeder Transaktion zu überprüfen). Das ist weniger Gas und ich scheine in der Lage zu sein, ein paar mehr Elemente als Argumente in ein Ereignis zu bekommen als als Rückgabewert (möglicherweise wegen des Optimierers).

.Sie können eine Struktur nicht in Solidität zurückgeben, Sie können sie nur innerhalb Ihres Vertrags verwenden, sie ist nützlich in Karten und einigen Strukturierungen, Sie können eine N-tole-ähnliche zurückgeben

zum Beispiel,

 struct Student {
         string name,
        string something}
  Student o = Student("Naruto","Uzumaki",...);

.... dann

 return (o.name,o.ninpo,..);
Dies ist die gleiche wie die erste Antwort oben ...