### Ipsilon Hugo de la Cruz Romero -- [github.com/hugo-dc](https://github.com/hugo-dc) Alex Beregszaszi [github.com/axic](https://github.com/axic) -- A protocol research team focusing on the EVM. Website: [ipsilon.xyz](https://ipsilon.xyz) --- ### EIP-3855: PUSH0 Instruction - Status: Review - Considered for inclusion in <br>_Shanghai_ Network Upgrade --- ### Introduction - Usage of constant value `0` - Value of zero frequently used by many instructions expecting offsets as inputs. --- ### Introduction - Examples: - Opcodes dealing with offsets: - `CALLDATACOPY` - `CODECOPY` - `EXTCODECOPY` - etc. - `CALL*`: Setting zeros as return data parameters when the contract prefers using `RETURNDATA*` to retreive the results. --- ### Abstract - New opcode `PUSH0` with a cost of `2` gas (`base`). - It is introduced as the instruction number `0x5f`. |Hex|Name| |---|----| |...|... | |**`0x5f`**| **PUSH0**| |`0x60`| PUSH1| |... | PUSHn| |`0X7f`| PUSH32| --- ### Motivation - Reduce gas usage and contract code size: - `PUSH1 00` ~ `60 00`: 400 gas for deployment, 3 gas for runtime. - `PUSH0` ~ `5f`: 200 gas for deployment, 2 gas for runtime. --- ### Motivation - Reduce risk of contracts (mis)using instructions as an optimisation measure. - `PC` - `MSIZE` - `CALLDATASIZE` - `RETURNDATASIZE` - `CODESIZE` - `CALLVALUE` - `SELFBALANCE` --- ### Example - EIP-2733 (*Withdrawn*) - If implemented, would have changed the behaviour of `RETURNDATASIZE` such that it may not be guaranteed to be zero at the beginning of the call frame. --- ### Analysis and Findings --- ### Analysis and Findings - Traced transactions in two different nodes syncing mainnet: - Geth Node 1: Syncing at block ~8M - Geth Node 2: Syncing at block ~12M --- ### Analysis and Findings - Result: Histogram of Opcode usage, with special column for `PUSH1 00` (`PUSH0`): ![](https://storage.googleapis.com/ethereum-hackmd/upload_6dfbcd92e97acc3630b1113e7d743a8e.png) ![](https://storage.googleapis.com/ethereum-hackmd/upload_1f96789b3db77b30d170b68fb55d7737.png) ![](https://storage.googleapis.com/ethereum-hackmd/upload_6a39ac8cee0a3f0faa29be02ea328037.png) --- #### General Opcode Usage ![](https://storage.googleapis.com/ethereum-hackmd/upload_7419f3867b20298e665e65889561887d.png =750x580) --- #### PUSHn Usage ![](https://storage.googleapis.com/ethereum-hackmd/upload_49e5f844744772f73602bb94e06e3d82.png =750x580) --- #### PUSH1 00 ![](https://storage.googleapis.com/ethereum-hackmd/upload_129a9d38c95bdd18d3d3270f42aba943.png =750x580) --- #### Other commonly used constants ![](https://storage.googleapis.com/ethereum-hackmd/upload_f838cd889445229b39b874c35b6d89c5.png =650x550) --- ### Commonly used constants - `0`: solved by `PUSH0` - `1`: largely used in loops, could be solved by `INC`/`DEC` - `2`: mostly used by old contracts to emulate shifts - `31` and `32`: are mostly used by the ABI en/decoder in Solidity --- ### `INC`/`DEC` - `INC` to increase-by-one the top item, `DEC` to decrease - Useful for loops, where this is done with `PUSH1 1 ADD` - Pro: saves 2x200 gas for deployment, and at least costs half runtime - Con: too much of a CISC direction
{"title":"PEEPanEIP-3855: PUSH0 Instruction","type":"slide","slideOptions":{"theme":"league","allottedMinutes":15}}
    1262 views
   owned this note