Zurückgeben von Strukturen und Listen in Solidity

Gibt es einen bestimmten Grund, warum Solidity Sie daran hindert, Strukturen, Listen und andere Datenstrukturen zurückzugeben? Ich verstehe, dass es sicher sein muss und das Zulassen des Array-/Listenzugriffs die Daten durcheinander bringen kann, aber warum nicht einmal Strukturen? Ich versuche, einen Vertrag abzuschließen, der eine Liste von Unfällen aus einer Blockchain von Unfallaufzeichnungen an ein bestimmtes Nummernschild (das eines der Felder in einer Struktur ist) zurückgibt, aber ich habe es nur geschafft, es zu erreichen gibt einen Datensatz zurück, und zwar auch durch seine einzelnen Felder. Es scheint mir nur sehr ineffizient zu sein..

Beachten Sie, dass ich zuerst versucht habe, string[] zurückzugeben, es aber in bytes[] ändern musste, da Solidity dies auch nicht zulässt.

/*
To get a list of incidents from a startID 
*/
function listIncidents(uint _startID, uint _count) constant returns(uint[10] _incIDs, bytes[10] _names, bytes[10] _descriptions, bytes[10] _places, bytes[10] _times, bytes[10] _dates) {

  uint maxIters = _count;
  if((_startID + _count) > getIncidentCount()) {
  maxIters = getIncidentCount() - _startID;
  }

  _incIDs = new uint[](maxIters);
  _names = new bytes[](maxIters);
  _descriptions = new bytes[](maxIters);
  _places = new bytes[](maxIters);
  _times = new bytes[](maxIters);
  _dates = new bytes[](maxIters);

  for(uint i=0;i<maxIters;i++) {
    uint _incidentID = _startID + i;

    PoliceRecord memory r = incidents[_incidentID];
    _incIDs[i] = _incidentID;
    _names[i] = bytes(r.incName);
    _descriptions[i] = bytes(r.incDescription);
    _places[i] = bytes(r.incPlace);
    _times[i] = bytes(r.incTime);
    _dates[i] = bytes(r.incDate);
   }
}

Antworten (1)

Sie können Arrays zurückgeben. Was Sie nicht tun können, ist Arrays von Arrays zurückzugeben , einschließlich string[]oder bytes[](weil ein stringoder bytesbereits ein Array ist).

Der Grund ist nur eine Einschränkung des ABI (Application Binary Interface). Wenn Sie dies versuchen, sollten Sie eine Warnung des Compilers sehen, die besagt:

Dieser Typ wird nur im neuen experimentellen ABI-Encoder unterstützt. Verwenden Sie "Pragma Experimental ABIEncoderV2;" um die Funktion zu aktivieren.

Wenn Sie damit durchkommen, Ihre Saiten auf Länge 32 zu begrenzen, könnten Sie bytes32stattdessen verwenden. Dieser Code funktioniert gut:

Pragma Solidität ^0.4.24;

contract Test {
    function test() public pure returns (bytes32[]) {
        bytes32[] memory foo = new bytes32[](2);
        foo[0] = "hello";
        foo[1] = "goodbye";

        return foo;
    }
}
Danke für die Antwort. Ich verstehe, dass Strings ein Array von Arrays sind, aber das ist im Grunde ein 2D-Array, und die meisten Sprachen unterstützen es, also gibt es einen bestimmten Grund, warum sie die Rückgabe von 2D-Arrays nicht zulassen würden? Wie würden Sie dieses Problem umgehen, mehrere Datensätze in einem Funktionsaufruf zurückzugeben, wenn beispielsweise nicht alle Felder in 32 Bytes passen? Danke.
Wie gesagt, es ist nur eine Einschränkung der aktuellen ABI-Spezifikation. (Es unterstützt einfach keine verschachtelten Arrays/Strukturen.) Es ist ein Designfehler, der vermutlich behoben wird, aber ich habe keine bestimmte ETA gesehen. Sie können den experimentellen v2-Encoder aktivieren, aber seien Sie gewarnt, dass er noch nicht fertiggestellt ist und daher noch nicht für die Verwendung in der Produktion empfohlen wird.
Ich habe eine verwandte Frage, könnten Sie bitte einen Blick darauf werfen? ethereum.stackexchange.com/q/118348/86303