Devuelve la estructura dentro de la matriz dentro de la matriz

pragma solidity >= 0.4.25 < 0.6;

contract Bank {
    struct Customer {
        uint age;
    }

    Customer[][] customers;

    function foo() public {
        if (customers.length > 0) {
            Customer[] storage northBranch = customers[0];
            if (northBranch.length > 1) {
                Customer storage customer = northBranch[1];
                customer.age = 23;
            }
        } else {
            Customer memory bob;
            bob.age = 34;
            customers.length += 1;
            customers[0].push(bob);
        }
    }
}

Estoy buscando ejemplos de funciones que devuelven y una matriz cuando se llama a una función. Hay muchos ejemplos, pero no pude encontrar una función que devuelva una matriz con matrices dentro con una estructura dentro.

Intento esto pero no funciona.

function get() external view returns (Customer[][]) {
    /*Customer[][] memory resCustomer;

    for(uint i = 0; i<customers.length;i++) {
        resCustomer[i][] = customers[i][];

    }*/

    return (customers);
}

ERROR:

TypeError: este tipo solo se admite en el nuevo codificador ABI experimental. Utilice "pragma experimental ABIEncoderV2;" para habilitar la función.

¿Alguna idea sobre cómo puedo viajar a través de la matriz principal para obtener una matriz interna y la estructura que está dentro?

En primer lugar, no funciona porque en la declaración de la función debe poner returns (Customers[][]), not returns (customers[][]). En segundo lugar, apuesto a que simplemente puede devolver su customerstabla, en lugar de replicarla primero (es decir, dentro de la función, simplemente haga return customers;).
Cambio el retorno y comento la replicación del arreglo. Pero aparece esto. imgur.com/a/Q4sb6A1
Pegue el error como texto (no como un enlace dudoso ni como una imagen) en su pregunta (no en la sección de comentarios).

Respuestas (2)

Como dice el error, la devolución de matrices dinámicas multidimensionales solo se admite como una función experimental utilizando ABIEncoderV2 (consulte la documentación de Solidity ).

Agregue la siguiente línea en la parte superior de su contrato:

pragma experimental ABIEncoderV2;

Su contrato completo será entonces:

pragma solidity >= 0.4.25 < 0.6;
pragma experimental ABIEncoderV2;

contract Bank {
    struct Customer {
        uint age;
    }

    Customer[][] customers;

    function foo() public {
        if (customers.length > 0) {
            Customer[] storage northBranch = customers[0];
            if (northBranch.length > 1) {
                Customer storage customer = northBranch[1];
                customer.age = 23;
            }
        } else {
            Customer memory bob;
            bob.age = 34;
            customers.length += 1;
            customers[0].push(bob);
        }
    }

    function get() external view returns (Customer[][] memory) {
        return (customers);
    }
}

Asegúrese de usar Web3.js v1.0.0-beta.36 para hacer uso de esta funcionalidad, ya que la decodificación completa de matrices dinámicas multidimensionales solo se agregó a partir de esa versión (consulte web3.js#1148 ). Sin embargo, todavía no hay una garantía sólida de que funcione como se espera, ya que es una característica experimental.

Esta es una característica experimental, por lo que no se recomienda usar algo como esto en entornos de producción. Tal vez podría volver a evaluar si realmente necesita almacenar sus datos en una estructura de este tipo, o si también es posible algo más simple.

Dado que aún no se admite la devolución de una matriz dinámica doble (como cadena [] o bytes []) o una matriz de estructura a menos que no agregue la línea pragma experimental ABIEncoderV2;en la parte superior de su código, como respondió Rosco, lo que puede hacer en su get()función es devolver múltiples valores (que son compatibles con solidity ) al desenvolver su estructura.

Por ejemplo, tienes estructura

Customer {
    uint age;
    address id;
    bytes32 name;
}

y estado

Customer[] customers;

puede escribir la función get() de la siguiente manera:

function get() external view returns (uint[] memory ages, uint[] memory ids, bytes32[] names) {

    ages = new uint[](customers.length);
    ids = new address[](customers.length);
    names = new bytes32[](customers.length);

    for(uint i = 0; i<customers.length;i++) {
        ages[i] = customers[i].age;
        ids[i] = customers[i].id;
        names[i] = customers[i].name;
    }
}

Dado que tiene Customer[][], intente encontrar una forma inteligente de desenvolver esta estructura para sus necesidades.

¡¡Espero eso ayude!!