Warum fällt mein TX aufgrund von Gasmangel aus, obwohl die richtige Gasmenge zugeführt wurde?

Vorbehalt: Ich habe versucht, Links zu meinen Transaktionen und Adressen in etherscan.io bereitzustellen, aber ich „brauche mindestens 10 Reputation, um mehr als 2 Links zu posten“.

Ich habe ein Konto, das ich säubern möchte. Ich möchte die ETH zu einem Fundsplitting-Vertrag (ETC/ETH) fegen. Ich interessiere mich nur dafür, den ETH-Saldo zu fegen, und mein Ziel ist es, dass das Konto am Ende einen Saldo von Null hat (z. B. kein Staub).

Dies ist der Fondsaufteilungsvertrag, den ich zu verwenden versuche: 0x1e143b2588705dfea63a17f2032ca123df995ce0

Es scheint, als ob das für diese Operation benötigte Gas 29.717 ist. Hier ist zum Beispiel eine Beispieltransaktion, die ich an den Vertrag gesendet habe, der laut etherscan.io diese Menge an Gas erforderte: 0x7cd52325c0945d0de975a6713abdc50659c0c62ef523a1a99f2ad2a2d4128a8f

Wenn ich jedoch eine Transaktion sende und die Gasmenge auf 29.717 begrenze, schlägt meine Transaktion fehl. Hier ist zum Beispiel eine Beispieltransaktion, die ich zum Vertrag mit einem Gaslimit von 29.717 geschickt habe, die aufgrund von Gasmangel fehlgeschlagen ist: 0xcd31481b4dd9410daa22c8a47f9a4b29ef4a305877174eb346433bb4e6b03089(TX)

Ich habe festgestellt, dass die Mindestmenge an Gas, die ich angeben muss, damit einer dieser Transfers funktioniert, 31.991 beträgt:

  • Transaktion mit 31.991 Gas, die funktioniert hat: 0x7cd52325c0945d0de975a6713abdc50659c0c62ef523a1a99f2ad2a2d4128a8f(TX)
  • Transaktion mit 31.990 Gas, die fehlgeschlagen ist: 0x8c92fde3cf07b3cdbf4dcc54ed6ccfb072f22933ab556612f3d23317a2466280(TX)

Wenn der TX jedoch durchläuft, scheint es, als ob er nur 29.717 Gas verbraucht hätte. Zum Beispiel: Konto 0x19d90f1106c600bd8a70b5775776b4ecdc7a945b(Adresse) hatte einen Saldo von 0.01282711 ETH(bei Block 1964300).

Ich habe die Transaktion 0xb57c8b5aede3070e2fb80ea9a21ec43293cb5c7392ccb36357388422e9055509(TX) mit den folgenden Details gesendet:

  • Wert:0.01218729 ETH
  • Gas:31991
  • Gaspreis:20000000000 Wei

So:

  • Saldo vor TX:0.01282711 ETH
  • Betrag zu senden:0.01218729 ETH
  • Angebliche Kosten für TX: Gas* Price=0.00063982 ETH
  • Saldo - Zu sendender Betrag - Angebliche Kosten für TX = NULL!

Wie Sie jedoch sehen können, hat das Konto 0x19d90f1106c600bd8a70b5775776b4ecdc7a945b(Adresse) einen Saldo von 0.00004548 ETH.

Dies wiederum bedeutet, dass die tatsächlichen Kosten des TX waren 0.00059434 ETH: Tatsächliche Kosten des TX = Saldo vor TX – gesendeter Betrag – tatsächlicher Endsaldo = 0,01282711 – 0,01218729 – 0,00004548 = 0,00059434.

Bei einem Gaspreis von 20000000000 Wei, bedeutet dies, dass die verbrauchte Gasmenge war: 29717(0,00059434/0,00000002 = 29717)

Also die Frage sind:

  1. Warum scheitern die Transaktionen, die ein Gaslimit angeben 29717?
  2. Wie übertrage ich das Geld so, dass der Endsaldo eines ETH-Kontos Null ist, wenn ich den obigen Vertrag verwende?

