ZKsync Gateway settlement layer
ZKsync Gateway is an optional settlement layer for ZK chains, including both rollups and validiums. It is purpose-built to enhance interoperability, provide proof aggregation, and offer cost efficiencies for chains that wish to settle on top of it.
Learn more about ZKsync Gateway in the protocol documentation.
Running ZKsync Gateway locally
- Create a new ZK chain that will become your local gateway chain:
zkstack chain create \ --chain-name gateway \ --chain-id 506 \ --prover-mode no-proofs \ --wallet-creation localhost \ --l1-batch-commit-data-generator-mode rollup \ --base-token-address 0x0000000000000000000000000000000000000001 \ --base-token-price-nominator 1 \ --base-token-price-denominator 1 \ --set-as-default false \ --evm-emulator false \ --ignore-prerequisites --update-submodules false
- Initialise
gateway
chain:zkstack chain init \ --deploy-paymaster \ --l1-rpc-url=http://localhost:8545 \ --server-db-url=postgres://postgres:notsecurepassword@localhost:5432 \ --server-db-name=zksync_server_localhost_gateway \ --chain gateway --update-submodules false
- Transform
gateway
chain from rollup into a ZKsync Gateway settlement layer:zkstack chain gateway convert-to-gateway --chain gateway --ignore-prerequisites
- Start
gateway
chain server:mkdir zlogs zkstack server --ignore-prerequisites --chain gateway &> ./zlogs/gateway.log &
- Migrate existing ZK chain to settle on
gateway
:zkstack chain gateway migrate-to-gateway --chain YOUR_CHAIN_NAME --gateway-chain-name gateway
- Start your chain server:
zkstack server --ignore-prerequisites --chain YOUR_CHAIN &> ./era.log &
Migrate existing ZK chain to Gateway on testnet or mainnet
ZK chains can be migrated to use ZKsync Gateway as their settlement layer by updating the chain's metadata and
coordinating the transition with off-chain services.
This migration is performed using the zkstack cli
tool.
Requirements
In order to migrate a chain, operators will need the following information:
- Tooling:
- zkstack CLI
- Foundry
- Credentials:
- Private key of the L2 network chain governor.
- RPC URLs for all the networks involved:
- Ethereum and L2 network to migrate.
- ZKsync Gateway: more info in ZKsync Gateway overview.
- Addresses:
L1_BRIDGEHUB_ADDRESS
: can be found in the ZK chains info pageREFUND_RECIPIENT_ADDRESS
: address that will receive gas refunds.VALIDATOR_1_ADDRESS
: address of the operator.VALIDATOR_2_ADDRESS
: address of the blob operator.NEW_SL_DA_VALIDATOR
: data availability contract validator deployed on Gateway. See data availability considerations for more info
- Chain identifiers:
L2_CHAIN_ID
: id of the L2 network to migrate.GATEWAY_CHAIN_ID
: more info in ZKsync Gateway overview.
- ZKsync Gateway configuration: the ZK Stack config file for the ZKsync Gateway, which contains relevant information of how the chain operates.
This file can be found in the zksync-era repository.
Save in
etc/ecosystem/gateway/<gateway>.yaml
.
Notify server about migration
Pause the ETH transaction sender on the server to avoid having unconfirmed transactions on L1:
zkstack chain gw notify-about-to-gateway-update-calldata \
<L1_BRIDGEHUB_ADDRESS> \
<L2_CHAIN_ID> \
<L1_RPC_URL> \
--l2-rpc-url=<L2_RPC_URL> \
--gw-rpc-url=<GATEWAY_RPC_URL>
Send migration calldata on L1
Send the generated migration calldata to L1
cast send <L1_BRIDGEHUB_ADDRESS> <CALLDATA> \
--rpc-url=<L1_RPC_URL> \
--private-key=<PRIVATE_KEY>
Generate calldata for migration
The following command will check the status of the migration to Gateway and will only output the calldata after the notification has passed
and the server is ready to migrate.
To prepare the calldata even before the server is ready (helpful for multisigs), please provide --no-cross-check
option.
Governor must have enough ZK to top up validators (min-validator-balance).
zkstack chain gw migrate-to-gateway-calldata \
--l1-rpc-url <L1_RPC_URL> \
--l1-bridgehub-addr <L1_BRIDGEHUB_ADDRESS> \
--max-l1-gas-price <MAX_L1_GAS_PRICE> \
--gateway-chain-id <GATEWAY_CHAIN_ID> \
--gateway-rpc-url <GATEWAY_RPC_URL> \
--refund-recipient <REFUND_RECIPIENT_ADDRESS> \
--l2-chain-id <L2_CHAIN_ID> \
--l2-rpc-url <L2_RPC_URL> \
--gateway-config-path <GATEWAY_CONFIG_PATH> \
--validator-1 <VALIDATOR_1_ADDRESS> \
--validator-2 <VALIDATOR_2_ADDRESS> \
--min-validator-balance <MIN_VALIDATOR_BALANCE> \
--new-sl-da-validator <NEW_SL_DA_VALIDATOR>
This will generate L1 → Gateway transaction. The L2 network server will restart 2 times:
- When the gateway status changed on L1.
- When the transaction is processed on ZKsync Gateway.
Submit final migration transaction
Send the output calldata from previous step to L1 to confirm migration:
cast send <TO_ADDRESS> <CALLDATA> \
--rpc-url=<L1_RPC_URL> \
--private-key=<PRIVATE_KEY>
Verify migration
Check that settlementLayer(chainId)
on the
Bridgehub contract
returns the ZKsync Gateway chain id:
506
(testnet) or 9075
(mainnet).
CLI Reference
For more information about commands and calldata generation details, refer to the official zkstack cli migration guide.