note: มาลองรัน L2 chain ด้วย OP Stack กัน

Nattawat Songsom
5 min readAug 5, 2023

--

มา walkthrough รวดเดียวให้จบไปเลยกัน

note: ผมใช้ ubuntu 20 นะครับ

เริ่มจาก sudo apt-get update

จากนั้นลง software ที่ต้องใช้ตามภาพ

note: เหมือนตอน sudo apt-get install -y nodejs npm เค้าจะใส่คำสั่งมาเกินเลย error หะ จริงๆ sudo apt-get install -y nodejs ก็พอ

note: ต้องลง yarn ก่อนไป install foundry ซึ่งทำได้ด้วยคำสั่ง

## To install the Yarn package manager, run:
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update && sudo apt-get install yarn

note: คำสั่ง yarn install:foundry เป็นการ install แบบ local ใน folder ที่มี package.json แต่เราจะ install แบบ global โดยใช้คำสั่งด้านล่างแทน

curl -L https://foundry.paradigm.xyz | bash
source /root/.bashrc
foundryup

โอเค ต่อมาเราจะลง component ต่างๆของ optimism chain ลงในเครื่องโดยคำสั่ง

cd ~
git clone https://github.com/ethereum-optimism/optimism.git
cd optimism
pnpm install
make op-node op-batcher op-proposer
pnpm build

ต่อมาก็ลง op-geth

cd ~
git clone https://github.com/ethereum-optimism/op-geth.git
cd op-geth
make geth

โอเค ต่อมาจะเป็นการเตรียม account สำหรับ component ต่างๆของ chain L2 โดยประกอบด้วย

  • admin account สำหรับไว้ upgreade contract (upgrade ยังไงหว่า เดี๋ยวเจอแล้วจะมาแปะอีกที)
  • batcher account สำหรับ publish transaction data จาก sequencer ไปยัง L1
  • proposer account สำหรับ publish trasaction result ของ L2 ไปยัง L1
  • sequencer account สำหรับการ sign block บน p2p network

โดยในการ gen account สามารถใช้ rekey ที่ติดมากับ optimisim monorepo ที่เรา clone มาแล้วได้เลยด้วยคำสั่ง

cd ~
cd packages/contracts-bedrock
echo "Admin:"
cast wallet new
echo "Proposer:"
cast wallet new
echo "Batcher:"
cast wallet new
echo "Sequencer:"
cast wallet new

จะได้ private key มาประมาณนี้

Admin:
Successfully created new keypair.
Address: 0x9f92bdF0db69264462FC305913960Edfcc7a7c7F
Private key: 0x30e66956e1a12b81f0f2cfb982286b2f566eb73649833831d9f80b12f8fa183c
Proposer:
Successfully created new keypair.
Address: 0x31dE9B6473fc47af36ec23878bA34824B9F4AB30
Private key: 0x8bd1c8dfffef880f8f9ab8162f97ccd119c1aac28fe00dacf919459f88e0f37d
Batcher:
Successfully created new keypair.
Address: 0x6A3DC843843139f17Fcf04C057bb536A421DC9c6
Private key: 0x3ce44144b7fde797a28f4e47b210a4d42c3a3b642e538b54458cba2740db5ac2
Sequencer:
Successfully created new keypair.
Address: 0x98C6cadB1fe77aBB7bD968fC3E9b206111e72848
Private key: 0x3f4241229bb6f155140d98e0f5dd2aad7ae983f5af5d61555d05eb8e5d9514db

โอเค จริงๆใน tutorial ต้นฉบับ เป็นการรัน L2 chain บน Goerli L1 chain

โดยต้องใส่ GETH ให้แต่ละ account ดังนี้

Admin — 2 ETH
Proposer — 5 ETH
Batcher — 10 ETH

ซึ่งใช้เยอะแบบนี้คงต้องไปซื้อเอา

ดังนั้นแทนที่จะใช้ Goerli ่เราจะลองใช้ local chain ของเราเอง เพื่อให้เราสามารถเสก ETH ได้เองกัน

โดยเนื่องจากเราลง foundry ในเครื่องไปแล้ว ดังนั้นเราจะใช้ anvil ใน foundry เพื่อเปิด chain เองกัน โดยรันคำสั่ง

