Establecer una estructura una vez causa un error al compilar: pila demasiado profunda

Vea mi contrato inteligente a continuación:

contract Test {

    struct MyBool {
        bool initialized; // /!\ if false then 'NA' else fetch value's property
        bool value;
    }

    struct Patient {
        uint8 age;
        uint8 bp;
        uint8 sg;
        int8 al;
        int8 su;
        MyBool rbc;
        MyBool pc;
        MyBool pcc;
        MyBool ba;
        uint16 bgr;
        uint8 bu;
        uint8 sc;
        uint16 sod;
        uint8 pot;
        uint8 hemo;
        uint8 pcv;
        uint8 wc;
        uint8 rc;
        MyBool htn;
        MyBool dm;
        MyBool cad;
        MyBool appet;
        MyBool pe;
        MyBool ane;
    }

    uint nextPatientId;
    mapping (uint256 => Patient) private patients;

    function Test() {
        // age, bp, sg, al, su, rbc, pc, pcc, ba, bgr, bu, sod
        addPatient(4, 0, 20, 1, 0, -1, 1, 0, 0, 99, 23, 145);
    }

    function setMyBool(int8 value) private returns (bool initialized, bool newValue) {
        if (value < -1  || value > 1) {
            throw;
        }
        // if different than 'NA'
        if (-1 != value) {
            initialized = true;
            newValue = (value==1) ? true : false;
        }
    }

    function getMyBool(MyBool patientField) private returns (int8) {
        if (patientField.initialized == true) {
            return (int8)((patientField.value) ? 1 : 0); 
        } else {
            return 127;
        }
    }

    function getNextPatientId() constant returns (uint) {
        return nextPatientId;
    }

    function addPatient(uint8 age, uint8 bp, uint8 sg, int8 al, int8 su,
                        int8 rbc, int8 pc, int8 pcc, int8 ba,
                        uint16 bgr, uint8 bu, uint16 sod) returns (uint id) {
        var patient = patients[nextPatientId];

        patient.age = age; patient.bp = bp; patient.sg = sg; patient.al = al; patient.su = su;
        (patient.rbc.initialized, patient.rbc.value) = setMyBool(rbc);
        (patient.pc.initialized, patient.pc.value) = setMyBool(pc);
        (patient.pcc.initialized, patient.pcc.value) = setMyBool(pcc);
        (patient.ba.initialized, patient.ba.value) = setMyBool(ba);
        patient.bgr = bgr; patient.bu = bu; patient.sod = sod;

        nextPatientId++;
        id = nextPatientId;
    }

    function getMyPatient(uint id) constant returns (uint8 age, uint8 bp, uint8 sg, int8 al, int8 su,
                        int8 rbc, int8 pc, int8 pcc, int8 ba,
                        uint16 bgr, uint8 bu, uint16 sod) {
        age = patients[id].age; bp = patients[id].bp; sg = patients[id].sg; al = patients[id].al; su = patients[id].su;
        rbc = getMyBool(patients[id].rbc); pc = getMyBool(patients[id].pc); pcc = getMyBool(patients[id].pcc); ba = getMyBool(patients[id].ba);
        bgr = patients[id].bgr; bu = patients[id].bu; sod = patients[id].sod;
    }

}

Leí aquí y allá que los parámetros de una función no pueden exceder una cantidad específica constante debido al comportamiento de "pila".

Como puede ver, mi estructura es bastante grande y quería tener un getter y un setter de esto.

No es posible devolver una estructura, pero recuperar todo el valor de una estructura llamando a varios métodos está bien para mí. Simplemente no quiero este comportamiento al configurar uno.

Hay una solución para esto ? Pensé en tener una matriz constante como parámetros para disminuir la cantidad de variables, pero no estoy seguro de que sea una forma adecuada.

EDITAR El código anterior funciona porque solo conservo la mayor cantidad posible de parámetros que el compilador me permite tener, pero lo que realmente quiero es un configurador completo de mi estructura como la siguiente, por ejemplo (que no funciona)

