Skip to content

Commit 7d390a7

Browse files
authored
Merge pull request #129 from OffchainLabs/update-tutorials-5
Update tutorials to ArbSDK v4 (5)
2 parents 27e71fd + d371406 commit 7d390a7

27 files changed

Lines changed: 450 additions & 422 deletions

File tree

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ yarn install
3131
#### :white_check_mark: General interop
3232

3333
- 🤝 [Greeter](./packages/greeter/) (parent to child messages)
34-
- 📤 [Outbox](./packages/outbox-execute/) (child to parent messages)
34+
- 📤 [Outbox tutorial: execute a child-to-parent message](./packages/outbox-execute/) (child to parent messages)
3535
-[Parent chain confirmation checker](./packages/parent-chain-confirmation-checker/)
36-
-[L2 block verification in assertion](./packages/l2-block-verification-in-assertion/)
36+
-[Block verification in parent chain's assertion](./packages/block-verification-in-parent-chain-assertion/)
3737

3838
#### :white_check_mark: Advanced features
3939

@@ -53,4 +53,6 @@ To do that, fill the information of your chain in the [`customNetwork.json`](./c
5353

5454
To obtain the information of a specific chain, you can use the method [`prepareArbitrumNetwork`](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/utils/registerNewNetwork.ts#L18) of the Orbit SDK.
5555

56+
You can also register multiple chains if you need to (for example, for the `l1-l3-teleport` tutorial). In that case, create an array of chain information objects in the `customNetwork.json` file.
57+
5658
<p align="center"><img src="assets/logo.svg" width="300"></p>

customNetwork.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"bridge": "0x5eCF728ffC5C5E802091875f96281B5aeECf6C49",
66
"inbox": "0x9f8c1c641336A371031499e3c362e40d58d0f254",
77
"outbox": "0x50143333b44Ea46255BEb67255C9Afd35551072F",
8-
"rollup": "0x837Fadd53667eFCE195D5B75063aaB277f7d712C",
8+
"rollup": "0x7d98BA231d29D5C202981542C0291718A7358c63",
99
"sequencerInbox": "0x18d19C5d3E685f5be5b9C86E097f0E439285D216"
1010
},
1111
"explorerUrl": "",

packages/address-table/scripts/exec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ const { arbLog, requireEnvVariables } = require('arb-shared-dependencies')
77
const {
88
ARB_ADDRESS_TABLE_ADDRESS,
99
} = require('@arbitrum/sdk/dist/lib/dataEntities/constants')
10-
requireEnvVariables(['PRIVATE_KEY', 'CHAIN_RPC'])
1110
require('dotenv').config()
11+
requireEnvVariables(['PRIVATE_KEY', 'CHAIN_RPC'])
1212

1313
/**
1414
* Set up: instantiate wallets connected to providers

packages/arb-shared-dependencies/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,13 @@ const addCustomNetworkFromFile = () => {
6868
'utf8'
6969
)
7070
const customNetworkInformation = JSON.parse(customNetworkFileContents)
71-
registerCustomArbitrumNetwork(customNetworkInformation)
71+
if (customNetworkInformation instanceof Array) {
72+
customNetworkInformation.map(customNetwork =>
73+
registerCustomArbitrumNetwork(customNetwork)
74+
)
75+
} else {
76+
registerCustomArbitrumNetwork(customNetworkInformation)
77+
}
7278
}
7379

7480
module.exports = {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This is a sample .env file for use in local development.
2+
# Duplicate this file as .env here
3+
4+
# The main chain's RPC
5+
# (this can be an Arbitrum network, or your Orbit chain)
6+
CHAIN_RPC="https://sepolia-rollup.arbitrum.io/rpc"
7+
8+
# The parent chain's RPC
9+
# (this can be Ethereum, or the chain your Orbit chain settles to)
10+
PARENT_CHAIN_RPC="https://sepolia.infura.io/v3/<your infura key>"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Block verification in an assertion posted on the parent chain
2+
3+
This tutorial shows how to verify whether a block of a chain has been processed as part of an RBlock assertion on its parent chain.
4+
5+
It uses the `Rollup` contract to find the latest confirmed (or created if configured in the script) RBlock/node, find the event that created it, and get the latest processed block hash of the child chain that's part of the assertion of that RBlock/node.
6+
7+
Then it checks whether the block number passed as argument was created before the latest block hash of the child chain processed.
8+
9+
See [./exec.js](./scripts/exec.js) for inline explanations.
10+
11+
## Set environment variables
12+
13+
Set the values shown in `.env-sample` as environmental variables. To copy it into a `.env` file:
14+
15+
```bash
16+
cp .env-sample .env
17+
```
18+
19+
You'll still need to edit some variables, i.e., `CHAIN_RPC` and `PARENT_CHAIN_RPC`.
20+
21+
Note that you can also set the environment variables in an `.env` file in the root of the monorepo, which will be available in all tutorials.
22+
23+
## Run
24+
25+
```shell
26+
yarn run exec {block_number}
27+
```
28+
29+
<p align="left">
30+
<img width="350" height="150" src= "../../assets/logo.svg" />
31+
</p>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "block-verification-in-parent-chain-assertion",
3+
"version": "1.0.0",
4+
"description": "This tutorial shows how to verify whether a block has been processed as part of an RBlock assertion on the parent chain.",
5+
"scripts": {
6+
"exec": "ts-node scripts/exec.ts"
7+
},
8+
"dependencies": {
9+
"@arbitrum/sdk": "^v4.0.1",
10+
"ts-node": "^10.9.2",
11+
"typescript": "^4.9.5"
12+
}
13+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { providers, Contract } from "ethers"
2+
import { getArbitrumNetwork } from '@arbitrum/sdk'
3+
import { RollupCore__factory } from "@arbitrum/sdk/dist/lib/abi/factories/RollupCore__factory"
4+
import { arbLog, requireEnvVariables, addCustomNetworkFromFile } from 'arb-shared-dependencies'
5+
require('dotenv').config()
6+
requireEnvVariables(['CHAIN_RPC', 'PARENT_CHAIN_RPC'])
7+
8+
/**
9+
* Set up: instantiate wallets connected to providers
10+
*/
11+
const parentChainProvider = new providers.JsonRpcProvider(
12+
process.env.PARENT_CHAIN_RPC
13+
)
14+
const childChainProvider = new providers.JsonRpcProvider(process.env.CHAIN_RPC)
15+
16+
/**
17+
* Use the latest node created instead of the last confirmed one
18+
*/
19+
const useCreatedNodeInsteadOfConfirmed = false;
20+
21+
const main = async (childChainBlockNumberToVerify: number) => {
22+
await arbLog('Find whether a block of the child chain has been processed as part of an RBlock on the parent chain')
23+
24+
/**
25+
* Add the custom network configuration to the SDK if present
26+
*/
27+
addCustomNetworkFromFile()
28+
29+
/**
30+
* Use childChainNetwork to find the Rollup contract's address and instantiate a contract handler
31+
*/
32+
const childChainNetwork = await getArbitrumNetwork(childChainProvider)
33+
const rollupAddress = childChainNetwork.ethBridge.rollup
34+
const rollup = new Contract(rollupAddress, RollupCore__factory.abi, parentChainProvider)
35+
console.log(`Rollup contract found at address ${rollup.address}`)
36+
37+
/**
38+
* Get the latest node created or confirmed
39+
*/
40+
const nodeId = useCreatedNodeInsteadOfConfirmed ? await rollup.latestNodeCreated() : await rollup.latestConfirmed()
41+
console.log(`Latest ${useCreatedNodeInsteadOfConfirmed ? 'created' : 'confirmed'} Rblock/node: ${nodeId}`)
42+
43+
/**
44+
* Find the NodeCreated event
45+
*/
46+
const nodeCreatedEventFilter = rollup.filters.NodeCreated(nodeId)
47+
const nodeCreatedEvents = await rollup.queryFilter(nodeCreatedEventFilter)
48+
if (!nodeCreatedEvents) {
49+
console.error(`INTERNAL ERROR: NodeCreated events not found for Rblock/node: ${nodeId}`)
50+
return
51+
}
52+
const nodeCreatedEvent = nodeCreatedEvents[0]
53+
console.log(`NodeCreated event found in transaction ${nodeCreatedEvent.transactionHash}`)
54+
55+
/**
56+
* Finding the assertion within the NodeCreated event, and getting the afterState
57+
*/
58+
if (!nodeCreatedEvent.args) {
59+
console.error(`INTERNAL ERROR: NodeCreated event does not have an assertion for Rblock/node: ${nodeId}`)
60+
return
61+
}
62+
const assertion = nodeCreatedEvent.args.assertion
63+
const afterState = assertion.afterState
64+
65+
/**
66+
* Latest child chain's block hash processed is in the first element of the bytes32Vals property in the globalState
67+
*/
68+
const lastChildChainBlockHash = afterState.globalState.bytes32Vals[0]
69+
console.log(`Last block hash of the child chain processed in this Rblock/node: ${lastChildChainBlockHash}`)
70+
71+
/**
72+
* Getting the block number from that block hash
73+
*/
74+
const lastChildChainBlock = await childChainProvider.getBlock(lastChildChainBlockHash)
75+
const lastChildChainBlockNumber = lastChildChainBlock.number
76+
console.log(`Last block number of the child chain processed in this Rblock/node: ${lastChildChainBlockNumber}`)
77+
78+
/**
79+
* Final verification
80+
*/
81+
console.log(`************`)
82+
if (lastChildChainBlockNumber > childChainBlockNumberToVerify) {
83+
console.log(`${childChainBlockNumberToVerify} has been processed as part of the latest ${useCreatedNodeInsteadOfConfirmed ? 'created' : 'confirmed'} RBlock/node`)
84+
} else {
85+
console.log(`${childChainBlockNumberToVerify} has NOT been processed as part of the latest ${useCreatedNodeInsteadOfConfirmed ? 'created' : 'confirmed'} RBlock/node`)
86+
}
87+
console.log(`************`)
88+
};
89+
90+
// Getting the transaction hash from the command arguments
91+
if (process.argv.length < 3) {
92+
console.log(`Missing block number of the child chain to verify whether it has been processed in the latest ${useCreatedNodeInsteadOfConfirmed ? 'created' : 'confirmed'} RBlock/node`)
93+
console.log(`Usage: yarn run exec <block number>`)
94+
process.exit()
95+
}
96+
97+
const childChainBlockNumber = Number(process.argv[2]);
98+
99+
// Calling main
100+
main(childChainBlockNumber)
101+
.then(() => process.exit(0))
102+
.catch(error => {
103+
console.error(error)
104+
process.exit(1)
105+
});

packages/contract-deposit/scripts/exec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const {
1818
ParentEthDepositTransactionReceipt,
1919
} = require('@arbitrum/sdk')
2020
const { getBaseFee } = require('@arbitrum/sdk/dist/lib/utils/lib')
21+
require('dotenv').config()
2122
requireEnvVariables([
2223
'PRIVATE_KEY',
2324
'CHAIN_RPC',

packages/greeter/scripts/exec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const {
1515
getArbitrumNetwork,
1616
} = require('@arbitrum/sdk')
1717
const { getBaseFee } = require('@arbitrum/sdk/dist/lib/utils/lib')
18+
require('dotenv').config()
1819
requireEnvVariables(['PRIVATE_KEY', 'CHAIN_RPC', 'PARENT_CHAIN_RPC'])
1920

2021
/**

0 commit comments

Comments
 (0)