From 00946b17c93ab5e9c3d5b97db32bdf027ba80507 Mon Sep 17 00:00:00 2001 From: hopeyen Date: Mon, 26 Aug 2024 16:42:13 -0500 Subject: [PATCH] feat: scripts for raas --- hardhat.config.ts | 7 ++ scripts/deploymentUtils.ts | 55 ++++++++- scripts/local-deployment/createRollup.ts | 106 ++++++++++++++++++ .../local-deployment/deployBlobVerifierL1.ts | 57 ++++++++++ scripts/local-deployment/deployCreator.ts | 88 +++++++++++++++ 5 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 scripts/local-deployment/createRollup.ts create mode 100644 scripts/local-deployment/deployBlobVerifierL1.ts create mode 100644 scripts/local-deployment/deployCreator.ts diff --git a/hardhat.config.ts b/hardhat.config.ts index e18b78dc..b326a5f8 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -99,6 +99,12 @@ module.exports = { ? [process.env['DEVNET_PRIVKEY']] : [], }, + holesky: { + url: 'https://holesky.infura.io/v3/' + process.env['INFURA_KEY'], + accounts: process.env['DEVNET_PRIVKEY'] + ? [process.env['DEVNET_PRIVKEY']] + : [], + }, rinkeby: { url: 'https://rinkeby.infura.io/v3/' + process.env['INFURA_KEY'], accounts: process.env['DEVNET_PRIVKEY'] @@ -144,6 +150,7 @@ module.exports = { mainnet: process.env['ETHERSCAN_API_KEY'], goerli: process.env['ETHERSCAN_API_KEY'], sepolia: process.env['ETHERSCAN_API_KEY'], + holesky: process.env['ETHERSCAN_API_KEY'], rinkeby: process.env['ETHERSCAN_API_KEY'], arbitrumOne: process.env['ARBISCAN_API_KEY'], arbitrumTestnet: process.env['ARBISCAN_API_KEY'], diff --git a/scripts/deploymentUtils.ts b/scripts/deploymentUtils.ts index d99766db..11d06bb2 100644 --- a/scripts/deploymentUtils.ts +++ b/scripts/deploymentUtils.ts @@ -7,7 +7,7 @@ import { bytecode as UpgradeExecutorBytecode, } from '@offchainlabs/upgrade-executor/build/contracts/src/UpgradeExecutor.sol/UpgradeExecutor.json' import { Toolkit4844 } from '../test/contract/toolkit4844' -import { ArbSys__factory } from '../build/types' +import { ArbSys__factory, EigenDABlobVerifierL1__factory } from '../build/types' import { ARB_SYS_ADDRESS } from '@arbitrum/sdk/dist/lib/dataEntities/constants' // Define a verification function @@ -74,17 +74,64 @@ export async function deployContract( return contract } + +// This function is called for RollupCreator on L1, where EigenDAServiceManager +// is needed as a constructor argument +// The deployed blob verifier is the EigendaRollupManager argument during rollup creation +export async function deployBlobVerifierL1( + contractName: string, + signer: any, + constructorArgs: any[] = [], + verify: boolean = true, + overrides?: Overrides +): Promise { + console.log("Deploying contract EigenDA x Arbitrum", contractName) + const eigenDARollupUtils = await deployContract('EigenDARollupUtils', signer, [], verify) + console.log("EigenDARollupUtils deployed at", eigenDARollupUtils.address) + + const eigenda_blob_verifier = await ethers.getContractFactory(contractName, { + libraries: { + EigenDARollupUtils: eigenDARollupUtils.address + } + }) as EigenDABlobVerifierL1__factory + + const connectedFactory: ContractFactory = eigenda_blob_verifier.connect(signer) + + let deploymentArgs = [...constructorArgs] + if (overrides) { + deploymentArgs.push(overrides) + } + + const contract: Contract = await connectedFactory.deploy(...deploymentArgs) + await contract.deployTransaction.wait() + console.log(`New ${contractName} created at address:`, contract.address) + + if (verify) + await verifyContract(contractName, contract.address, constructorArgs) + + return contract +} + // Deploy upgrade executor from imported bytecode export async function deployUpgradeExecutor(signer: any): Promise { + console.log("Deploying contract EigenDA x Arbitrum UpgradeExecutor") const upgradeExecutorFac = await ethers.getContractFactory( UpgradeExecutorABI, UpgradeExecutorBytecode ) const connectedFactory: ContractFactory = upgradeExecutorFac.connect(signer) const upgradeExecutor = await connectedFactory.deploy() + await upgradeExecutor.deployTransaction.wait() + console.log("Upgrade executor deployed at", upgradeExecutor.address) return upgradeExecutor } +const L1ServiceManagers = { + 1: "0x870679E138bCdf293b7Ff14dD44b70FC97e12fc0", // Ethereum + 5: "0xa3b1689Ab85409B15e07d2ED50A6EA9905074Ee5", // Goerli + 17000: "0x54A03db2784E3D0aCC08344D05385d0b62d4F432", // Holesky +} + // Function to handle all deployments of core contracts using deployContract function export async function deployAllContracts( signer: any, @@ -92,8 +139,12 @@ export async function deployAllContracts( verify: boolean = true ): Promise> { const isOnArb = await _isRunningOnArbitrum(signer) + const chainId = signer.provider.network.chainId - const eigenDARollupManager = await deployContract('EigenDABlobVerifierL2', signer, [], verify) + // If signer is on L1, deploy EigenDABlobVerifierL1 with EigenDAServiceManager as constructor argument + // If signer is on L2, deploy EigenDABlobVerifierL2; blob verifier is used as eigenDARollupManager as part of rollup creation + const eigenDARollupManager = (L1ServiceManagers.hasOwnProperty(chainId)) ? + await deployBlobVerifierL1('EigenDABlobVerifierL1', signer, [L1ServiceManagers[chainId as keyof typeof L1ServiceManagers]], verify) : await deployContract('EigenDABlobVerifierL2', signer, [], verify) const ethBridge = await deployContract('Bridge', signer, [], verify) const reader4844 = isOnArb diff --git a/scripts/local-deployment/createRollup.ts b/scripts/local-deployment/createRollup.ts new file mode 100644 index 00000000..6a27691a --- /dev/null +++ b/scripts/local-deployment/createRollup.ts @@ -0,0 +1,106 @@ +import { ethers } from 'hardhat' +import '@nomiclabs/hardhat-ethers' +import { deployAllContracts, deployBlobVerifierL1 } from '../deploymentUtils' +import { createRollup } from '../rollupCreation' +import { promises as fs } from 'fs' +import { BigNumber } from 'ethers' +import { RollupAdminLogic__factory } from '../../build/types' + +async function main() { + /// read env vars needed for deployment + let childChainName = process.env.CHILD_CHAIN_NAME as string + if (!childChainName) { + throw new Error('CHILD_CHAIN_NAME not set') + } + + let deployerPrivKey = process.env.DEPLOYER_PRIVKEY as string + if (!deployerPrivKey) { + throw new Error('DEPLOYER_PRIVKEY not set') + } + + let parentChainRpc = process.env.PARENT_CHAIN_RPC as string + if (!parentChainRpc) { + throw new Error('PARENT_CHAIN_RPC not set') + } + + if (!process.env.PARENT_CHAIN_ID) { + throw new Error('PARENT_CHAIN_ID not set') + } + + const deployerWallet = new ethers.Wallet( + deployerPrivKey, + new ethers.providers.JsonRpcProvider(parentChainRpc) + ) + + /// get fee token address, if undefined use address(0) to have ETH as fee token + let feeToken = process.env.FEE_TOKEN_ADDRESS as string + if (!feeToken) { + feeToken = ethers.constants.AddressZero + } + console.log('Fee token address:', feeToken) + + const rollupCreatorAddress = process.env.ROLLUP_CREATOR as string + if (!rollupCreatorAddress) { + throw new Error('ROLLUP_CREATOR not set') + } + const rollupCreatorFac = await ethers.getContractFactory('RollupCreator') + const rollupCreator = rollupCreatorFac.attach(rollupCreatorAddress) + + const eigenDARollupManager = process.env.EIGENDA_ROLLUP_MANAGER as string + if (!eigenDARollupManager) { + throw new Error('EIGENDA_ROLLUP_MANAGER not set') + } + + /// Create rollup + const chainId = (await deployerWallet.provider.getNetwork()).chainId + console.log( + 'Create rollup on top of chain', + chainId, + 'using RollupCreator', + rollupCreator.address + ) + const result = await createRollup( + deployerWallet, + true, + rollupCreator.address, + feeToken, + eigenDARollupManager, + ) + + if (!result) { + throw new Error('Rollup creation failed') + } + + const { rollupCreationResult, chainInfo } = result + + /// store deployment address + // chain deployment info + const chainDeploymentInfo = + process.env.CHAIN_DEPLOYMENT_INFO !== undefined + ? process.env.CHAIN_DEPLOYMENT_INFO + : 'deploy.json' + await fs.writeFile( + chainDeploymentInfo, + JSON.stringify(rollupCreationResult, null, 2), + 'utf8' + ) + + // child chain info + chainInfo['chain-name'] = childChainName + const childChainInfo = + process.env.CHILD_CHAIN_INFO !== undefined + ? process.env.CHILD_CHAIN_INFO + : 'l2_chain_info.json' + await fs.writeFile( + childChainInfo, + JSON.stringify([chainInfo], null, 2), + 'utf8' + ) +} + +main() + .then(() => process.exit(0)) + .catch((error: Error) => { + console.error(error) + process.exit(1) + }) diff --git a/scripts/local-deployment/deployBlobVerifierL1.ts b/scripts/local-deployment/deployBlobVerifierL1.ts new file mode 100644 index 00000000..ea481425 --- /dev/null +++ b/scripts/local-deployment/deployBlobVerifierL1.ts @@ -0,0 +1,57 @@ +import { ethers } from 'hardhat' +import '@nomiclabs/hardhat-ethers' +import { deployBlobVerifierL1 } from '../deploymentUtils' +import { promises as fs } from 'fs' + + +async function main() { + /// read env vars needed for deployment + let childChainName = process.env.CHILD_CHAIN_NAME as string + if (!childChainName) { + throw new Error('CHILD_CHAIN_NAME not set') + } + + let deployerPrivKey = process.env.DEPLOYER_PRIVKEY as string + if (!deployerPrivKey) { + throw new Error('DEPLOYER_PRIVKEY not set') + } + + let parentChainRpc = process.env.PARENT_CHAIN_RPC as string + if (!parentChainRpc) { + throw new Error('PARENT_CHAIN_RPC not set') + } + + let eigenDAServiceManagerAddress = process.env.EIGENDA_SERVICE_MANAGER_ADDRESS as string + if (!eigenDAServiceManagerAddress) { + throw new Error('EIGENDA_SERVICE_MANAGER_ADDRESS not set') + } + + if (!process.env.PARENT_CHAIN_ID) { + throw new Error('PARENT_CHAIN_ID not set') + } + + const deployerWallet = new ethers.Wallet( + deployerPrivKey, + new ethers.providers.JsonRpcProvider(parentChainRpc) + ) + + // deploy templates and rollup creator + const blobVerifierL1 = await deployBlobVerifierL1('EigenDABlobVerifierL1', deployerWallet, [eigenDAServiceManagerAddress], true) + console.log('BlobVerifierL1 deployed at', blobVerifierL1.address) + + /// store deployment address + // chain deployment info + const verifierDeploymentInfo = 'blob_verifier_l1_deploy.json' + await fs.writeFile( + verifierDeploymentInfo, + JSON.stringify(blobVerifierL1.address, null, 2), + 'utf8' + ) +} + +main() + .then(() => process.exit(0)) + .catch((error: Error) => { + console.error(error) + process.exit(1) + }) diff --git a/scripts/local-deployment/deployCreator.ts b/scripts/local-deployment/deployCreator.ts new file mode 100644 index 00000000..067a575c --- /dev/null +++ b/scripts/local-deployment/deployCreator.ts @@ -0,0 +1,88 @@ +import { ethers } from 'hardhat' +import '@nomiclabs/hardhat-ethers' +import { deployAllContracts, deployBlobVerifierL1 } from '../deploymentUtils' +import { createRollup } from '../rollupCreation' +import { promises as fs } from 'fs' +import { BigNumber } from 'ethers' +import { RollupAdminLogic__factory } from '../../build/types' + +async function main() { + /// read env vars needed for deployment + let childChainName = process.env.CHILD_CHAIN_NAME as string + if (!childChainName) { + throw new Error('CHILD_CHAIN_NAME not set') + } + + let deployerPrivKey = process.env.DEPLOYER_PRIVKEY as string + if (!deployerPrivKey) { + throw new Error('DEPLOYER_PRIVKEY not set') + } + + let parentChainRpc = process.env.PARENT_CHAIN_RPC as string + if (!parentChainRpc) { + throw new Error('PARENT_CHAIN_RPC not set') + } + + if (!process.env.PARENT_CHAIN_ID) { + throw new Error('PARENT_CHAIN_ID not set') + } + + const deployerWallet = new ethers.Wallet( + deployerPrivKey, + new ethers.providers.JsonRpcProvider(parentChainRpc) + ) + + const maxDataSize = + process.env.MAX_DATA_SIZE !== undefined + ? ethers.BigNumber.from(process.env.MAX_DATA_SIZE) + : ethers.BigNumber.from(117964) + + /// get fee token address, if undefined use address(0) to have ETH as fee token + let feeToken = process.env.FEE_TOKEN_ADDRESS as string + if (!feeToken) { + feeToken = ethers.constants.AddressZero + } + console.log('Fee token address:', feeToken) + + // deploy templates and rollup creator + console.log('Deploy RollupCreator') + + const contracts = await deployAllContracts(deployerWallet, maxDataSize, false) + + console.log('Set templates on the Rollup Creator') + await ( + await contracts.rollupCreator.setTemplates( + contracts.bridgeCreator.address, + contracts.osp.address, + contracts.challengeManager.address, + contracts.rollupAdmin.address, + contracts.rollupUser.address, + contracts.upgradeExecutor.address, + contracts.validatorUtils.address, + contracts.validatorWalletCreator.address, + contracts.deployHelper.address, + { gasLimit: BigNumber.from('300000') } + ) + ).wait() + + console.log('Rollup creator is ready for rollup creation') + + /// store deployment address + // chain deployment info + const chainDeploymentInfo = + process.env.CHAIN_DEPLOYMENT_INFO !== undefined + ? process.env.CHAIN_DEPLOYMENT_INFO + : 'rollupCreatorContracts.json' + await fs.writeFile( + chainDeploymentInfo, + JSON.stringify(contracts, null, 2), + 'utf8' + ) +} + +main() + .then(() => process.exit(0)) + .catch((error: Error) => { + console.error(error) + process.exit(1) + })