function addPatient(uint8 age, uint8 bp, uint8 sg, int8 al, int8 su,
            int8 rbc, int8 pc, int8 pcc, int8 ba,
            uint16 bgr, uint8 bu, uint16 sod, 
            uint8 pot, uint8 hemo, uint8 pcv, uint8 wc, uint8 rc,
            int8 htn, int8 dm, int8 cad, int8 appet, int8 pe, int8 ane) returns (uint id) {
    var patient = patients[nextPatientId];

    patient.age = age; patient.bp = bp; patient.sg = sg; patient.al = al; patient.su = su;
    (patient.rbc.initialized, patient.rbc.value) = setMyBool(rbc);
    (patient.pc.initialized, patient.pc.value) = setMyBool(pc);
    (patient.pcc.initialized, patient.pcc.value) = setMyBool(pcc);
    (patient.ba.initialized, patient.ba.value) = setMyBool(ba);
    patient.bgr = bgr; patient.bu = bu; patient.sod = sod;

    patient.pot = pot; patient.hemo = hemo; patient.pcv = pcv; patient.wc = wc; patient.rc = rc;
    (patient.htn.initialized, patient.htn.value) = setMyBool(htn);
    (patient.dm.initialized, patient.dm.value) = setMyBool(dm);
    (patient.cad.initialized, patient.cad.value) = setMyBool(cad);
    (patient.appet.initialized, patient.appet.value) = setMyBool(appet);
    (patient.pe.initialized, patient.pe.value) = setMyBool(pe);
    (patient.ane.initialized, patient.ane.value) = setMyBool(ane);


    nextPatientId++;
    id = nextPatientId;
}
Este contrato compilado y ejecutado en la solidez del navegador. Pude agregar un paciente pasado 24x1... 1,1,1,1,1,1... Los detalles sobre cómo está compilando e implementando, los pasos para reproducir el error pueden ayudar a identificar el problema.
También ejecuto esto en la solidez del navegador. Lamento no haber sido claro, pero de hecho el contrato funciona, pero funciona solo porque mantengo la firma de addPatient en solo unos pocos parámetros en lugar de lo que acabo de editar aquí.
El almacenamiento de datos es bastante complicado y están sucediendo muchas cosas aquí que me hacen decir "hmmm..." La solución que está considerando parece un enfoque válido para el problema inmediato. Ejemplo: función testIO(uint8[24] datospaciente) devuelve(bool éxito) {}
Bueno, lo haré por el momento como una solución rápida, gracias.

Respuestas (1)

Después de probar el otro enfoque que consiste en usar una matriz estática donde cada valor de índice representa una variable previamente relacionada con una variable de mi estructura 'Paciente', puedo confirmar que funciona muy bien y también hace que el código sea más claro (para leer al menos) .

Lo único que recomiendo es tener un documento adecuado que explique su matriz de esta manera:

/* uint16[25] kidneyData;
 *
 * -------------------------------------------------------------------------------------------------------------------------------------------------
 * |                   DECIMAL VALUE                     |      FLOAT VALUE     |               NOMINAL VALUE                             | RESULT |
 * -------------------------------------------------------------------------------------------------------------------------------------------------
 * |  0  | 1  | 2  | 3  | 4  | 5   | 6  | 7   | 8   | 9  | 10 | 11 | 12  | 13   | 14  | 15 | 16  | 17 | 18  | 19 | 20  | 21    | 22 | 23  |   24   |
 * | age | bp | sg | al | su | bgr | bu | sod | pcv | wc | rc | sc | pot | hemo | rbc | pc | pcc | ba | htn | dm | cad | appet | pe | ane |   res  |
 * -------------------------------------------------------------------------------------------------------------------------------------------------
 *
 * EXEMPLE :
 *                   | age | bp | sg | al | su | bgr | bu | sod | pcv | wc | rc | sc | pot | hemo | rbc | pc | pcc | ba | htn | dm | cad | appet | pe | ane |
 * caduceus.addPatient([60,  80,  25,   0,   0,   131,  10, 146,  41, 10700, 510, 50,  500,  1450,   1,   1,   0,    0,   0,    0,   0,     1,     0,   0]);
 *
 */