Skip to content

Commit 18d0d08

Browse files
authored
Merge pull request #1367 from qbzzt/250204-message-passing
Fixing the errors in the message passing tutorial
2 parents 534f0cf + bb9aa21 commit 18d0d08

File tree

2 files changed

+141
-53
lines changed

2 files changed

+141
-53
lines changed

pages/stack/interop/tutorials/message-passing.mdx

Lines changed: 67 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -93,19 +93,24 @@ For development purposes, we'll first use autorelay mode to handle message execu
9393
<Steps>
9494
### Setting up test networks
9595

96+
97+
<Callout type="warning" emoji="⚠️">
98+
If you attempt to run these steps with the [devnet](../tools/devnet), you *must* Send the executing message yourself, as explained [here](#implement-manual-message-relaying).
99+
</Callout>
100+
96101
1. In the directory where Supersim is installed, start it with autorelay.
97102

98103
```sh
99-
supersim
104+
./supersim --interop.autorelay
100105
```
101106

102107
Supersim creates three `anvil` blockchains:
103108

104-
\| Role | ChainID | RPC URL |
105-
\| -------\* | ------: | ---------------------------------------------\* |
106-
\| L1 | 900 | [http://127.0.0.1:8545](http://127.0.0.1:8545) |
107-
\| OPChainA | 901 | [http://127.0.0.1:9545](http://127.0.0.1:9545) |
108-
\| OPChainB | 902 | [http://127.0.0.1:9546](http://127.0.0.1:9546) |
109+
| Role | ChainID | RPC URL |
110+
| -------- | ------: | --------------------------------------------- |
111+
| L1 | 900 | [http://127.0.0.1:8545](http://127.0.0.1:8545) |
112+
| OPChainA | 901 | [http://127.0.0.1:9545](http://127.0.0.1:9545) |
113+
| OPChainB | 902 | [http://127.0.0.1:9546](http://127.0.0.1:9546) |
109114

110115
2. In a separate shell, store the configuration in environment variables.
111116

@@ -141,8 +146,8 @@ For development purposes, we'll first use autorelay mode to handle message execu
141146
2. In `src/Greeter.sol` put this file.
142147
This is a variation on [Hardhat's Greeter contract](https://github.com/matter-labs/hardhat-zksync/blob/main/examples/upgradable-example/contracts/Greeter.sol).
143148

144-
```solidity file=<rootDir>/public/tutorials/Greeter.sol#L1-L20 hash=b3c5550bcc2cc4272125388ef23a67e7
145-
```
149+
```solidity file=<rootDir>/public/tutorials/Greeter.sol#L1-L20 hash=b3c5550bcc2cc4272125388ef23a67e7
150+
```
146151

147152
3. Deploy the `Greeter` contract to Chain B and store the resulting contract address in the `GREETER_B_ADDR` environment variable.
148153

@@ -441,10 +446,10 @@ In production we will not have this, we need to create our own executing message
441446

442447
2. Create or replace `src/app.mts` with this code.
443448

444-
```solidity file=<rootDir>/public/tutorials/app.mts#L1-L51 hash=8f6f776884b8e37ae613f7aea8cd6a3b
445-
```
449+
```typescript file=<rootDir>/public/tutorials/app.mts#L1-L51 hash=8f6f776884b8e37ae613f7aea8cd6a3b
450+
```
446451

447-
3. Run the program, see that a greeting from chain A is related to chain B.
452+
3. Run the program, see that a greeting from chain A is relayed to chain B.
448453

449454
```sh
450455
npm start
@@ -490,50 +495,50 @@ In production we will not have this, we need to create our own executing message
490495

491496
1. Replace `src/app.mts` with:
492497

493-
```js file=<rootDir>/public/tutorials/app.mts#L1-L51 hash=8f6f776884b8e37ae613f7aea8cd6a3b
494-
```
498+
```typescript file=<rootDir>/public/tutorials/app_v2.mts hash=a7b0f60aa6f1e48fc9994178ed3d5498
499+
```
495500

496-
<details>
497-
<summary>Explanation</summary>
501+
<details>
502+
<summary>Explanation</summary>
498503

499-
1. **Import Required Libraries**
504+
1. **Import Required Libraries**
500505

501-
* Imports functions from `viem` for wallet creation, HTTP transport, and contract interactions.
502-
* Imports `@eth-optimism/viem` utilities for handling OP-Stack-specific actions and interoperability.
503-
* Loads ABI definitions from `Greeter.json` and `GreetingSender.json` for contract interactions.
506+
* Imports functions from `viem` for wallet creation, HTTP transport, and contract interactions.
507+
* Imports `@eth-optimism/viem` utilities for handling OP-Stack-specific actions and interoperability.
508+
* Loads ABI definitions from `Greeter.json` and `GreetingSender.json` for contract interactions.
504509

505-
2. **Initialize Wallet Clients**
510+
2. **Initialize Wallet Clients**
506511

507-
* Uses `privateKeyToAccount` to generate an account from an environment variable.
508-
* Creates `walletA` for chain `supersimL2A` and `walletB` for chain `supersimL2B`, extending them with Viem's public and OP-Stack-specific actions.
512+
* Uses `privateKeyToAccount` to generate an account from an environment variable.
513+
* Creates `walletA` for chain `supersimL2A` and `walletB` for chain `supersimL2B`, extending them with Viem's public and OP-Stack-specific actions.
509514

510-
3. **Get Contract Instances**
515+
3. **Get Contract Instances**
511516

512-
* Retrieves contract instances for `greeter` on `walletB` and `greetingSender` on `walletA` using `getContract`.
513-
* The addresses are taken from environment variables, and the clients are set to the respective wallets.
517+
* Retrieves contract instances for `greeter` on `walletB` and `greetingSender` on `walletA` using `getContract`.
518+
* The addresses are taken from environment variables, and the clients are set to the respective wallets.
514519

515-
4. **Direct Greeting on Chain B**
520+
4. **Direct Greeting on Chain B**
516521

517-
* Calls `setGreeting` on `greeter` to store a greeting directly on chain B.
518-
* Waits for the transaction to be confirmed using `waitForTransactionReceipt`.
519-
* Reads and logs the greeting stored on chain B.
522+
* Calls `setGreeting` on `greeter` to store a greeting directly on chain B.
523+
* Waits for the transaction to be confirmed using `waitForTransactionReceipt`.
524+
* Reads and logs the greeting stored on chain B.
520525

521-
5. **Cross-Chain Greeting via Chain A**
526+
5. **Cross-Chain Greeting via Chain A**
522527

523-
* Calls `setGreeting` on `greetingSender` to send a greeting through chain A.
524-
* Waits for the transaction receipt on chain A.
528+
* Calls `setGreeting` on `greetingSender` to send a greeting through chain A.
529+
* Waits for the transaction receipt on chain A.
525530

526-
6. **Retrieve and Relay the Cross-Chain Message**
531+
6. **Retrieve and Relay the Cross-Chain Message**
527532

528-
* Extracts the message from the transaction receipt using `createInteropSentL2ToL2Messages`.
529-
* Relays the message to chain B using `walletB.interop.relayMessage`.
530-
* Waits for confirmation of the relay transaction.
533+
* Extracts the message from the transaction receipt using `createInteropSentL2ToL2Messages`.
534+
* Relays the message to chain B using `walletB.interop.relayMessage`.
535+
* Waits for confirmation of the relay transaction.
531536

532-
7. **Verify the Updated Greeting on Chain B**
537+
7. **Verify the Updated Greeting on Chain B**
533538

534-
* Reads the greeting from `greeter` after the relay process.
535-
* Logs the updated greeting, showing that it was successfully relayed from chain A to chain B.
536-
</details>
539+
* Reads the greeting from `greeter` after the relay process.
540+
* Logs the updated greeting, showing that it was successfully relayed from chain A to chain B.
541+
</details>
537542

538543
2. Rerun the JavaScript program, and see that the message is relayed.
539544

@@ -546,29 +551,38 @@ In production we will not have this, we need to create our own executing message
546551
The same contracts are deployed on [the devnet](../tools/devnet).
547552
You can relay messages in exactly the same way you'd do it on Supersim.
548553

549-
\| Contract | Network | Address |
550-
\| ---------------\* | -------------------------------------------\* | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\* |
551-
\| `Greeter` | [Devnet 1](../tools/devnet#interop-devnet-1) | [`0x1A183FCf61053B7dcd2322BbE766f7E1946d3718`](https://sid.testnet.routescan.io/address/0x1A183FCf61053B7dcd2322BbE766f7E1946d3718) |
552-
\| `GreetingSender` | [Devnet 0](../tools/devnet#interop-devnet-1) | [`0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f`](https://sid.testnet.routescan.io/address/0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f/contract/420120000/readContract?chainid=420120000) |
554+
| Contract | Network | Address |
555+
| --------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
556+
| `Greeter` | [Devnet 1](../tools/devnet#interop-devnet-1) | [`0x1A183FCf61053B7dcd2322BbE766f7E1946d3718`](https://sid.testnet.routescan.io/address/0x1A183FCf61053B7dcd2322BbE766f7E1946d3718) |
557+
| `GreetingSender` | [Devnet 0](../tools/devnet#interop-devnet-1) | [`0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f`](https://sid.testnet.routescan.io/address/0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f/contract/420120000/readContract?chainid=420120000) |
553558

554-
To modify the program to relay messagez on devnet, follow these steps:
559+
To modify the program to relay messages on devnet, follow these steps:
555560

556561
1. In `src/app.mts`, replace these lines to update the chains and contract addresses.
557562

558-
\| Line number | New content |
559-
\| ----------: | -------------------------------------------------------------------------\* |
560-
\| 10 | `import { interopAlpha0, interopAlpha1 } from '@eth-optimism/viem/chains'` |
561-
\| 24 | ` chain: interopAlpha0,` |
562-
\| 32 | ` chain: interopAlpha1,` |
563-
\| 40 | ` address: "0x1A183FCf61053B7dcd2322BbE766f7E1946d3718",` |
564-
\| 46 | ` address: "0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f",` |
563+
| Line number | New content |
564+
| ----------: | ------------------------------------------------------------------------- |
565+
| 9 | `import { interopAlpha0, interopAlpha1 } from '@eth-optimism/viem/chains'` |
566+
| 23 | ` chain: interopAlpha0,` |
567+
| 31 | ` chain: interopAlpha1,` |
568+
| 39 | ` address: "0x1A183FCf61053B7dcd2322BbE766f7E1946d3718",` |
569+
| 45 | ` address: "0x9De9f84a4EB3616B44CF1d68cD1A9098Df6cB25f",` |
565570

566-
2. Set `PRIV_KEY` to the private key of an address that has Sepolia ETH on the two chains.
571+
2. Set `PRIV_KEY` to the private key of an address that has [Sepolia ETH](https://cloud.google.com/application/web3/faucet/ethereum/sepolia).
567572

568573
```sh
569574
export PRIV_KEY=0x<private key here>
570575
```
571576

577+
3. Send ETH to the two L2 blockchains.
578+
579+
```sh
580+
cast send --rpc-url https://endpoints.omniatech.io/v1/eth/sepolia/public --private-key $PRIV_KEY --value 0.001ether 0x7385d89d38ab79984e7c84fab9ce5e6f4815468a
581+
cast send --rpc-url https://endpoints.omniatech.io/v1/eth/sepolia/public --private-key $PRIV_KEY --value 0.001ether 0x7385d89d38ab79984e7c84fab9ce5e6f4815468a
582+
```
583+
584+
Wait a few minutes until you can see the ETH [on your explorer](https://sid.testnet.routescan.io/).
585+
572586
3. Rerun the test.
573587

574588
```sh

public/tutorials/app_v2.mts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import {
2+
createWalletClient,
3+
http,
4+
publicActions,
5+
getContract,
6+
Address,
7+
} from 'viem'
8+
import { privateKeyToAccount } from 'viem/accounts'
9+
import { supersimL2A, supersimL2B } from '@eth-optimism/viem/chains'
10+
11+
import {
12+
walletActionsL2,
13+
publicActionsL2,
14+
createInteropSentL2ToL2Messages,
15+
} from '@eth-optimism/viem'
16+
17+
import greeterData from './Greeter.json'
18+
import greetingSenderData from './GreetingSender.json'
19+
20+
const account = privateKeyToAccount(process.env.PRIV_KEY as `0x${string}`)
21+
22+
const walletA = createWalletClient({
23+
chain: supersimL2A,
24+
transport: http(),
25+
account
26+
}).extend(publicActions)
27+
.extend(publicActionsL2())
28+
.extend(walletActionsL2())
29+
30+
const walletB = createWalletClient({
31+
chain: supersimL2B,
32+
transport: http(),
33+
account
34+
}).extend(publicActions)
35+
.extend(publicActionsL2())
36+
.extend(walletActionsL2())
37+
38+
const greeter = getContract({
39+
address: process.env.GREETER_B_ADDR as Address,
40+
abi: greeterData.abi,
41+
client: walletB
42+
})
43+
44+
const greetingSender = getContract({
45+
address: process.env.GREETER_A_ADDR as Address,
46+
abi: greetingSenderData.abi,
47+
client: walletA
48+
})
49+
50+
const txnBHash = await greeter.write.setGreeting(
51+
["Greeting directly to chain B"])
52+
await walletB.waitForTransactionReceipt({hash: txnBHash})
53+
54+
const greeting1 = await greeter.read.greet()
55+
console.log(`Chain B Greeting: ${greeting1}`)
56+
57+
const txnAHash = await greetingSender.write.setGreeting(
58+
["Greeting through chain A"])
59+
const receiptA = await walletA.waitForTransactionReceipt({hash: txnAHash})
60+
61+
const sentMessage =
62+
(await createInteropSentL2ToL2Messages(walletA, { receipt: receiptA }))
63+
.sentMessages[0]
64+
const relayMsgTxnHash = await walletB.interop.relayMessage({
65+
sentMessageId: sentMessage.id,
66+
sentMessagePayload: sentMessage.payload,
67+
})
68+
69+
const receiptRelay = await walletB.waitForTransactionReceipt(
70+
{hash: relayMsgTxnHash})
71+
72+
const greeting2 = await greeter.read.greet()
73+
console.log(`Chain A Greeting: ${greeting2}`)
74+

0 commit comments

Comments
 (0)