System Information

Geth-Version: 1.4.10-stable-c2eea630 Betriebssystem & Version: Linux

Erwartetes Verhalten

Transaktion 0x19d90f1106c600bd8a70b5775776b4ecdc7a945b hätte erfolgreich sein sollen.

Tatsächliches Verhalten

Transaktion 0x19d90f1106c600bd8a70b5775776b4ecdc7a945b ist aufgrund von Gasmangel fehlgeschlagen.

Schritte zum Reproduzieren des Verhaltens

Verwenden Sie die transfer(address)Vertragsfunktion 0x1e143b2588705dfea63a17f2032ca123df995ce0, indem Sie einen bestimmten Betrag senden und die Gasmenge begrenzen29717

Hier ist eine Beispieltransaktion zu diesem Vertrag, die Sie über die JSON-RPC-API senden können:'{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"from":"0xe7c7d161800ebb5112d7d892510e9f1dafc4010c","to":"0x1e143b2588705dfea63a17f2032ca123df995ce0","value":"0x1F99A58657EED0","data":"0x1a69523000000000000000000000000029d5527caa78f1946a409fa6acaf14a0a4a0274b"}],"id":6}'

Antworten (1)

Das Verständnis dieses Rätsels kann lehrreich sein. Das Verhalten lässt sich durch die Art und Weise erklären, wie die CALLAnweisung in Bezug auf Gas funktioniert.

Wir können die VM-Traces der Transaktionen hier vergleichen:

(Links führen zum Programmzähler kurz vor dem Fehler CALL).

Betrachten wir beide Transaktionen parallel, Awird die erfolgreiche Transaktion und Bdie fehlgeschlagene sein. Der Wert ist das verbleibende Gas bei jedem Schritt.

  1. Vertragsruf: A = 31991, B = 29717.
  2. Bevor der Vertrag überhaupt beginnt, 22680verbraucht werden. A = 9311, B = 7037.
  3. Es wird eine Anzahl von Anweisungen ausgeführt, die kumulierte Kosten von haben 271.
  4. Vor der eigentlichen Übertragung CALLim Schritt 65 sind wir also bei A = 9040, B = 6766.
  5. An diesem Punkt Bscheitert, weil es nicht genug Benzin hat, um die CALLAnweisung auszuführen, was kostet 9040 gas.
  6. Nach dem Anruf 9040 gassind sie jedoch noch nicht ganz aufgezehrt A: Wir sind zurück bei 2300.
  7. Asetzt seinen Betrieb bis zur letzten Anweisung fort, an der er sitzt 2274.
  8. Die ungenutzten 2274werden erstattet und das gesamte verbrauchte Gas ist in der Tat 31991-2274 = 29717.

Es gibt zwei Punkte, die das überraschende Verhalten erklären.

  • Die Kosten für einen wertübertragenden CALL betragen 40 + 9000. (gemäß Yellow Paper Anhang G ).
  • Von diesen Kosten wird ein Betrag von 2300 Gas abgezogen und als Gas an den Empfänger weitergeleitet .

Der zweite Punkt ist der Schlüssel. Im Rahmen eines Vertrages, der einen anderen Vertrag aufruft, wird dieses sogenannte stipendminimale Gas bereitgestellt, um die Betriebskosten einer grundlegenden Fallback-Funktion zu decken. Beachten Sie, dass es auch möglich ist, manuell mehr Gas weiterzuleiten, wenn bekannt ist, dass der Empfänger einen größeren Bedarf hat.

Da in unserem Fall das Empfängerkonto kein Vertrag ist, stipendwurde das zurückerstattet. Gewissermaßen waren es nur die CALLBetriebskosten, 6740 gasaber wir mussten zeigen, dass wir zumindest 9040den Fall eines Vertragsangerufenen decken mussten.

In früheren Versionen wurde das gesamte Gas des Anrufers an den Angerufenen weitergeleitet, dies war jedoch missbrauchsanfällig und das neue Verhalten wurde eingeführt.

Weitere Links: