Gemäß der neuesten Version des Yellow Paper und der Solidity-Assembly-Spezifikation kann Revert Opcode einen Fehlercode zurückgeben.
http://solidity.readthedocs.io/en/develop/assembly.html
revert(p, s) - Ausführung beenden, Zustandsänderungen rückgängig machen, Daten zurückgeben mem[p..(p+s))
Die Revert-Funktion in reiner Solidität hat jedoch 0 Argumente. Ich denke, es unterstützt noch keinen Rückgabecode.
[F] : Wie kann ich die Wiederherstellung von der Solidity-Assembly verwenden, um einen Fehlercode an die aufrufende web3-JavaScript-Anwendung zu übergeben? Falls dies nicht möglich ist, begründen Sie bitte warum.
Update : siehe auch Solidity: Wie können wir eine Fehlermeldung in "require" schreiben?
Wie in den Kommentaren besprochen, gibt es keine einfache Möglichkeit, den Rückgabegrund in der Dapp zu erhalten. Diese Funktion wird jedoch möglicherweise in Zukunft unterstützt.
Hier ist die anfängliche EIP und ihre Diskussion:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-658.md https://github.com/ethereum/EIPs/pull/658
Vorherige Antwort
Soweit ich weiß, ist es einem Client wie web3 nicht möglich, die Revert-Ausgabe zu lesen, ebenso wie es nicht möglich ist, die Ausgabe im Falle eines normalen Transaktionsabschlusses zu lesen. Revert verwendet Ausgabedaten o
wie im Yellow Paper definiert, die für Nachrichtenaufrufe verwendet werden können, aber für Transaktionen ignoriert werden.
Nachrichtenaufrufe haben auch eine zusätzliche Komponente – die Ausgabedaten, die durch das Byte-Array o gekennzeichnet sind. Dies wird bei der Ausführung von Transaktionen ignoriert, jedoch können aufgrund der Ausführung von VM-Code Nachrichtenaufrufe initiiert werden, und in diesem Fall werden diese Informationen verwendet.
Die Wirkung des REVERT-Opcodes ist durch die Formel 140 gegeben, die sich auf den Ausgang bezieht o
.
Remix zeigt jedoch die Ausgabe bei Verwendung von JavaScript VM, da es Transaktionen synchron ausführt:
pragma solidity^0.4.11;
contract C {
function testRevert() pure public returns (uint result) {
uint memOffset;
assembly {
memOffset := msize() // Get the highest available block of memory
mstore(add(memOffset, 0x00), 6) // Set value
mstore(0x40, add(memOffset, 0x20)) // Update the msize offset to be our memory reference plus the amount of bytes we're using
revert(memOffset, 0x20) // revert returning 1 byte
}
}
}
Decodierte Ausgabe:
{
"0": "uint256: result 6"
}
Bei der Ausführung auf Testnets oder Mainnet gibt es keine Ausgabe.
Es sollte möglich sein, die Revert-Ausgabe zu lesen, wenn Low-Level-Assembly verwendet call
wird delegatecall
( callcode
ich werde diese Antwort aktualisieren, wenn ich ein funktionierendes Codebeispiel habe).
Ich gehe davon aus, dass in Solidity eine try-catch
-ähnliche Funktion hinzugefügt wird, wenn call
, delegatecall
, callcode
und Verträge über ihre Schnittstelle aufgerufen werden (wird die Antwort aktualisieren, wenn ich Referenzen habe).
status
Eigenschaft in der tx-Quittung gibt, aber es kann nur 0
oder sein 1
. Wissen Sie, ob es Pläne gibt (z. B. ERC/EIPs), die Retourendaten auf der Quittung zu speichern? Das Auslösen eines Fehlerereignisses würde dem Zurücksetzen der gesamten Transaktion widersprechen. Für das Fehlerereignis müsste ich die Erstellung des Ereignisses festschreiben, aber alles andere rückgängig machen. Was wäre ein Muster dafür?sentGas == usedGas
vorherige Überprüfung, aber effektiv können Sie in der Benutzeroberfläche nur sagen, "Es ging durch" oder "Etwas ist schief gelaufen". Aber was genau schief gelaufen ist, geht in der Zusammenfassung verloren. Ich denke, man könnte die Ablaufverfolgung der Transaktion durchgehen, um den Speicherort zu finden, aber es klingt für diesen Anwendungsfall nach einer Problemumgehung.
Garen Vartanian
require
Nachrichtenfeld gilt?ivicaa