Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

INVALID operation opcode. #5

Closed
rkart14 opened this issue Jan 29, 2021 · 2 comments
Closed

INVALID operation opcode. #5

rkart14 opened this issue Jan 29, 2021 · 2 comments

Comments

@rkart14
Copy link

rkart14 commented Jan 29, 2021

Hi,

Great costs...

On execution of any invalid operation, whether the designated INVALID op or simply an undefined op, all remaining gas is consumed and the state is reverted to the point immediately prior to the beginning of the current execution context..

Could you explain what you mean by this ? if the revert happens, all remaining gas is NOT consumed, but it goes back to the caller's account

@wolflo
Copy link
Owner

wolflo commented Jan 29, 2021

This is true of REVERT, but not of INVALID. INVALID is unique in that it's not actually an opcode. That is, it doesn't exist in the list of operations that client implementations know how to handle (see geth's opcodes).

REVERT is an EVM instruction with defined semantics (end execution, return remaining gas, and place mem[ost:ost+len] in returndata). But the EVM has several exceptional states that occur when the next operation cannot be executed. In all of these cases, the remaining gas is consumed and execution is ended.

There is a long list of things that can cause such an exception: overflowing or underflowing the stack, trying to jump to an invalid jump destination, trying to execute a state-changing opcode within a STATICCALL, running out of gas, trying to send value > BALANCE with a CALL or CALLCODE, using CREATE2 to deploy to an account that already exists, exceeding the 1024 call depth limit, bad memory access*, or trying to execute an instruction that doesn't exist.

The last one means that any unassigned opcode does the same thing as the INVALID opcode. At some point compilers started using these unassigned opcodes to force execution to end, usually to indicate that something particularly bad or unexpected happened. But, unassigned opcodes can become assigned in the future. If you deploy a contract with the 0x0c opcode, for example, it will cause an exception as of the Istanbul hardfork. In the future, though, it might be given some meaningful semantics that would change the semantics of your entire contract.

Because of this, everyone at some point (EIP-141) came to a consensus that we would designate one of these unassigned opcodes and agree to never assign it in the future. So, INVALID is actually just an opcode that the EVM doesn't know how to execute and everyone has agreed that we will keep it that way.

As a more concrete example of INVALID vs REVERT, REVERT is what solidity uses if a require() condition is not met, while INVALID is used when an assert() condition is not met.

@rkart14
Copy link
Author

rkart14 commented Jan 29, 2021

Thanks for such a great answer. Really appreciated !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants