Этот тип поддерживается только в новом экспериментальном кодировщике ABI. Почему?

У меня есть следующая структура, и контракт хранит ее массив:

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

У меня также есть функция, которая возвращает Issuer по его индексу в массиве:

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

Я использую солидность 0.4.21. VS Code выделяет красным цветом Issuerтип возвращаемого значения в функции и отображает ошибку:

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) {
                                                          ^-------^

Я не могу понять, почему этот тип не поддерживается в качестве возвращаемого типа. Есть идеи?

Ответы (1)

Стандартный ABI не поддерживает структуры. Вы можете возвращать элементы структуры в обычно разделенном интерфейсе фиксированной длины. Например:

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

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

Идея возврата объекта структуры является экспериментальной, например

return(myStruct[key]);

Кроме того, ваш фрагмент не включает все это, но я подозреваю, что issuerIndexэто список ключей, а не фактический объект. Ваш интерфейс говорит, что он возвращает объект (экспериментальную функцию), но, возможно, вы имели в виду, returns(bytes32 key)что все будет в порядке.

Надеюсь, это поможет.

ОБНОВИТЬ

Основываясь на приведенном ниже комментарии, проблема заключается в том, что возвращаемое значение передается как тип «Издатель», который будет экспериментальным объектом структуры. Он должен быть приведен как адрес типа.

Чтобы вернуть адрес эмитента из сопоставления:

returns(address issuer) { ...

return issuersIndex[index];

issuerIndexиндекс адресов; issuersпредставляет собой карту адресов к Issuerобъектам. Таким образом, чтобы получить эмитента по индексу, я сначала получаю адрес эмитента, issuerIndexа затем фактический Issuerиз issuersкарты. Я делаю это, потому что иногда мне нужно получить эмитента по индексу, а иногда по адресу, поэтому я должен поддерживать оба. Спасибо за ваше объяснение!
Обновите ^ для ясности.