So zeigen Sie Strukturen mit Trüffel an

In meinem Vertrag habe ich so ein Mappingmapping(uint => myStruct)

Ich habe eine checkFunktion, wo ich eine gebe und ich möchte alle Informationen in der Struktur (es gibt Strings, Adressen, uints, ...) mit einer Funktion in meinem truffle uint iderhalten .callapp.js

Was ist der beste Weg, das zu tun? Kann ich jedes Feld in eine Zeichenfolge konvertieren und ein Array von Zeichenfolgen senden? Sollte ich für jedes Feld einen separaten Getter erstellen und so viele Funktionen verwenden call?

Im Moment gebe ich nur struct zurück und ich bekommeinvalid solidity type!: tuple

Sie können keine Struktur in Solidität zurückgeben, zumindest nicht für die aktuelle Version. Sie müssen also jeden Wert einzeln zurückgeben. etwas wie:return ( struct.member1,struct.member2)
Bitte beachten Sie, dass an Solidity gearbeitet wird, um die Serialisierung komplexer Typen zu unterstützen blog.ricmoo.com/…
@MedMansour Sie können jeden Wert separat in einer einzigen Rückgabe zurückgeben? Das ändert alles, wenn js damit umgehen kann!

Antworten (4)

Sie benötigen keine zusätzliche Solidity-Funktion, um die Informationen aus einer Struktur zu erhalten. Sie können die Struktur direkt mit web3 aufrufen.

Es ist hilfreich, wenn Sie eine Funktion im Vertrag haben, um die Anzahl der Token zu erhalten, da Sie sonst möglicherweise mit while anstelle von for stecken bleiben. Nehmen wir an, Sie haben eine Funktion, die Ihnen struct.length gibt

var OwnableList = [];

//to get one struct entry you do this.

function getStructData(tokenId) {

    myContract.Ownables(tokenId, function(error, details) {
        if(details == undefined) {
            return false;
        } else {
            var name = details[0];
            var creator = details[1];
            var currentOwner = details[2];
            var isDestructible = details[3];
            var price = parseInt(details[4]);
            OwnableList.push({name: name, creator: creator, currentOwner: currentOwner, isDestructible: isDestructible, price: price});
    })
    return true;
    }
}

//to get all struct entrys you do this

