Gibt die Struktur innerhalb von Array innerhalb von Array zurück

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);
        }
    }
}

Ich suche nach Beispielen für Funktionen, die zurückgeben, und ein Array, wenn eine Funktion aufgerufen wird. Es gibt viele Beispiele, aber ich konnte keine Funktion finden, die ein Array mit Arrays im Inneren mit struct im Inneren zurückgibt.

Ich versuche das, aber es funktioniert nicht.

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

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

    }*/

    return (customers);
}

FEHLER:

TypeError: Dieser Typ wird nur im neuen experimentellen ABI-Encoder unterstützt. Verwenden Sie "Pragma Experimental ABIEncoderV2;" um die Funktion zu aktivieren.

Irgendeine Idee, wie ich über das Hauptarray reisen kann, um ein inneres Array und die darin enthaltene Struktur zu erhalten?

Erstens funktioniert es nicht, weil Sie in der Funktionsdeklaration returns (Customers[][]), nicht setzen sollten returns (customers[][]). Zweitens wette ich, dass Sie Ihre Tabelle einfach zurückgeben können customers, anstatt sie zuerst zu replizieren (dh innerhalb der Funktion einfach do return customers;).
Ich ändere die Rückgabe und kommentiere die Replikation des Arrays. Bu erscheinen diese. imgur.com/a/Q4sb6A1
Bitte fügen Sie den Fehler als Text (kein dubioser Link, kein Bild) in Ihre Frage ein (nicht in den Kommentarbereich).

Antworten (2)

Wie der Fehler sagt, wird die Rückgabe mehrdimensionaler dynamischer Arrays nur als experimentelle Funktion mit ABIEncoderV2 unterstützt (siehe Solidity-Dokumentation ).

Fügen Sie die folgende Zeile oben in Ihrem Vertrag hinzu:

pragma experimental ABIEncoderV2;

Ihr vollständiger Vertrag lautet dann:

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);
    }
}

Stellen Sie sicher, dass Sie Web3.js v1.0.0-beta.36 verwenden, um diese Funktionalität zu nutzen, da die vollständige Dekodierung mehrdimensionaler dynamischer Arrays erst ab dieser Version hinzugefügt wurde (siehe web3.js#1148 ). Es gibt jedoch noch keine feste Garantie dafür, dass es wie erwartet funktioniert, da es sich um eine experimentelle Funktion handelt.

Dies ist eine experimentelle Funktion, daher wird davon abgeraten, so etwas in Produktionsumgebungen zu verwenden. Vielleicht könnten Sie noch einmal überdenken, ob Sie Ihre Daten wirklich in einer solchen Struktur speichern müssen oder ob auch etwas Einfacheres möglich ist.

Da die Rückgabe eines doppelten dynamischen Arrays (z. B. string[] oder bytes[]) oder eines Arrays von Strukturen noch nicht unterstützt wird, es sei denn, Sie fügen die Zeile pragma experimental ABIEncoderV2;oben in Ihrem Code nicht hinzu, wie von Rosco beantwortet, was Sie tun können Ihre get()Funktion besteht darin, mehrere Werte zurückzugeben (die von solidity unterstützt werden ), indem Sie Ihre Struktur entpacken.

Zum Beispiel haben Sie struct

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

und Staat

Customer[] customers;

Sie können die Funktion get() wie folgt schreiben:

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;
    }
}

Da Sie Customer[][] haben, versuchen Sie, diese Struktur auf intelligente Weise für Ihre Bedürfnisse zu entpacken.

Ich hoffe es hilft!!