Vollständige Mappings/Arrays zurückgeben

In einem Vertrag (nur eine Demo) habe ich:

struct Bank {
    string name;
    mapping(address => uint) balances;
}

mapping(address => uint) userIsAtBank;
Bank[] banks;

Jetzt hätte ich gerne eine Funktion, die das Mapping userIsAtBank/ die Array-Banken kopiert, ohne es zu durchlaufen (wie alle Werte in einer Rückgabe) und ein neues Mapping mit denselben Werten setzt. In meinem Beispiel: userIsAtBankNew = userIsAtBank - und: banksNew = banks. Ist das möglich?

Wenn es nicht möglich ist, was ist der beste Weg, um eine Länge von 25.000 zu durchlaufen (wenn zum Beispiel die letzte Bank Banken [25000] ist), ohne dass die Transaktion abgelehnt wird oder zu teuer ist?

Antworten (1)

Sie sind auf dem richtigen Weg, wenn Sie Ihr Denken auf steigende Kosten richten.

Möglicherweise können Sie das Limit mit Effizienzsteigerungen leicht verschieben, aber die einzige Möglichkeit, das Problem zu lösen, besteht darin, den Ansatz zu überdenken, sodass jede Transaktion in O (1) ... einer Operation abgeschlossen wird.

Der vorgeschlagene Ansatz ist nicht sehr Blockchain. Angenommen, Client Alice ruft die Liste mit 25.000 Banken ab. Warum sollte sie es wieder holen? Wenn sie Ereignisprotokolle abhört, wird sie die Banknummer 25.001 kennen, wenn sie hinzugefügt wird. Warum sollte sie fragen?

Sie können einen zweigleisigen Ansatz verwenden.

  1. Keine einzige Operation mit n Iterationen und steigenden Kosten. 25.000 Operationen mit festen Gaskosten - in jeder Größenordnung genau gleich. Holen Sie sie einzeln ab.
  2. Verwenden Sie Ereignisprotokolle, um Clients über alle wichtigen Statusänderungen zu informieren – erstellen, abrufen, aktualisieren, löschen. In der Tat ist das Abhören der Ereignisprotokolle und das Ändern lokaler Tabellen möglicherweise die einzige Client-Seite, die Sie benötigen.

Schauen Sie sich hier Mapped Struct with Index an: Gibt es gut gelöste und einfache Speichermuster für Solidity?

Die Datenstruktur beginnt genau nach Ihrem Muster. Was folgt, sind Funktionen, um mit einzelnen Instanzen gleichzeitig umzugehen. Erklärt mit der Begründung und einem vollständigeren Beispiel hier: https://medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a

Ich hoffe es hilft.

ps Ich sollte erwähnen, dass es nicht möglich ist, die Schlüssel in einem aufzuzählen oder zu zählen mappingoder Zuordnungen in einem Zug weiterzugeben. Sie können dies mit dynamischen Arrays tun, aber es wird nicht vollständig unterstützt und es funktioniert nicht zwischen Verträgen. Eine Zeile nach der anderen vermeidet die Einschränkungen und Skalierungsprobleme.