From 2a4f0bace829baa12d8fe67f81723017247cf301 Mon Sep 17 00:00:00 2001 From: zkJoaquin Date: Tue, 6 Feb 2024 19:30:36 +0800 Subject: [PATCH 1/2] add changeFeeParams case for scroll/zksync --- examples/scroll/hardhat.config.js | 1 + examples/scroll/scripts/5_changeFeeParams.js | 58 ++++++++ examples/zksync/hardhat.config.js | 1 + examples/zksync/scripts/changeFeeParams.js | 135 +++++++++++++++++++ examples/zksync/scripts/setValidator.js | 4 +- 5 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 examples/scroll/scripts/5_changeFeeParams.js create mode 100644 examples/zksync/scripts/changeFeeParams.js diff --git a/examples/scroll/hardhat.config.js b/examples/scroll/hardhat.config.js index ff1927b..b826b98 100644 --- a/examples/scroll/hardhat.config.js +++ b/examples/scroll/hardhat.config.js @@ -3,6 +3,7 @@ require('./scripts/1_initConfig'); require('./scripts/2_syncL2Requests'); require('./scripts/3_syncBatchRoot'); require('./scripts/4_setValidator'); +require('./scripts/5_changeFeeParams'); const BaseConfig = require('../../hardhat.base.config'); diff --git a/examples/scroll/scripts/5_changeFeeParams.js b/examples/scroll/scripts/5_changeFeeParams.js new file mode 100644 index 0000000..0223a68 --- /dev/null +++ b/examples/scroll/scripts/5_changeFeeParams.js @@ -0,0 +1,58 @@ +const { providers, Wallet, utils } = require('ethers'); +const { readDeployContract, getLogName } = require('../../../script/utils'); +const logName = require('../../../script/deploy_log_name'); +const { task, types } = require('hardhat/config'); + +require('dotenv').config(); + +task('changeFeeParams', 'Change fee params for zkLink') + .setAction(async (taskArgs, hre) => { + + const walletPrivateKey = process.env.DEVNET_PRIVKEY; + const l1Provider = new providers.JsonRpcProvider(process.env.L1RPC); + const ethereumName = process.env.ETHEREUM; + const scrollName = process.env.SCROLL; + const l1Wallet = new Wallet(walletPrivateKey, l1Provider); + + const l1WalletAddress = await l1Wallet.getAddress(); + const l1WalletBalance = utils.formatEther(await l1Wallet.getBalance()); + console.log(`${l1WalletAddress} balance on l1: ${l1WalletBalance} ether`); + + const arbitratorAddr = readDeployContract( + logName.DEPLOY_ARBITRATOR_LOG_PREFIX, + logName.DEPLOY_LOG_ARBITRATOR, + ethereumName, + ); + if (arbitratorAddr === undefined) { + console.log('The arbitrator address not exist'); + return; + } + console.log(`The arbitrator address: ${arbitratorAddr}`); + + const l1GatewayLogName = getLogName(logName.DEPLOY_L1_GATEWAY_LOG_PREFIX, scrollName); + const scrollL1GatewayAddr = readDeployContract(l1GatewayLogName, logName.DEPLOY_GATEWAY, ethereumName); + if (scrollL1GatewayAddr === undefined) { + console.log('scroll l1 gateway address not exist'); + return; + } + console.log(`The scroll l1 gateway address: ${scrollL1GatewayAddr}`); + + // forward message to L2 + const arbitrator = await hre.ethers.getContractAt('Arbitrator', arbitratorAddr, l1Wallet); + /** + * The adapterParams is the parameters for the adapter, which is used to parse the calldata. + * finalizeMessageGasLimit: the gas limit for the L2 to finalize the message. + */ + const { INIT_FEE_PARAMS } = require('../../../script/zksync_era'); + const finalizeMessageGasLimit = 1000000; + const adapterParams = hre.ethers.utils.defaultAbiCoder.encode(['uint256'], [finalizeMessageGasLimit]); + let tx = await arbitrator.changeFeeParams(scrollL1GatewayAddr, INIT_FEE_PARAMS, adapterParams, { + value: hre.ethers.utils.parseEther('0.001'), + }); + console.log(`The tx hash: ${tx.hash} , waiting confirm...`); + await tx.wait(); + console.log(`The tx confirmed`); + + // Waiting for the official Scroll bridge to forward the message to L2 + // No user action is required for follow-up. + }); diff --git a/examples/zksync/hardhat.config.js b/examples/zksync/hardhat.config.js index 8a270d6..785d267 100644 --- a/examples/zksync/hardhat.config.js +++ b/examples/zksync/hardhat.config.js @@ -3,6 +3,7 @@ require('@matterlabs/hardhat-zksync-verify'); require('./scripts/syncL2Requests'); require('./scripts/syncBatchRoot'); require('./scripts/setValidator'); +require('./scripts/changeFeeParams'); const BaseConfig = require('../../hardhat.base.config'); diff --git a/examples/zksync/scripts/changeFeeParams.js b/examples/zksync/scripts/changeFeeParams.js new file mode 100644 index 0000000..f7d08fd --- /dev/null +++ b/examples/zksync/scripts/changeFeeParams.js @@ -0,0 +1,135 @@ +const { Provider, Wallet, utils } = require('zksync-ethers'); +const { ethers } = require('ethers'); +const { readDeployContract, getLogName } = require('../../../script/utils'); +const logName = require('../../../script/deploy_log_name'); +const { task, types } = require('hardhat/config'); + +require('dotenv').config(); + +task('changeFeeParams', 'Change fee params for zkLink') + .setAction(async (taskArgs, hre) => { + + const walletPrivateKey = process.env.DEVNET_PRIVKEY; + const l1Provider = new Provider(process.env.L1RPC); + console.log(`Block number: ${await l1Provider.getBlockNumber()}`); + + const l2Provider = new Provider(process.env.L2RPC); + console.log(`Block number: ${await l2Provider.getBlockNumber()}`); + const zksyncName = process.env.ZKSYNC; + const ethereumName = process.env.ETHEREUM; + const l1Wallet = new ethers.Wallet(walletPrivateKey, l1Provider); + const zksyncWallet = new Wallet(walletPrivateKey, l2Provider, l1Provider); + + const l1WalletAddress = await l1Wallet.getAddress(); + console.log(`The l1 wallet address: ${l1WalletAddress}`); + const l1WalletBalance = ethers.formatEther(await l1Provider.getBalance(l1WalletAddress)); + console.log(`${l1WalletAddress} balance on l1: ${l1WalletBalance} ether`); + + const arbitratorAddr = readDeployContract( + logName.DEPLOY_ARBITRATOR_LOG_PREFIX, + logName.DEPLOY_LOG_ARBITRATOR, + ethereumName, + ); + if (arbitratorAddr === undefined) { + console.log('arbitrator address not exist'); + return; + } + console.log(`The arbitrator address: ${arbitratorAddr}`); + + const zkLinkAddr = readDeployContract( + logName.DEPLOY_ZKLINK_LOG_PREFIX, + logName.DEPLOY_LOG_ZKLINK_PROXY, + zksyncName, + ); + if (zkLinkAddr === undefined) { + console.log('zkLink address not exist'); + return; + } + console.log(`The zkLink address: ${zkLinkAddr}`); + + const l1GatewayLogName = getLogName(logName.DEPLOY_L1_GATEWAY_LOG_PREFIX, zksyncName); + const l1GatewayAddr = readDeployContract(l1GatewayLogName, logName.DEPLOY_GATEWAY, ethereumName); + if (l1GatewayAddr === undefined) { + console.log('l1 gateway address not exist'); + return; + } + console.log(`The l1 gateway address: ${l1GatewayAddr}`); + + const l2GatewayAddr = readDeployContract(logName.DEPLOY_L2_GATEWAY_LOG_PREFIX, logName.DEPLOY_GATEWAY, zksyncName); + if (l2GatewayAddr === undefined) { + console.log('l2 gateway address not exist'); + return; + } + console.log(`The l2 gateway address: ${l2GatewayAddr}`); + const { INIT_FEE_PARAMS } = require('../../../script/zksync_era'); + const arbitrator = await hre.ethers.getContractAt('Arbitrator', arbitratorAddr, l1Wallet); + const zkLinkFactory = await hre.ethers.getContractFactory('ZkLink'); + const zkLinkCallValue = ethers.parseEther('0'); + const zkLinkCallData = zkLinkFactory.interface.encodeFunctionData('changeFeeParams', [INIT_FEE_PARAMS]); + const l2GatewayFactory = await hre.ethers.getContractFactory('ZkSyncL2Gateway'); + const l2GatewayCallData = l2GatewayFactory.interface.encodeFunctionData('claimMessage', [ + zkLinkCallValue, + zkLinkCallData, + ]); + + /** + * The estimateL1ToL2Execute method gives us the gasLimit for sending an L1->L2 message + */ + const l2Addr = utils.applyL1ToL2Alias(l2GatewayAddr); + const l2GasLimit = await l2Provider.estimateL1ToL2Execute({ + contractAddress: l2Addr, + calldata: l2GatewayCallData, + overrides: { + value: zkLinkCallValue, + }, + }); + console.log(`Estimate gasLimit on L1 is ${l2GasLimit.valueOf()}`); + + /** + * The getGasPrice method gives us the current gas price on L1 + */ + const l1GasPrice = await l1Provider.getGasPrice(); + console.log(`Current gas price on L1 is ${ethers.formatEther(l1GasPrice)} ETH`); + + /** + * The getBaseCost method gives us the base cost of sending an L1->L2 message + */ + const baseCost = await zksyncWallet.getBaseCost({ + // L2 computation + gasLimit: l2GasLimit, + // L1 gas price + gasPrice: l1GasPrice, + }); + console.log(`Executing this transaction will cost ${ethers.formatEther(baseCost)} ETH`); + console.log(`The msg value: ${BigInt(zkLinkCallValue) + BigInt(baseCost)}`); + + /** + * We encode the adapter params for the L1->L2 message + */ + const abiCoder = ethers.AbiCoder.defaultAbiCoder(); + const l2GasPerPubdataByteLimit = 800; + const adapterParams = abiCoder.encode(['uint256', 'uint256'], [l2GasLimit, l2GasPerPubdataByteLimit]); + + console.log(`Send a l1 message to l2...`); + const l1Tx = await arbitrator.changeFeeParams(l1GatewayAddr, INIT_FEE_PARAMS, adapterParams, { + // send the required amount of ETH + value: BigInt(baseCost) + BigInt(zkLinkCallValue), + gasPrice: l1GasPrice, + }); + const l1TxHash = l1Tx.hash; + console.log(`The l1 tx hash: ${l1TxHash}`); + await l1Tx.wait(); + + /** + * In principle, a single L1 txn can trigger any number of L1-to-L2 messages (each with its own sequencer number). + * In this case, we know our txn triggered only one + * Here, We check if our L1 to L2 message is redeemed on L2 + */ + console.log('Waiting for the L2 execution of the transaction. This may take up to 10-15 minutes ⏰'); + const txHandle = await l1Provider.getTransaction(l1TxHash); + const l2Tx = await l2Provider.getL2TransactionFromPriorityOp(txHandle); + console.log(`The l2 tx hash: ${l2Tx.hash}`); + const l2TxStatus = await l2Provider.getTransactionStatus(l2Tx.hash); + console.log(`The l2 tx status: ${l2TxStatus}`); + console.log(`L2 retryable ticket is executed 🥳 `); + }); diff --git a/examples/zksync/scripts/setValidator.js b/examples/zksync/scripts/setValidator.js index b58d196..ddf8980 100644 --- a/examples/zksync/scripts/setValidator.js +++ b/examples/zksync/scripts/setValidator.js @@ -7,8 +7,8 @@ const { task, types } = require('hardhat/config'); require('dotenv').config(); task('setValidator', 'Set validator for zkLink') - .addParam('validator', 'Validator Address', undefined, types.string, false) - .addParam('active', 'Whether to activate the validator address', true, types.boolean, true) + .addParam('validator', 'Validator Address', undefined, types.string) + .addOptionalParam('active', 'Whether to activate the validator address', true, types.boolean) .setAction(async (taskArgs, hre) => { const validatorAddr = taskArgs.validator; const isActive = taskArgs.active; From b3d2e4e47ac650808005da80d7ad5e10f60f74ae Mon Sep 17 00:00:00 2001 From: zkJoaquin Date: Tue, 6 Feb 2024 20:18:37 +0800 Subject: [PATCH 2/2] lint fix --- examples/scroll/scripts/5_changeFeeParams.js | 102 ++++----- examples/zksync/scripts/changeFeeParams.js | 226 +++++++++---------- 2 files changed, 160 insertions(+), 168 deletions(-) diff --git a/examples/scroll/scripts/5_changeFeeParams.js b/examples/scroll/scripts/5_changeFeeParams.js index 0223a68..56b6ef0 100644 --- a/examples/scroll/scripts/5_changeFeeParams.js +++ b/examples/scroll/scripts/5_changeFeeParams.js @@ -1,58 +1,56 @@ const { providers, Wallet, utils } = require('ethers'); const { readDeployContract, getLogName } = require('../../../script/utils'); const logName = require('../../../script/deploy_log_name'); -const { task, types } = require('hardhat/config'); +const { task } = require('hardhat/config'); require('dotenv').config(); -task('changeFeeParams', 'Change fee params for zkLink') - .setAction(async (taskArgs, hre) => { - - const walletPrivateKey = process.env.DEVNET_PRIVKEY; - const l1Provider = new providers.JsonRpcProvider(process.env.L1RPC); - const ethereumName = process.env.ETHEREUM; - const scrollName = process.env.SCROLL; - const l1Wallet = new Wallet(walletPrivateKey, l1Provider); - - const l1WalletAddress = await l1Wallet.getAddress(); - const l1WalletBalance = utils.formatEther(await l1Wallet.getBalance()); - console.log(`${l1WalletAddress} balance on l1: ${l1WalletBalance} ether`); - - const arbitratorAddr = readDeployContract( - logName.DEPLOY_ARBITRATOR_LOG_PREFIX, - logName.DEPLOY_LOG_ARBITRATOR, - ethereumName, - ); - if (arbitratorAddr === undefined) { - console.log('The arbitrator address not exist'); - return; - } - console.log(`The arbitrator address: ${arbitratorAddr}`); - - const l1GatewayLogName = getLogName(logName.DEPLOY_L1_GATEWAY_LOG_PREFIX, scrollName); - const scrollL1GatewayAddr = readDeployContract(l1GatewayLogName, logName.DEPLOY_GATEWAY, ethereumName); - if (scrollL1GatewayAddr === undefined) { - console.log('scroll l1 gateway address not exist'); - return; - } - console.log(`The scroll l1 gateway address: ${scrollL1GatewayAddr}`); - - // forward message to L2 - const arbitrator = await hre.ethers.getContractAt('Arbitrator', arbitratorAddr, l1Wallet); - /** - * The adapterParams is the parameters for the adapter, which is used to parse the calldata. - * finalizeMessageGasLimit: the gas limit for the L2 to finalize the message. - */ - const { INIT_FEE_PARAMS } = require('../../../script/zksync_era'); - const finalizeMessageGasLimit = 1000000; - const adapterParams = hre.ethers.utils.defaultAbiCoder.encode(['uint256'], [finalizeMessageGasLimit]); - let tx = await arbitrator.changeFeeParams(scrollL1GatewayAddr, INIT_FEE_PARAMS, adapterParams, { - value: hre.ethers.utils.parseEther('0.001'), - }); - console.log(`The tx hash: ${tx.hash} , waiting confirm...`); - await tx.wait(); - console.log(`The tx confirmed`); - - // Waiting for the official Scroll bridge to forward the message to L2 - // No user action is required for follow-up. - }); +task('changeFeeParams', 'Change fee params for zkLink').setAction(async (taskArgs, hre) => { + const walletPrivateKey = process.env.DEVNET_PRIVKEY; + const l1Provider = new providers.JsonRpcProvider(process.env.L1RPC); + const ethereumName = process.env.ETHEREUM; + const scrollName = process.env.SCROLL; + const l1Wallet = new Wallet(walletPrivateKey, l1Provider); + + const l1WalletAddress = await l1Wallet.getAddress(); + const l1WalletBalance = utils.formatEther(await l1Wallet.getBalance()); + console.log(`${l1WalletAddress} balance on l1: ${l1WalletBalance} ether`); + + const arbitratorAddr = readDeployContract( + logName.DEPLOY_ARBITRATOR_LOG_PREFIX, + logName.DEPLOY_LOG_ARBITRATOR, + ethereumName, + ); + if (arbitratorAddr === undefined) { + console.log('The arbitrator address not exist'); + return; + } + console.log(`The arbitrator address: ${arbitratorAddr}`); + + const l1GatewayLogName = getLogName(logName.DEPLOY_L1_GATEWAY_LOG_PREFIX, scrollName); + const scrollL1GatewayAddr = readDeployContract(l1GatewayLogName, logName.DEPLOY_GATEWAY, ethereumName); + if (scrollL1GatewayAddr === undefined) { + console.log('scroll l1 gateway address not exist'); + return; + } + console.log(`The scroll l1 gateway address: ${scrollL1GatewayAddr}`); + + // forward message to L2 + const arbitrator = await hre.ethers.getContractAt('Arbitrator', arbitratorAddr, l1Wallet); + /** + * The adapterParams is the parameters for the adapter, which is used to parse the calldata. + * finalizeMessageGasLimit: the gas limit for the L2 to finalize the message. + */ + const { INIT_FEE_PARAMS } = require('../../../script/zksync_era'); + const finalizeMessageGasLimit = 1000000; + const adapterParams = hre.ethers.utils.defaultAbiCoder.encode(['uint256'], [finalizeMessageGasLimit]); + let tx = await arbitrator.changeFeeParams(scrollL1GatewayAddr, INIT_FEE_PARAMS, adapterParams, { + value: hre.ethers.utils.parseEther('0.001'), + }); + console.log(`The tx hash: ${tx.hash} , waiting confirm...`); + await tx.wait(); + console.log(`The tx confirmed`); + + // Waiting for the official Scroll bridge to forward the message to L2 + // No user action is required for follow-up. +}); diff --git a/examples/zksync/scripts/changeFeeParams.js b/examples/zksync/scripts/changeFeeParams.js index f7d08fd..791cf48 100644 --- a/examples/zksync/scripts/changeFeeParams.js +++ b/examples/zksync/scripts/changeFeeParams.js @@ -2,134 +2,128 @@ const { Provider, Wallet, utils } = require('zksync-ethers'); const { ethers } = require('ethers'); const { readDeployContract, getLogName } = require('../../../script/utils'); const logName = require('../../../script/deploy_log_name'); -const { task, types } = require('hardhat/config'); +const { task } = require('hardhat/config'); require('dotenv').config(); -task('changeFeeParams', 'Change fee params for zkLink') - .setAction(async (taskArgs, hre) => { +task('changeFeeParams', 'Change fee params for zkLink').setAction(async (taskArgs, hre) => { + const walletPrivateKey = process.env.DEVNET_PRIVKEY; + const l1Provider = new Provider(process.env.L1RPC); + console.log(`Block number: ${await l1Provider.getBlockNumber()}`); - const walletPrivateKey = process.env.DEVNET_PRIVKEY; - const l1Provider = new Provider(process.env.L1RPC); - console.log(`Block number: ${await l1Provider.getBlockNumber()}`); + const l2Provider = new Provider(process.env.L2RPC); + console.log(`Block number: ${await l2Provider.getBlockNumber()}`); + const zksyncName = process.env.ZKSYNC; + const ethereumName = process.env.ETHEREUM; + const l1Wallet = new ethers.Wallet(walletPrivateKey, l1Provider); + const zksyncWallet = new Wallet(walletPrivateKey, l2Provider, l1Provider); - const l2Provider = new Provider(process.env.L2RPC); - console.log(`Block number: ${await l2Provider.getBlockNumber()}`); - const zksyncName = process.env.ZKSYNC; - const ethereumName = process.env.ETHEREUM; - const l1Wallet = new ethers.Wallet(walletPrivateKey, l1Provider); - const zksyncWallet = new Wallet(walletPrivateKey, l2Provider, l1Provider); + const l1WalletAddress = await l1Wallet.getAddress(); + console.log(`The l1 wallet address: ${l1WalletAddress}`); + const l1WalletBalance = ethers.formatEther(await l1Provider.getBalance(l1WalletAddress)); + console.log(`${l1WalletAddress} balance on l1: ${l1WalletBalance} ether`); - const l1WalletAddress = await l1Wallet.getAddress(); - console.log(`The l1 wallet address: ${l1WalletAddress}`); - const l1WalletBalance = ethers.formatEther(await l1Provider.getBalance(l1WalletAddress)); - console.log(`${l1WalletAddress} balance on l1: ${l1WalletBalance} ether`); + const arbitratorAddr = readDeployContract( + logName.DEPLOY_ARBITRATOR_LOG_PREFIX, + logName.DEPLOY_LOG_ARBITRATOR, + ethereumName, + ); + if (arbitratorAddr === undefined) { + console.log('arbitrator address not exist'); + return; + } + console.log(`The arbitrator address: ${arbitratorAddr}`); - const arbitratorAddr = readDeployContract( - logName.DEPLOY_ARBITRATOR_LOG_PREFIX, - logName.DEPLOY_LOG_ARBITRATOR, - ethereumName, - ); - if (arbitratorAddr === undefined) { - console.log('arbitrator address not exist'); - return; - } - console.log(`The arbitrator address: ${arbitratorAddr}`); + const zkLinkAddr = readDeployContract(logName.DEPLOY_ZKLINK_LOG_PREFIX, logName.DEPLOY_LOG_ZKLINK_PROXY, zksyncName); + if (zkLinkAddr === undefined) { + console.log('zkLink address not exist'); + return; + } + console.log(`The zkLink address: ${zkLinkAddr}`); - const zkLinkAddr = readDeployContract( - logName.DEPLOY_ZKLINK_LOG_PREFIX, - logName.DEPLOY_LOG_ZKLINK_PROXY, - zksyncName, - ); - if (zkLinkAddr === undefined) { - console.log('zkLink address not exist'); - return; - } - console.log(`The zkLink address: ${zkLinkAddr}`); + const l1GatewayLogName = getLogName(logName.DEPLOY_L1_GATEWAY_LOG_PREFIX, zksyncName); + const l1GatewayAddr = readDeployContract(l1GatewayLogName, logName.DEPLOY_GATEWAY, ethereumName); + if (l1GatewayAddr === undefined) { + console.log('l1 gateway address not exist'); + return; + } + console.log(`The l1 gateway address: ${l1GatewayAddr}`); - const l1GatewayLogName = getLogName(logName.DEPLOY_L1_GATEWAY_LOG_PREFIX, zksyncName); - const l1GatewayAddr = readDeployContract(l1GatewayLogName, logName.DEPLOY_GATEWAY, ethereumName); - if (l1GatewayAddr === undefined) { - console.log('l1 gateway address not exist'); - return; - } - console.log(`The l1 gateway address: ${l1GatewayAddr}`); + const l2GatewayAddr = readDeployContract(logName.DEPLOY_L2_GATEWAY_LOG_PREFIX, logName.DEPLOY_GATEWAY, zksyncName); + if (l2GatewayAddr === undefined) { + console.log('l2 gateway address not exist'); + return; + } + console.log(`The l2 gateway address: ${l2GatewayAddr}`); + const { INIT_FEE_PARAMS } = require('../../../script/zksync_era'); + const arbitrator = await hre.ethers.getContractAt('Arbitrator', arbitratorAddr, l1Wallet); + const zkLinkFactory = await hre.ethers.getContractFactory('ZkLink'); + const zkLinkCallValue = ethers.parseEther('0'); + const zkLinkCallData = zkLinkFactory.interface.encodeFunctionData('changeFeeParams', [INIT_FEE_PARAMS]); + const l2GatewayFactory = await hre.ethers.getContractFactory('ZkSyncL2Gateway'); + const l2GatewayCallData = l2GatewayFactory.interface.encodeFunctionData('claimMessage', [ + zkLinkCallValue, + zkLinkCallData, + ]); - const l2GatewayAddr = readDeployContract(logName.DEPLOY_L2_GATEWAY_LOG_PREFIX, logName.DEPLOY_GATEWAY, zksyncName); - if (l2GatewayAddr === undefined) { - console.log('l2 gateway address not exist'); - return; - } - console.log(`The l2 gateway address: ${l2GatewayAddr}`); - const { INIT_FEE_PARAMS } = require('../../../script/zksync_era'); - const arbitrator = await hre.ethers.getContractAt('Arbitrator', arbitratorAddr, l1Wallet); - const zkLinkFactory = await hre.ethers.getContractFactory('ZkLink'); - const zkLinkCallValue = ethers.parseEther('0'); - const zkLinkCallData = zkLinkFactory.interface.encodeFunctionData('changeFeeParams', [INIT_FEE_PARAMS]); - const l2GatewayFactory = await hre.ethers.getContractFactory('ZkSyncL2Gateway'); - const l2GatewayCallData = l2GatewayFactory.interface.encodeFunctionData('claimMessage', [ - zkLinkCallValue, - zkLinkCallData, - ]); + /** + * The estimateL1ToL2Execute method gives us the gasLimit for sending an L1->L2 message + */ + const l2Addr = utils.applyL1ToL2Alias(l2GatewayAddr); + const l2GasLimit = await l2Provider.estimateL1ToL2Execute({ + contractAddress: l2Addr, + calldata: l2GatewayCallData, + overrides: { + value: zkLinkCallValue, + }, + }); + console.log(`Estimate gasLimit on L1 is ${l2GasLimit.valueOf()}`); - /** - * The estimateL1ToL2Execute method gives us the gasLimit for sending an L1->L2 message - */ - const l2Addr = utils.applyL1ToL2Alias(l2GatewayAddr); - const l2GasLimit = await l2Provider.estimateL1ToL2Execute({ - contractAddress: l2Addr, - calldata: l2GatewayCallData, - overrides: { - value: zkLinkCallValue, - }, - }); - console.log(`Estimate gasLimit on L1 is ${l2GasLimit.valueOf()}`); + /** + * The getGasPrice method gives us the current gas price on L1 + */ + const l1GasPrice = await l1Provider.getGasPrice(); + console.log(`Current gas price on L1 is ${ethers.formatEther(l1GasPrice)} ETH`); - /** - * The getGasPrice method gives us the current gas price on L1 - */ - const l1GasPrice = await l1Provider.getGasPrice(); - console.log(`Current gas price on L1 is ${ethers.formatEther(l1GasPrice)} ETH`); + /** + * The getBaseCost method gives us the base cost of sending an L1->L2 message + */ + const baseCost = await zksyncWallet.getBaseCost({ + // L2 computation + gasLimit: l2GasLimit, + // L1 gas price + gasPrice: l1GasPrice, + }); + console.log(`Executing this transaction will cost ${ethers.formatEther(baseCost)} ETH`); + console.log(`The msg value: ${BigInt(zkLinkCallValue) + BigInt(baseCost)}`); - /** - * The getBaseCost method gives us the base cost of sending an L1->L2 message - */ - const baseCost = await zksyncWallet.getBaseCost({ - // L2 computation - gasLimit: l2GasLimit, - // L1 gas price - gasPrice: l1GasPrice, - }); - console.log(`Executing this transaction will cost ${ethers.formatEther(baseCost)} ETH`); - console.log(`The msg value: ${BigInt(zkLinkCallValue) + BigInt(baseCost)}`); + /** + * We encode the adapter params for the L1->L2 message + */ + const abiCoder = ethers.AbiCoder.defaultAbiCoder(); + const l2GasPerPubdataByteLimit = 800; + const adapterParams = abiCoder.encode(['uint256', 'uint256'], [l2GasLimit, l2GasPerPubdataByteLimit]); - /** - * We encode the adapter params for the L1->L2 message - */ - const abiCoder = ethers.AbiCoder.defaultAbiCoder(); - const l2GasPerPubdataByteLimit = 800; - const adapterParams = abiCoder.encode(['uint256', 'uint256'], [l2GasLimit, l2GasPerPubdataByteLimit]); + console.log(`Send a l1 message to l2...`); + const l1Tx = await arbitrator.changeFeeParams(l1GatewayAddr, INIT_FEE_PARAMS, adapterParams, { + // send the required amount of ETH + value: BigInt(baseCost) + BigInt(zkLinkCallValue), + gasPrice: l1GasPrice, + }); + const l1TxHash = l1Tx.hash; + console.log(`The l1 tx hash: ${l1TxHash}`); + await l1Tx.wait(); - console.log(`Send a l1 message to l2...`); - const l1Tx = await arbitrator.changeFeeParams(l1GatewayAddr, INIT_FEE_PARAMS, adapterParams, { - // send the required amount of ETH - value: BigInt(baseCost) + BigInt(zkLinkCallValue), - gasPrice: l1GasPrice, - }); - const l1TxHash = l1Tx.hash; - console.log(`The l1 tx hash: ${l1TxHash}`); - await l1Tx.wait(); - - /** - * In principle, a single L1 txn can trigger any number of L1-to-L2 messages (each with its own sequencer number). - * In this case, we know our txn triggered only one - * Here, We check if our L1 to L2 message is redeemed on L2 - */ - console.log('Waiting for the L2 execution of the transaction. This may take up to 10-15 minutes ⏰'); - const txHandle = await l1Provider.getTransaction(l1TxHash); - const l2Tx = await l2Provider.getL2TransactionFromPriorityOp(txHandle); - console.log(`The l2 tx hash: ${l2Tx.hash}`); - const l2TxStatus = await l2Provider.getTransactionStatus(l2Tx.hash); - console.log(`The l2 tx status: ${l2TxStatus}`); - console.log(`L2 retryable ticket is executed 🥳 `); - }); + /** + * In principle, a single L1 txn can trigger any number of L1-to-L2 messages (each with its own sequencer number). + * In this case, we know our txn triggered only one + * Here, We check if our L1 to L2 message is redeemed on L2 + */ + console.log('Waiting for the L2 execution of the transaction. This may take up to 10-15 minutes ⏰'); + const txHandle = await l1Provider.getTransaction(l1TxHash); + const l2Tx = await l2Provider.getL2TransactionFromPriorityOp(txHandle); + console.log(`The l2 tx hash: ${l2Tx.hash}`); + const l2TxStatus = await l2Provider.getTransactionStatus(l2Tx.hash); + console.log(`The l2 tx status: ${l2TxStatus}`); + console.log(`L2 retryable ticket is executed 🥳 `); +});