diff --git a/pages/builders/app-developers/tutorials/cross-dom-bridge-eth.mdx b/pages/builders/app-developers/tutorials/cross-dom-bridge-eth.mdx
index 4d5e6a95c..3cbe5253e 100644
--- a/pages/builders/app-developers/tutorials/cross-dom-bridge-eth.mdx
+++ b/pages/builders/app-developers/tutorials/cross-dom-bridge-eth.mdx
@@ -133,7 +133,7 @@ You can get some Sepolia ETH from [this faucet](https://sepoliafaucet.com).
## Deposit ETH
-Now that you have some ETH on L1 you can deposit that ETH into the `L1StandardBridge` contract. You'll then receive the same number of ETH on L2 in return.
+Now that you have some ETH on L1 you can deposit that ETH into the `OptimismPortalProxy` contract. You'll then receive the same number of ETH on L2 in return.
@@ -167,7 +167,7 @@ Now that you have some ETH on L1 you can deposit that ETH into the `L1StandardBr
Wait for the L1 transaction to be processed and log the receipt.
- ```js file=/public/tutorials/cross-dom-bridge-eth.js#L52-L53 hash=0de1fe6dd17f753ab80d356b38d9ca41
+ ```js file=/public/tutorials/cross-dom-bridge-eth.js#L52-L53 hash=bccea143ce3571de154531c40e9a0d04
```
{Extract the L2 transaction hash
}
@@ -188,7 +188,7 @@ Now that you have some ETH on L1 you can deposit that ETH into the `L1StandardBr
- ```js file=/public/tutorials/cross-dom-bridge-eth.js#L3-L63 hash=b7d72a54dcdbb9b89c6874e2862fde00
+ ```js file=/public/tutorials/cross-dom-bridge-eth.js#L3-L63 hash=1198e2379e95a0e6c72c03692f10e9ee
```
diff --git a/pages/stack/interop.mdx b/pages/stack/interop.mdx
index c601fdb88..4e2ff4222 100644
--- a/pages/stack/interop.mdx
+++ b/pages/stack/interop.mdx
@@ -27,4 +27,9 @@ Documentation covering Cross Chain Message, Explainer, Message Passing, Op Super
+
+
+
+
+
diff --git a/pages/stack/interop/explainer.mdx b/pages/stack/interop/explainer.mdx
index 4de32d7fd..2b9685b90 100644
--- a/pages/stack/interop/explainer.mdx
+++ b/pages/stack/interop/explainer.mdx
@@ -11,11 +11,11 @@ import { InteropCallout } from '@/components/WipCallout'
-# Interoperability explainer
+# Interoperability explainer
## Why do we need interoperability?
-It is easy for a blockchain to be certain about information it generates itself.
+It is easy for a blockchain to be certain about information it generates itself.
Information that comes from other sources is harder to provide in a safe, decentralized, and uncensorable manner (this is called [The Oracle Problem](https://chain.link/education-hub/oracle-problem)).
The next major scalability improvement to the OP Stack is to enable a network of chains to feel like a single blockchain.
This goal requires low-latency, seamless message passing and asset bridging.
@@ -23,15 +23,15 @@ This goal requires low-latency, seamless message passing and asset bridging.
*Interoperability* is a set of protocols and services that lets OP Stack blockchains read each others' state.
Interoperability provides the following benefits:
-- 1-block latency asset movement, removing the problem of capital fragmentation leading to better capital efficiency.
-- Improved experience for both users and developers.
-- Secure transfer of assets, such as ETH and ERC-20 tokens, across L2s.
-- Horizontal scalability for applications that need it.
+* 1-block latency asset movement, removing the problem of capital fragmentation leading to better capital efficiency.
+* Improved experience for both users and developers.
+* Secure transfer of assets, such as ETH and ERC-20 tokens, across L2s.
+* Horizontal scalability for applications that need it.
## Interoperability architecture
A pre-interop OP Stack node consists of two pieces of software: a consensus client (e.g. op-node) and an execution client, which is responsible for processing user transactions and constructing blocks (e.g. op-geth).
-Interoperability among OP Stack chains is enabled via a new service called [*OP Supervisor*](/stack/interop/op-supervisor).
+Interoperability among OP Stack chains is enabled via a new service called [*OP Supervisor*](/stack/interop/op-supervisor).
Every node operator is expected to run this service in addition to the [rollup node](/builders/node-operators/architecture#rollup-node) and [execution client](/builders/node-operators/architecture#execution-client).
```mermaid
@@ -145,28 +145,26 @@ Interop expands the scope of trust for unsafe blocks (blocks that are shared thr
If a sequencer chooses to accept unsafe messages, the sequencer must trust the sequencer that produces the inbound message as well as any referenced unsafe messages produced from sequencers in the transitive dependency set.
-
-What is the transitive dependency set?
-
-The transitive dependency set of a blockchain is all the chains on which it depends, and all the chains that depend on them, and so on.
-For example, in the illustration above, the dependency set of chain A is just chain B.
-However, the *transitive* dependency set includes chain B, the chains that depend on it (C and D) and the chains that depend on them (E).
-If there was a chain that depended on E, that chain would be part of the transitive dependency set too.
-
-```mermaid
-
-flowchart LR
- A[Chain A] <--> B[Chain B]
- B <--> C[Chain C]
- B <--> D[Chain D]
- D <--> E[Chain E]
- F[Chain F] <--> G[Chain G]
-```
-
-For example, there could be a block in chain D that depends on an initiating message in chain E>
-If the block with that initiating message is still unsafe (not written to L1), then the block in chain D is also usafe, even if it has been written to L1.
-As a result, a block in chain B that depends on the chain D block can also be unsafe, as can a block in chain A that depends on the block in chain B.
-
+ What is the transitive dependency set?
+
+ The transitive dependency set of a blockchain is all the chains on which it depends, and all the chains that depend on them, and so on.
+ For example, in the illustration above, the dependency set of chain A is just chain B.
+ However, the *transitive* dependency set includes chain B, the chains that depend on it (C and D) and the chains that depend on them (E).
+ If there was a chain that depended on E, that chain would be part of the transitive dependency set too.
+
+ ```mermaid
+
+ flowchart LR
+ A[Chain A] <--> B[Chain B]
+ B <--> C[Chain C]
+ B <--> D[Chain D]
+ D <--> E[Chain E]
+ F[Chain F] <--> G[Chain G]
+ ```
+
+ For example, there could be a block in chain D that depends on an initiating message in chain E>
+ If the block with that initiating message is still unsafe (not written to L1), then the block in chain D is also usafe, even if it has been written to L1.
+ As a result, a block in chain B that depends on the chain D block can also be unsafe, as can a block in chain A that depends on the block in chain B.
Notably this trust assumption is only for *unsafe* blocks, and *only* if the sequencer allows messages from unsafe blocks to be processed.
@@ -202,8 +200,8 @@ To move an asset from chain E to chain B, it is necessary to move the asset from
### Superchain interop cluster
-The Superchain builds on top of the interop protocol and implements a single mesh network with complete dependencies.
-In this model, each blockchain in the Superchain interop cluster would have direct connections to every other blockchain, creating a fully connected mesh network.
+The Superchain builds on top of the interop protocol and implements a single mesh network with complete dependencies.
+In this model, each blockchain in the Superchain interop cluster would have direct connections to every other blockchain, creating a fully connected mesh network.
This model provides the highest level of interoperability, as any blockchain can transact directly with any other.
```mermaid
@@ -213,10 +211,8 @@ flowchart LR
A <--> C <--> E <--> B <--> D <--> A
```
-
Each blockchain in the Superchain interop cluster shares the same security model to mitigate the weakest-link scenario. As outlined in the [Standard Rollup Charter](https://gov.optimism.io/t/season-6-standard-rollup-charter-ratification/8135#p-36758-governing-policies-11), these chains share the same L1 `ProxyAdmin` Owner. Any changes to the Superchain interop cluster must follow the standard Protocol Upgrade vote procedure—the established governance process for Superchain modifications.
-
{/*
## Interop assets
@@ -229,8 +225,7 @@ This means ETH and ERC-20s can seamlessly and securely move across L2s, and inte
*/}
## Next steps
-* Want to learn more? Read our guide on the anatomy of a [cross-chain message](cross-chain-message) or check out this [interop design video walk-thru](https://www.youtube.com/watch?v=FKc5RgjtGes).
-* Ready to get started? Use [Supersim](supersim), a local dev environment that simulates interop for testing applications against a local version of the Superchain.
-* For more info about how OP Stack interoperability works under the hood, [check out the specs](https://specs.optimism.io/interop/overview.html).
-
+* Want to learn more? Read our guide on the anatomy of a [cross-chain message](cross-chain-message) or check out this [interop design video walk-thru](https://www.youtube.com/watch?v=FKc5RgjtGes).
+* Ready to get started? Use [Supersim](supersim), a local dev environment that simulates interop for testing applications against a local version of the Superchain.
+* For more info about how OP Stack interoperability works under the hood, [check out the specs](https://specs.optimism.io/interop/overview.html).
diff --git a/pages/stack/interop/predeploy.mdx b/pages/stack/interop/predeploy.mdx
index d89f3b4ee..672938171 100644
--- a/pages/stack/interop/predeploy.mdx
+++ b/pages/stack/interop/predeploy.mdx
@@ -13,7 +13,7 @@ import { InteropCallout } from '@/components/WipCallout'
# Interoperability predeploys
-The following predeploys have been added to enable interoperability.
+The following predeploys have been added to enable interoperability.
*Predeployed smart contracts* exist at predetermined addresses, coming from the genesis state.
They're similar to [precompiles](https://www.evm.codes/precompiled) but run directly in the EVM instead of running as native code.
@@ -22,9 +22,9 @@ They're similar to [precompiles](https://www.evm.codes/precompiled) but run dire
The `CrossL2Inbox` is the system predeploy for cross chain messaging.
Anyone can trigger the execution or validation of cross chain messages, on behalf of any user.
-- **Address:** `0x4200000000000000000000000000000000000022`
-- **Specs:** [`CrossL2Inbox`](https://specs.optimism.io/interop/predeploys.html#crossl2inbox)
-- **Source code:** [`CrossL2Inbox`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol)
+* **Address:** `0x4200000000000000000000000000000000000022`
+* **Specs:** [`CrossL2Inbox`](https://specs.optimism.io/interop/predeploys.html#crossl2inbox)
+* **Source code:** [`CrossL2Inbox`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol)
## L2ToL2CrossDomainMessenger
@@ -32,9 +32,9 @@ The `L2ToL2CrossDomainMessenger` is a higher level abstraction on top of the `Cr
It's utilized for secure ERC20 token transfers between L2 chains.
Messages sent through the `L2ToL2CrossDomainMessenger` on the source chain receive both replay protection and domain binding (the executing transaction can only be valid on a single chain).
-- **Address:** `0x4200000000000000000000000000000000000023`
-- **Specs:** [`L2ToL2CrossDomainMessenger`](https://specs.optimism.io/interop/predeploys.html#l2tol2crossdomainmessenger)
-- **Source code:** [`L2ToL2CrossDomainMessenger`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol)
+* **Address:** `0x4200000000000000000000000000000000000023`
+* **Specs:** [`L2ToL2CrossDomainMessenger`](https://specs.optimism.io/interop/predeploys.html#l2tol2crossdomainmessenger)
+* **Source code:** [`L2ToL2CrossDomainMessenger`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol)
{/*
## OptimismSuperchainERC20Factory
@@ -60,6 +60,6 @@ This contract is the `Beacon` part, which provides the implementation address fo
The `SuperchainTokenBridge` is an abstraction on top of the `L2toL2CrossDomainMessenger` that facilitates token bridging using interop. It has mint and burn rights over `OptimismSuperchainERC20` tokens, as described in the [token bridging spec](https://specs.optimism.io/interop/token-bridging.html).
-- **Address:** `0x4200000000000000000000000000000000000028`
-- **Specs:** [`SuperchainTokenBridge`](https://specs.optimism.io/interop/predeploys.html#superchainerc20bridge)
-- **Source code:** [`SuperchainTokenBridge`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol)
+* **Address:** `0x4200000000000000000000000000000000000028`
+* **Specs:** [`SuperchainTokenBridge`](https://specs.optimism.io/interop/predeploys.html#superchainerc20bridge)
+* **Source code:** [`SuperchainTokenBridge`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol)
diff --git a/pages/stack/interop/security.mdx b/pages/stack/interop/security.mdx
index 7dec4e67a..a0b488677 100644
--- a/pages/stack/interop/security.mdx
+++ b/pages/stack/interop/security.mdx
@@ -18,37 +18,34 @@ import { InteropCallout } from '@/components/WipCallout'
This interop vulnerability arises when an initiating message seems to exist, prompting the processing of the executing message. However, the initiating message ends up not actually appear in the canonical chain.
Excluding L1 reorgs, this can happen in two ways:
-- *Equivocation*. A sequencer publishes a block using the gossip protocol that is different from the one that eventually gets written to L1.
- The problem happens when the gossip protocol block includes a log entry that is used as an initiating message, but the real block (the one written to L1) doesn't.
- The way this is handled is that a block that depends on an unsafe block is, itself, unsafe.
- It does not get treated as safe until all the blocks on which it depends (directly or indirectly) are also written to L1.
+* *Equivocation*. A sequencer publishes a block using the gossip protocol that is different from the one that eventually gets written to L1.
+ The problem happens when the gossip protocol block includes a log entry that is used as an initiating message, but the real block (the one written to L1) doesn't.
+ The way this is handled is that a block that depends on an unsafe block is, itself, unsafe.
+ It does not get treated as safe until all the blocks on which it depends (directly or indirectly) are also written to L1.
-- *Faulty information*. The sequencer operator can run a verifier node for every chain in the dependency set, in which case it can deduce the initiating messages from the safe transactions of every chain.
- To save on resources, the sequencer can choose to query existing nodes of the source blockchain.
- In that case, if the information provided to sequencer is incorrect, of course the blocks posted by the sequencer will be also incorrect.
+* *Faulty information*. The sequencer operator can run a verifier node for every chain in the dependency set, in which case it can deduce the initiating messages from the safe transactions of every chain.
+ To save on resources, the sequencer can choose to query existing nodes of the source blockchain.
+ In that case, if the information provided to sequencer is incorrect, of course the blocks posted by the sequencer will be also incorrect.
- In this case, invalid blocks will be replaced with deposit only blocks by other verifiers.
+ In this case, invalid blocks will be replaced with deposit only blocks by other verifiers.
+ What are deposit only blocks?
- What are deposit only blocks?
+ Normally the blocks that make it to the canonical blockchain are those posted to L1 by the sequencer.
+ However, when those blocks are missing or invalid (for example because they rely on an initiating message that is missing), they're replaced by *deposit only blocks*, blocks whose content can be calculated from L1 without relying on the sequencer.
- Normally the blocks that make it to the canonical blockchain are those posted to L1 by the sequencer.
- However, when those blocks are missing or invalid (for example because they rely on an initiating message that is missing), they're replaced by *deposit only blocks*, blocks whose content can be calculated from L1 without relying on the sequencer.
+ The way this works is that there are two types of user transactions in an OP Stack block:
- The way this works is that there are two types of user transactions in an OP Stack block:
+ * Sequencer transactions, which go through the sequencer.
+ These transactions are extremely cheap, but in theory a sequencer could censor them.
+ * Deposit transactions, which users submit through L1.
+ These transactions have the cost of an L1 transaction, which is a lot higher, but they cannot be censored by the sequencer.
- - Sequencer transactions, which go through the sequencer.
- These transactions are extremely cheap, but in theory a sequencer could censor them.
- - Deposit transactions, which users submit through L1.
- These transactions have the cost of an L1 transaction, which is a lot higher, but they cannot be censored by the sequencer.
-
- A deposit only block only contains the deposit transactions and some internal transactions, not the sequencer transactions.
-
- For more information about this process, [see the technical specifications](https://specs.optimism.io/protocol/derivation.html#deriving-the-transaction-list).
+ A deposit only block only contains the deposit transactions and some internal transactions, not the sequencer transactions.
+ For more information about this process, [see the technical specifications](https://specs.optimism.io/protocol/derivation.html#deriving-the-transaction-list).
-
## The latency/security tradeoff
@@ -62,7 +59,7 @@ There are three different possibilities, at different levels of latency and secu
### Unsafe initiating messages
L2 blocks start as unsafe, meaning that there's no L1 evidence for them, and the sequencer for that blockchain can send out incorrect information.
-Sending out incorrect information, for example that a certain transaction is included in a block when it isn't, is called *equivocation*.
+Sending out incorrect information, for example that a certain transaction is included in a block when it isn't, is called *equivocation*.
A sequencer that builds blocks with interop can choose to accept messages from unsafe blocks (received through the gossip protocol), for minimal latency.
However, because of equivocation risk, a block that is written to L1 (*local safe*) can only be considered truly safe (the techincal term is *cross safe*), for itself and the previous blocks in its blockchain are also written to L1.
@@ -92,7 +89,7 @@ sequenceDiagram
Alternatively, a sequencer can be configured to only accept executing messages once the initiating message is in a cross safe block.
A cross safe block is one that is written to L1, and whose dependecies (direct or indirect, including dependencies of previous blocks in the same chain) are all written to L1.
-When a block is cross safe, the source sequencer cannot equivocate, and the state will only need to be recalculated if there's an [L1 reorg](https://www.alchemy.com/overviews/what-is-a-reorg#what-happens-to-reorgs-after-the-merge).
+When a block is cross safe, the source sequencer cannot equivocate, and the state will only need to be recalculated if there's an [L1 reorg](https://www.alchemy.com/overviews/what-is-a-reorg#what-happens-to-reorgs-after-the-merge).
The cost of this enhanced security that it would take longer for a message to pass from one blockchain to the other.
Higher throughput OP Stack chains like Base and OP Mainnet submit a batch about every 5 minutes, so on average it takes about 2.5 minutes for an initiating message to become safe.
@@ -131,12 +128,9 @@ Currently, this adds [about 15 minutes](https://ethereum.org/en/roadmap/single-s
-
-Even if a sequencer accepts unsafe initiating messages, the blocks it constructs that rely on them are considered unsafe until the blocks with those initiating messages are written to L1 and become safe.
-
+ Even if a sequencer accepts unsafe initiating messages, the blocks it constructs that rely on them are considered unsafe until the blocks with those initiating messages are written to L1 and become safe.
-
{/*
## What is stopping a sequencer from censoring a cross-chain message?
There is nothing stopping a sequencer from censoring a transaction when it is sent directly to the sequencer. This does not mean the network has no censorship resistance, users can always send a deposit transaction for censorship resistance as strong as L1 guarantees. The tradeoff here is the latency, instead of being confirmed in ~2 seconds, the transaction can be confirmed at the rate of L1 block production. It may be possible to adopt something like [EIP-7547](https://eips.ethereum.org/EIPS/eip-7547) in the future to enable low latency censorship resistance.
@@ -146,4 +140,4 @@ There is nothing stopping a sequencer from censoring a transaction when it is se
## What is stopping a shared sequencer from including just the executing message and not the initiating message?
The protocol enforces the fact that all executing messages are valid. It does this by reorganizing out executing messages that have invalid initiating messages. Running software that does not enforce this would be non-standard behavior and would leave yourself at risk of accepting an invalid executing message and therefore running on a forked chain.
-*/}
\ No newline at end of file
+*/}
diff --git a/public/tutorials/cross-dom-bridge-eth.js b/public/tutorials/cross-dom-bridge-eth.js
index 82abb4d6e..8169e4900 100644
--- a/public/tutorials/cross-dom-bridge-eth.js
+++ b/public/tutorials/cross-dom-bridge-eth.js
@@ -49,7 +49,7 @@ const depositArgs = await publicClientL2.buildDepositTransaction({
const depositHash = await walletClientL1.depositTransaction(depositArgs);
console.log(`Deposit transaction hash on L1: ${depositHash}`);
-const depositReceipt = await publicClientL1.waitForTransactionReceipt({ depositHash });
+const depositReceipt = await publicClientL1.waitForTransactionReceipt({ hash: depositHash });
console.log('L1 transaction confirmed:', depositReceipt);
const [l2Hash] = getL2TransactionHashes(depositReceipt);
diff --git a/words.txt b/words.txt
index 92f79e7e6..260236dfc 100644
--- a/words.txt
+++ b/words.txt
@@ -78,6 +78,7 @@ DATACAP
datacap
DATADIR
datadir
+dependencies
Devnet
devnet
devnets
@@ -158,6 +159,7 @@ Inator
inator
INFLUXDBV
influxdbv
+inteoperates
interchain
IPCDISABLE
ipcdisable
@@ -395,6 +397,7 @@ TXPOOL
txpool
txproxy
txproxyd
+uncensorable
uncountered
undercollateralize
Unichain
@@ -402,6 +405,7 @@ unmetered
Unprotect
unsubmitted
UPNP
+usafe
VERKLE
verkle
VHOSTS