Wäre es besser, "throw" statt "return false" zu verwenden?

Mein Ziel ist es, eine einfache Funktion auszuführen, aber der Benutzer sollte sich bewusst sein, wenn der Anruf fehlschlägt. Ein Beispiel für eine einfache Funktion ist hier zu sehen .

Anstelle von return falsemöchte ich verwenden throw. Wäre ihre Wirkung auf den Fluss der Funktion dieselbe? Und welcher verbraucht weniger Sprit?

Welches könnte insgesamt motivierter sein, es zu verwenden?

Antworten (3)

Diese Diskussion ist hauptsächlich im Zusammenhang mit einem Vertrag von Bedeutung, der einen anderen Vertrag aufruft. Wenn der Callee-Vertrag wirft, gibt es catchin aktuellen EVM-Versionen keine im Caller-Vertrag. Daher ist es unmöglich, einen Throw-Fehler bei Bedarf zu beheben. Dies wird jedoch in den üblichen Anwendungsfällen selten benötigt.

Die Verwendung von throw macht es einfacher zu sehen, ob die Transaktion einen Fehler in einem Blockchain-Explorer hatte.

Siehe auch Diskussion über kommende Funktionen, die sich mit diesen https://github.com/ethereum/EIPs/issues/140 befassen

"Die Verwendung von throw macht es einfacher zu sehen, ob die Transaktion einen Fehler in einem Blockchain-Explorer hatte.". Die Ironie dabei ist, dass throw SCHWIERIGER zu diagnostizieren ist, wenn Sie Dinge gerne programmgesteuert erledigen (dh kein Mensch in der Schleife), weil alles, was Sie bekommen, gasUsed = gasSent ist, Sie keine Fehlermeldung erhalten und nicht herausfinden können, welche Codezeile fehlgeschlagen ist in welchem ​​Vertrag.
@PaulS: Transaktionen haben auch keinen Rückgabewert.
Transaktionen können Nachrichten protokollieren, so mache ich automatisierte Tests. (und/oder Schreibzugriffsfunktionen). Eine abgebrochene Transaktion protokolliert nichts ...

Ich dachte nur, ich würde mich einschalten, falls diese Fragen und Antworten für andere nützlich sind. Stellen Sie sich der Kürze halber vor, ich hätte meiner Meinung nach allem vorangestellt .

Es ist eine sehr allgemeine Frage. Ich würde die Situationen in zwei Fälle einteilen:

  1. „Nein“ ist eine gültige Antwort auf eine Frage
  2. Irgendetwas stimmt mit der Transaktion nicht

Im ersten Fall return falsevielleicht der richtige Weg. Zum Beispiel: "Ist es Montag?" - Nein. Nichts ist besonders falsch und "Nein" ist eine gültige und erwartete Antwort. Implizit sollte der Anrufer auf die Möglichkeit vorbereitet sein, dass ein „Nein“ zurückkommt, und entsprechend damit umgehen.

Eine große Anzahl von Fällen fällt in die zweite Kategorie; Irgendwas stimmt nicht. In diesen Fällen ist es throw; meiner Meinung nach fast immer vorzuziehen .

Bedenken Sie, dass wir einen Vertrag bereitstellen können und der Anrufer in Zukunft möglicherweise ein anderer Vertrag ist. Wenn wir return falsetatsächlich den Anrufer mit der Verantwortung belasten, mit unerwarteten Ergebnissen zu kämpfen. Das führt zu Komplexität und Komplexität ist etwas, was wir in Smart Contracts nicht wollen. Auf der anderen Seite throwtun wir allen zukünftigen Anrufern einen Dienst, wenn wir das erste Anzeichen von Schwierigkeiten bemerken; Wenn unsere Funktion "nicht passiert" ist, ist nichts passiert.

Das ist genau das Gegenteil von der Philosophie in anderen Umgebungen, in denen man fast besessen davon ist, Fehler zu erkennen und Probleme zu erklären. Ich denke, es verdient eine Erwähnung für diejenigen, die anfangen und sich möglicherweise über den üblichen Ansatz wundern.

In einem Smart Contract neige ich dazu, früh zu scheitern, hart zu scheitern und nichts zu erklären. Also throwbei (fast) jeder Gelegenheit.

Allgemeine Heuristik:

  1. Validieren Sie die Eingabe und lösen Sie sie aus, wenn etwas nicht stimmt.
  2. Sachen machen.
  3. Überprüfen Sie die Ergebnisse und werfen Sie, wenn etwas nicht stimmt.
  4. Geben Sie "Erfolg" oder Ergebnis zurück.

Es mag ein wenig brutal erscheinen. Ein Smart Contract sollte sich meiner Meinung nach auf die Wahrung der Integrität von Anwendungen (und Daten) konzentrieren und dies auf möglichst einfache Weise tun, da wir es mit einer Plattform zu tun haben, auf der ein Fehler oder Versehen nicht triviale Folgen haben und schwierig sein könnte oder unmöglich zu beheben.

Wir streben nach „offensichtlich richtig“. Die Minimierung der Komplexität impliziert, dass die Erklärung der Gründe ein separates Anliegen ist (das die Kunden herausfinden müssen). Throwist normalerweise die sicherste und einfachste Reaktion auf Ausnahmen, die die Integrität des Systems bedrohen.

Ich hoffe es hilft.

Im Allgemeinen JA , es ist besser, throwanstelle von zu verwenden return false.

Ein objektiver Grund ist, dass throwes sicherer ist, weil es alle Zustandsänderungen rückgängig macht: Es ist sicher, dass sich nichts ändert, wenn der Anruf fehlschlägt. Es kann möglich sein, alle Änderungen manuell zu verfolgen und rückgängig zu machen, aber es ist möglich, etwas zu übersehen, wenn Sie es "manuell" tun.

Ein subjektiver Grund ist, dass Korrektheit, Sicherheit und Sicherheit die wichtigsten Prioritäten für dezentrale, vertrauenswürdige Anwendungen sind (wie @Rob beschreibt) und throwobjektiv sicherer sind.

Throw vs. Return beschreibt:

Warum verwendenthrow

  • Alle Nebeneffekte des Codes werden rückgängig gemacht
  • Einige Brieftaschen können im Voraus vorhersagen throwund den Benutzer warnen

Warum verwendenreturn

  • Der ahnungslose Benutzer verbraucht weniger Gas (wieder unter der Annahme, dass es sich nicht um einen böswilligen Anruf handelt).
  • Anders als bei throw.

Eine weitere Überlegung ist die Fehlerberichterstattung. Mit throwgibt es derzeit keine Möglichkeit, mehr Informationen über den Fehler zu erhalten, während Ereignisse und Fehlercodes verwendet werden könnten return, um einen genaueren Grund für den Fehler zu vermitteln.

Eine weitere Sache, die Sie bei der Verwendung von web3.js beachten sollten, ist, dass throwweb3.js derzeit ein Problem mit falsevalues ​​hat, wenn ein Solidity auftritt .


In der Zukunft

revertwird wahrscheinlich diejenige sein, die verwendet werden sollte, da sie alle Vorteile von throwund hat return:

Die REVERTAnweisung bietet eine Möglichkeit, die Ausführung zu stoppen und Zustandsänderungen rückgängig zu machen, ohne das gesamte bereitgestellte Gas zu verbrauchen, und mit der Möglichkeit, einen Grund zurückzugeben.