Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"admin": {
"l1admin": {
"address": "0x91eDD257B4184aC152cce1bbEC29FD93979Ae0db"
},
"l2admin": {
"address": "0x187712a3e229498E9E42888761Ab9B92bceB46c7"
},
"proposer": {
"endpoint": "https://op-signer.beta2.testnet.l2.quarkchain.io:8080",
"address": "0x34dFb869A870Ff1DC0b1e495BFce871576EBb558",
Expand Down
331 changes: 331 additions & 0 deletions L2/deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,331 @@
# Deployment Guide — QuarkChain L2 (Testnet & Mainnet)

## 1. Prepare L1 full nodes
Provision two L1 full nodes:
- Primary (production)
- Secondary (hot standby/backup)


## 2. Prepare admin wallets
These roles own proxy admins and contract owners.
- l1ProxyAdminOwner (Gnosis Safe): Upgrade L1 contract implementations and own L1 contract roles (e.g., systemConfigOwner)..
- l2ProxyAdminOwner (Hardware wallet): Upgrade L2 contract implementations; own L2 contracts (e.g., SoulGasToken), and vault recipients (baseFeeVaultRecipient, l1FeeVaultRecipient, sequencerFeeVaultRecipient).

Testnet admin wallets
- l1ProxyAdminOwner (Gnosis Safe): 0x91eDD257B4184aC152cce1bbEC29FD93979Ae0db
- l2ProxyAdminOwner (Hardware Wallet): 0x187712a3e229498E9E42888761Ab9B92bceB46c7

Mainnet admin wallets
- l1ProxyAdminOwner (Gnosis Safe): 0xC427A79CFc2863fd6c7D22dE394efE8935190734
- l2ProxyAdminOwner (Hardware Wallet): 0x9e370b5f0c91c0f00ffe863d16d5c1b8d5f1746b

## 3. Prepare op-signer service for batcher, proposer and challenger
- Setup op-signer service for op-proposer/op-batcher/op-challenger (https://github.com/QuarkChain/pm/blob/main/op-signer.md)
- Fund each signer with ETH. (Setup wallet monitor to watch the balance later)
- Prepare the [remote_signer.json](https://github.com/QuarkChain/pm/blob/main/L2/assets/remote_signer.json) that will be used in opup

## 4. Prepare deployer and sequencer wallet
- Fund deployer with ETH

## 5. Deploy inbox contract with EthStorage enabled (https://github.com/ethstorage/es-op-batchinbox/pull/1)
```bash
# deployment:
# 1. Filled the .env
# 2. Deploy
./deploy.s.sh deploy
# 3. Make sure all three contracts are verifed
# 4. Record addresses proxy and proxyAdmin
# 5. Set ethstorage contract
# 6. Deposit 0.1 ETH for storage fee
```
### Testnet:
- batchInbox proxy: 0xf62e8574B92dc8764c5Ad957b5B0311595f5A3f9
- batchInbox impl: 0x900e510791F59705e86E9D6bc8be05f7679d8A3e
- batchInbox proxyAdmin: 0xc2bf5eF8F82eD93f166B49CcF29D45699236Af03
### Mainnet:
- batchInbox proxy: 0xA68295D77766d4e04854746e3C1873c891C1765E
- batchInbox impl: 0x5e84c44a636A07582CED20C4DA8c1A3f22944aC6
- batchInbox proxyAdmin: 0x32b9d95A3eDA963e968DF4ABb18908b3caC9268b


## 6. Prepare parameters:
### Testnet:
- Chain ID: 110011
- soulGasTokenBlock: nil
- l2GenesisBlobTimeOffset: nil
- Scalar and Multiplier (more details [here](https://github.com/QuarkChain/optimism/issues/57#issuecomment-3471127676)):
- l1BaseFeeScalarMultiplier: 100000 (10^5)
- L1BlobBaseFeeScalarMultiplier: 10000000 (10^7)
- L1BaseFeeScalar: 58803
- L1BlobBaseFeeScalar: 114098
- SuperChainConfig [address](https://docs.optimism.io/reference/addresses): 0xC2Be75506d5724086DEB7245bd260Cc9753911Be
- Submission:
- MaxChannelDuration for batcher: 900 / 3h
- OutputRootProposalInterval for proposer: 12h
- Cost
- delta submission: https://sepolia.etherscan.io/tx/0x415809eea9f4cf5d38da5e4064b53c36137be6c7f6f3750cec836cc0eec77751
- hashkey: https://etherscan.io/tx/0xec79b9ad6594e388829a3063fa8bce371a8b341928f55a939aa72e52be0401ca
- delta propose: https://sepolia.etherscan.io/tx/0x8e18a93466b7ca702cb09fb3b754318502f5c82d2a7471d900cdb8677ae20daf
- hashkey propose: https://etherscan.io/tx/0x4b3731f755d4a2a61f8db93755b83767f999931592cb6c33e4c294fd762532a6
- hashkey resolve: https://etherscan.io/address/0x82bdac18f0fbaed34d6a644e9713530259885426
### Mainnet:
- Chain ID: 100011
- soulGasTokenBlock: nil
- l2GenesisBlobTimeOffset: nil
- Scalar and Multiplier (more details [here](https://github.com/QuarkChain/optimism/issues/57#issuecomment-3471127676)):
- l1BaseFeeScalarMultiplier: 100000 (10^5)
- L1BlobBaseFeeScalarMultiplier: 10000000 (10^7)
- L1BaseFeeScalar: 58803
- L1BlobBaseFeeScalar: 114098
- SuperChainConfig [address](https://docs.optimism.io/reference/addresses): 0x95703e0982140D16f8ebA6d158FccEde42f04a4C
- Submission:
- MaxChannelDuration for batcher: 900 / 3h
- OutputRootProposalInterval for proposer: 12h


## 7. Run op-up
```bash
# Sepolia:
`REMOTE_SIGNER=1 just up --es`
# Mainnet:
`REMOTE_SIGNER=1 MAINNET=1 just up --es`
```

### 7.1 .envrc
#### Testnet:
- L1_RPC_URL: http://65.108.230.142:8545
- L1_RPC_KIND: standard
- L1_BEACON_URL: http://65.108.230.142:3500
- L1_BEACON_ARCHIVER_URL: https://archive.testnet.ethstorage.io:9635
- L1_CHAIN_ID: 11155111
- L2_CHAIN_ID: 110011
#### Mainnet:
- L1_RPC_URL: mainnet-rpc-url
- L1_RPC_KIND: standard
- L1_BEACON_URL: mainnet-beacon-url
- L1_BEACON_ARCHIVER_URL: https://archive.mainnet.ethstorage.io:9645
- L1_CHAIN_ID: 1
- L2_CHAIN_ID: 100011

### 7.2 contract and op-deployer branch
- contract: merge_op_contracts_v4.1.0
- op-deployer: merge_op-deployer_v0.4.5

### 7.3 intent.toml
#### Testnet:
- l1BaseFeeScalarMultiplier: 100000
- L1BlobBaseFeeScalarMultiplier: 10000000
- Delete `soulGasTokenTimeOffset = "0x0"`
- Delete `l2GenesisBlobTimeOffset = "0x0"`
- batchInboxAddress: 0xf62e8574B92dc8764c5Ad957b5B0311595f5A3f9
#### Mainnet:
- l1BaseFeeScalarMultiplier: 100000
- L1BlobBaseFeeScalarMultiplier: 10000000
- Delete `soulGasTokenTimeOffset = "0x0"`
- Delete `l2GenesisBlobTimeOffset = "0x0"`
- batchInboxAddress: 0xA68295D77766d4e04854746e3C1873c891C1765E

### 7.4 MaxChannelDuration && OutputRootProposalInterval
- MaxChannelDuration: 900 (900 * 12 / 3600 = 3)
- OutputRootProposalInterval: 12h

### 7.5 Verify
- Verify all the binary are launched successfully
- Verify code for L1 + L2 contracts

### 7.6 Double check private RPC

## 8. Set new superchainConfigProxy
```bash
# prepare L1 contract address
just l1 > address.json
function json2_to_env() {
for key0 in $( jq -r 'to_entries|map("\(.key)")|.[]' $1 ); do
value=$(jq -r \.$key0 $1)
skey=$(echo $key0 | sed -r 's/([a-z0-9])([A-Z])/\1_\L\2/g' | sed -e 's/\(.*\)/\U\1/')
echo $skey=$value
export $skey=$value
done
}
json2_to_env address.json
```

```bash
# 1. deploy StorageSetter
forge create src/universal/StorageSetter.sol:StorageSetter --broadcast --private-key $GS_ADMIN_PRIVATE_KEY --rpc-url $L1_RPC_URL

# 2. prepare calldata for upgradeAndCall
cast calldata "setBytes32(bytes32, bytes32)" 0x0000000000000000000000000000000000000000000000000000000000000000 0x0000000000000000000000000000000000000000000000000000000000000000

0x4e91db0800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

# 3. call upgradeAndCall
upgradeAndCall(opChainProxyAdmin, systemConfigProxy, storageSetter, calldata);

# 4. prepare calldata for upgradeAndCall
cast calldata "upgrade(uint256, address)" $L2_CHAIN_ID $SuperchainConfigProxy

# 5. call upgradeAndCall
upgradeAndCall(opChainProxyAdmin, systemConfigProxy, systemConfigImpl, calldata);

# 6. check if the SuperchainConfigProxy was changed
```

## 9. Set L1BaseFeeScalar/L1BlobBaseFeeScalar using proxyAdminOwner
- L1BaseFeeScalar: 58803
- L1BlobBaseFeeScalar: 114098

## 10. Set eip1559Denominator/eip1559Elasticity
- eip1559Denominator: 250
- eip1559Elasticity: 6


## 10 Verify the deployment
### 10.1 Verify the admin owner for L1 and L2
#### L1 admin
```bash
# pick one of the L1 contract, e.g. systemConfigProxyAddress
# query the proxy admin address, check if the address is the same as we deployed
cast call $SYSTEM_CONFIG_PROXY "admin()" -r $L1_RPC_URL
# query the admin owner of the proxy admin, check if the address is the same as the l1ProxyAdminOwner
cast call $OP_CHAIN_PROXY_ADMIN_IMPL "owner()" -r $L1_RPC_URL
```
#### L2 admin
```bash
# pick one of the L2 contract, e.g. L2StandardBridge
# query the proxy admin address, check if the address is the same as we deployed
cast call 0x4200000000000000000000000000000000000010 "admin()"
# query the admin owner of the proxy admin, check if the address is the same as the l2ProxyAdminOwner
cast call 0x4200000000000000000000000000000000000018 "owner()"
```

### 10.2 Verify the parameters
#### 10.2.1 Check with L1 contract
##### SYSTEM_CONFIG_PROXY
- l2ChainID
- superchainConfig
- systemConfigOwner
- unsafeBlockSigner
- batcher
- batchInboxAddress
- l1BaseFeeScalar
- l1BlobBaseFeeScalar
- operatorFeeScalar
- operatorFeeConstant
- eip1559Denominator
- eip1559Elasticity
- gasLimit

##### DISPUTE_GAME_FACTORY_PROXY
```bash
cast call $DISPUTE_GAME_FACTORY_PROXY "gameImpls(uint32)" 1 -r $L1_RPC_URL
# check proposer
cast call $PERMISSIONED_DISPUTE_GAME_IMPL "proposer()" -r $L1_RPC_URL
# check challenger
cast call $PERMISSIONED_DISPUTE_GAME_IMPL "challenger()" -r $L1_RPC_URL
```

#### 10.2.2 Check rollup_config and genesis
##### rollup config
- batcherAddr
- gasLimit
- sequencerWindowSize
- l1_chain_id
- l2_chain_id
- batch_inbox_address
- deposit_contract_address (OptimismPortalProxy)
- l1_system_config_address
- protocol_versions_address
- eip1559DenominatorCanyon
- eip1559Denominator
- eip1559Elasticity
- l1BaseFeeScalarMultiplier
- l1BlobBaseFeeScalarMultiplier
- isSoulBackedByNative
- use_inbox_contract
##### genesis
- chainId
- eip1559Elasticity
- eip1559Denominator
- eip1559DenominatorCanyon
- isSoulBackedByNative
- l1BaseFeeScalarMultiplier
- l1BlobBaseFeeScalarMultiplier


### 10.2.3 Check with L2 Contract
Query baseFeeVaultRecipient / l1FeeVaultRecipient / sequencerFeeVaultRecipient
```bash
# baseFeeVaultRecipient
cast call 0x4200000000000000000000000000000000000019 "recipient()"
# l1FeeVaultRecipient
cast call 0x420000000000000000000000000000000000001A "recipient()"
# sequencerFeeVaultRecipient
cast call 0x4200000000000000000000000000000000000011 "recipient()"
```
## 11. Initial Test
Refer to this [doc](https://github.com/QuarkChain/pm/blob/main/L2/opup_devnet_test.md)

## 12 Submit the genesis / rollup config / L1 contract address to the pm repo

## 13. Lauch Public RPC Node

## 14. Domain(Explorer+RPC) / Faucet

## 15. Migration Bridge
Need to confirm the UI + allowance (https://github.com/QuarkChain/quarkchain-migrate-website/issues/1)

## 16. Roll Bridge
Need to determine the ERC20 token listed on the UI

## 17. op-monitor + grafana / FDG watcher / FDG test

## 18. Chain monitor
balance of batacher / proposer / challenger / batchInbox for batcher

## 19. Firewall and 2fa
port list
```bash
ssh
222
blockscout
80
8080
8081
7432
7433
op-node
9003
8547 - monitor
op-geth
8545 - public rpc
30303
da-server
8888
```

Edit the rules
```bash
sudo ufw status numbered
sudo ufw delete 2
sudo ufw allow from 65.21.21.253 to any port 8547 proto tcp
sudo ufw allow from 65.109.110.98 to any port 8545 proto tcp
```

## 20. Update doc

## 21. Minotor migration/bridge website

## 22. Tests
- proposer / batcher / challenger can submit a tx successfully
- L1 cost shown on the explorer
- QKC cost [verification](https://explorer.mainnet.l2.quarkchain.io/tx/0xfb2f61f252e409f590d2c3f1f3dc68fb48d76bbbf731391b8efade1d1aaaf411)
- ERC20 deposit and withdraw
- 7702
- Full node sync
- Adhoc test
- Archiver test (Fusaka change)