Was ist der Unterschied zwischen einer Transaktion und einem Anruf?

Was ist der Unterschied zwischen einer Transaktion und einem Anruf? In einigen Schnittstellen kann ich über Aufrufe oder über Transaktionen mit Verträgen interagieren. Was ist der Unterschied zwischen den beiden und können Verträge auch Transaktionen und Anrufe ausführen?

HINWEIS zur Vermeidung von Verwirrung: callIn dieser Frage sind weder EVM CALL - Opcode noch Solidity <address>.call() , die Änderungen an Vertragszuständen vornehmen, sondern Web3.js API web3.eth.call(), die keine Zustandsänderungen vornehmen.

Antworten (2)

Anruf

Ein Aufruf ist ein lokaler Aufruf einer Vertragsfunktion, die nichts in der Blockchain sendet oder veröffentlicht.

Es ist eine schreibgeschützte Operation und verbraucht kein Ether. Es simuliert, was in einer Transaktion passieren würde, verwirft aber alle Statusänderungen, wenn es fertig ist.

Es ist synchron und der Rückgabewert der Vertragsfunktion wird sofort zurückgegeben.

Seine web3.js-API ist web3.eth.call und wird für Solidity view, pure, constantfunctions verwendet .

Sein zugrunde liegender JSON-RPC ist eth_call

Transaktion

Eine Transaktion wird an das Netzwerk gesendet, von Minern verarbeitet und, falls gültig, in der Blockchain veröffentlicht.

Es handelt sich um eine Schreiboperation, die sich auf andere Konten auswirkt, den Zustand der Blockchain aktualisiert und Ether verbraucht (es sei denn, ein Miner akzeptiert dies mit einem Gaspreis von null).

Es ist asynchron, da es möglich ist, dass kein Miner die Transaktion in einen Block aufnimmt (z. B. kann der Gaspreis für die Transaktion zu niedrig sein). Da es asynchron ist, ist der unmittelbare Rückgabewert einer Transaktion immer der Hash der Transaktion. Um den "Rückgabewert" einer Transaktion an eine Funktion zu erhalten, müssen Ereignisse verwendet werden (es sei denn, es handelt sich um Fall4, der unten beschrieben wird). Für ethers.js ein Beispiel: Vertragsereignisse mit ethers.js abhören?

Seine web3.js-API ist web3.eth.sendTransaction und wird verwendet, wenn eine Solidity-Funktion nicht als markiert ist constant.

Sein zugrunde liegender JSON-RPC ist eth_sendTransaction

sendTransaction wird verwendet, wenn ein Verb benötigt wird, da es klarer ist als eine einfache Transaktion.

Empfehlung, zuerst anrufen, dann sendTransaction

Da eine sendTransaction Ether kostet, ist es eine gute Praxis, "das Wasser zu testen", indem Sie zuerst vor der sendTransaction einen Aufruf ausgeben. Dies ist eine kostenlose Möglichkeit zum Debuggen und Abschätzen, ob es Probleme mit sendTransaction geben wird, beispielsweise wenn eine Out of Gas-Ausnahme auftritt.

Dieser „Trockenlauf“ funktioniert normalerweise gut, aber in einigen Fällen ist zu beachten, dass der Aufruf eine Schätzung ist, z. B. eine Vertragsfunktion, die den vorherigen Blockhash zurückgibt, unterschiedliche Ergebnisse zurückgibt, je nachdem, wann der Aufruf durchgeführt wurde und wann die Transaktion durchgeführt wurde tatsächlich abgebaut.

Beachten Sie schließlich, dass es manchmal notwendig sein kann, die tatsächliche Gasmenge für den Anruf anzugeben , obwohl ein Anruf kein Ether verbraucht : Das Standardgas für den Anruf in Clients wie Geth kann immer noch unzureichend sein und immer noch zu Out führen von Gas.

Fall 4: Können Verträge Transaktionen erzeugen?

Es gibt 4 Fälle, wie eine Vertragsfunktion aufgerufen werden kann.

Hier sind die 4 Fälle, und die ersten 3 wurden oben behandelt :

  1. direkter Aufruf einer Vertragsfunktion, entstanden durch Aufruf

  2. direkter Aufruf einer Vertragsfunktion, die mit sendTransaction entstanden ist

  3. contract Aufruf einer Contract-Funktion, entstanden bei call

4. Vertrag Aufruf einer Vertragsfunktion, hervorgegangen aus sendTransaction

Obwohl Case4 so klingt, als könne ein Vertrag „auch Transaktionen durchführen“, da er sich innerhalb einer Transaktion befindet, sind die Definition einer Transaktion Daten, die von einem externen Akteur signiert wurden. Case4 ist also keine Transaktion.

Aus dem Gelben Papier :

Transaktion : Ein Datenelement, das von einem externen Akteur signiert wurde. Es repräsentiert entweder eine Nachricht oder ein neues autonomes Objekt. Transaktionen werden in jedem Block der Blockchain aufgezeichnet.

