Este tipo solo es compatible con el nuevo codificador ABI experimental. ¿Por qué?

Tengo la siguiente estructura y el contrato almacena una matriz:

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

También tengo una función que devuelve Emisor por su índice en la matriz:

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

Yo uso solidez 0.4.21. VS Code resalta el color rojo Issuercomo tipo de devolución en la función y muestra el error:

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

No puedo entender por qué ese tipo no es compatible como tipo de retorno. ¿Algunas ideas?

Respuestas (1)

La ABI estándar no admite estructuras. Puede devolver los miembros de una estructura en una interfaz normalmente delimitada de longitud fija. Por ejemplo:

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

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

La idea de devolver el objeto struct es experimental, por ejemplo

return(myStruct[key]);

Además, su fragmento no incluye todo, pero sospecho que issuerIndexes una lista de claves, no el objeto real. Su interfaz dice que devuelve el objeto (la función experimental), pero posiblemente lo que quiso decir fue returns(bytes32 key)cuál estaría bien.

Espero eso ayude.

ACTUALIZAR

Según el comentario a continuación, el problema es que el valor de retorno se convierte como tipo "Emisor", que sería el objeto de estructura experimental. Debe ser emitido como dirección de tipo.

Para devolver la dirección del Emisor del mapeo:

returns(address issuer) { ...

return issuersIndex[index];

issuerIndexes un índice de direcciones; issuerses un mapa de direcciones a Issuerobjetos. Por lo tanto, para obtener un Emisor por índice, primero obtengo la dirección del Emisor issuerIndexy luego la real Issuerdel issuersmapa. Lo hago porque a veces necesito obtener el Emisor por índice y, a veces, por dirección, por lo que debo mantener ambos. ¡Gracias por su explicación!
Actualice ^ para mayor claridad.