Skip to content

Commit 14c24a2

Browse files
authored
chore: multichain deploy scripts (#1449)
**Motivation:** We want scripts to deploy multichain. **Modifications:** Added 3 scripts: 1. Deploy Core 2. Deploy Multichain (verifier, table updater) 3. Deploy globalConfirmerOperatorSet **Result:** Complete deploy scripts
1 parent 2dcdb1c commit 14c24a2

File tree

7 files changed

+861
-1
lines changed

7 files changed

+861
-1
lines changed

script/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
output/*
1+
output/devnet/*
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.27;
3+
4+
import "@openzeppelin/contracts/utils/Strings.sol";
5+
import "src/test/utils/OperatorWalletLib.sol";
6+
import "src/contracts/interfaces/IBN254TableCalculator.sol";
7+
import "src/contracts/interfaces/ICrossChainRegistry.sol";
8+
9+
import "src/contracts/libraries/Merkle.sol";
10+
11+
import "forge-std/Script.sol";
12+
import "forge-std/Test.sol";
13+
14+
// forge script script/deploy/devnet/mutlichain/deploy_globalRootConfirmerSet.s.sol --sig "run(string memory)" $SEED
15+
contract DeployGlobalRootConfirmerSet is Script, Test {
16+
using Strings for uint256;
17+
using Merkle for bytes32[];
18+
using BN254 for BN254.G1Point;
19+
20+
function run(
21+
string memory salt
22+
) public {
23+
/**
24+
*
25+
* WALLET CREATION
26+
*
27+
*/
28+
29+
// 1. Create a BN254 Wallet
30+
Operator memory operator = OperatorWalletLib.createOperator(salt);
31+
32+
/**
33+
*
34+
* Create the `BN254OperatorInfo` struct
35+
*
36+
*/
37+
38+
// 1. Generate the `BN254OperatorInfo` struct
39+
IBN254TableCalculatorTypes.BN254OperatorSetInfo memory operatorSetInfo;
40+
41+
// 2. Set the numOperators and totalWeights
42+
operatorSetInfo.numOperators = 1;
43+
uint256[] memory weights = new uint256[](1);
44+
weights[0] = 1;
45+
operatorSetInfo.totalWeights = weights;
46+
47+
// 3. Set the apk
48+
BN254.G1Point memory aggregatePubkey;
49+
aggregatePubkey = aggregatePubkey.plus(operator.signingKey.publicKeyG1);
50+
operatorSetInfo.aggregatePubkey = aggregatePubkey;
51+
52+
// 4. Set the operatorInfoTreeRoot
53+
bytes32[] memory operatorInfoLeaves = new bytes32[](1);
54+
operatorInfoLeaves[0] = keccak256(
55+
abi.encode(
56+
IBN254TableCalculatorTypes.BN254OperatorInfo({pubkey: operator.signingKey.publicKeyG1, weights: weights})
57+
)
58+
);
59+
operatorSetInfo.operatorInfoTreeRoot = operatorInfoLeaves.merkleizeKeccak();
60+
61+
/**
62+
*
63+
* Create the `operatorSetConfig` struct
64+
*
65+
*/
66+
ICrossChainRegistry.OperatorSetConfig memory operatorSetConfig;
67+
operatorSetConfig.owner = operator.key.addr;
68+
operatorSetConfig.maxStalenessPeriod = 1 days;
69+
70+
/**
71+
*
72+
* OUTPUT - OPERATOR SET INFO
73+
*
74+
*/
75+
string memory parent_object = "parent object";
76+
77+
// Serialize operatorSetInfo
78+
string memory operatorSetInfo_object = "operatorSetInfo";
79+
vm.serializeBytes32(operatorSetInfo_object, "operatorInfoTreeRoot", operatorSetInfo.operatorInfoTreeRoot);
80+
vm.serializeUint(operatorSetInfo_object, "numOperators", operatorSetInfo.numOperators);
81+
82+
// Serialize apk as nested object
83+
string memory apk_object = "apk";
84+
vm.serializeUint(apk_object, "x", operatorSetInfo.aggregatePubkey.X);
85+
string memory apkOutput = vm.serializeUint(apk_object, "y", operatorSetInfo.aggregatePubkey.Y);
86+
vm.serializeString(operatorSetInfo_object, "apk", apkOutput);
87+
88+
// Serialize totalWeights array
89+
string memory operatorSetInfoOutput =
90+
vm.serializeUint(operatorSetInfo_object, "totalWeights", operatorSetInfo.totalWeights);
91+
92+
// Serialize operatorSetConfig
93+
string memory operatorSetConfig_object = "operatorSetConfig";
94+
vm.serializeAddress(operatorSetConfig_object, "owner", operatorSetConfig.owner);
95+
string memory operatorSetConfigOutput =
96+
vm.serializeUint(operatorSetConfig_object, "maxStalenessPeriod", operatorSetConfig.maxStalenessPeriod);
97+
98+
// Combine both objects into final output
99+
vm.serializeString(parent_object, "operatorSetInfo", operatorSetInfoOutput);
100+
string memory finalJson = vm.serializeString(parent_object, "operatorSetConfig", operatorSetConfigOutput);
101+
102+
vm.writeJson(finalJson, "script/output/devnet/multichain/globalRootOperatorInfo.json");
103+
104+
/**
105+
*
106+
* OUTPUT - BLS WALLET
107+
*
108+
*/
109+
110+
// Write operator data to a separate function to avoid stack too deep
111+
_writeOperatorData(operator);
112+
}
113+
114+
function _writeOperatorData(
115+
Operator memory operator
116+
) internal {
117+
string memory operator_object = "operator";
118+
119+
// Serialize regular wallet info
120+
string memory wallet_object = "wallet";
121+
vm.serializeUint(wallet_object, "privateKey", operator.key.privateKey);
122+
string memory walletOutput = vm.serializeAddress(wallet_object, "address", operator.key.addr);
123+
124+
// Serialize BLS wallet info
125+
string memory blsWallet_object = "blsWallet";
126+
vm.serializeUint(blsWallet_object, "privateKey", operator.signingKey.privateKey);
127+
128+
// Serialize publicKeyG1
129+
string memory publicKeyG1_object = "publicKeyG1";
130+
vm.serializeUint(publicKeyG1_object, "x", operator.signingKey.publicKeyG1.X);
131+
string memory publicKeyG1Output = vm.serializeUint(publicKeyG1_object, "y", operator.signingKey.publicKeyG1.Y);
132+
vm.serializeString(blsWallet_object, "publicKeyG1", publicKeyG1Output);
133+
134+
// Serialize publicKeyG2
135+
string memory publicKeyG2_object = "publicKeyG2";
136+
vm.serializeUint(publicKeyG2_object, "x0", operator.signingKey.publicKeyG2.X[0]);
137+
vm.serializeUint(publicKeyG2_object, "x1", operator.signingKey.publicKeyG2.X[1]);
138+
vm.serializeUint(publicKeyG2_object, "y0", operator.signingKey.publicKeyG2.Y[0]);
139+
string memory publicKeyG2Output =
140+
vm.serializeUint(publicKeyG2_object, "y1", operator.signingKey.publicKeyG2.Y[1]);
141+
string memory blsWalletOutput = vm.serializeString(blsWallet_object, "publicKeyG2", publicKeyG2Output);
142+
143+
// Combine wallet and blsWallet into operator object
144+
vm.serializeString(operator_object, "wallet", walletOutput);
145+
string memory operatorOutput = vm.serializeString(operator_object, "blsWallet", blsWalletOutput);
146+
147+
// Write to separate file
148+
vm.writeJson(operatorOutput, "script/output/devnet/multichain/operatorWallet.json");
149+
}
150+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.27;
3+
4+
// OpenZeppelin Contracts
5+
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
6+
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
7+
8+
// Core Contracts
9+
import "src/contracts/permissions/PauserRegistry.sol";
10+
import "src/contracts/core/AllocationManager.sol";
11+
import "src/contracts/permissions/PermissionController.sol";
12+
13+
// Multichain Contracts
14+
import "src/contracts/multichain/CrossChainRegistry.sol";
15+
import "src/contracts/multichain/BN254TableCalculator.sol";
16+
import "src/contracts/permissions/KeyRegistrar.sol";
17+
import "src/test/mocks/EmptyContract.sol";
18+
19+
// Forge
20+
import "forge-std/Script.sol";
21+
import "forge-std/Test.sol";
22+
23+
// forge script script/deploy/devnet/deploy_multichain_l1.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --broadcast --sig "run()" --verify $ETHERSCAN_API_KEY
24+
contract DeployMultichain_L1 is Script, Test {
25+
Vm cheats = Vm(VM_ADDRESS);
26+
27+
address owner = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479;
28+
29+
// EigenLayer Contracts on PREPROD
30+
EmptyContract public emptyContract;
31+
AllocationManager public allocationManager = AllocationManager(0xFdD5749e11977D60850E06bF5B13221Ad95eb6B4);
32+
PermissionController public permissionController = PermissionController(0xa2348c77802238Db39f0CefAa500B62D3FDD682b);
33+
PauserRegistry public pauserRegistry = PauserRegistry(0x50712285cE831a6B9a11214A430f28999A5b4DAe);
34+
35+
// Multichain Contracts
36+
ProxyAdmin public proxyAdmin;
37+
KeyRegistrar public keyRegistrar;
38+
KeyRegistrar public keyRegistrarImplementation;
39+
CrossChainRegistry public crossChainRegistry;
40+
CrossChainRegistry public crossChainRegistryImplementation;
41+
BN254TableCalculator public bn254TableCalculator;
42+
43+
function run() public {
44+
uint256 chainId = block.chainid;
45+
emit log_named_uint("You are deploying on ChainID", chainId);
46+
47+
/**
48+
*
49+
* CONTRACT DEPLOYMENT
50+
*
51+
*/
52+
vm.startBroadcast();
53+
54+
emptyContract = new EmptyContract();
55+
proxyAdmin = new ProxyAdmin();
56+
57+
// First, deploy the *proxy* contracts, using the *empty contract* as inputs
58+
// Key Registrar
59+
keyRegistrar =
60+
KeyRegistrar(address(new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "")));
61+
62+
// Cross Chain Registry
63+
crossChainRegistry = CrossChainRegistry(
64+
address(new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), ""))
65+
);
66+
67+
// BN254 Table Calculator
68+
69+
// Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs
70+
keyRegistrarImplementation = new KeyRegistrar(permissionController, allocationManager, "9.9.9");
71+
crossChainRegistryImplementation =
72+
new CrossChainRegistry(allocationManager, keyRegistrar, permissionController, pauserRegistry, "9.9.9");
73+
74+
// Third, upgrade the proxies to point to the new implementations
75+
proxyAdmin.upgrade(
76+
ITransparentUpgradeableProxy(payable(address(keyRegistrar))), address(keyRegistrarImplementation)
77+
);
78+
proxyAdmin.upgradeAndCall(
79+
ITransparentUpgradeableProxy(payable(address(crossChainRegistry))),
80+
address(crossChainRegistryImplementation),
81+
abi.encodeWithSelector(CrossChainRegistry.initialize.selector, owner, 0)
82+
);
83+
84+
// Fourth, deploy the non-upgradeable contracts
85+
bn254TableCalculator = new BN254TableCalculator(keyRegistrar, allocationManager, 100);
86+
87+
// Transfer ownership to the 0xDA address
88+
proxyAdmin.transferOwnership(owner);
89+
90+
vm.stopBroadcast();
91+
92+
/**
93+
*
94+
* OUTPUT
95+
*
96+
*/
97+
string memory parent_object = "parent object";
98+
99+
string memory deployed_addresses = "addresses";
100+
vm.serializeAddress(deployed_addresses, "emptyContract", address(emptyContract));
101+
vm.serializeAddress(deployed_addresses, "proxyAdmin", address(proxyAdmin));
102+
vm.serializeAddress(deployed_addresses, "keyRegistrar", address(keyRegistrar));
103+
vm.serializeAddress(deployed_addresses, "keyRegistrarImplementation", address(keyRegistrarImplementation));
104+
vm.serializeAddress(deployed_addresses, "crossChainRegistry", address(crossChainRegistry));
105+
vm.serializeAddress(
106+
deployed_addresses, "crossChainRegistryImplementation", address(crossChainRegistryImplementation)
107+
);
108+
string memory deployed_addresses_output =
109+
vm.serializeAddress(deployed_addresses, "bn254TableCalculator", address(bn254TableCalculator));
110+
111+
string memory finalJson = vm.serializeString(parent_object, deployed_addresses, deployed_addresses_output);
112+
113+
vm.writeJson(finalJson, "script/output/devnet/multichain/deploy_multichain_l1.json");
114+
}
115+
}

0 commit comments

Comments
 (0)