Weiter oben wurde angegeben, dass Events verwendet werden müssen, um den Rückgabewert einer Vertragsfunktion zu erhalten, die von sendTransaction stammt. Das gilt und gilt für Case2. Für Case4 erhält der Vertrag direkt den Rückgabewert einer Vertragsfunktion und kann diesen verwenden. So steht es im Gelben Papier fett gedruckt:

Nachrichtenanruf : Die Weitergabe einer Nachricht von einem Konto an ein anderes. Wenn dem Zielkonto ein nicht leerer EVM-Code zugeordnet ist, dann wird die VM mit dem Zustand des Objekts gestartet und die Nachricht bearbeitet. Wenn der Absender der Nachricht ein autonomes Objekt ist, leitet der Aufruf alle Daten weiter, die von der VM-Operation zurückgegeben werden

Mit diesen Definitionen aus dem Yellow Paper ist ersichtlich, dass Case4 ein Message Call innerhalb einer Transaktion ist (also Zustandsänderungen), es keine Verschachtelung von Transaktionen gibt und dass eine Aktivitätseinheit in der Ethereum-Blockchain alle innerhalb einer einzigen Transaktion ist die mehrere Message Calls enthalten kann .

Update: Da der Aufruf einer Funktion mehrdeutig sein kann (ist es ein eth_call oder ein eth_sendTransaction?), gibt es einen Vorschlag für eth_simulateTransaction .

Ich würde nur eine abschließende Klärung / Schlussfolgerung zur möglichen Mehrdeutigkeit zwischen einem web3-Aufruf () und einem Nachrichtenaufruf () zwischen zwei Verträgen hinzufügen? Die Syntax würde sehr ähnlich aussehen und daher könnte man sehen, dass, wenn ein Vertrag einen anderen Vertrag aufruft, dieser ähnlich wie ein Web3-Aufruf funktioniert, was nicht der Fall ist. Es simuliert es nicht in dieser Umgebung. Es führt zu Zustandsänderungen.
Danke, positiv bewertet und konnte den allerletzten Absatz optimieren.
Ich nenne diese Antwort als Tag-Wiki für den Vertragsaufruf. Fühlen Sie sich frei, das Wiki und den Auszug zu überprüfen und beizutragen .
Ändert sich irgendetwas davon mit der „Abstraktion“, die in Metropolis kommt?
Ich sehe eine Meldung für einen View-Funktionsaufruf in Remix, die besagt: „(Kosten fallen nur an, wenn durch einen Vertrag aufgerufen)“. Ich habe eine Adressguthaben-Prüffunktion, die einen externen Token-Vertrag mit der Erc20- balanceOfMethode aufruft. In diesem Fall wird der Token-Vertrag also tatsächlich von meinem Smart Contract aufgerufen. Wird dies wie angegeben Gas kosten, obwohl der gesamte Prozess schreibgeschützt ist?
@GViz Eine Transaktion, die eine viewoder pure-Funktion aufruft, erfordert niemals eine Zahlung für Gas. Sie haben Recht, dass ein einfacher Weg zu sagen ist, dass ein vollständiger schreibgeschützter Prozess kein Gas kostet. Beachten Sie, dass Gas immer noch von viewFunktionen verwendet wird .
@eth toller Punkt, Gas wird vorübergehend verwendet – aber nicht bezahlt – wenn Ansichtsfunktionen ausgeführt werden, um zu verhindern, dass beliebig große Routinen (z. B. Endlosschleifen) ausgeführt werden.
ist calleine atomare Operation? Mit anderen Worten, wenn das callirgendwo in der Mitte fehlschlägt, wird es zurückgesetzt?
@ user1870400 behält eth_callnichts bei: "Rollback" ist das Standardverhalten.
@eth wann werden Zustandsaktualisierungen in den Speicher geschrieben (persistent)? Nach meinem Verständnis beim Lesen der Codebasis sieht es so aus, als würden Zustandsaktualisierungen in den Speicher geschrieben, wenn der Block bis dahin an Blockchain angehängt wird. Ist das korrekt?

Der Unterschied zwischen einem Aufruf und einer Transaktion ist folgender:

  • Transaktionen werden von Ihrem Client erstellt, signiert und an das Netzwerk gesendet. Sie werden schließlich den Zustand der Blockchain verändern, indem sie zum Beispiel Salden oder Werte in Smart Contracts manipulieren.

  • Aufrufe sind Transaktionen, die lokal auf der lokalen Maschine des Benutzers ausgeführt werden, die allein das Ergebnis auswertet. Diese sind schreibgeschützt und schnell. Sie können die Blockchain in keiner Weise verändern, da sie niemals an das Netzwerk gesendet werden. Einige Beispiele "Read-only/Probelauf/Übung".

Anrufe sind nützlich, um Smart Contracts zu debuggen, da sie keine Transaktionsgebühren oder Benzin kosten.

Eine Weile gesucht; das hat es mir endlich erklärt (ich habe einfach den constantModifikator auf meine Funktion gesetzt und es hat funktioniert)