Wie erhalte ich den Rückgabewert eines Vertrags aus einem Vertragsaufruf?

Wenn ein Vertrag etwas zurückgibt (ob eine Zeichenfolge oder return true/return false), wie erhält man seinen Rückgabewert?
Ich meine, wo wird der Rückgabewert gespeichert? Ist die Verwendung erforderlich RETURNDATACOPYoder befindet sich der Wert im Fall von auf dem Stapel return true/return false ? Wenn es sich auf dem Stack befindet, wie kann man wissen, ob der Vertrag aufgrund eines Problems bei der Ausführung (wie Revert oder kein Gas) beendet wurde oder weil die Ausführung bei der Rückgabe von false erfolgreich war?

Natürlich spreche ich, während ich die Site oder die Art des Rückgabewerts kenne, sodass die Verwendung RETURNDATASIZEnicht erforderlich ist. Ich möchte keine Solidity- oder Vyper-Antwort, sondern wissen, wie die Dinge auf der bloßen Ebene funktionieren.

Antworten (1)

Hier gibt es eine Reihe von Fragen, die ich versuchen werde zu entpacken.

1. Wie erhalte ich seinen Rückgabewert?

Wenn ein Vertrag in der EVM endet, hat er einen anhaltenden Zustand, der mit bezeichnet wird H. Dieser Haltezustand nimmt drei mögliche Werte an:

  • ()wenn die Ausführung ohne Rückgabewert angehalten werden muss
  • die leere Menge, nennen wir sie, Nonewenn die Ausführung fortgesetzt werden muss
  • oder eine Liste von zwei Zahlen (offset, length), die einem Rückgabewert entsprechen

Die Konvention ist, dass offset, lengthden Bytes im Speicher entsprechen, mem[offset, offset + length - 1]die den Rückgabedaten entsprechen.

2. Wo wird der Rückgabewert gespeichert?

Ihre Frage ist jedoch, wie kommen die Rücksendedaten dorthin? Nun, normalerweise füllt der kompilierte Vertrag den Maschinenspeicher vor der Beendigung mit den erforderlichen Daten.

3. Ist es notwendig, zu verwenden RETURNDATACOPY?

RETURNDATACOPYist eigentlich für den Sonderfall, in dem ein Vertrag einen anderen aufruft und die Rückgabedaten von diesem anderen Vertrag sammeln muss. Wenn ein anderer Vertrag aufgerufen wird, kann der übergeordnete Vertrag konzeptionell auf die Rückgabedaten in einer aufgerufenen Variablen outputoder mu_oin der Yellow-Paper-Notation zugreifen.

Das Ziel von ist es, Daten in den aktuellen Speicher RETURNDATACOPYzu kopieren , damit sie zurückgegeben werden können.mu_omu_m

4. Wenn es sich auf dem Stack befindet, woher wissen Sie, ob der Vertrag aufgrund eines Ausführungsproblems beendet wurde?

Wie oben besprochen, werden die Rückgabedaten im Speicher gespeichert, bevor der Vertrag angehalten wird. Es gibt andere Möglichkeiten zu verstehen, wie der Vertrag angehalten wurde, insbesondere den Anhaltezustand, die außergewöhnliche Anhaltefunktion und andere.

5. Wo werden die Daten nach dem Anruf an den übergeordneten Vertrag zurückgegeben?

In Erinnerung. Dies ist ein Auszug aus der Definition von CALLim Yellow Paper.

Auszug aus der Definition von CALL

Wie Sie sehen, werden die Ausgabedaten im Speicher gespeichert und dann mu_oals Kurzform/Zeiger auf diesen Teil im Speicher eingeführt.

Ja, ich weiß bereits, dass der RETURNOpcode Daten aus dem Speicher liest ... Aber meine Frage ist, wo werden die Daten nach dem Aufruf an den übergeordneten Vertrag zurückgegeben?
In Erinnerung. Ich habe die Antwort bearbeitet, um das zu zeigen. Insbesondere beim Ausführen von CALL geben Sie an, wohin genau im Speicher die Rückgabedaten geschrieben werden.
Auch für einen einfachen True/False-Rückgabewert?
Ja, in der Tat! EVM zeichnet sich nicht durch Einfachheit aus.
Und wenn Null auf den Stack geschoben wird, wurde die Vertragsausführung aus irgendeinem Grund rückgängig gemacht? nicht wahr?
Nun, 0 ist in EVM dasselbe wie false, also ist das ein gültiger Rückgabewert. Revert geschieht, wenn der REVERTOpcode verwendet wird.
Nein, tut mir leid, ich wollte direkt nach dem Ende des Anrufs auf die Rückkehr geschoben werden. Und aus irgendeinem Grund meinte ich so etwas wie REVERToder aus Gas oder Stapelunterlauf.