Возврат структур и списков в Solidity

Есть ли конкретная причина, по которой Solidity не позволяет вам возвращать структуры, списки и другие структуры данных? Я понимаю, что он должен быть безопасным, и разрешение доступа к массиву/списку может испортить данные, но почему даже не структуры? Я пытаюсь заключить контракт, который возвращает список аварий, произошедших с конкретным номерным знаком (который является одним из полей в структуре) из блокчейна записей об авариях, но мне удалось получить его только вернуть одну запись, это тоже по отдельным полям. Просто мне это кажется очень неэффективным..

Обратите внимание, что сначала я попытался вернуть строку [], но мне пришлось изменить ее на байты [], поскольку Solidity этого тоже не позволяет.

/*
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);
   }
}

Ответы (1)

Вы можете возвращать массивы. Чего вы не можете сделать, так это вернуть массивы массивов , включая string[]or bytes[](потому что stringor bytesуже является массивом).

Причина как раз в ограничении ABI (бинарного интерфейса приложения). Когда вы попытаетесь это сделать, вы должны увидеть предупреждение от компилятора, в котором говорится:

Этот тип поддерживается только в новом экспериментальном кодировщике ABI. Используйте «экспериментальную прагму ABIEncoderV2;» чтобы включить эту функцию.

Если вам сойдет с рук ограничение длины строк до 32, вы можете использовать bytes32вместо этого. Этот код работает нормально:

прочность прагмы ^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;
    }
}
Спасибо за ответ. Я понимаю, что строки представляют собой массив массивов, но в основном это 2D-массив, и большинство языков поддерживают его, поэтому есть ли какая-то особая причина, по которой они не позволяют возвращать 2D-массивы? Кроме того, как бы вы обошли эту проблему возврата нескольких записей в одном вызове функции, если, скажем, все поля не помещаются в 32 байта? Спасибо.
Как я уже сказал, это просто ограничение текущей спецификации ABI. (Он просто не поддерживает вложенные массивы/структуры.) Это недостаток дизайна, который, по-видимому, будет исправлен, но я не видел конкретного ETA. Вы можете включить экспериментальный кодировщик версии 2, но имейте в виду, что он еще не доработан и поэтому пока не рекомендуется использовать его в производстве.
У меня есть связанный с этим вопрос, не могли бы вы взглянуть? эфириум.stackexchange.com/q/118348/86303