Panic vs Error: the developers Friend & Foe
Let's talk about Panic vs Error.
"Error" refers to a condition indicating that a contract has encountered an issue it cannot handle. This could be due to an invalid input, an unexpected state, or other issues the contract was not designed to handle.
"Panic" refers to a condition indicating that the EVM has encountered an issue it cannot handle. This could be due to an unhandled exception, an out-of-gas situation, or other issues that the EVM was not designed to handle. (ex If you divide or modulo by zero)
One key difference between "Error" and "Panic" is that "Error" is a condition that is expected to be handled by the contract, while "Panic" is a condition that is not likely to be handled by the contract.
When a contract encounters an "Error," it uses the "REVERT" opcode to halt execution and revert any changes made to the contract state. This allows the contract to gracefully handle unexpected conditions and return to a known, stable state.
When the EVM encounters a "critical error (Panic)," it stops all execution and reverts all changes to the contract state. This is a last-resort measure to prevent the EVM from entering an unknown or unstable state.
Properly functioning code should never create a Panic, not even on invalid external input. If this happens, then there is a bug in your contract that you should fix.
Solidity supports two error signatures for error handling, `Error(string)` and `Panic(uint256)`, to ease the developer's life.
An `Error(string)` exception (or an exception without data) is generated by the compiler in the following situations:
"Panic(uint)" uses specific error codes to distinguish certain situations in which the panic is triggered. This is the current list of error codes (which can be extended in the future):
But there exist some ambiguous situations that can either cause an Error or a Panic.
I made two simple contracts in the remix to check how it gets compiled at the bytecode level and how solidity does its magic.
In the OPCODE view of the contract, first "Errors," you will find the following in this bytecode. The "PUSH32 08c379a0..." which the function signature of "Error(string)."
Similarly, In the Opcode view of the second contract, Errors2, you will find the "PUSH32 4e487b71..." which is the function signature of "Panic(unit)."
That concludes that solidity introduces these signatures in bytecode to revert with error data.
BONUS: You can Handle the error in solidity for cases including external contract calls or contract creation.
I hope you enjoyed the Panic. 🏴☠️