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

Add zkevm differences #326

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions learn_evm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ List of EVM Technical Knowledge
- [Transaction Tracing](tracing.md): Helper scripts and guidance for generating and navigating transaction traces
- [Arithmetic Checks](./arithmetic-checks.md): Guide to performing arithmetic checks in the EVM
- [Yellow Paper Guidance](yellow-paper.md): Symbol reference for more easily reading the Ethereum yellow paper
- [zkEVM <> EVM](zkevm.md): Summarizes the differences between EVM and zkEVM
- [Forks <> EIPs](eips_forks.md): Summarizes the EIPs included in each fork
- [Forks <> CIPs](cips_forks.md): Summarizes the CIPs and EIPs included in each Celo fork _(EVM-compatible chain)_
- [Upgrades <> TIPs](tips_upgrades.md): Summarizes the TIPs included in each TRON upgrade _(EVM-compatible chain)_
Expand Down
21 changes: 21 additions & 0 deletions learn_evm/zkevm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The following list presents differences between the EVM and the zkEVM implemented by zkSync Era

| EVM Opcode | Difference Description |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CREATE`, `CREATE2` | On zkSync Era, contract deployment is performed using the hash of the bytecode, and the `factoryDeps` field of EIP712 transactions contains the bytecode. The actual deployment occurs by providing the contract's hash to the `ContractDeployer` system contract. See the [zkSync Era documentation](https://era.zksync.io/docs/reference/architecture/differences-with-ethereum.html#evm-instructions) for more information about these differences. |
| `CALL`, `STATICCALL`, `DELEGATECALL` | For calls, you specify a memory slice to write the return data to, e.g. out and outsize arguments for call(g, a, v, in, insize, out, outsize). In EVM, if outsize != 0, the allocated memory will grow to out + outsize (rounded up to the words) regardless of the returndatasize. On zkSync Era, returndatacopy, similar to calldatacopy, is implemented as a cycle iterating over return data with a few additional checks and trigerring a panic if out + outsize > returndatasize to simulate the same behavior as in EVM. |
| `MSTORE`, `MLOAD` | Unlike EVM, where memory growth is measured in words, zkEVM measures in bytes. For instance, `mstore(100, 0)` will result in `msize` of `132` on zkEVM, while it is `160` on EVM. Also, EVM has quadratic memory growth for memory payments, but zkEVM charges fees linearly at a rate of `1` erg per byte. Our compiler optimizes unused memory reads/writes, which results in a different `msize` compared to Ethereum, since fewer bytes are allocated. This difference in memory growth may cause EVM to panic, but zkEVM will not in some cases. |
| `CALLDATALOAD`, `CALLDATACOPY` | If `offset` is over `2^32-33` when using `calldataload(offset)`, the execution will panic. The `calldatacopy(to, offset, len)` function in zkEVM contains a loop that uses the `calldataload` and `mstore` functions during each iteration. This means that if `2^32-32 + offset % 32 < offset + len`, the code will panic. |
| `RETURN` | Constructors in the zkSync Era return an array of immutable values initialized up to the point of assembly block execution, when using RETURN within the constructor. |
| `TIMESTAMP`, `NUMBER` | For more information about blocks on zkSync Era, including the differences between `block.timestamp` and `block.number`, refer to the [documentation](https://era.zksync.io/docs/reference/concepts/blocks.html#blocks-in-zksync-era). |
| `COINBASE` | This returns the address of the `Bootloader` contract, which is `0x8001` on the zkSync Era. |
| `DIFFICULTY` | Returns a constant value of `2500000000000000` on zkSync Era. |
| `BASEFEE` | This is not a constant on zkSync Era and is instead defined by the fee model. Most of the time it is 0.25 gwei, but under very high L1 gas prices it may rise. |
| `SELFDESTRUCT` | Considered harmful and deprecated in [EIP-6049](https://eips.ethereum.org/EIPS/eip-6049). Always produces a compile-time error with the zkEVM compiler. |
| `CALLCODE` | Deprecated in [EIP-2488](https://eips.ethereum.org/EIPS/eip-2488) in favor of `DELEGATECALL`. Always produces a compile-time error with the zkEVM compiler. |
| `PC` | Inaccessible in Yul and Solidity `>=0.7.0`, but accessible in Solidity `0.6`. Always produces a compile-time error with the zkEVM compiler. |
| `CODESIZE` | Yul uses a special instruction `datasize` to distinguish the contract code and constructor arguments, so we substitute `datasize` with 0 and `codesize` with `calldatasize` in zkSync Era deployment code. This way when Yul calculates the calldata size as `sub(codesize, datasize)`, the result is the size of the constructor arguments. |
| `CODECOPY` | In the context of deploy code, this copies the constructor arguments. In the context of old EVM codegen runtime code, this zeroes out memory. And in the context of new yul codegen runtime code, this produces a compile-time error. |
| `EXTCODECOPY` | Contract bytecode cannot be accessed on zkEVM architecture. Only its size is accessible with both `CODESIZE` and `EXTCODESIZE`. `EXTCODECOPY` always produces a compile-time error with the zkEVM compiler. |
| `DATASIZE`, `DATAOFFSET`, `DATACOPY` | Contract deployment is handled by two parts of the zkEVM protocol: the compiler front end and the system contract called `ContractDeployer. See the [zkSync Era documentation](https://era.zksync.io/docs/reference/architecture/differences-with-ethereum.html#datasize-dataoffset-datacopy) for more information about these differences. |
| `SETIMMUTABLE`, `LOADIMMUTABLE` | zkEVM does not provide any access to the contract bytecode, so the behavior of immutable values is simulated with the system contracts. See the [zkSync Era documentation](https://era.zksync.io/docs/reference/architecture/differences-with-ethereum.html#setimmutable-loadimmutable) for more information about these differences. |