function dumpStructData() {
    myContract.totalOwnables(function(error, total) {
        for(i=0; i<parseInt(total); i++) {
            getStructData(i);
        }
    }
}

//now you can just read the struct

function showStruct() {
    console.log(JSON.stringify(OwnableList);
}

Anscheinend wurde meine Frage falsch verstanden, aber ich habe das Problem mit Hilfe von Mikko Ohtamaa in den Kommentaren gelöst.

Aus irgendeinem Grund war mir nicht klar, dass ich mehrere Variablen (und von verschiedenen Typen!) Zurückgeben kann. Sobald Sie wissen, dass Sie dies tun können, gibt es wirklich kein Problem. Javascript kommt damit sehr gut zurecht.

Meine Lösung sieht in etwa so aus:

contract myContract {
  struct Ownable {
    string name;
    address creator;
    address currentOwner;
    bool isDestructible;
    uint price;
  }

  mapping (uint => Ownable) public Ownables;

  function getOwnableInfo(uint OwnableId) public view returns (string, address, address, bool, uint){
    Ownable o = Ownables[OwnableId];
    return (o.name, o.creator, o.currentOwner, o.isDestructible, o.price);
  }

  /.../
}

Und in der entsprechenden Trüffel callwird ein Array mit den Variablen der Rückgabe in der angegebenen Reihenfolge zurückgegeben:

myContractInstance.getOwnableInfo.call(ownableId).then((resultArray => {
  name = resultArray[0];
  creator = resultArray[1];
  currentOwner = resultArray[2];
  /.../
});

Anmerkungen:

  • Schauen Sie nicht zu sehr in die Ownable o = Ownables[OwnableId];, ich habe das gemacht, um die Lesbarkeit zu verbessern, ich denke nicht, dass es nützlich oder überhaupt eine gute Sache ist.
  • Wenn eine der Daten eine große Zahl ist (normalerweise ein Wei-Preis), konvertiere ich sie mit bignumber, resultArray[4].toNumber()damit JavaScript damit umgehen kann.

Der beste Weg, um etwas in eine Struktur einzufügen und alle Datensätze zu erhalten, ist:

pragma solidity ^0.4.17;

contract test {
    struct Record {
        string name;
        string homeAddress;
    }

    Record[] public records;

    function AddRecord(string Address , string Name) public {
        Record memory newRec = Record({
            name : Name,
            homeAddress : Address
        });

        records.push(newRec);
    }

    function recordsArrayLength() public view returns(uint256){
        return records.length;
    }

}

und verwenden Sie in Ihrer Benutzeroberfläche diesen Code:

Verwenden Sie zuerst let len = await test.methods.recordsArrayLength().call()das lengthArray of Records und rufen Sie es ab, und drücken Sie dann diesen Code:

let records = []

for(let i=0;i<len;i++){
    records.push(await test.methods.records(i))
}

und jetzt haben Sie alle struct

Anstatt die Struktur zurückzugeben, geben Sie also ein Array mit einer Struktur zurück?
ja das stimmt
Ich bin mir nicht sicher, wie Sie das verstanden haben, aber ich möchte nichts zu einer Struktur hinzufügen , ich möchte nur alle darin enthaltenen Informationen abrufen.

Es ist tangential zu Ihrer Frage, aber eine der besten Möglichkeiten, Daten zu organisieren, ist eine zugeordnete Struktur mit einem Index von Schlüsseln. Dadurch ist es möglich, auf einen bestimmten Datensatz zuzugreifen oder seine Existenz zu überprüfen, ohne zu wissen, in welcher Zeile er sich befindet, und ohne eine Liste durchsuchen zu müssen. Der Index ist eine ungeordnete Liste von Schlüsseln, die es ermöglicht, die Schlüssel zu zählen und die vorhandenen Schlüssel aufzuzählen.

mapping(bytes32 => RecordStruct) public recordStructs;
bytes32 public recordKeys;

Werfen Sie hier einen Blick auf einige Varianten, Implementierungsdetails und Diskussionen über Einschränkungen und Vorteile verschiedener Ansätze.

Gibt es gut gelöste und einfache Speichermuster für Solidity?

Auch, obwohl in den Beispielen nicht gezeigt, können Ereignis-Emitter den Speicherzustand für Software-Clients sichtbar machen. Mit umfassenden Ereignisprotokollen kann man den Vertrag mit der Annahme schreiben, dass Kunden jederzeit über den vollständigen Zustand informiert sind. Dies reduziert Bedenken in der Kette erheblich.

Ich hoffe es hilft.

Was meinst du mit " ohne zu wissen, in welcher Reihe es steht "? Ihre Antwort sieht interessant aus, aber ich bin mir nicht sicher, was Sie erreichen wollen.
Sie mapping(uint => myStruct)haben Strukturen, die nach Nummer gespeichert sind, und die Frage betrifft die Migration zu einem Array (auch nach Nummer). Ich möchte per Schlüssel (z. B. "ORD002" oder "0x123...") abrufen und nicht suchen. Ich möchte auch eine Liste und eine Zählung.
Ich glaube du hast meine Frage falsch verstanden. Ich möchte nicht migrieren, ich habe eine Struktur mit mehreren Daten verschiedener Typen, und ich möchte eine Funktion mit Truffle schreiben, callum all diese Informationen zu erhalten.
Ich habe eine Antwort darüber geschrieben, wie ich mein Problem gelöst habe, vielleicht verstehen Sie besser, was ich meinte.