Skip to content

Commit d116f8f

Browse files
Merge pull request #1372 from qbzzt/250211-xchain-eth
Crosschain Bridging of ETH tutorial
2 parents b77e515 + b3a10b1 commit d116f8f

File tree

5 files changed

+362
-43
lines changed

5 files changed

+362
-43
lines changed

components/AutorelayCallout.tsx

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,19 @@
55
* @returns {ReactElement} The AutorelayCallout component, a callout that explains about autorelays.
66
*/
77
import type { ReactElement } from 'react';
8-
import { useState } from 'react';
8+
import { Callout } from 'nextra/components'
99

10-
interface Props {
11-
context?: string;
12-
}
13-
export function AutorelayCallout({ context }: Props): ReactElement {
10+
// nx-w-full nx-flex nx-mt-6
11+
// nx-mt-6 nx-justify-center nx-items-center nx-bg-white dark:nx-bg-black"
12+
13+
// import { Callout } from 'vocs/components'
14+
15+
export function AutorelayCallout(): ReactElement {
1416
return (
15-
<div
16-
className="custom-callouts nx-w-full nx-mt-6 nx-flex nx-justify-center nx-items-center nx-bg-white dark:nx-bg-black"
17-
>
18-
<div className="nx-w-full nx-px-4 nx-text-center nx-font-medium nx-text-sm nx-text-left">
19-
<div className="nx-text-left">
17+
<Callout>
2018
Normally we expect Superchain blockchains to run an autorelayer and relay your messages automatically.
2119
However, for performance reasons or reliability, you might decide to submit the executing message manually.
2220
See below to learn how to do that.
23-
</div>
24-
</div>
25-
</div>
21+
</Callout>
2622
);
2723
}

pages/stack/interop/superchain-weth.mdx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ import { InteropCallout } from '@/components/WipCallout'
1212

1313
# Superchain ETH
1414

15-
Superchain ETH enables seamless ETH transfers across the [Superchain interop cluster](/stack/interop/explainer#superchain-interop-cluster). It is implemented using three key contracts:
15+
<Callout>
16+
This is an explanation of how interop ETH works.
17+
You can find a step by step tutorial [here](tutorials/bridge-crosschain-eth).
18+
</Callout>
19+
20+
21+
InteroperableETH enables seamless ETH transfers across Superchain blockchains. It is implemented using three key contracts:
1622

1723
* [`SuperchainWETH`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainWETH.sol): A bridge contract that facilitates ETH transfers between Superchain blockchains.
1824
* [`ETHLiquidity`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/ETHLiquidity.sol): A liquidity provider for ETH transfers.

pages/stack/interop/tutorials/bridge-crosschain-eth.mdx

Lines changed: 243 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,54 +4,273 @@ lang: en-US
44
description: Learn how to bridge native cross-chain ETH transfers.
55
---
66

7-
import { Callout } from 'nextra/components'
8-
import { Steps } from 'nextra/components'
7+
import { Callout, Steps, Tabs } from 'nextra/components'
98
import { InteropCallout } from '@/components/WipCallout'
9+
import { AutorelayCallout } from '@/components/AutorelayCallout'
1010

1111
<InteropCallout />
1212

1313
# Bridging native cross-chain ETH transfers
1414

15+
<Callout>
16+
This tutorial provides step-by-step instructions for bridging ETH from one Superchain Interop chain to another.
17+
For a conceptual overview,
18+
see the [interoperable ETH explainer](/stack/interop/superchain-weth).
19+
</Callout>
20+
21+
## Overview
22+
1523
Crosschain ETH transfers in the Superchain are facilitated through the [SuperchainWETH](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainWETH.sol) contract.
16-
This tutorial walks through how to send native ETH from chain 901 to 902. To simplify these steps, [supersim](/stack/interop/tools/supersim) will be run with the `--interop.autorelay` flag. The `--interop.autorelay` flag automatically triggers the relay message transaction once the initial send transaction is completed on the source chain, improving the developer experience by removing the need to manually send the relay message.
24+
This tutorial walks through how to send native ETH from one chain to another.
25+
You can do this on [Supersim](/stack/interop/tools/supersim), [the Interop devnet](/stack/interop/tools/devnet), or production once it is released.
26+
27+
### What you'll build
28+
29+
* A TypeScript application to transfer ETH chains
30+
31+
### What you'll learn
32+
33+
* How to send ETH on the blockchain and between blockchains
34+
* How to relay messages between chains
35+
36+
## Prerequisites
37+
38+
Before starting this tutorial, ensure your development environment meets the following requirements:
39+
40+
### Technical knowledge
41+
42+
* Intermediate TypeScript knowledge
43+
* Understanding of smart contract development
44+
* Familiarity with blockchain concepts
1745

46+
### Development environment
47+
48+
* Unix-like operating system (Linux, macOS, or WSL for Windows)
49+
* Node.js version 16 or higher
50+
* Git for version control
51+
52+
### Required tools
53+
54+
The tutorial uses these primary tools:
55+
56+
* Foundry: For smart contract development
57+
* Supersim: For local blockchain simulation
58+
* TypeScript: For implementation
59+
* Viem: For blockchain interaction
1860

1961
<Steps>
20-
### Start `supersim` with the autorelayer enabled
62+
### Install prerequisite software
2163

22-
```sh
23-
supersim --interop.autorelay
24-
```
64+
1. Install [Foundry](https://book.getfoundry.sh/getting-started/installation).
65+
1. Install [Node](https://nodejs.org/en).
66+
1. Install [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git).
67+
The exact mechanism to do this depends on your operating system; most come with it preinstalled.
2568

26-
### Initiate the send transaction on chain 901
69+
### Configure the network
2770

28-
* In this step, you'll send ETH from Chain 901 to Chain 902 through `SuperchainWETH` contract deployed at `0x4200000000000000000000000000000000000024`.
29-
* Use the following command:
71+
You can run this tutorial either with [Supersim](/stack/interop/tools/supersim) running locally, or using the [Interop devnet](/stack/interop/tools/devnet).
72+
Select the correct tab and follow the directions.
3073

31-
```sh
32-
cast send 0x4200000000000000000000000000000000000024 "sendETH(address _to, uint256 _chainId)" 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 902 --value 10ether --rpc-url http://127.0.0.1:9545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
33-
```
3474

35-
### Wait for the relayed message to appear on chain 902
75+
<Tabs items={['Supersim', 'Interop devnet']}>
76+
<Tabs.Tab>
77+
1. Follow the [Installation Guide](/app-developers/tutorials/supersim/getting-started/installation) to install Supersim for running blockchains with Interop.
3678

37-
In a few seconds, you should see the relayed message on chain 902:
79+
1. Start Supersim.
3880

39-
```sh
40-
# example
41-
INFO [12-02|14:53:02.434] SuperchainWETH#RelayETH chain.id=902 from=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 to=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 amount=10,000,000,000,000,000,000 source=901
42-
```
81+
```sh
82+
./supersim --interop.autorelay
83+
```
84+
85+
1. Supersim uses Foundry's `anvil` blockchains, which start with ten prefunded accounts.
86+
Set these environment variables to access one of those accounts on the L2 blockchains.
87+
88+
```sh
89+
export PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
90+
```
91+
92+
1. Specify the URLs to the chains.
93+
94+
```sh
95+
SRC_URL=http://localhost:9545
96+
DST_URL=http://localhost:9546
97+
```
98+
99+
<details>
100+
<summary>Sanity check</summary>
101+
102+
Get the ETH balances for your address on both the source and destination chains.
103+
104+
```sh
105+
cast balance --ether `cast wallet address $PRIVATE_KEY` --rpc-url $SRC_URL
106+
cast balance --ether `cast wallet address $PRIVATE_KEY` --rpc-url $DST_URL
107+
```
108+
109+
</details>
110+
111+
112+
</Tabs.Tab>
113+
114+
<Tabs.Tab>
115+
1. Set `PRIVATE_KEY` to the private key of an address that has [Sepolia ETH](https://cloud.google.com/application/web3/faucet/ethereum/sepolia).
116+
117+
```sh
118+
export PRIVATE_KEY=0x <<<PRIVATE_KEY>>>
119+
```
120+
121+
1. Send ETH to the two L2 blockchains via their OptimismPortal contracts on Sepolia.
122+
123+
```sh
124+
cast send --rpc-url https://endpoints.omniatech.io/v1/eth/sepolia/public --private-key $PRIVATE_KEY --value 0.02ether 0x7385d89d38ab79984e7c84fab9ce5e6f4815468a
125+
cast send --rpc-url https://endpoints.omniatech.io/v1/eth/sepolia/public --private-key $PRIVATE_KEY --value 0.02ether 0x55f5c4653dbcde7d1254f9c690a5d761b315500c
126+
```
127+
128+
1. Wait a few minutes until you can see the ETH [on the block explorer](https://sid.testnet.routescan.io/) for your address.
129+
130+
1. Specify the URLs to the chains.
131+
132+
```sh
133+
SRC_URL=https://interop-alpha-0.optimism.io
134+
DST_URL=https://interop-alpha-1.optimism.io
135+
```
43136

44-
### Check the balance on chain 902
137+
<details>
138+
<summary>Sanity check</summary>
45139

46-
Verify that the balance of the ETH on chain 902 has increased:
140+
Get the ETH balances for your address on both the source and destination chains.
141+
142+
```sh
143+
cast balance --ether `cast wallet address $PRIVATE_KEY` --rpc-url $SRC_URL
144+
cast balance --ether `cast wallet address $PRIVATE_KEY` --rpc-url $DST_URL
145+
```
146+
</details>
147+
</Tabs.Tab>
148+
</Tabs>
149+
150+
### Transfer ETH using Foundry
151+
152+
Run these commands:
47153

48154
```sh
49-
cast balance 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --rpc-url http://127.0.0.1:9546
155+
DST_CHAINID=`cast chain-id --rpc-url $DST_URL`
156+
MY_ADDRESS=`cast wallet address $PRIVATE_KEY`
157+
SUPERCHAIN_WETH=0x4200000000000000000000000000000000000024
158+
BEFORE=`cast balance $MY_ADDRESS --rpc-url $DST_URL | cast from-wei`
159+
cast send --rpc-url $SRC_URL --private-key $PRIVATE_KEY $SUPERCHAIN_WETH "sendETH(address,uint256)" $MY_ADDRESS $DST_CHAINID --value 0.001ether
160+
sleep 10
161+
AFTER=`cast balance $MY_ADDRESS --rpc-url $DST_URL | cast from-wei`
162+
echo -e Balance before transfer\\t$BEFORE
163+
echo -e Balance after transfer\\t$AFTER
50164
```
165+
166+
### Create the TypeScript project
167+
168+
<AutorelayCallout />
169+
170+
To create an executing message on the destination chain we use [the `@eth-optimism/viem` package](https://www.npmjs.com/package/@eth-optimism/viem).
171+
For that we need TypeScript code.
172+
173+
1. Create a new TypeScript project.
174+
175+
```sh
176+
mkdir transfer-eth
177+
cd transfer-eth
178+
npm init -y
179+
npm install --save-dev -y viem tsx @types/node @eth-optimism/viem typescript
180+
mkdir src
181+
```
182+
183+
2. Download the ABI for `SuperchainWETH`.
184+
185+
```sh
186+
curl https://raw.githubusercontent.com/ethereum-optimism/optimism/refs/heads/develop/packages/contracts-bedrock/snapshots/abi/SuperchainWETH.json > src/SuperchainWETH.abi.json
187+
```
188+
189+
3. Place this in `src/transfer-eth.mts`:
190+
191+
```typescript file=<rootDir>/public/tutorials/transfer-eth.mts hash=c6032f96e0fc040ad8fff7bc2892bbb6
192+
```
193+
194+
<details>
195+
<summary>Explanation of `transfer-eth.mts`</summary>
196+
197+
```typescript file=<rootDir>/public/tutorials/transfer-eth.mts#L13-L18 hash=5312f4634ac8762504935cd52d18c8ab
198+
```
199+
200+
Import all chain definitions from `@eth-optimism/viem`.
201+
202+
```typescript file=<rootDir>/public/tutorials/transfer-eth.mts#L29-L32 hash=e8c21357997ea12151305337eced7d71
203+
```
204+
205+
If the address we use is `0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266`, one of the prefunded addresses on `anvil`, assume we're using Supersim.
206+
Otherwise, use Interop devnet.
207+
208+
```typescript file=<rootDir>/public/tutorials/transfer-eth.mts#L78-L80 hash=4933c70a9078c2369ef90bfe163f5fd7
209+
```
210+
211+
To relay a message we need the information in the receipt.
212+
Also, we need to wait until the transaction with the relayed message is actually part of a block.
213+
214+
```typescript file=<rootDir>/public/tutorials/transfer-eth.mts#L87-L89 hash=573f22b2b21415ff51c59c713fda07d1
215+
```
216+
217+
A single transaction can send multiple messages.
218+
But here we know we sent just one, so we look for the first one in the list.
219+
220+
```typescript file=<rootDir>/public/tutorials/transfer-eth.mts#L90-L96 hash=4b26775b46c116262af4c7299d6f1127
221+
```
222+
223+
This is how you use `@eth-optimism/viem` to create an executing message.
224+
</details>
225+
226+
### Run the example
227+
228+
1. Run the example.
229+
230+
```sh
231+
npx tsx src/transfer-eth.mts
232+
```
233+
234+
2. Read the results.
235+
236+
```
237+
Before transfer
238+
239+
Address: 0x7ED53BfaA58B79Dd655B2f229258C093b6C09A8C
240+
Balance on source chain: 0.020999799151902245
241+
Balance on destination chain: 0.026999459226731331
242+
```
243+
244+
The initial state. Note that the address depends on your private key; it should be different from mine.
245+
246+
```
247+
After transfer on source chain
248+
249+
Address: 0x7ED53BfaA58B79Dd655B2f229258C093b6C09A8C
250+
Balance on source chain: 0.019999732176717961
251+
Balance on destination chain: 0.026999459226731331
252+
```
253+
254+
After the initiating message the balance on the source chain is immediately reduced.
255+
Notice that even though we are sending 0.001 ETH, the balance on the source chain is reduced by a bit more (here, approximately 67 gwei).
256+
This is the cost of the initiating transaction on the source chain.
257+
Of course, as there has been no transaction on the destination chain, that balance is unchanged.
258+
259+
```
260+
After relaying message to destination chain
261+
262+
Address: 0x7ED53BfaA58B79Dd655B2f229258C093b6C09A8C
263+
Balance on source chain: 0.019999732176717961
264+
Balance on destination chain: 0.027999278943880868
265+
```
266+
267+
Now the balance on the destination chain increases, by slightly less than 0.001 ETH.
268+
The executing message also has a transaction cost (in this case, about 180gwei).
51269
</Steps>
52270

53271
## Next steps
54272

55-
* Checkout the [SuperchainWETH guide](/stack/interop/superchain-weth) for more information.
273+
* Check out the [SuperchainWETH guide](/stack/interop/superchain-weth) for more information.
56274
* Use the [SuperchainERC20 Starter Kit](/app-developers/starter-kit) to deploy your token across the Superchain.
57-
* Review the [Superchain Interop Explainer](/stack/interop/explainer) for answers to common questions about interoperability.
275+
* Review the [Superchain interop explainer](/stack/interop/explainer) for answers to common questions about interoperability.
276+

0 commit comments

Comments
 (0)