anvil

จะได้ result แบบนี้ ให้เปิดค้างไว้

โดยเราจะใช้ account พวกนี้แทนพวก admin batcher … ที่เรา gen ไปก่อนหน้าเลยแล้วกัน

โอเค ต่อมาจะเป็นการ config ตัว network L2 ของเรา โดยเราต้องเข้าไปที่ folder ที่เก็บ example config ก่อน

cd ~/optimism
cd packages/contracts-bedrock

สร้างไฟล์ config จาก eaxmple

cp .envrc.example .envrc

แก้ไฟล์ config

nano .envrc

โดยแก้ตามนี้

ETH_RPC_URL แก้ให้ชี้ไป RPC ของ anvil ซึ่งคือ http://127.0.0.1:8545/

PRIVATE_KEY ใส่ private key ของ accout admin ไป

DEPLOYMENT_CONTEXT อันนี้มาตั้งชื่อ chain เป็น getting-started กัน

โอเค ต่อมาเป็นการสั่งให้ chain ใช้ config นี้ โดยเราต้องลง direnv ก่อน

apt  install direnv

จากนั้นให้เรา hook ตัว direnv เข้ากับ bash shell ด้วยการแก้ไฟล์ ~/.bashrc

nano ~/.bashrc

โดยเติม eval "$(direnv hook bash)" ไปที่บรรทัดล่างสุด แล้ว เปิด terminal ใหม่

โอเค กลับไปที่ folder ไฟล์ config network

cd ~/optimism
cd packages/contracts-bedrock

note: ต้องใช้ user เดียวกับที่ทำใน terminal แรกแหะ ใน case นี้เป็น root

note: จะขึ้น error นี้มา

ให้รันคำสั่ง

direnv allow .

ตอนนี้พอเราออกไปที่อื่น แล้วเข้ามาที่ folder นี้ใหม่ก็จะไม่ขึ้น error แล้ว

โอเค ต่อมาเราจะต้องกำหนดเลข block ที่ L2 จะเริ่ม

โดยเราจะใช้ finalized block ของ anvil ละกัน

โดยเราสามารหาเลข block นั้นได้ด้วยคำสั่ง

cast block finalized --rpc-url http://localhost:8545 | grep -E "(timestamp|hash|number)"

จะได้ result แบบนี้

hash                 0xb17ac070f0565f4ec886c34a7299833547c4c34f05b78326a99f88440887c1ba
number 0
timestamp 1691220541

โอเค มาแก้ config ของ chain ในไฟล์ deploy-config/getting-started.json กัน

nano deploy-config/getting-started.json

โดยหา value ที่เป็นคำเหล่านี้ ADMIN, PROPOSER, BATCHER, SEQUENCER

แล้ว replace ด้วย address ของ wallet ต่างๆที่เราเตรียมไว้

และแก้ BLOCKHASH และ TIMESTAMP เป็นค่าของ finalized block ที่เราได้มา

จากนั้นเราจะมา deloy contract บน L1 ที่ต้องใช้กัน

โดยเริ่มจากสร้าง folder

mkdir deployments/getting-started

จากนั้น deploy contract ด้วย

forge script scripts/Deploy.s.sol:Deploy --private-key $PRIVATE_KEY --broadcast --rpc-url $ETH_RPC_URL
forge script scripts/Deploy.s.sol:Deploy --sig 'sync()' --private-key $PRIVATE_KEY --broadcast --rpc-url $ETH_RPC_URL

โดยใช้ private key ของ ADMIN และ rpc url ของ anvil

โอเค setup L1 ไปละ มา setup L2 กันต่อ

cd ~/optimism/op-node
go run cmd/main.go genesis l2 --deploy-config ../packages/contracts-bedrock/deploy-config/getting-started.json --deployment-dir ../packages/contracts-bedrock/deployments/getting-started/ --outfile.l2 genesis.json --outfile.rollup rollup.json --l1-rpc http://localhost:8545

แต่เจอ error แหะ

เป็นเพราะ block ของ anvil ไม่ได้ถูกขุดไปเรื่อยๆรึเปล่า ?

