Fragen im Zusammenhang mit den Nachwirkungen des Unterbrechens einer iterativen Schleife

Schleifen, die keine feste Anzahl von Iterationen haben, beispielsweise Schleifen, die von Speicherwerten abhängen, müssen mit Vorsicht verwendet werden: Aufgrund des Blockgaslimits können Transaktionen nur eine bestimmte Menge Gas verbrauchen. Entweder explizit oder nur aufgrund des normalen Betriebs kann die Anzahl der Iterationen in einer Schleife über die Blockgasgrenze hinaus anwachsen, was dazu führen kann, dass der gesamte Vertrag an einem bestimmten Punkt ins Stocken gerät.

Was passiert, wenn ein Szenario eintritt, in dem ein Loop über die Blockgasgrenze hinauswächst? insbesondere; wie lange wird der Vertrag ausgesetzt?
Um zu erweitern, wenn nur 50 von 500 (eine Zufallszahl) Werte eines Arrays von der Schleifeniteration betroffen wären, wäre die Funktion, die die Schleife gestartet hat, dann weitere 9 Mal aufrufbar und würde die verbleibenden 450 Werte des Arrays beeinflussen oder würde es nur kontinuierlich nur die ersten 50 von 500 bewirken?
Wie kann man schließlich richtig dagegen vorgehen, wenn man Speicherwerte durchläuft und nicht Eingabeargumente für Funktionsparameter?

Antworten (1)

Ob der Vertrag ins Stocken gerät oder nicht, hängt von Ihrer genauen Implementierung ab.

Wenn Sie eine Funktion in Ihrem Vertrag haben, die bei jedem Aufruf über das gesamte Array iteriert, wird der Vertrag dauerhaft angehalten, wenn das Array auf eine Größe anwächst, die das Blockgaslimit überschreitet (es sei denn, Sie haben eine andere Funktion, die das können Sie beliebige Einträge aus dem Array löschen).

Wenn Sie andererseits eine Funktion haben, die ein Array von Indizes akzeptiert und nur mit diesen Indizes direkt über ein Speicherarray iteriert (dh Sie schleifen über Ihr Eingabearray, nicht über das Speicherarray), können Sie das Abwürgen vermeiden Situation, indem einfach so viele Indizes übergeben werden, wie unter der Blockgasgrenze erlaubt sind.

Die Milderung hängt von der Codestruktur ab. Es ist möglich, dass ein Array zu groß ist, um es auf einmal zu durchlaufen, aber Sie können problemlos Funktionen erstellen, die ohne Schleifen direkt auf Indizes zugreifen.

Wenn Sie beispielsweise einen Array-Eintrag ändern möchten, bei dem der Wert ist 4839, und Ihr Array 10000 Einträge hat, wäre eine naive Möglichkeit, ihn einfach zu durchlaufen, jeden Eintrag zu überprüfen und zu ändern, wenn Sie einen finden, der gleich ist 4839. Dies ist anfällig dafür, die Blockgasgrenze zu erreichen, wenn die Arraygröße wächst.

Eine bessere Implementierung wäre, Ihr Array zu lesen, es außerhalb der Kette zu durchlaufen und dann eine Funktion zu haben, die eine Liste von Indizes akzeptiert, die Sie ändern möchten, und ihre neuen Werte. Anstatt das gesamte Array innerhalb des Vertrags zu durchlaufen, können Sie jetzt die Indexliste durchlaufen und einfach diese Einträge aktualisieren.

Hallo Raghav, wenn ich eine Funktion mit dem Ziel durchlaufe, einen bestimmten Anteil an Token an alle Staker freizugeben, wäre es dann eine schlechte Idee, durch eine Speicheranordnung von Stakern (die auf Tausende anwachsen könnten) zu iterieren, und sollte ich stattdessen B. 50 Adressen pro Transaktion durch eine Funktion im Speicherargumentarray von Adressen durchlaufen (um letztendlich zu vermeiden, die Blockgrenze zu überschreiten)?