Gibt es eine Möglichkeit, mehrere Strukturen (oder die Felder davon) in Solidity zurückzugeben, wenn eines der Strukturfelder vom Typ "Bytes" ist?

Ich möchte Strukturschlüssel aus meinem Vertrag zurückgeben, um sie im Frontend anzuzeigen, idealerweise 10 gleichzeitig. Ich verstehe, dass ich, wenn ich keyByOwneröffentlich mache, jeweils einen einzelnen Schlüssel mit dem erstellten Getter zurückgeben kann, aber ich brauche 10 Schlüssel und möchte die Getter-Funktion nicht 10 Mal aufrufen.

Ich habe versucht, den hier beschriebenen Ansatz zu verwenden, um ein Tupel von Arrays zurückzugeben: https://medium.com/coinmonks/solidity-tutorial-returning-structs-from-public-functions-e78e48efb378 Ich denke, das wäre der richtige Weg Fahren Sie fort, außer dass es nicht zu funktionieren scheint, wenn das dataFeld des Schlüssels vom Typ ist bytes(es funktioniert gut, wenn ich type byesin type ändere bytes32), was mir diesen Fehler gibt:

TypeError: This type is only supported in the new experimental ABI encoder. Use "pragma experimental ABIEncoderV2;" to enable the feature.
    returns (uint[], bytes[])
                     ^-----^

Gibt es eine Möglichkeit, mehrere Strukturen (oder die Felder davon) in Solidity zurückzugeben, wenn eines der Strukturfelder vom Typ ist bytes?

Hier meine Funktion:

struct Key {
  uint expirationTimestamp;
  bytes data;
 }

 mapping (address => Key) internal keyByOwner;

 address[] public owners;

  function getKeysByPage(uint _startIndex)
    external
    view
    returns (uint[], bytes[])
  {
    require(outstandingKeys() > 0, "No keys to retrieve");
    require(_startIndex >= 0 && _startIndex < outstandingKeys(), "Index must be in-bounds");
    uint endOfPageIndex;

    if (_startIndex + 9 > owners.length) {
      endOfPageIndex = owners.length - 1;
    } else {
      endOfPageIndex = _startIndex + 9;
    }

    address[] memory ownersByPage = new address[](10);
    uint[] memory timestampsArray = new uint[](10);
    bytes[] memory keyDataArray = new bytes[](10);
    Key memory tempKey;
    uint pageIndex = 0;

    // Build the specified set of owners into a new temporary array
    for (uint256 i = _startIndex; i <= endOfPageIndex; i++) {
      ownersByPage[pageIndex] = owners[i];
      pageIndex++;
    }

    // Loop through ownersByPage & build the requested keys into 2 new temporary arrays
    for (uint256 n = 0; n < ownersByPage.length; n++) {
      tempKey = keyByOwner[ownersByPage[n]];
      timestampsArray[n] = tempKey.expirationTimestamp;
      keyDataArray[n] = tempKey.data;
    }

    return(timestampsArray, keyDataArray);
  }

Antworten (1)

Die Rückgabe von Structs und Tupeln von Structs ist mit der aktuellen ABI nicht möglich. Wenn Sie jedoch pragma experimental ABIEncoderV2direkt nach Ihrer pragma solidityZeile hinzufügen, wird es problemlos kompiliert. Leider wird es nicht empfohlen, mit einer experimentellen Funktion in die Produktion zu gehen, daher besteht die einzige praktikable Alternative jetzt darin, die primitiven Typen jeder Struktur nacheinander zurückzugeben.

Speziell für Ihr Szenario müssen Sie vorübergehend einen kompatiblen Typ verwenden. Beispielsweise könnten Sie Ihr dynamisches Byte-Array in bytes32 konvertieren .

Danke Paul. Mir war bewusst, dass es mit dem Header funktioniert pragma experimental ABIEncoderV2, aber wie gesagt, nicht gut genug für die Produktion. Ich kann Tupel von Arrays zurückgeben, aber es scheint nicht zu funktionieren, wenn eines der Arrays im Tupel vom Typ bytesoder vom Typ ist string, wahrscheinlich weil beide dynamische Arrays sind. Können Sie näher darauf eingehen, "dass die einzig praktikable Alternative jetzt darin besteht, die primitiven Typen jeder Struktur in einer Reihe zurückzugeben."?
Oh Entschuldigung, ich bezog mich allgemein auf Strukturen. Ich habe die Antwort aktualisiert.
Also ja, leider ist das das einzige, was Sie im Moment tun können.
Keine Sorge, das war meine ursprüngliche Frage. In meinem Beispiel habe ich die Felder von 10 Strukturen genommen und sie in 2 neue Arrays neu zusammengesetzt, eines für jedes der Felder. Ich hatte gehofft, dass Solidity 0.5 dies vielleicht lösen würde, aber jetzt werde ich mir den Link ansehen, den Sie zum Konvertieren dynamischer Byte-Arrays in Bytes32 gepostet haben.