---
title: "EIP-3855 — PUSH0 Opcode"
description: "EIP-3855 — PUSH0 Opcode mapped to Neo N3."
---
# EIP-3855 — PUSH0 Opcode
[Back to Protocol-Level EIPs](/standards-mirror/protocol-eips)
<StandardsMirror>
<StandardEntry
id="eip-3855"
title="EIP-3855 — PUSH0 Opcode"
eip="3855"
status="Final"
neoMapping="Native PUSH0 in NeoVM"
category="Opcodes"
parityLabel="Native"
parityClass="sm-pill-native"
>
<template #spec>
## EIP-3855: PUSH0 Opcode
Before EIP-3855, pushing zero onto the EVM stack required `PUSH1 0x00` (2 bytes,
3 gas). EIP-3855 added `PUSH0` (`0x5f`) — 1 byte, 2 gas. A trivial-looking change
that saves significant bytecode size and gas across the entire ecosystem because
zero is the most-pushed value.
### Status
Activated in the Shanghai hard fork (April 2023). Solidity 0.8.20+ emits PUSH0 by
default for chains that support it.
### Neo Equivalent
NeoVM has had `PUSH0` (opcode `0x10`) since launch, plus `PUSH1` through `PUSH16` as
direct integer constants. There was no need for a retrofit because the design
included it from day one.
::: tip Live on Neo TestNet
Both implementations are deployed on Neo N3 TestNet (network magic `894710606`).
| **Solidity** (`neo-solc`) | `0x52b860448a5d1ff537160a0bee8c83cdfe72fe4d` | [`0xba96b7c4…1c0a8d`](https://dora.coz.io/transaction/neo3/testnet/0xba96b7c4398ed9d881c0a789b9222059ae2bba193dc20fc6327f8ead2b1c0a8d) |
| **Neo C#** (`nccs`) | `0x6704d604997959ce4e098bd96ecbacef358e9ff6` | [`0x92572481…a6c00c`](https://dora.coz.io/transaction/neo3/testnet/0x925724819e4e732f7bc33eb652acb633a2a08ccd98b5646413e832bdc7a6c00c) |
Checked-in snapshot: Solidity 2 / 2 assertions pass; Neo C# 2 / 2 assertions pass. This is a validation snapshot, not an all-green parity certification; see [TestNet Results](/standards-mirror/deployments/RESULTS) for failure details.
Source pairs: [`docs/standards-mirror/deployments/eip-3855/`](https://github.com/r3e-network/neo-devpack-solidity/tree/main/docs/standards-mirror/deployments/eip-3855).
:::
</template>
<template #solidity>
```
EVM bytecode comparison:
Pre-EIP-3855: 60 00 PUSH1 0x00
[2 bytes, 3 gas]
Post-EIP-3855: 5f PUSH0
[1 byte, 2 gas]
Across an entire compiled contract, this can save dozens of bytes and millions of
gas across thousands of executions. OZ's ERC-20 dropped ~50 bytes after the
PUSH0 introduction.
```
</template>
<template #csharp>
```
NeoVM bytecode (since day one):
PUSH0 (0x10) // push integer 0
PUSH1 (0x11) // push integer 1
PUSH2 (0x12) // push integer 2
...
PUSH16 (0x20) // push integer 16
PUSHM1 (0x0F) // push integer -1
PUSHA (0x0A) // push address
PUSHNULL (0x0B) // push StackItem.Null
PUSHDATA1 (0x0C) ... // push N bytes (N <= 255)
A Solidity-to-NeoVM compiler (like neo-devpack-solidity) emits PUSH0 directly when it
needs zero. There's no retrofit story here because the VM was designed with
small-integer constant opcodes from the start.
```
### Compiler Note
The `neo-devpack-solidity` compiler maps Solidity zero literals to NeoVM `PUSH0` on every
emit. No version gate, no chain-version conditional — the opcode has always been
available.
</template>
</StandardEntry>
</StandardsMirror>