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

Some clarifications for BEGINDATA. #3328

Merged
merged 1 commit into from
Mar 5, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions EIPS/eip-2327.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,33 @@ created: 2019-10-28
---

## 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.
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 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 `JUMPDEST`s 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.
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 `JUMPDEST`s 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](./eip-615.md) 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. Additionally, it paves the way for suggestions such as [EIP-1712](https://github.com/ethereum/EIPs/pull/1712) to disallow unused opcodes, jumptables [EIP-615](./eip-615.md) and speculative proposals to disallow for deployment of contracts with stack usage violations.
The `BEGINDATA` opcode has been suggested before as part of the EIP `Subroutines and Static Jumps for the EVM` [EIP-615](./eip-615.md) 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](https://github.com/ethereum/EIPs/pull/1712) to disallow unused opcodes, jumptables [EIP-615](./eip-615.md) and speculative proposals to disallow for deployment of contracts with stack usage violations.

## Specification
While computing the valid `JUMPDEST`s of a contract, halt analysis if `BEGINDATA` is encountered. A `JUMP` to a value higher than the `PC` value of `BEGINDATA` should throw with a `BAD_JUMP_DESTINATION` error. Bytes past `BEGINDATA` remain accessible via `CODECOPY` and `EXTCODECOPY`.
While computing the valid `JUMPDEST`s 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](./eip-615.md).
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some examples of this at https://github.com/wolflo/meta-jumpers, although I believe the ones in that repo were designed specifically to exhibit this behavior, and does not exactly warrant being regarded as "real world examples"

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.
Expand Down