Dieser Typ wird nur im neuen experimentellen ABI-Encoder unterstützt - warum?

Ich habe die folgende Struktur und der Vertrag speichert ein Array davon:

struct Issuer {
    address id;
    bytes32 name;
    IssuerStatus status;
    uint index; 
}

Ich habe auch eine Funktion, die Issuer anhand ihres Index im Array zurückgibt:

function getIssuerAtIndex(uint index) public view returns (Issuer) {
    return issuers[issuersIndex[index]];   
}

Ich verwende Solidität 0.4.21. VS Code hebt Issuerden Rückgabetyp in der Funktion rot hervor und zeigt den Fehler an:

TypeError: This type is only supported in the new experimental ABI encoder. Use "pragma experimental ABIEncoderV2;" to enable the feature.
function getIssuerAtIndex(uint index) public view returns (Issuer) {
                                                          ^-------^

Ich kann nicht herausfinden, warum dieser Typ nicht als Rückgabetyp unterstützt wird. Irgendwelche Ideen?

Antworten (1)

Die Standard-ABI unterstützt keine Strukturen. Sie können die Mitglieder einer Struktur in einer normal begrenzten Schnittstelle mit fester Länge zurückgeben. Zum Beispiel:

function getter(bytes32 key) public returns(byte32 name, uint amount, bool isValid) :

return(myStruct[key].name, myStruct[key].amount, myStruct[key].isValid);

Die Idee, das Strukturobjekt zurückzugeben, ist experimentell, z

return(myStruct[key]);

Außerdem enthält Ihr Snippet nicht das Ganze, aber ich vermute, dass issuerIndexes sich um eine Liste von Schlüsseln handelt, nicht um das eigentliche Objekt. Ihre Schnittstelle sagt, dass sie das Objekt (die experimentelle Funktion) zurückgibt, aber möglicherweise meinten Sie, returns(bytes32 key)was in Ordnung wäre.

Ich hoffe es hilft.

AKTUALISIEREN

Basierend auf dem Kommentar unten besteht das Problem darin, dass der Rückgabewert als Typ „Issuer“ umgewandelt wird, was das experimentelle Strukturobjekt wäre. Es sollte als Typadresse gecastet werden.

So geben Sie die Adresse des Ausstellers aus der Zuordnung zurück:

returns(address issuer) { ...

return issuersIndex[index];

issuerIndexist ein Verzeichnis von Adressen; issuersist eine Zuordnung von Adressen zu IssuerObjekten. Um also einen Aussteller nach Index zu erhalten, erhalte ich zuerst die Adresse des Ausstellers von issuerIndexund dann die tatsächliche Adresse von Issuerder issuersKarte. Ich mache es, weil ich manchmal den Aussteller nach Index und manchmal nach Adresse abrufen muss, also muss ich beide pflegen. Ich danke Ihnen für Ihre Erklärung!
Aktualisieren Sie ^ für Klarheit.