Welche Einschränkungen gibt es bei der Schätzung von Gas und wann wäre die Schätzung erheblich falsch?

web3.eth.estimateGasund JSON-RPC- SchätzungGas kann verwendet werden, um zu sehen, wie viel Gas für eine Transaktion angegeben werden sollte, bevor die Transaktion erstellt wird.

Gibt es Einschränkungen, da es sich um eine Schätzung handelt? In welchen Fällen sollte man sich weniger auf seine Verwendung verlassen, da dies zu einer Schätzung führen kann, die nicht aussagekräftig oder genau ist?

Antworten (3)

schätzt Gas funktioniert, indem es vorgibt, dass die Transaktion tatsächlich in die Blockchain aufgenommen wurde, und dann die genaue Gasmenge zurückgibt, die berechnet worden wäre, wenn diese vorgetäuschte Operation echt gewesen wäre. Mit anderen Worten, es verwendet genau das gleiche Verfahren, das ein Miner verwenden würde , um die tatsächliche Gebühr zu berechnen.

Angesichts dieses Ansatzes könnte ein zufälliger Beobachter denken, dass es keine Einschränkungen gibt und dass die Schätzung immer genau richtig sein wird. Leider würden sie sich irren .

Stellen Sie sich einen einfachen Vertrag vor, der den neuesten Block-Hash überprüft und dann einen anderen großen, gasfressenden Vertrag aufruft, nur wenn das 10. Bit im Block-Hash eine 1 ist. Wenn Sie esschätzenGas verwenden, um den Verbrauch einer Transaktion zu messen, die diesen einfachen Vertrag aufruft , hängt Ihr Ergebnis vollständig davon ab, ob der letzte Block eine 1 im 10. Bit seines Block-Hashes enthielt. Wenn ein neuer Block zwischen Ihrem Aufruf von taxGas und dem Zeitpunkt, an dem die Transaktion tatsächlich aufgenommen wird, veröffentlicht wird, besteht eine Wahrscheinlichkeit von 50 %, dass Ihre Schätzung völlig falsch ist . Dies mag wie ein erfundenes Beispiel erscheinen, aber viele Verträge verwenden Block-Hashes als Entropiequelle und ändern ihr Verhalten basierend auf dem, was der Hash ist. Das ist also etwas, das definitiv in freier Wildbahn passieren könnte.

Aber es kommt noch schlimmer. Was ist, wenn der Vertrag, den Ihre Transaktion aufruft, sein Verhalten basierend auf den an ihn übermittelten Transaktionen ändert? Jetzt ist es möglich, dass der Gasverbrauch je nach der Reihenfolge, in der die Transaktionen übermittelt wurden, unterschiedlich ist .

Nehmen wir zum Beispiel an, dass ein häufig aufgerufener Vertrag fast immer nur ein paar hundert Gas kostet, um anzurufen . Aber es enthält eine seltsame Klausel in seinem Code, so dass eine Nachricht, die von einem bestimmten Schlüssel signiert wird, sein Verhalten ändert und es dazu bringt, jedes Mal, wenn es aufgerufen wird, Millionen von Gas zu verbrauchen . Die gleiche Taste ist dann in der Lage, das Verhalten wieder zurück zu ändern. Jetzt kann der Besitzer dieses Schlüssels den Gasverbrauch des Vertrags nach Belieben ändern. Wenn der Eigentümer ein Miner ist, könnte er diesen „gefangenen Vertrag“ verwenden, um dieses Gasverschwendungsverhalten am Anfang jedes Blocks, den sie berechnen, einzuschalten und am Ende auszuschalten. Solange sie diese privaten Transaktionen niemals öffentlich veröffentlichen, wird jeder Aufruf von taxGas einen niedrigen Wert zurückgeben, während jederEine wirklich eingereichte Transaktion kostet Millionen von Gas (das direkt in die Tasche des Bergmanns fließt). Bei einer sorgfältigen Vertragsgestaltung müssten sie die Berechnungen gar nicht erst durchführen, weil sie wissen, wie das Ergebnis aussehen wird. Und sie könnten diesen "Gebührendiebstahl-Angriff" nach dem Zufallsprinzip ausführen und ihn nur gelegentlich ausführen, damit niemand es merkt, bis viele Benutzer hereingelegt wurden.

Auch dieses Beispiel ist erfunden. Aber der Punkt ist, dass Sie immer überlegen sollten, ob ein Angreifer etwas zu gewinnen hat, wenn Sie eine falsche Schätzung abgeben . Wenn es einen möglichen Vektor gibt, fügen Sie zusätzlichen Code in den Teil Ihrer App ein, um die Situation zu behandeln, in der Ihre Schätzung falsch ist. Eine einfache Technik, die Sie immer anwenden sollten, ist das Einbeziehen einer Sane-Gas-Grenze . Auf diese Weise gibt es zumindest eine Obergrenze dafür, was ein Angreifer tun kann. Denken Sie darüber hinaus daran, dass es sich um den geschätzten Gasanruf handelt, nicht um den garantierten maximalen Gasanruf, und verlassen Sie sich nur vernünftig darauf.

tl; dr:
Wenn es eine Möglichkeit gibt, dass sich die Folgen Ihrer Transaktion ändern, je nachdem, wann oder an wen sie übermittelt wird, besteht die Möglichkeit, dass die Schätzung von Gas um beliebig große Beträge falsch ist. Treffen Sie zusätzliche Vorsichtsmaßnahmen.