งั้นมาเปิด chain anvil ใหม่ แบบให้ block ถูกขุดทุก 10 วินาทีแล้วกัน

# Produces a new block every 10 seconds
anvil --block-time 10

เอาละ มาหา finalized block ของ chain ใหม่นี้กัน

cast block finalized --rpc-url http://localhost:8545 | grep -E "(timestamp|hash|number)" 

จะได้

hash                 0xf5bd890185c6fbb8d386b54a54719dc6910138afefbd3fb4e4f2fa228bb84e5d
number 0
timestamp 1691225369

โอเค ต้องมาแก้ config ของ L1 กันใหม่

nano ~/optimism/packages/contracts-bedrock/deploy-config/getting-started.json

แก้ l1StartingBlockTag เป็น blockhash ของ finalized block

แก้ l2OutputOracleStartingTimestamp เป็น timestamp ของ finalized block

โอเค deploy contract ที่จะเป็นต้องใช้บน L1 กันใหม่

cd ~/optimism/packages/contracts-bedrock
forge script scripts/Deploy.s.sol:Deploy --private-key $PRIVATE_KEY --broadcast --rpc-url $ETH_RPC_URL
forge script scripts/Deploy.s.sol:Deploy --sig 'sync()' --private-key $PRIVATE_KEY --broadcast --rpc-url $ETH_RPC_URL

โอเค มาสร้างไฟล์ genesis.json กับ rollup.json ของ L2 กันใหม่กัน

cd ~/optimism/op-node
go run cmd/main.go genesis l2 --deploy-config ../packages/contracts-bedrock/deploy-config/getting-started.json --deployment-dir ../packages/contracts-bedrock/deployments/getting-started/ --outfile.l2 genesis.json --outfile.rollup rollup.json --l1-rpc http://localhost:8545

เอ้า ยัง error เหมือนเดิมเลยแหะ

กำ พออ่าน error ดูดีๆแล้ว เหมือนว่าจะเป็นเพราะ value l2BlockTime เป็น 2 ซึ่งเยอะกว่า 0 แหะ

เอาจริงๆ เหมือน file getting-started.json นี้จะทำมาเพื่อเชื่อม goerli เลย งั้นมาแก้ l1ChianID เป็น 31337 กัน

error ยังไม่หายแหะ

ตัว OP stack ไปถึง L1 blocktime เป็น 0 มาได้ยังไงหว่า

โอเค ไม่เป็นไร งั้นลองมา fork goerli ด้วย anvil แทนแล้วกัน

โอเค เดี๋ยวเราเติม — blocktime เป็น 12 วิไปด้วย

โอเค มารันคำสั่งกันใหม่อีกรอบดู

พอ deploy contract แล้ว error แหะ

พอเข้าไปดูไฟล์ .chainId ตาม error ก็เจอว่ายังเป็นค่าเก่าแหะ

ไม่รู้ว่าไฟล์นี้ถูกสร้างตอนไหนแหะ

งั้นแก้ค่าเป็น 5 ไปตรงๆเลยแล้วกัน

ทำยังไงก็ error แหะ

งั้นลบ folder สร้างใหม่ไปเลยแล้วกัน

cd ~/optimism/packages/contracts-bedrock
rm -rf deployments/getting-started
mkdir deployments/getting-started
forge script scripts/Deploy.s.sol:Deploy --private-key $PRIVATE_KEY --broadcast --rpc-url $ETH_RPC_URL
forge script scripts/Deploy.s.sol:Deploy --sig 'sync()' --private-key $PRIVATE_KEY --broadcast --rpc-url $ETH_RPC_URL
cd ~/optimism/op-node
go run cmd/main.go genesis l2 --deploy-config ../packages/contracts-bedrock/deploy-config/getting-started.json --deployment-dir ../packages/contracts-bedrock/deployments/getting-started/ --outfile.l2 genesis.json --outfile.rollup rollup.json --l1-rpc http://localhost:8545

โอเค กลับมาที่ error blocktime l1 = 0 แหะ

โอเค งั้นลองหา code ที่ print error นี้มากัน

อืม หาไม่เจอแหะว่าค่า l1BlockTime มาจากไหน 555

ค้างไว้ตรงนี้ก่อนแล้วกัน

--

--

Responses (1)