This EIP would allow apps and tools to have a standard way to get revert messages of a transaction.
Hey there, I like this idea and I also see how this is useful in practice. However, this will incur gas extra gas cost on any REVERT
operation which has nonzero byte length. This will:
- Increase gas costs of anything which runs in a REVERT which reports nonzero data
- Due to raising gas costs of the REVERT opcode this might now break things (REVERT having not enough gas to pay for log costs â the revert now gets converted in an INVALID. This also means that if return bytes were written as REVERT error data these are now cleared, because the call frame turns in a INVALID call frame instead of a REVERT one)
Have you considered this alternative: introduce 5 new opcodes with exactly the same semantics as LOGx
(LOG0
⌠LOG4
) which we call RLOG
. The logs are now kept and emitted even in case this call frame / upper call frames REVERT / INVALID.
Did you also consider the fact that you could create a wrapper in the calling code which will catch and LOG
data in case it runs in a REVERT? Without doing a fork or introducing new opcodes, you could: (1) call the contract and on (2) return values, check if the call succeeded. If this is not the case, check if there is RETURNDATA (RETURNDATASIZE > 0
). If this is the case, now emit a log (you can read the reverted data from the returndata and thus log this)
I donât think it needs to be a log but return data could become a separate part of the transaction receipt. We would need to meter it in the gas for the top-level transaction.
We had two ideas in mind to solve this:
- Make the log free like EIP-7708
- Charge the log gas as part of intrinsic gas
While I do like this idea (and makes sense to do it in addition to this), it doesnât really solve the issue that this EIP is trying to solve (create a standard way to get the revert message) since it would require smart contracts to opt in to this feature.
I donât quite get what you mean here - is this wrapper is a smart contract on chain?
I did consider transaction receipts - and it does make sense to at least place it there if we donât decide to do it as a log. However doing it as a log has some benefits:
- Filtering across a block(s)
- Monitor for failed transactions with
eth_subscribe
Adding it as a part of the receipt also brings issues with historical data since there would be some database migration required to service receipt queries for older transactions.
Also see Felixâs comments [here] regarding return data not being part of the receipt. (feat: add returndata to tx receipts by charles-cooper ¡ Pull Request #542 ¡ ethereum/execution-apis ¡ GitHub).
In case we decide to increase the cost of the REVERT
opcode, how big of an issue will be the edge-case of not having enough gas to emit the REVERT
log? The result would be a transaction with an âout-of-gasâ revert reason that has no emitted events on-chain, which is exactly the case with all reverted transactions right now.
And overall, to me it seems quite similar to having a transaction run out of gas exactly upon reaching a require(condition, "good revert reason")
statement in a smart contract even without a revert log - unfortunate, but the revert reason will be kind of âlostâ.
I see how this can be useful for some debugging/tracing, but could you please elaborate on what problem you are trying to solve?
Also a question how would the behavior of a STATICCALL
change? Currently emitting logs in a static context is prohibited.
The problem is providing to Blockchain users and app developers an easy, out-of-the-box and decentralized access to the revert reasons of their transactions. The usefulness of this feature may range from slightly better UX to potential security threats.
Currently, the revert reasons of transactions are either unknown, or may provided by Etherscan on supported chains. Which is a centralized service that is forced to trace transaction to discover this information in the first place, which is extremely inefficient. There is also no way to check if the displayed value is correct and it may even contain some false data.
As the EIP only affects the top execution frame of the transaction, and the top frame cannot be a STATICCALL
, there is no overlap between the two.