Wieso muss ich ein höheres gasLimit als schätzenGas angeben?

Wenn für einen Vertragsabruf voraussichtlich 41043 Gas verarbeitet werden müssen, wie es von geschätzt wird estimateGas, wie kommt es dann, dass ich gasLimit von ~70000 angeben muss, um verarbeitet zu werden?

Antworten (3)

Ich glaube, in einigen Fällen ist kumulatives Gasverbrauch nicht genau, weil Gas ausgegeben / Gas zurückerstattet wird. Wenn der Vertrag zu irgendeinem Zeitpunkt über das gasLimit hinausgeht, schlägt er mit einer „Out of Gas“-Ausnahme fehl. Wenn später im Vertrag eine Rückerstattung erfolgt, wird das kumulierte Gas sinken, auch wenn es während der Vertragsausführung über das steigt, was Sie für das „Gaslimit“ halten.

Schauen wir uns als Beispiel Etherdice an.

  • Der Vertrag hatte Daten im Speicher

  • Jedes Mal, wenn ein Benutzer eine Transaktion an den Vertrag sendet, löscht der Vertrag das älteste gespeicherte Element

  • Da der Vertrag jedoch nur am Ende der Transaktion zurückerstattet, blieben alle Gelder im Vertrag hängen, weil kein Benzin mehr vorhanden war.

Nehmen wir an, das Gas ist 100.000, bevor ein Benutzer eine Transaktion sendet. Nachdem der Benutzer die Transaktion gesendet hat, beträgt das Gas 100.000. Während des Vertrags "braucht" es zu einem bestimmten Zeitpunkt 200.000. Und in der Sekunde, in der es diese Grenze erreicht, ist es leer und fertig.

Im Fall von Etherdice war es sogar noch schlimmer, weil er das globale Limit von 3141592 erreichte, das es vor Homestead gab.

Danke für deine Antwort. Das macht sehr viel Sinn, aber ich glaube, ich mache keine Operation mit negativem Gaspreis - ein externer Anruf und ein paar Speicherschreibvorgänge (wobei der Wert überschrieben wird).
Sie sollten den kumulativen Gasverbrauch nicht berücksichtigen, es ist die kumulative Menge des verbrauchten Gases innerhalb des aktuellen Blocks. Schauen Sie sich verschiedene TX in verschiedenen Blöcken an, dieser Wert wird "zufällig" steigen oder fallen, sodass Sie das nicht verwenden können, um Ihr Gaslimit festzulegen (es sei denn, es gab nur Ihren TX im Block).

Du nicht.

Sie können das Gas genau angeben und es sollte problemlos durchgehen. Der einzige Fallstrick ist, dass, wenn sich der Vertragsstatus ändert, den Sie ausführen, und mehr Gas erforderlich wäre, als von einer einzigen Einheit bereitgestellt wird, verlieren Sie das gesamte bereitgestellte Gas und die Transaktion wird rückgängig gemacht.

Die Vertragslogik sollte kein Problem darstellen (der Gasverbrauch ist konstant), was bedeutet, dass der kumulative Gasverbrauch stabil ist. Deshalb frage ich mich, ob bei Angabe von 70.000 GasLimit alles in Ordnung ist (aber nur 40.000 verwendet werden), und wenn ich 50.000 angebe, wird das gesamte Gas ausgegeben und TX nicht verarbeitet.
@Ales Es sieht so aus, als ob Ihnen das Benzin ausgeht, also müssen Sie möglicherweise mit dem EVM debuggen, oder einfacher ist es, einen Blockchain-Explorer zu überprüfen, der den EVM simuliert: ethereum.stackexchange.com/q/1179/42
@eth ja, das scheint am wahrscheinlichsten zu sein, da gasLimit==cumulativeGasUsed für diese txs. Aber ich würde gerne den Grund dafür verstehen
Eine mögliche Erklärung: Wenn Miner Operationen für Verträge ausführen, schätzen sie manchmal (z. B. für externe Anrufe), wie viel Gas die Operation benötigen würde (und fügen möglicherweise eine Sicherheitsmarge hinzu), prüfen, ob genügend Gas vorhanden ist, und fahren erst dann fort Betrieb, wenn genügend Gas vorhanden ist. Wenn dies zutrifft, muss gasLimit immer größer sein als die tatsächlich benötigte und am Ende verbrauchte Gasmenge.
Ah, das ist ein sehr guter Punkt. Ich denke, schätztGas hat Rückerstattungen nicht berücksichtigt (dh Sie geben etwas Speicherplatz frei), was dazu führen könnte, dass der tatsächliche Bedarf unterschätzt wird. Siehe github.com/ethereum/go-ethereum/issues/2395
Eigentlich habe ich gerade den Code überprüft und es wurde schon vor einer Weile behoben. Obwohl es noch nicht im stabilen Zweig ist, sollte es bei der Entwicklung gut funktionieren. Bitte melden, wenn es bei dir nicht so ist.
Nun, ich verstehe, dass wir das nicht tun sollten , aber ich habe ein Gegenbeispiel. Schauen Sie sich Folgendes an: testnet.etherscan.io/tx/… Ich übergebe 325k und alles OK, weil der Anruf 323161 benötigt. Jetzt der exakt gleiche Anruf, aber ich übergebe stattdessen 324k Gas. Für den Rekord 324k > 323161 :) testnet.etherscan.io/tx/… und dieser letzte schlägt fehl.

Hier sind allgemeine Tipps, gefolgt von einer Zusammenfassung der anderen Antworten und Kommentare, um diese besondere Situation zu erklären.

Allgemeine Hinweise

Konkrete Frage

Fazit scheint zu sein:

  • OP führte einige Speicherschreibvorgänge durch (wobei der Wert überschrieben wird)
  • Die wenigen Speicherschreibvorgänge führen tatsächlich zu einer Gasrückerstattung
  • OP verwendete einen stabilen Zweig von Geth
  • Der stabile Zweig von Geth hat einen Fehler, der das Gas unterschätzt, da Geth es normalisiert hat, um Gasrückerstattungen einzuschließen, anstatt das während der Transaktion maximal verbrauchte Gas zu melden
  • Daher ging der Transaktion das Gas aus und es musste ein höheres Gaslimit verarbeitet werden

Geth v1.4 oder der developZweig hat den Fix für taxGas. Beachten Sie, dass es zwar estimateGaspraktisch zu verwenden ist, aber dennoch nicht für alle möglichen Szenarien korrekt ist.