Función de solidez para devolver una estructura de datos.

Al intentar devolver una estructura con Solidity como esta:

function getAssetStructById(uint256 assetId) constant returns (asst _asset) {
    return (assetsById[assetId]);
}

Este es el error de compilación que arroja:

Error: Internal type is not allowed for public or external functions.

Entonces, ¿cómo puedo recuperar los datos de la estructura? Intenté devolver todos los campos de la estructura, pero esto ya no funciona una vez que llega a 9 campos de datos, obteniendo el error:

'Stack too deep' compiler error.

Ref.: ¿Existe alguna limitación para el número de valores de retorno de las funciones de Solidity?

Esta es la estructura que me gustaría que devolviera la función:

struct asst {
    uint256 assetId;
    uint256 next;
    uint256 prev;
    uint256 timestampCreation;
    address assetOwner;
    address issuer;
    string content;
    uint256 sellPrice;
    assetState state;
}

¿Alguna idea de cómo hacer eso en Solidity? ¡Gracias!

Ref.: Devolver una estructura de un Contrato de Solidez

Respuestas (3)

Actualizar:

Mira aquí. Podemos devolver estructuras pero solo para llamadas internas.

Devolución de estructuras en nueva versión en Solidity

En este fragmento, function tryIt()devuelve verdadero después de una compilación exitosa. Solo está haciendo una llamada interna (éxito). getAssetStructById()falla cuando se llama desde el exterior.

pragma solidity 0.4.17;

contract Test {

    enum assetState{something}

    mapping(uint256 => asst) assetsById;

    struct asst {
        uint256 assetId;
        uint256 next;
        uint256 prev;
        uint256 timestampCreation;
        address assetOwner;
        address issuer;
        string content;
        uint256 sellPrice;
        assetState state;
    }

    function getAssetStructById(uint256 assetId) public view returns (asst _asset) {
        return (assetsById[assetId]);
    }

    function tryIt(uint id) public view returns(bool success) {
        asst memory a = getAssetStructById(id); 
        return true;
    }
}

Espero eso ayude.

Esto ya no es del todo exacto. ¿Puede actualizar su respuesta para reflejar que a partir de la versión 0.4.17 de Solidity, las estructuras pueden devolverse, pero solo mediante funciones internas ?

Actualmente no puede devolver estructuras en Soldity como la respuesta a la pregunta que vinculó correctamente. Pero puede desarmar su estructura y devolver los elementos individuales (Solidity admite múltiples valores de retorno):

function getAssetStructById(uint256 assetId) constant returns (
uint256 assetId,
uint256 next,
uint256 prev,
uint256 timestampCreation,
address assetOwner,
address issuer,
string content,
uint256 sellPrice,
assetState state
) {
    return (assetsById[assetId].assetId, /*add other fields here*/);
}

Actualmente estamos limitados en el número de variables locales totales, parámetros y valores devueltos. Solo puede eludir eso parcialmente mediante la reestructuración. Más a menudo que eso, lleva a la pregunta: ¿realmente necesita todos esos datos en la cadena de bloques? Almacenar, por ejemplo, un hash de un conjunto de datos más grande podría ser suficiente. También considere que cada llamada cuesta bastante gasolina si pasa una tonelada de parámetros.

Tuve el mismo problema hace más de un año. Tenía que hacer lo que se discute en esta respuesta. Otra posibilidad es el registro a través de eventos, con el fin de escribir pruebas unitarias. (por ejemplo, para comprobar el estado de un montón de contadores después de cada transacción). Eso es menos gas y parece que puedo obtener algunos elementos más en un evento como argumentos que como valor de retorno (posiblemente debido al optimizador)

.No puede devolver una estructura en solidez, puede usarla solo dentro de su contrato, es útil en mapas y algunas estructuraciones, puede devolver una tupla como

por ejemplo,

 struct Student {
         string name,
        string something}
  Student o = Student("Naruto","Uzumaki",...);

.... después

 return (o.name,o.ninpo,..);
esto es lo mismo que la primera respuesta anterior ...