The problem with having new versions is that the EVM spec would need to keep having those versions, and so as the EVM keeps evolving the de-facto spec size that clients have to implement will keep increasing forever. This is what I am desperately hoping we can get away from.
Why do we need to disable the code reading opcodes to enable this? Couldn’t we preserve the original bytes alongside any transpiled version? I assume it’s to save storage space, and if so, how bad would it be to keep both?
I guess this could work, though it would come at a cost of an extra 24000 bytes per account. It would also be much less elegant. Like, it seems clear to me that the correct way to do this if we created the EVM from scratch would be to have an executable-but-opaque code section and a readable-but-unexecutable data section, and my data field proposal tries to move the EVM in this direction.
Obviously when we convert existing (pre-EOF) contracts into some new EVM version, we would need to put the entire old code into the data field for backwards-compatibility reasons.
How do we plan to handle existing non-EOF contracts? Turn them off? Keep the current introspectable EVM forever, but only ever keep one opaque EVM?
My first instinct is:
Stage 1: keep the current EVM around, and work on the EOF EVM, so we have two versions (and temporarily three versions during upgrades)
Stage 2, when we have more spare time: do the work to translate existing EVM contracts into the EOF EVM, and accept the inefficiencies (redundancy from the entire code being in the data field, and having to transalate every dynamic jump into a case-switch-like statement with a jump table)
Did you exclude
CODESIZE
(0x38
) andEXTCODESIZE
(0x3B
) intentionally?
Ah no, it was a mistake to exclude those.