まいにちDapps15日目はOptimismが提供しているOPStackを使って独自のLayer2チェーンを作成してみます。OPStackは最近話題となっているCoinbase社のBaseというチェーンをはじめいくつかのL2チェーンに採用されています。OPStackによって各アプリが独自のApp Chainを持つことの流れは加速すると思いますので、どれくらいの難易度なのか、その手順を見ていきましょう。
OPStack
OPStackのGetting Startedを進めていきます。
前提条件としてprerequisites にあるソフトウェアをインストールしておく必要があります。これが入っていないとbuildが通らないので事前にインストールしておいてください。
ETHGlobalでのこちらの動画も参考にしています。
モノレポ全体をgit cloneします。
op-gethをcloneします。
cd ~
git clone https://github.com/ethereum-optimism/op-geth.git
以下のコマンドでキーを作成します。
echo "Admin:"
cast wallet new
echo "Proposer:"
cast wallet new
echo "Batcher:"
cast wallet new
echo "Sequencer:"
cast wallet new
作成されたアドレスは保存しておき、各アカウントに以下の量のETHを補充します(今回はSepoliaでやってみます)。1/10のくらいでも全然大丈夫でした。
Admin
— 2 ETHProposer
— 5 ETHBatcher
— 10 ETH
cd packages/contracts-bedrock
に移動して、
cast block finalized --rpc-url $ETH_RPC_URL | grep -E "(timestamp|hash|number)"
でSepoliaの最新のTimestampを取得します。
deploy-config/getting-started.jsonファイルを探し出し、各アドレスで変更します。
自分の場合こんな形になりました↓
{
"numDeployConfirmations": 1,
"finalSystemOwner": "0xd7A724C4C589EfBA058B8454519CceD05aCE7CDa",
"portalGuardian": "0xd7A724C4C589EfBA058B8454519CceD05aCE7CDa",
"l1StartingBlockTag": "0x832a16a4654d3ea99217d47c3a0eab515d72405c709c39d07e9dc1b2c9218d85",
"l1ChainID": 11155111,
"l2ChainID": 11155420,
"l2BlockTime": 2,
"maxSequencerDrift": 600,
"sequencerWindowSize": 3600,
"channelTimeout": 300,
"p2pSequencerAddress": "0x213bfFd68389E19850cBAd39Db42607929664bfE",
"batchInboxAddress": "0xff00000000000000000000000000000000042069",
"batchSenderAddress": "0x3229ad6426621884618C97Ca00223e62A6CB0162",
"l2OutputOracleSubmissionInterval": 120,
"l2OutputOracleStartingBlockNumber": 2,
"l2OutputOracleStartingTimestamp": 1692162516,
"l2OutputOracleProposer": "0x9eD06996584f9C9Ab5cE348c4251733846B2BA29",
"l2OutputOracleChallenger": "0xd7A724C4C589EfBA058B8454519CceD05aCE7CDa",
"finalizationPeriodSeconds": 12,
"proxyAdminOwner": "0xd7A724C4C589EfBA058B8454519CceD05aCE7CDa",
"baseFeeVaultRecipient": "0xd7A724C4C589EfBA058B8454519CceD05aCE7CDa",
"l1FeeVaultRecipient": "0xd7A724C4C589EfBA058B8454519CceD05aCE7CDa",
"sequencerFeeVaultRecipient": "0xd7A724C4C589EfBA058B8454519CceD05aCE7CDa",
"baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"baseFeeVaultWithdrawalNetwork": 0,
"l1FeeVaultWithdrawalNetwork": 0,
"sequencerFeeVaultWithdrawalNetwork": 0,
"gasPriceOracleOverhead": 2100,
"gasPriceOracleScalar": 1000000,
"enableGovernance": true,
"governanceTokenSymbol": "OP",
"governanceTokenName": "Optimism",
"governanceTokenOwner": "0xd7A724C4C589EfBA058B8454519CceD05aCE7CDa",
"l2GenesisBlockGasLimit": "0x1c9c380",
"l2GenesisBlockBaseFeePerGas": "0x3b9aca00",
"l2GenesisRegolithTimeOffset": "0x0",
"eip1559Denominator": 50,
"eip1559Elasticity": 10,
"systemConfigStartBlock": 2,
"l1BlockTime": 12
}
L1にコントラクトをデプロイします。
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
↑別々で実行したほうがいいと思います
deployments/getting-startedフォルダに以下のようにコントラクトのABIがたくさん生成されていれば成功しています。
L2側の設定をしていきます。
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 <YOUR RPC>
上記コードでエラーが出ますが、getting-started.jsonのl2BlockTimeを1以上に、l1BlockTimeという項目を新しく増やして2以上にするとエラーが出ません。
op-gethを立ち上げます。
op-nodeも走らせます。
officialページのコマンドをそのまま使うと./jwt.txt \の後に不要なスペースがあることによってエラーが出るという罠があるので削除して使用してください。
L2も立ち上がりました!
その後にL1からL2のブリッジコントラクトにETHを送り、L2でコントラクトをデプロイして関数を実行するというチュートリアルの続きもありますが今回はここまでとします!ぜひご自身でやってみてください。
まとめ
OPStackを使ってL2を作成する方法を学習しました。独自チェーンを作るという意味ではAvalancheのSubnetを立てる方法もあれば、同様のL2をZkRollupを使って立てるためのZkStackもあるようなのでこちらもいずれ見てみたいです。
弊社Pontechはweb3に関わる開発を得意とするテック企業です。サービス開発に関するご相談はこちらのフォームからお願いいたします。
また、受託開発案件に共に取り組むメンバーを募集しています!ご興味のある方はぜひお話させてください!