¿Cómo representarías esta estructura de datos?

He codificado un contrato inteligente que permite almacenar un cierto tipo de estructura de datos que se puede describir como algo así:

├── Client1(Contract)
│   ├── Year2018 (Struct containing string,uint and struct)
│   │   ├── Case 1 (Struct containing string)
│   │   └── Case 2 (Struct containing string)
│   └── Year2017
│       └── Case 1 (Struct containing string)
├── Client 2
│   └── Year2018
│          ├──Case1 (Struct containing string)
│          └──Case2 (You got it)

Logré llenarlo correctamente y analizarlo también (pero solo un caso INDIVIDUALMENTE). Me gustaría poder tener una función que devuelva todos los datos de forma organizada (como una matriz multidimensional o un JSON, por ejemplo). ¿Qué debo usar? ¿Es posible almacenar todos estos valores en una matriz de bytes?

¡Gracias por tus ideas y que tengas un buen día!

EDITAR:

¿Debería probar algo como esto?

function massImport(bytes[] _datas)  view external onlyOwner(){
        for(uint i = 0;i<_datas.length;i++){
            addYear(bytes(_datas[i]));
            for(uint j = 0; j<_datas[i].length;j++){
                addCase(bytes(_datas[i][j]));
            }
        }
    }

Escribí la función bytes()porque asumo que los bytes son la única matriz posible en este caso.

EDIT 2: Aquí está la estructura 'AÑO'

struct Year{ 
    string entryName; 
    string entryYear; 
    uint permissionType; 
    Elem elem; 
    uint[] elemList; 
    mapping(uint => Elem) allElem; 
    uint elemId; 
}

¿Crees que es demasiado pesado para almacenarlo completamente en la cadena de bloques?

Aparte de lo que necesita el usuario/servidor/aplicación/cliente, ¿qué necesidad de datos de año tiene la lógica del contrato?

Respuestas (2)

Es posible que se quede sin gasolina al tener esos bucles for anidados. ¿Qué hay de tener un mapeo de uint a string y usarlo para almacenar un hash de la información para cada año? Luego, podría almacenar sus estructuras en una base de datos centralizada y usar la cadena de bloques para fines de validación.

La idea detrás de esto es que para aprovechar la inmutabilidad de la cadena de bloques, no es necesario almacenar todo el contenido, sino solo un hash del contenido. Luego puede usar ese hash como prueba de que la información que tiene fuera de la cadena no cambió (porque si lo hiciera, su hash sería diferente al de la cadena). Muchos proyectos hacen esto, por ejemplo, https://www.po.et : no es factible almacenar un libro completo en la cadena de bloques, pero si lo hash y almacenas el hash, eso es suficiente para probar que en ese momento en el que tenías un libro con ese texto exacto.

Si desea almacenar todo en el contrato, no intentaría devolver una estructura compleja como esa directamente del contrato. En cambio, escribiría esa lógica en Javascript y llamaría al contrato varias veces para devolver la información para cada par de año y número de caso (o tal vez solo año).

Gracias por su respuesta, realmente no entiendo cómo puedo almacenar estas estructuras en una base de datos centralizada y luego usar la cadena de bloques para ser honesto.
@LucasLareginie Acabo de editar mi respuesta y agregué una explicación. Avísame si no está claro :)
Muchas gracias, tienes razón, no podré almacenar toda esta información... Se me ocurrió la idea de "Hashing" de los datos, pero realmente no entiendo cómo codificaría la estructura... .Y donde lo almacenaría .. Como en una base de datos clásica ?
@LucasLareginie Puede usar el paquete criptográfico para el nodo y hacer algo como esto: crypto.createHash('sha256').update(data, 'utf8').digest('base64'). Exacto, puedes usar cualquier base de datos clásica.

Una buena regla general al almacenar cosas en Solidity es "¿necesito operar con estos datos en la cadena?" Si no es necesario, entonces probablemente no necesite almacenarlo. Si solo está publicando estas cosas en la cadena de bloques para leerlas más tarde, puede hacer que un evento registre los datos y obtenerlos más tarde de esa manera, lo que es mucho más económico que almacenarlos todos.

También puede usar pragma experimental ABIEncoderV2;para proporcionar estructuras a una función para que la massImportfunción sea mucho más fácil de ver. Sin embargo, tenga en cuenta que la compatibilidad con ABIEncoderv2 todavía está en progreso para algunas bibliotecas (aunque el Web3.js más nuevo tiene una compatibilidad bastante buena).

¡Muchas gracias, echaré un vistazo a ABIEncoderv2 :)! Pero realmente no entiendo el concepto de "registrar los datos y obtenerlos más tarde de esa manera", ¿tiene algún ejemplo en mente o un enlace a la parte asociada en el documento? Gracias !
¡Ningún problema! Puede leer sobre cómo registrar/obtener eventos aquí solidity.readthedocs.io/en/v0.4.21/contracts.html#events . Es mucho más eficiente usar eventos si no necesita leer los datos del contrato más adelante.