send VS call - Unterschiede und wann zu verwenden und wann nicht zu verwenden

Kann jemand bitte die Unterschiede zwischen der Verwendung von Send und Call for Contracts erklären und wann diese verschiedenen Methoden verwendet und wann nicht verwendet werden sollen?

Zum Beispiel :

   msg.sender.send(number);  
   msg.sender.call.value(number)();

Ich weiß, dass das Senden 2300 Gas verbraucht und dass das Verwenden von Anrufen kein Gas verbraucht.

Antworten (3)

EDIT Dez. 2019: call.value()()sollte nun zum Transferieren von Ether verwendet werden. (Verwenden Sie nicht Senden oder Übertragen.)

Siehe: Ist transfer() nach dem Istanbul-Update noch sicher?

Vielen Dank für die Antwort, aber ich suchte auch nach weiteren Informationen darüber, wie diese verschiedenen Methoden auf Systemebene funktionieren. Generiert die Call-Methode beispielsweise Transaktionen auf der Blockchain?
A .callerstellt keine Transaktion; Ich habe gerade dies geschrieben, das andere Details enthält, nach denen Sie möglicherweise suchen: ethereum.stackexchange.com/a/6477/42
Ich denke, sendsendet mehr als 0 Gas, nicht wahr? Es sendet 23000
sendsendet 0 Gas, aber es gibt eine EVM-Regel, dass der Empfänger immer ein Stipendium von 2.300 Gas erhält (so dass er, wenn er möchte, immer genug Gas hat, um zu protokollieren, dass er etwas erhalten hat).
Alex Darby verwechselt wahrscheinlich .callJavascript (keine Transaktion) mit .callSolidity (bereits in einer Transaktion).
Nein, ich verwechsle den Aufruf nicht aus dem Javascript. Mein Beitrag erwähnt Javascript nicht,

1 Send() leitet kein Gas mehr weiter. Es verwendet einfach das fest codierte Stipendium (2300 Gas), das von den Wertübertragungskosten (mindestens 9040) abgezweigt wird. Es reicht aus, um Ether zu senden, aber auch genug, um im Grunde eine zusätzliche kleine Protokollierungsoperation (in einer Fallback-Funktion) durchzuführen. Die folgenden Vorgänge verbrauchen mehr Gas als das für eine Fallback-Funktion bereitgestellte Stipendium:

• Schreiben in den Speicher

• Erstellen eines Vertrags

• Aufruf einer externen Funktion, die viel Gas verbraucht

• Senden von Äther

2 Wenn einem send()Aufruf das Gas ausgeht, gibt er keinen Fehler aus, sondern gibt einfach „false“ zurück.

von solidity Doc:

Wenn ein Kontrakt Ether empfängt (ohne dass eine Funktion aufgerufen wird), wird die Fallback-Funktion ausgeführt. Der Vertrag kann sich nur darauf verlassen, dass ihm zu diesem Zeitpunkt das „Gas-Stipendium“ (2300 Gas) zur Verfügung steht. Dieses Stipendium reicht nicht aus, um in irgendeiner Weise auf Speicher zuzugreifen. Um sicherzustellen, dass Ihr Vertrag Ether auf diese Weise empfangen kann, überprüfen Sie die Gasanforderungen der Fallback-Funktion (z. B. im Abschnitt „Details“ in Browser-Solidity).

• Es gibt eine Möglichkeit, mit addr.call.value(x)() mehr Gas an den empfangenden Vertrag weiterzuleiten. Dies ist im Wesentlichen dasselbe wie addr.send(x), nur dass es das gesamte verbleibende Gas weiterleitet und dem Empfänger die Möglichkeit eröffnet, teurere Aktionen durchzuführen. Dies kann das Zurückrufen in den sendenden Vertrag oder andere Zustandsänderungen umfassen, an die Sie möglicherweise nicht gedacht haben. Es ermöglicht also eine große Flexibilität für ehrliche Benutzer, aber auch für böswillige Akteure.

Warnung : Verträge, die Ether empfangen, aber keine Fallback-Funktion definieren, lösen eine Ausnahme aus und senden den Ether zurück (dies war vor Solidity v0.4.0 anders). Wenn Sie also möchten, dass Ihr Vertrag Ether empfängt, müssen Sie eine Fallback-Funktion implementieren.

Gute Argumente. Zur Verdeutlichung der Leser gilt „gibt keinen Fehler, es wird einfach falsch zurückgegeben“ gilt auch für .call(). Und kann nicht genug betonen, dass .call()„ehrliche Benutzer, aber auch böswillige Akteure große Flexibilität haben“.

address.transfer()

  • wirft bei Misserfolg
  • leitet 2,300Gasstipendium weiter, sicher gegen Wiedereintritt
  • sollte in den meisten Fällen verwendet werden, da es der sicherste Weg ist, Äther zu versenden

address.send()

  • kehrt falsebei Misserfolg zurück
  • leitet 2,300Gasstipendium weiter, sicher gegen Wiedereintritt
  • sollte in seltenen Fällen verwendet werden, wenn Sie das Scheitern des Vertrags behandeln möchten

address.call.value().gas()()

  • kehrt falsebei Misserfolg zurück
  • leitet das gesamte verfügbare Gas weiter, ermöglicht die Angabe, wie viel Gas weitergeleitet werden soll
  • sollte verwendet werden, wenn Sie steuern müssen, wie viel Gas beim Senden von Ether weitergeleitet werden soll, oder um eine Funktion eines anderen Vertrags aufzurufen

Weitere Einzelheiten können Sie hier https://ethereum.stackexchange.com/a/38642/18932 nachlesen