Vertragsadresse. Übertragungsmethode Gaskosten

Wer zahlt das Benzin im folgenden Szenario?

Nehmen wir an, wir haben die folgende einfache Funktion. Das sendet einen Betrag aus dem Vertrag an den Absender zurück. Nur ein Beispiel.

    function withdraw() public payable 
    {
       address member = msg.sender;
       member.transfer(msg.value);
    }

Der Absender der Methode zahlt natürlich die Gebühr, um die Transaktion an die Methode zu senden und die Anweisungen auszuführen. Aber wer zahlt das Gas für die resultierende Transaktion, die aus diesem Code erstellt wird?

Zweitens, im Allgemeinen über die transfer()Methode, was sind die Standardparameter. Ich weiß, dass es ein Gaslimit von 2100 verwendet, aber was ist mit dem Gaspreis? Kommt dieses Gas auch aus dem übergebenen Wert oder aus dem Vertragssaldo und wird der gesamte Wert übertragen.

Stimmen Sie die Frage nicht wegen „Mangel an Forschung“ ab. Ich bin mir der üblichen Bedingungen für Gas aus der Waage bewusst, im Unterschied zum Transaktionswert. Nur neugierig auf die transfer()Methode im Besonderen. Da es nicht viele Dokumentationen zu seiner Implementierung gibt, die sich von unterscheiden send(), die ich finden konnte.

Antworten (3)

Wer zahlt das Gas für die resultierende Transaktion, die aus diesem Code erstellt wird?

Die transfer()Funktion führt nicht zu einer Transaktion. Dies führt zu einem Nachrichtenaufruf innerhalb der ursprünglichen Transaktion, die von einem externen Konto initiiert wurde . Die Blockchain zeichnet eine einzelne Transaktion auf, unabhängig davon, wie viele transfer()oder call()Aufrufe der Code enthält. Die Gaskosten werden von dem externen Konto abgezogen, das die Transaktion initiiert hat.

Ich weiß, dass es ein Gaslimit von 2100 verwendet, aber was ist mit dem Gaspreis?

Es wird der vom externen Kontoinhaber, der die Transaktion initiiert hat, angegebene Gaspreis verwendet.

Kommt dieses Gas auch aus dem übergebenen Wert oder aus dem Vertragssaldo und wird der gesamte Wert übertragen.

Die Gaskosten werden nicht vom Vertrag abgezogen, sondern das externe Konto, das die Transaktion veranlasst hat. Die Gaskosten werden zusätzlich zu dem eingegebenen Wert hinzugefügt. Das externe Konto muss einen Saldo von größer oder gleich aufweisen value + gaslimit * gasprice.

Ich bin nur neugierig auf die Methode transfer () im Besonderen. Da es nicht viel Dokumentation über seine Implementierung gibt, da es sich von send () unterscheidet, die ich finden konnte.

Beachten Sie beim Senden von Ether die relativen Kompromisse zwischen der Verwendung von someAddress.send(), someAddress.transfer(), und someAddress.call.value()():

  • someAddress.send()und someAddress.transfer()gelten als sicher gegen Wiedereintritt. Während diese Methoden immer noch die Codeausführung auslösen, erhält der aufgerufene Vertrag nur ein Stipendium von 2.300 Gas, was derzeit nur ausreicht, um ein Ereignis zu protokollieren.
  • x.transfer(y)äquivalent zu require(x.send(y))ist, wird es automatisch zurückgesetzt, wenn das Senden fehlschlägt.
  • someAddress.call.value(y)()sendet den bereitgestellten Ether und löst die Ausführung des Codes aus. Dem ausgeführten Code wird das gesamte verfügbare Gas für die Ausführung gegeben, was diese Art der Wertübertragung unsicher gegen Wiedereintritt macht.

Die Verwendung von send()oder transfer()verhindert den Wiedereintritt, jedoch auf Kosten der Inkompatibilität mit Verträgen, deren Fallback-Funktion mehr als 2.300 Gas erfordert. Es ist auch möglich, someAddress.call.value(ethAmount).gas(gasAmount)()eine benutzerdefinierte Gasmenge weiterzuleiten.

Ein Muster, das versucht, diesen Kompromiss auszugleichen, besteht darin, sowohl einen Push- als auch einen Pull-Mechanismus zu implementieren, wobei send()oder transfer()für die Push-Komponente und call.value()()für die Pull-Komponente verwendet wird.

Es ist darauf hinzuweisen, dass die ausschließliche Nutzung von send()oder transfer()für Wertübertragungen einen Vertrag nicht selbst gegen Wiedereintritt sichert, sondern nur diese spezifischen Wertübertragungen gegen Wiedereintritt sichert.

Weitere Informationen finden Sie hier https://consensys.github.io/smart-contract-best-practices/recommendations/#be-aware-of-the-tradeoffs-between-send-transfer-and-callvalue


Weitere Details finden Sie in dieser Antwort https://ethereum.stackexchange.com/a/38642/18932

Ich habe eine Benachrichtigung zu dieser Frage erhalten. Kommen Sie zurück, um sich das 5 Jahre später anzusehen. Ich sehe, wie ich auf diesen Gedankengang gekommen bin – ein tieferes Verständnis der EVM fehlte. Das war eine super hilfreiche Antwort!

Der Absender der Methode zahlt natürlich die Gebühr, um die Transaktion an die Methode zu senden und die Anweisungen auszuführen. Aber wer zahlt das Gas für die resultierende Transaktion, die aus diesem Code erstellt wird?

Vielleicht lese ich das nicht richtig, aber Sie beantworten im Grunde die Frage und stellen dann die Frage. Der Absender zahlt für das Benzin.

Zweitens, allgemein über die Methode transfer(), was sind die Standardparameter. Ich weiß, dass es ein Gaslimit von 2100 verwendet, aber was ist mit dem Gaspreis? Kommt dieses Gas auch aus dem übergebenen Wert oder aus dem Vertragssaldo und wird der gesamte Wert übertragen.

transfer()kann sich tatsächlich unterscheiden, je nachdem, was tatsächlich im Solidity-Code selbst enthalten ist. Es ist nicht unbedingt standardmäßig 21000. Da die Überweisung tatsächlich Daten sendet und nicht nur eine direkt zahlbare Transaktion, müssten Sie ein höheres Gaslimit festlegen.

Was den Gaspreis und das Gaslimit betrifft, hat Ihr tatsächlicher Funktionsaufruf bereits einen festgelegten Bereich oder Füllstand an Gas, den er basierend auf der Komplexität des Codes selbst verwenden wird, wobei das meiste davon aus dem Hinzufügen/Ändern von Speicher stammt.

Der Standardgaspreis wird durch das Medium bestimmt, das Sie zum Senden des Anrufs selbst verwenden. web3untersucht zum Beispiel die aktuelle Situation des genutzten Netzes und stellt den Gaspreis dynamisch ein, basierend auf der Bestätigung innerhalb von 5-10 Sekunden.

Das Gaslimit wird auch web3dynamisch durch den erwarteten Gasverbrauch für den Anruf festgelegt. 21000 wird häufig für zahlbare Überweisungen verwendet, die keine zusätzlichen Daten enthalten.

Ja - guter Punkt zur 1. Punktklärung. Es kam von einem schlechten Verständnis der Methode transfer(). Mir war nicht bewusst, dass es nicht zu einer zweiten Transaktion kam.
Wenn ich zwei Antworten markieren könnte - Ihre Antwort beantwortet definitiv und liefert gute Informationen. +1
Die Gasschätzung für einfache Transfers gibt eine Gasgebühr von 21.040 zurück, wenn mit web3 geschätzt oder auf Remix getestet wird. Ich hoffe, dass dies ein Fehler ist, da die meisten Krypto-Börsen jetzt das Gaslimit für Abhebungen auf 21.000 setzen.

Schöne qus, kommen wir zu deiner Faust qus:

Der Absender der Methode zahlt natürlich die Gebühr, um die Transaktion an die Methode zu senden und die Anweisungen auszuführen. Aber wer zahlt das Gas für die resultierende Transaktion, die aus diesem Code erstellt wird?

msg.sender zahlt Gas. dh der Methodenaufrufer von pull() zahlt für die Transaktionskosten. Sobald Ihre Transaktionen validiert und zu Blockchain-Minern hinzugefügt wurden, erhalten Sie einen Anreiz.

Kommen wir zu Ihrem 2. Qus Ans:

Sie können den Gas- und Gaspreiswert festlegen, indem Sie gas und gasPrice zusammen mit from- und to-Werten für die Funktion sendTransaction() angeben

web3.eth.sendTransaction({from: 'myWallet', to: 'coinbaseWallet', value: web3.toWei(0.1,'ether'),gas: 5000, gasPrice: web3.toWei(40,'gwei')});
Danke. Mir sind die standardmäßigen und akzeptierten Parameter für sendTransaction von Web3 bekannt. Meine Frage bezog sich speziell auf die Adresse von solidity. transfer ()