I studied EVM implementations and the bytecode sequences used by them. I wondered that there are three opcodes which are recognized by the EVM but actually are invalid opcodes.
B0 PUSH
B1 DUP
B2 SWAP
If I execute the opcode B0
with Geth-EVM i get the following output:
./geth-evm-1.8.0-stable --json --code b0 run
{"pc":0,"op":176,"gas":"0x2540be400","gasCost":"0x0","memory":"0x","memSize":0,"stack":[],"depth":1,"opName":"PUSH","error":"invalid opcode 0xb0"}
{"output":"","gasUsed":"0x2540be400","time":137988,"error":"invalid opcode 0xb0"}
{"output":"","gasUsed":"0x2540be400","time":210042,"error":"invalid opcode 0xb0"}
As one can see, the opcode B0
is recognized and processed as PUSH
opcode. At the same time the error field writes invalid opcode 0xb0
. The same holds for the other two opcodes. I tested this also with the Parity-EVM implementation. Parity does not know the opcodes and prints directly an error:
./parity-evm --json --code b0
{"pc":0,"op":176,"opName":"","gas":"0xffffffffffffffff","gasCost":"0x0","memory":"0x","stack":[],"storage":{},"depth":1}
{"error":"EVM: Bad instruction b0","gasUsed":"ffffffffffffffff","time":9881}
Why do these opcodes exist and for what reason? Why does the EVM of go-ethereum know the opcodes but not the implementation of Parity?
EDIT:
I also found this const
in the go-ethereum source code:
// unofficial opcodes used for parsing
const (
PUSH OpCode = 0xb0 + iota
DUP
SWAP
)
They mention, that they use it for parsing and they are unofficial.