Gute Antwort. Wie können Bergleute das Gasverschwendungsverhalten einschalten und „diese privaten Transaktionen niemals öffentlich veröffentlichen“? Oder sollte das eine separate Frage sein?
Mit „niemals öffentlich veröffentlichen“ meine ich nur, dass sie die Transaktionen niemals an andere Bergleute zur Aufnahme versenden. Wenn sie die Start/Stopp-Transaktion in ihren eigenen Block aufnehmen, wird sie natürlich als Teil des Blocks veröffentlicht. Eine sorgfältige Blockchain-Analyse würde also immer noch erkennen, was sie tun. Ich meinte nur, dass sie niemals "ein Risiko eingehen", ob oder wann jemand anderes ihre Transaktion einbeziehen kann, indem sie sie über das p2p-Netzwerk sendet, so wie eine normale Transaktion gesendet würde. Ist das sinnvoll?
Ja dank. Bei tldr ist „an wen es übermittelt wird“ nicht so klar, weil das „an“ in der Transaktion festgelegt ist. Beziehen Sie sich mit "an wen" auf Ihr Beispiel einer Transaktion, die von einem bestimmten Schlüssel signiert wurde?
Das Schlüsselwort ist "submitted", nicht addressed: Ich sprach davon, welcher Miner die Transaktion verarbeitet. Aber wenn dieser Teil verwirrend ist, kann ich versuchen, es anders zu formulieren.
Wenn Sie nur den Bergmann meinen, wäre eine Umformulierung meiner Meinung nach viel klarer :) Beispiel "... ändert sich je nachdem, wer der Bergmann ist oder wann er abgebaut wird"
Ich glaube nicht, dass das zweite Beispiel in der Antwort zu 100% richtig ist. Wenn der Miner das Verhalten zu Beginn der Blockberechnung ändert und nie veröffentlicht, bedeutet dies, dass, wenn jemand die Transaktion durchführt, nur dann viel Gas benötigt wird, wenn dieser jemand die Transaktion mit diesem bestimmten Miner durchgeführt hat, da dort die böse Transaktion ( Änderungsgeschäft) ist. Die Chance dafür ist sehr gering. @eth was denkst du?
@NikaKurashvili Sie haben Recht, dass nur der bestimmte Miner davon profitieren kann und seine Chancen, einen Block abzubauen, proportional zu seiner Hashrate sind. Aber was hier beschrieben wird, soll kein Angriff sein, der jederzeit von allen Minern durchgeführt werden kann. Nichts Widersprüchliches in dem, was Sie und die Antwort sagen.
Das 2. Beispiel nahm das Hauptproblem des heutigen Ethereum-Netzwerks vorweg ...

Eine Einschränkung, die ich gefunden habe, oder zumindest ein bemerkenswerter Aspekt der eth.estimateGas-Methode, ist, dass sie nur wie beabsichtigt funktioniert, wenn der eigentliche Aufruf keine Ausnahme auslöst.

Dies kann durchaus ein Fehler in der aktuellen Version von Geth sein, aber ich habe herausgefunden, dass ein Aufruf einer Methode, die eine Ausnahme auslöst, immer dasselbe Ergebnis der Gasschätzung liefert, nämlich einen Wert von 50000000 Gaseinheiten. Bei einem Gaspreis von 20000000000 brachten meine geschätzten Gasanrufe genau 1 Ether, was eine riesige Menge für einen einfachen Anruf zu sein schien, der eine Ausnahme auslöste.

Das ist ein bisschen schade, da ich keinen zuverlässigen Weg gefunden habe, Gas in Transaktionen zu schätzen, die tatsächlich eine Ausnahme auslösen (die Gas verbrauchen) - aber zumindest ist es wissenswert ;-) Es sieht also gut aus Idee, Ihre Transaktion zu debuggen.

Übrigens scheint dieser "50000000"-Wert derselbe zu sein, der verwendet wird, um gasbezogene Variablen im Quellcode der go-API zu initialisieren ( https://github.com/ethereum/go-ethereum/blob/master/eth/api .go ), was darauf hinzudeuten scheint, dass dies eher ein Fehler als ein Feature ist ;-)

Hochgestimmt. Wenn möglich, reichen Sie es bitte unter github.com/ethereum/go-ethereum/issues ein (und aktualisieren Sie die Antwort mit dem, was passiert).
Interessanterweise haben wir die Funktion "schätzenGas" auf diese Weise absichtlich verwendet , um festzustellen, ob jemand bereits über einen DAO-Vorschlag abgestimmt hatte oder versuchte, DAO zu senden, als er gesperrt war. Da wir wussten, dass der Vertrag unter diesen Umständen kippen würde, würden wir Gas schätzen und wenn es das ganze Gas auffressen würde, würden wir eine Warnung anzeigen, anstatt den TX zu senden. Dies verhinderte, dass Leute zweimal abstimmten / versuchten, DAO an das Frontend zu senden, wo wir das Messaging kontrollieren und somit Support-E-Mails reduzieren konnten.

Eine Einschränkung (nach meiner eigenen Beobachtung, hoffentlich wird mich jemand korrigieren, wenn ich falsch liege) ist, dass Sie selbst bei estimateGaskorrekter Schätzung nicht das Gaslimit erhalten, das Sie beim Senden Ihrer Transaktion festlegen müssen.

Das Problem ist, dass Rückerstattungen erst am Ende der Transaktion gutgeschrieben werden. Wenn Sie also eine Transaktion haben, die etwas Arbeit erledigt und dabei etwas Speicher bereinigt, müssen Sie ein Gaslimit festlegen, das hoch genug ist, um die ganze Arbeit ohne zu erledigen der Vorteil der Rückerstattung.