The OP Mainnet upgrade to the Bedrock release will take place on June 6, 2023 at 16:00 UTC!
There will be 2-4 hours of downtime.
See here for additional details. (opens new window)
Bedrock Differences
Bedrock is the next major release of the Optimism network, planned for the second quarter of 2023 (subject to approval by Optimism governance). It will further reduce the differences between Optimism and L1 Ethereum (opens new window). Here are the major changes:
# Guide by persona
If you want to jump directly to the parts relevant to your job role, here are the parts we think will be most useful
Wallet developer
As a wallet developer you are most likely to interact with the JSON RPC, and your users want to know how much their transactions are going to cost. Timing may also be relevant.
Dapp frontend developer
As an application developer you are probably interested in the fact Bedrock has a mempool and the changes in transaction fees. You might also be interested in changes in the RPC interface and block timing.
Dapp backend (protocol) developer
As an application developer you are probably interested in the fact Bedrock has a mempool and the changes in transaction fees. You might also be interested in changes in the RPC interface and block timing.
Infrastructure provider (or anybody else running a node)
To run a node you need to understand the executables required to run it. You might also be interested in the existence of the mempool and the changes in block timing, fees, and the JSON RPC.
See here for a more detailed guide on how to run a Bedrock node.
Bridge developer
As a bridge developer you are likely most interested in deposits into Optimism and withdrawals back into Ethereum L1.
# The EVM
# Block Production
Block Time Subject to Change
Currently blocks are produced every two seconds. However, that value may change in the future.
Unlike the legacy network which mines a block for every incoming transaction, the Bedrock network will produce new blocks every two seconds. This introduces the following changes to the EVM:
TIMESTAMP
will return the timestamp of the block. It will update every two seconds.BLOCKNUMBER
will return an actual block number. It will update every two seconds. The one-to-one mapping between blocks and transactions will no longer apply.
The Bedrock upgrade also introduces the concept of system transactions. System transactions are created by the op-node
, and are used to execute deposits and update the L2's view of L1. They have the following attributes:
- Every block will contain at least one system transaction called the L1 attributes deposited transaction (opens new window). It will always be the first transaction in the block.
- Some blocks will contain one or more user-deposited transactions (opens new window).
- All system transactions have an EIP-2718 (opens new window)-compatible transaction type of
0x7E
. - All system transactions are unsigned, and set their
v
,r
, ands
fields tonull
.
For more information about these transactions, see the deposited transactions specification (opens new window) on GitHub.
Known Issue
Some Ethereum client libraries, such as Web3j, cannot parse the null
signature fields described above. To work around this issue, you will need to manually filter out the system transactions before passing them to the library.
# EIP-1559
As part of the Bedrock upgrade, we have upgraded the network to support EIP-1559 (opens new window). In EIP-1559 the cost of a unit of gas is composed of two components:
- Base fee: This fee is the same for all transactions in a block. It varies between blocks based on the difference between the actual size of the blocks (which depends on the demand for block space) and the target block size. When the block uses more gas than the target block size the base fee goes up to discourage demand. When the block uses less gas than the target block size the base fee goes down to encourage demand.
- Priority fee: This fee is specified in the transaction itself and varies between transactions. Block proposers are expected to select the transactions that offer them the highest priority fees first.
There are some differences between Ethereum and Optimism in this regard:
- ETH is not burned. Burning ETH on L2 would only lock it in the bridge forever.
- The EIP 1559 parameters have different values. Once those values are finalized they will be posted here.
The L1 security fee, which is the majority of the transaction cost, uses the same mechanism as before the upgrade. However, the transactions to L1 are going to be submitted on a non-contract address. Between that and improved compression, the L1 security fee should be reduced by about 20%.
From an application development perspective, EIP-1559 introduces the following changes:
- The
BASEFEE
opcode is now supported. TheBASEFEE
opcodes returns the base fee of the current block. - The
eth_maxPriorityFeePerGas
andeth_feeHistory
RPC methods are now supported.eth_maxPriorityFeePerGas
returns a fee per gas that is an estimate of how much you can pay as a priority fee, or 'tip', to get a transaction included in the current block.eth_feeHistory
returns a collection of historical gas information from which you can decide what to submit as yourmaxFeePerGas
and/ormaxPriorityFeePerGas
.
# Removed Opcodes
One of the design goals of the Bedrock upgrade is to be maximally EVM equivalent. To reduce differences between Optimism's EVM and vanilla Ethereum's EVM, we have removed the L1BLOCKNUMBER
opcode.
# ETH Balances
The previous version of the system used an ERC20 contract called OVM_ETH
to represent ETH balances. These balances will be migrated into the Bedrock network's state as part of the migration. To preserve backwards compatibility, the methods on the OVM_ETH
contract will continue to work. Note, however, that the totalSupply()
method will return zero.
# Chain Reorganizations
Unlike the legacy network, Bedrock nodes always derive blocks from L1. This means that if L1 experiences a reorg, L2 will reorganize itself to match the state of L1. Blocks that have not been submitted to L1 yet are gossipped via a peer-to-peer network, and can be reorganized if the data on L1 does not match the data gossiped over P2P.
Bedrock adopts the same vocabulary as the Beacon Chain to describe block finality. Blocks can be in one of the following states:
unsafe
, meaning that the block has been received via gossip but has not yet been submitted to L1. Unsafe blocks can be reorged if L1 reorgs, or the sequencer reorgs.safe
, meaning that the block has been submitted to L1. Safe blocks can also be reorged if L1 reorgs.finalized
, meaning that the block has reached sufficient depth to be considered final. Finalized blocks cannot be reorged.
The current safe
, unsafe
, and finalized
blocks can be queried via JSON-RPC.
# Historical Data
Bedrock nodes can serve pre-Bedrock block bodies, transactions, and receipts out of the box. However, you will need to run a Legacy Geth instance to serve historical execution traces. See the Node Operator Guide for more information about how to do this.
Note that the following legacy fields have been removed from pre-Bedrock JSON-RPC transaction responses:
queueOrigin
l1TxOrigin
l1BlockNumber
l1Timestamp
index
queueIndex
rawTransaction
If your application needs these fields, query Legacy Geth instead of op-geth
.
# JSON-RPC
Bedrock supports all of the standard JSON-RPC methods exposed by go-ethereum. In order to reduce differences between Bedrock and vanilla Ethereum, some legacy methods have been removed. These methods and their replacements are:
eth_getBlockRange
: Useeth_getBlockByNumber
in a batch request instead.rollup_getInfo
: None of the information returned by this method exists on Bedrock, so there is no replacement for this method.rollup_gasPrices
: Useeth_gasPrice
instead. The L1 and L2 fees are combined, and returned as a single value.
To query op-node
's sync status, use the optimism_syncStatus
RPC method. This method will return the current safe
, unsafe
, and finalized
as seen by the op-node
.
# Mempool
Since the legacy network creates a block for every transaction, it processes new transactions in a first-come-first-serve manner. Bedrock, however, creates blocks on a fixed interval and therefore needs a mempool to store pending transactions until they are included in a block. To minimize MEV, Bedrock's mempool is private. To submit transactions, you will need to configure op-geth
to forward transactions to the sequencer. This may change in the future.
The sequencer processes transactions in the mempool in order of their base and priority fees.
# Two-Phase Withdrawals
On the legacy network, funds are withdrawn as follows:
- Users send a withdrawal message.
- Users wait seven days for the withdrawal to be finalized.
- Users post a withdrawal proof on L1, and claim their funds.
However, this introduces a security risk. If the withdrawal proof can be successfully forged, an attacker could withdraw funds from the bridge that they are not authorized to. This kind of attack has been exploited before - a fraudulent proof led to the loss of $100M on Binance Smart Chain (opens new window).
To eliminate this risk, Bedrock requires users to post their withdrawal proofs upfront. Users must wait for a valid output root to be proposed so that the withdrawal proof can be validated onchain. Once the seven-day waiting period has expired, users can then finalize the withdrawal and claim their funds. The updated withdrawal flow is as follows:
- Users send a withdrawal message.
- Users wait for a state output to be proposed onchain. This can take up to an hour.
- Users call
proveWithdrawalTransaction()
on theOptimismPortal
to post and validate their proof. - Users wait for the withdrawal to be finalized. This takes seven days on mainnet.
- Users call
finalizeWithdrawal()
on theOptimismPortal
to claim their funds.
Visualized, this flow looks like this:
By posting the proof upfront, it gives onchain monitoring tools enough time to detect a fraudulent withdrawal proof and attempt corrective action. Regular users can do this monitoring too. For example, an exchange could halt withdrawals in the event of a fraudulent proof.
Since this change fundamentally changes the way withdrawals are handled, it is not backwards-compatible with the old network. If you are performing withdrawals outside our standard bridge interface, you will need to update your software. The easiest way to to do this is to use our TypeScript SDK (opens new window), which includes two-phase withdrawals support out of the box.
For more information on two-phase withdrawals, see the withdrawals specification on GitHub (opens new window).
# Deposit Replayability
Breaking Change
The changes described in this section are not backwards-compatible with the old network. Please read this section carefully.
On the legacy network, deposits are replayable. This is no longer the case in Bedrock. Additionally, as part of the migration, all deposits on the legacy network that have not been replayed will no longer be replayable. This means that if you have not replayed your deposit, you must do so before the migration. This affects fewer than 100 transactions of the nearly 40 million on mainnet.
# Contracts
# L1 contracts
# L2OutputOracle
The L2OutputOracle
contract (opens new window) contains the state root of the Optimism blockchain.
Once fault proofs are activated, it will be the one that receives the result of the fault proof process.
This is the contract that replaces the old State Commitment Chain.
# OptimismPortal
The OptimismPortal
contract (opens new window) provides the low-level API for communications between layers. Unless you are trying to send L2 transactions via L1 to bypass the sequencer, we strongly recommend sending messages between L1 and L2 via the L1CrossDomainMessenger and L2CrossDomainMessenger.
# Existing interface
These contracts provide the same interface as existed pre-Bedrock so dapps don’t have to be modified to run on Bedrock.
- L1CrossDomainMessenger (opens new window):
The
L1CrossDomainMessenger
contract is used for sending messages between Ethereum and Optimism. Those messages may or may not have assets attached to them. - L1StandardBridge (opens new window):
The
L1StandardBridge
contract usesL1CrossDomainMessenger
to transfer ETH and ERC-20 tokens between Ethereum and Optimism.
# L2 contracts (predeploys)
# L1Block
The L1Block
contract (opens new window) sits at address 0x4200000000000000000000000000000000000015
.
You can use the getter functions (opens new window) to get these parameters:
number
: The latest L1 block number known to L2 (theL1BlockNumber
contract is still supported to avoid breaking existing applications)timestamp
: The timestamp of the latest L1 blockbasefee
: The base fee of the latest L1 blockhash
: The hash of the latest L1 blocksequenceNumber
: The number of the L2 block within the epoch (the epoch changes when there is a new L1 block)
Currently the L1 information is delayed by two block confirmations (~24 seconds) to minimize the impact of reorgs.
# SequencerFeeVault
The SequencerFeeVault
contract (opens new window) handles funding the sequencer on L1 using the ETH base fee on L2.
The fees are calculated using EIP 1559 (opens new window), the same mechanism that Ethereum uses (but with different parameter values).
# L2ToL1MessagePasser
The L2ToL1MessagePasser
contract (opens new window) is used internally by L2CrossDomainMessenger
to initiate withdrawals.
Note that in Bedrock there are two contracts:
- The legacy contract (opens new window) at address
0x4200000000000000000000000000000000000000
- The new contract (opens new window) at address
0x4200000000000000000000000000000000000016
# Existing interface
These contracts provide the same interface as existed pre-Bedrock so dapps don’t have to be modified to run on Bedrock.
- L1BlockNumber (opens new window):
The
L1BlockNumber
contract provides the number of the latest L1 block. In Bedrock it is simply a proxy toL1Block
. - L2CrossDomainMessenger (opens new window):
The
L2CrossDomainMessenger
contract is used to send messages from Optimism to Ethereum. - L2StandardBridge (opens new window):
The
L2StandardBridge
contract is used to "attach" assets (ETH and ERC-20 tokens) to messages that are then sent byL2CrossDomainMessenger
. - WETH9 (opens new window): The WETH9 contract (opens new window) is an ERC-20 token that wraps around ETH to provide extra functionality, such as approvals.
# Historical contracts
These are contracts that are no longer relevant, but are kept as part of the state in case there is a call in any dapp that uses them.
DeployerWhitelist (opens new window): The
DeployerWhitelist
contract used to manage the whitelist before Optimism moved out of beta (opens new window).OVM_ETH (opens new window): The
OVM_ETH
contract used to manage users ETH balances prior to Bedrock.
# Communication between layers
In Optimism terminology "deposit" refers to any message going from the Ethereum blockchain to Optimism, whether it has any assets attached or not. Similarly, "withdrawal" refers to any message going from Optimism to Ethereum.
See here for the messenger specs (opens new window) and here for the bridge specs (opens new window).
# Deposits (from Ethereum to Optimism)
To create a deposit we recommend that you use the pre-Bedrock contracts L1StandardBridge
(opens new window) and L1CrossDomainMessenger
(opens new window).
OptimismPortal
(opens new window) also has low-level deposit functionality.
With the OptimismPortal’s depositTransaction
function you can do from L1 anything you can do by contacting L2 directly: send transactions, send payments, create contracts, etc.
This provides an uncensorable alternative in case the sequencer is down.
Even though the sequencer is down, verifiers (nodes that synchronize the Optimism state from L1) are still going to receive such transactions and modify the state accordingly.
When the sequencer is back up it has to process the transactions in the same order to have a valid state.
We recommend adding a 50% buffer to whatever is returned by estimateGas
to ensure that your deposit will not run out of gas (Note: the Optimism SDK already does this under the hood). For example, if you wish to send a deposit of ETH, you might call eth_estimateGas
and see that the deposit is expected to consume 100,000 gas
. You should then multiply that estimated about by 1.5
and then send your transaction with a gasLimit
of at least 150,000 gas
.
Tips
In order to prevent the Optimism network from being DOSed via forced L1 to L2 transactions that bypass the Sequencer, a fee adjustment schedule to all L1→L2 transactions that closely mimics EIP1559 is included with Bedrock. Like in the current network, deposit fees are paid by burning some amount of L1 gas proportional to your deposit's L2 gas limit. Unfortunately, this means that you may have cases where you estimate how much gas an L1→L2 deposit will cost, and deposit fees increase by the time your transaction gets included in a block and executed, causing your deposit to run out of gas and revert. This is why we recommend adding a 50% buffer to your gasLimit
to ensure your deposit will not run out of gas.
Deposits that come from contracts still use address aliasing.
Deposits will also be faster, probably about 2.5 minutes or less, rather than the 10-20 minutes they take now.
You can read the full deposit specifications here (opens new window).
You can read the full withdrawal specifications here (opens new window)
# Behind the scenes
This section discusses some of the changes in Optimism internals.
# The transaction trail
There is no longer a CTC (canonical transaction chain) contract. Instead, L2 blocks are saved to the Ethereum blockchain using a non-contract address to minimize the L1 gas expenses. Please see the Public Testnets page for more information on where to find batch submission addresses.
The block and transaction format is also different (opens new window).