EIP-2327: BEGINDATA opcode


Metadata
Status: StagnantStandards Track: CoreCreated: 2019-10-28
Authors
Martin Lundfall (@MrChico)

Simple Summary


Introduces a new opcode BEGINDATA, which indicates that the remaining bytes of the contract should be regarded as data rather than contract code and cannot be executed.

Abstract


It is common for smart contracts to efficiently store data directly in the contract bytecode. Examples include constructor arguments, constant variables, compiler metadata and the contract runtime during the init phase. Currently, such data is not distinguished from normal bytecode and is still being analysed for JUMPDESTs by EVM interpreters. This EIP introduces a new opcode BEGINDATA at byte 0xb6, which marks the remainding bytecode as data, indicating to EVM interpreters, static analysis tools and chain explorers that the remaining bytes do not represent opcodes.

Motivation


The BEGINDATA opcode has been suggested before as part of the EIP Subroutines and Static Jumps for the EVM EIP-615 as a way to determine the position of jumptables in contract bytecode. It is here introduced in its own right in order to exclude data from the JUMPDEST analysis of contracts, making it impossible to jump to data. This makes it easier for static analysis tools to analyse contracts, allows disassemblers, chain explorers and debuggers to not display data as a mess of INVALID opcodes and may even provide a marginal improvement in performance. It also helps scalability because it improves on-chain evaluation of transactions from other chains in that the validation that the code conforms to a certain pattern does not need to do a full jumpdest analysis to see that data is not executed and thus does not have to conform to the pattern (used by the optimism project). Additionally, it paves the way for suggestions such as EIP-1712 to disallow unused opcodes, jumptables EIP-615 and speculative proposals to disallow for deployment of contracts with stack usage violations.

Specification


While computing the valid JUMPDESTs of a contract, halt analysis once the first BEGINDATA is encountered. In other words: A jump to any codelocation equal to or greater than the location of the first BEGINDATA causes a BAD_JUMP_DESTINATION error. If BEGINDATA is encountered during contract execution, it has the same semantics as STOP. It uses 0 gas.

Bytes past BEGINDATA remain accessible via CODECOPY and EXTCODECOPY. BEGINDATA does not influence CODESIZE or EXTCODESIZE.

Rationale


The byte 0xb6 was chosen to align with EIP-615. The choice to STOP if BEGINDATA is encountered is somewhat arbitrary. An alternative would be to be to abort the execution with an out-of-gas error.

Backwards Compatibility


The proposal will not change any existing contracts unless their current behaviour relies upon the usage of unused opcodes.

Since contracts have been using data from the very start, in a sense all of them use unused opcodes, but they would have to use data in a way that it is skipped during execution and jumped over. The Solidity compiler never generated such code. It has to be evaluated whether contracts created by other means could have such a code structure.

Test Cases


Test cases should include:

  1. A contract which jumps to a destination X, where X has a pc value higher than the BEGINDATA opcode, and the byte at X is 0x5b. This should fail with a BAD_JUMP_DESTINATION error.
  2. A contract which encounters the BEGINDATA opcode (should stop executing the current call frame)

Implementation


Not yet.

Copyright


Copyright and related rights waived via CC0.