forked from DecentralizedClimateFoundation/DCIPs
65 lines
3.5 KiB
Markdown
65 lines
3.5 KiB
Markdown
---
|
|
eip: 3855
|
|
title: PUSH0 instruction
|
|
description: Introduce a new instruction which pushes the constant value 0 onto the stack
|
|
author: Alex Beregszaszi (@axic), Hugo De la cruz (@hugo-dc), Paweł Bylica (@chfast)
|
|
discussions-to: https://ethereum-magicians.org/t/eip-3855-push0-instruction/7014
|
|
status: Stagnant
|
|
type: Standards Track
|
|
category: Core
|
|
created: 2021-02-19
|
|
---
|
|
|
|
## Abstract
|
|
|
|
Introduce the `PUSH0` (`0x5f`) instruction, which pushes the constant value 0 onto the stack.
|
|
|
|
## Motivation
|
|
|
|
Many instructions expect offsets as inputs, which in a number of cases are zero. A good example is the return data parameters of `CALLs`, which are set to zeroes in case the contract prefers using `RETURNDATA*`. This is only one example, but there are many other reasons why a contract would need to push a zero value. They can achieve that today by `PUSH1 0`, which costs 3 gas at runtime, and is encoded as two bytes which means `2 * 200` gas deployment cost.
|
|
|
|
Because of the overall cost many try to use various other instructions to achieve the same effect. Common examples include `PC`, `MSIZE`, `CALLDATASIZE`, `RETURNDATASIZE`, `CODESIZE`, `CALLVALUE`, and `SELFBALANCE`. Some of these cost only 2 gas and are a single byte long, but their value can depend on the context.
|
|
|
|
We have conducted an analysis on Mainnet (block ranges 8,567,259…8,582,058 and 12,205,970…12,817,405), and ~11.5% of all the `PUSH*` instructions executed push a value of zero.
|
|
|
|
The main motivations for this change include:
|
|
1. Reducing contract code size.
|
|
2. Reducing the risk of contracts (mis)using various instructions as an optimisation measure. Repricing/changing those instructions can be more risky.
|
|
3. Reduce the need to use `DUP` instructions for duplicating zeroes.
|
|
|
|
To put the "waste" into perspective, across existing accounts 340,557,331 bytes are wasted on `PUSH1 00` instructions, which means 68,111,466,200 gas was spent to deploy them. In practice a lot of these accounts share identical bytecode with others, so their total stored size in clients is lower, however the deploy time cost must have been paid nevertheless.
|
|
|
|
An example for 2) is changing the behaviour of `RETURNDATASIZE` such that it may not be guaranteed to be zero at the beginning of the call frame. This was proposed as a way to chain transactions (i.e. EIP-2733).
|
|
|
|
## Specification
|
|
|
|
The instruction `PUSH0` is introduced at `0x5f`. It has no immediate data, pops no items from the stack, and places a single item with the value 0 onto the stack. The cost of this instruction is 2 gas (aka `base`).
|
|
|
|
## Rationale
|
|
|
|
### Gas cost
|
|
|
|
The `base` gas cost is used for instructions which place constant values onto the stack, such as `ADDRESS`, `ORIGIN`, and so forth.
|
|
|
|
### Opcode
|
|
|
|
`0x5f` means it is in a "contiguous" space with the rest of the `PUSH` implementations and potentially could share the implementation.
|
|
|
|
## Backwards Compatibility
|
|
|
|
This EIP introduces a new opcode which did not exists previously. Already deployed contracts using this opcode could change their behaviour after this EIP.
|
|
|
|
## Test Cases
|
|
|
|
- `5F` -- successful execution, stack consist of a single item, set to zero
|
|
- `5F5F..5F` (1024 times) -- successful execution, stack consists of 1024 items, all set to zero
|
|
- `5F5F..5F` (1025 times) -- execution aborts due to out of stack
|
|
|
|
## Security Considerations
|
|
|
|
The authors are not aware of any impact on security. Note that jumpdest-analysis is unaffected, as `PUSH0` has no immediate data bytes.
|
|
|
|
## Copyright
|
|
|
|
Copyright and related rights waived via [CC0](../LICENSE.md).
|