-
Notifications
You must be signed in to change notification settings - Fork 28
docs: update chain expansion guide for bytecode deployment #76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d6e0649
6faff9e
a24a065
d0acb7a
588dc8d
0ebc8dd
62951fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -62,15 +62,83 @@ For running integration tests in Anvil node, run `make anvil-tests`. This runs t | |||||||||
|
||||||||||
* `cast code $address` | ||||||||||
|
||||||||||
## On-chain Deployment & Verification | ||||||||||
## Chain Expansion Guide | ||||||||||
This section explains how to expand the existing smart contracts to new blockchains. | ||||||||||
|
||||||||||
### Prerequisites | ||||||||||
#### Fund deployer and owner | ||||||||||
Make sure there are enough native tokens for the new chain in the deployer address (for contract deployment) and temporary owner | ||||||||||
address (for setup and stake). Otherwise, you may hit `insufficient fund` error at any step. | ||||||||||
|
||||||||||
#### Add new blockchain RPC URLs to foundry | ||||||||||
1. Add new blockchain to `[rpc_endpoints]` in `foundry.toml` following the format of `blockchain_a = ${BLOCKCHAIN_A_RPC_URL}` | ||||||||||
2. Update `.env.example` with the new RPC URL env var (e.g. `BLOCKCHAIN_A_RPC_URL`), also update your local `.env` to set up the new env var (e.g. `BLOCKCHAIN_A_RPC_URL=https://blockchaina.rpc.com`). | ||||||||||
3. Add new blockchain (e.g. `"blockchain_a"`) to `getChains()` function in `./script/bytecode-deploy/100_Constants.sol`. | ||||||||||
4. Since the length of `getChains()` changed above, update the length of local chain list generated by `getChains()` in deployment scripts. | ||||||||||
|
||||||||||
### Deploy & Verify UpgradableMSCAFactory and dependency smart contracts. | ||||||||||
Deploy, setup and verify UpgradableMSCAFactory compatible with ERC-4337 v0.7 and ERC-6900 v0.7. | ||||||||||
|
||||||||||
#### Run deploy commands: | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we mention that this will attempt to deploy on all chains listed in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good point, added to the change |
||||||||||
|
||||||||||
Note that deploy commands attempt to deploy on all chains listed in `foundry.toml`. | ||||||||||
|
||||||||||
```shell | ||||||||||
# Deploy PluginManager | ||||||||||
forge script script/bytecode-deploy/101_DeployPluginManager.s.sol -vvvv --slow --broadcast --force --multi | ||||||||||
|
||||||||||
# Deploy UpgradableMSCAFactory | ||||||||||
forge script script/bytecode-deploy/102_DeployUpgradableMSCAFactory.s.sol -vvvv --slow --broadcast --force --multi | ||||||||||
|
||||||||||
# Deploy ColdStorageAddressBookPlugin | ||||||||||
forge script script/bytecode-deploy/103_DeployColdStorageAddressBookPlugin.s.sol -vvvv --slow --broadcast --force --multi | ||||||||||
|
||||||||||
# Deploy WeightedWebauthnMultisigPlugin | ||||||||||
forge script script/bytecode-deploy/104_DeployWeightedWebauthnMultisigPlugin.s.sol -vvvv --slow --broadcast --force --multi | ||||||||||
|
||||||||||
``` | ||||||||||
#### Setup UpgradableMSCAFactory: | ||||||||||
|
||||||||||
Update `chains[]` list in `105_SetUpgradableMSCAFactoryPlugins.s.sol` and `106_StakeUpgradableMSCAFactory.s.sol`. Update `stakeValue` list in `106_StakeUpgradableMSCAFactory.s.sol`. And run | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nitpick] Consider adding further details or a reference link that explains how to update the chains[] and stakeValue lists for clarity, especially for new contributors who may be unfamiliar with the required changes.
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||||||
```shell | ||||||||||
forge script script/bytecode-deploy/105_SetUpgradableMSCAFactoryPlugins.s.sol -vvvv --slow --broadcast --force --multi | ||||||||||
forge script script/bytecode-deploy/106_StakeUpgradableMSCAFactory.s.sol -vvvv --slow --broadcast --force --multi | ||||||||||
``` | ||||||||||
#### Verify contracts on block explorers. | ||||||||||
|
||||||||||
Use the json files in `script/bytecode-deploy/standard-json-input` to verify smart contracts. If the smart contract has | ||||||||||
constructor arguments, it's recorded in `*_constructor_arg` files. Select the following options in block explorers verify contract UI: | ||||||||||
* Compiler Type: `Solidity(Standard-Json-Input)` | ||||||||||
* Compiler Version: `v0.8.24` | ||||||||||
* License Type: `GNU GPLv3` | ||||||||||
|
||||||||||
### Deploy & Verify EPv0.7 SponsorPaymaster | ||||||||||
Deploy, setup and verify SponsorPaymaster compatible with ERC-4337 v0.7. | ||||||||||
|
||||||||||
#### Run deploy command | ||||||||||
1. Replace the placeholders and run the command in `script/cmd/DeploySponsorPaymaster`. | ||||||||||
2. Replace the placeholders and run the command in `script/cmd/DeploySponsorPaymasterProxy`. | ||||||||||
|
||||||||||
#### Setup SponsorPaymaster | ||||||||||
|
||||||||||
Need to use block explorer to run `addStake` and `setVerifyingSigner` from owner address. | ||||||||||
|
||||||||||
#### Verify SponsorPaymaster | ||||||||||
Use `script/verify/SponsorPaymaster.json` and `script/verify/SponsorPaymasterProxy.json` to verify. Select the | ||||||||||
following options in block explorers verify contract UI: | ||||||||||
* Compiler Type: `Solidity(Standard-Json-Input)` | ||||||||||
* Compiler Version: `v0.8.24` | ||||||||||
* License Type: `GNU GPLv3` | ||||||||||
|
||||||||||
## Develop a New Smart Contract | ||||||||||
|
||||||||||
### Start a Local Network (optional, for testing) | ||||||||||
|
||||||||||
`npx hardhat node` (if using hardhat stack) | ||||||||||
|
||||||||||
`make anvil` (if using foundry stack). To get a list of pre-funded addresses, you can look at the beginning of the logs in the `anvil` Docker container, or reference <https://github.com/foundry-rs/foundry/blob/0d8302880b79fa9c3c4aa52ab446583dece19a34/crates/anvil/README.md?plain=1#L48>. | ||||||||||
|
||||||||||
### (NEW) Deploy & Verify | ||||||||||
### Deploy & Verify | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nitpick] It might be helpful to include a brief note summarizing the key differences between this new 'Chain Expansion Guide' and the previous deployment instructions, reducing potential confusion.
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||||||
scripts and artifacts under `./script/bytecode-deploy` are using bytecode deployment and standard json input verification. | ||||||||||
|
||||||||||
#### artifact generation | ||||||||||
|
@@ -127,98 +195,6 @@ forge script script/bytecode-deploy/<SCRIPT_FILE> -vvvv --slow --broadcast --fo | |||||||||
#### Verification | ||||||||||
Use the standard json output and constructor arg file under script/bytecode-deploy.standard-json-input to verify smart contracts in block explorer. | ||||||||||
|
||||||||||
### Deploy & Verify | ||||||||||
#### SCA and Paymaster | ||||||||||
1. Deployment | ||||||||||
* Run the command `env $(grep -v '^#' .env) yarn hardhat deploy --network <chain>` where `<chain>` is one of {`mumbai`, `goerli`}. | ||||||||||
|
||||||||||
If you only want to deploy a specific set of smart contracts, you can add the `--tags` flag, for example: `env $(grep -v '^#' .env) yarn hardhat deploy --tags SponsorPaymaster --network goerli` | ||||||||||
2. Verification | ||||||||||
* ECDSA wallet factory `env $(grep -v '^#' .env) npx hardhat verify --network mumbai --constructor-args script/ecdsa_account_factory_constructor_args.js ECDSA_ACCOUNT_FACTORY_ADDRESS` | ||||||||||
* Sponsor paymaster `env $(grep -v '^#' .env) npx hardhat verify --network goerli --constructor-args script/sponsor_paymaster_constructor_args.js STABLECOIN_PAYMASTER_ADDRESS` | ||||||||||
* Fallback: If the verification commands do not work for contracts deployed through the hardhat deployment scripts, you can still verify manually through etherscan's UI by submitting the standard input json. | ||||||||||
|
||||||||||
You can find this file under `deployments/polygon/solcInputs` (you can try different blockchains but I'm unsure of results). Then submit the file that you think is the one for the contract you're trying to verify. It's a bit of guessing, but you can look at the source code to try and figure it out. You may also need to verify the proxies manually through etherscan after having verified the implementation. | ||||||||||
#### MSCA | ||||||||||
1. Set up `DEPLOYER_PRIVATE_KEY`, `RPC_URL` and `ETHERSCAN_API_KEY` in .env | ||||||||||
2. Run `source .env` | ||||||||||
3. Run the desired numbered scripts inside the `script/` folder using the below command format. Make sure any environment variable values from previous steps are updated if needed as you progress through the scripts. | ||||||||||
* `forge script script/<SCRIPT_NAME> --rpc-url $RPC_URL --broadcast --verify -vvvv` | ||||||||||
|
||||||||||
Example: `forge script script/001_DeployPluginManager.s.sol --rpc-url $RPC_URL --broadcast --verify -vvvv` | ||||||||||
|
||||||||||
Tip: before executing the above command, verify the simulation works as expected by running the above command without the `--broadcast` and `--verify` flags. This way, you can also make sure your address will have enough tokens to cover the transaction fee estimated in the simulation. | ||||||||||
|
||||||||||
Note: if you are deploying on a local network, don't use the `--verify` flag. | ||||||||||
|
||||||||||
4. Include the relevant logs from the `broadcast` folder in your commit. | ||||||||||
|
||||||||||
Tip: if you did multiple runs, search the appropriate block explorer for the tx hash corresponding to the desired contract's deployment, and then search the logs for the transaction hash. | ||||||||||
|
||||||||||
Tip: logs are organized by chain ID in the lower levels in the `broadcast` folder. Use <https://chainlist.org/> to lookup IDs of common chains. | ||||||||||
|
||||||||||
5. Create or update the corresponding file in the `script/cmd` folder using the creation bytecode of the contract from the logs. See the below "Chain Expansion" section for details on how to format the files in the `script/cmd` folder. | ||||||||||
6. Verify in block explorer like etherscan using standard input json | ||||||||||
* Create the standard input json: run the below command | ||||||||||
|
||||||||||
```shell | ||||||||||
forge verify-contract <contract_address> <relative_path_to_source:classname> --show-standard-json-input > <script/verify/<filename> | ||||||||||
|
||||||||||
# Example | ||||||||||
forge verify-contract 0x03431fb00fb2e26b5bc502dfef8da30e1c8643b8 src/msca/6900/v0.7/plugins/v1_0_0/utility/DefaultTokenCallbackPlugin.sol:DefaultTokenCallbackPlugin --show-standard-json-input > script/verify/DefaultTokenCallbackPlugin.json | ||||||||||
``` | ||||||||||
* Verify and publish in block explorer (etherscan example) | ||||||||||
* Compiler type: `Solidity (Standard-Json-Input)` | ||||||||||
* Compiler version: `v0.8.24` | ||||||||||
* License: Option 5 in https://etherscan.io/contract-license-types | ||||||||||
* Upload the JSON file | ||||||||||
* If the contract you are verifying took constructor arguments, input the output of the below command with the `0x` prefix removed into the "Constructor Arguments ABI-encoded" section: | ||||||||||
|
||||||||||
```shell | ||||||||||
cast abi-encode "constructor(<arg type 1>, <arg type 2>, ...)" "arg1Val" "arg2Val" | ||||||||||
|
||||||||||
# Example | ||||||||||
cast abi-encode "constructor(address,address,uint256)" "0x0166EA90E565476f13c6a0D25ED2C35599E58785" "0x0000000071727De22E5E9d8BAf0edAc6f37da032" 18 | ||||||||||
``` | ||||||||||
|
||||||||||
Make sure to save this output under `script/verify/<ContractName>/abiEncodedConstructorArgs`. | ||||||||||
|
||||||||||
Tip: if your contract's constructor arguments have complicated types, you can get this value instead by `console.log`ing the output of `abi.encode(arg1, arg2, ...)` in Solidity. | ||||||||||
|
||||||||||
* For account factory contracts, you may also need to manually verify the proxy contract. To do this, you will first need to create an account using the account factory, and follow the above strategy. After verifying one account, all subsequent proxies should be automatically detected. | ||||||||||
|
||||||||||
Tip: analyze the account creation function on the factory (e.g. `createAccount` for `SingleOwnerMSCAFactory`) to deduce the constructor arguments for the proxy deployment when trying to verify it on a block explorer. | ||||||||||
|
||||||||||
* Click verify and publish | ||||||||||
|
||||||||||
### Deployment Metadata | ||||||||||
|
||||||||||
The below contract deployment are based on abi and bytecode to ensure the same address across all EVM-compatible chains. The abi and bytecode for each of the contracts are available at the locations below. These files were generated from first deployments, will all fields except `abi` and `bytecode` removed. | ||||||||||
|
||||||||||
| Contract Name | Location | | ||||||||||
|:------------------------:|:------------------------:| | ||||||||||
| ECDSAAcountFactory | `deploy/metadata/ECDSAAccountFactory.json` | | ||||||||||
| SponsorPaymaster_Implementation | `deploy/metadata/SponsorPaymaster_Implementation.json` | | ||||||||||
| SponsorPaymaster_Proxy | `deploy/metadata/SponsorPaymaster_Proxy.json` | | ||||||||||
|
||||||||||
### Chain Expansion | ||||||||||
|
||||||||||
To ensure consistent deployment of contracts across chains, we store the `cast send` deployment commands for contracts in the `script/cmd` folder. To deploy these contracts, simply run the command inside the file corresponding to that contract on the command line. | ||||||||||
|
||||||||||
To build the `cast send` deployment command for a contract: | ||||||||||
1. Run the Solidity deployment script for the contract in the `script/*` folder: | ||||||||||
1. Find the deployment result in broadcast/* | ||||||||||
2. Looking for “transactions” -> ”transaction” → “data” in run-*.json | ||||||||||
3. Copy the "data" in step 2 without "0x" prefix. | ||||||||||
4. Add `cast send --rpc-url $RPC_URL --private-key $DEPLOYER_PRIVATE_KEY 0x4e59b44847b379578588920cA78FbF26c0B4956C 0x0000000000000000000000000000000000000000000000000000000000000000` in front of the bytecode from previous step (no space) | ||||||||||
|
||||||||||
Refer to the note after these steps, you may not need the `0x0...` prefix. The `0x4e59b44847b379578588920cA78FbF26c0B4956C` is foundry's default create2 address deployer. See <https://book.getfoundry.sh/reference/cast/cast-create2>. | ||||||||||
5. Run the command in step5 in Terminal. | ||||||||||
6. Save this command to script/cmd folder with `<script_name>` | ||||||||||
7. Create the README under `broadcast` folder for the chain id. For example, see `broadcast/011_DeployTokenCallbackPlugin.s.sol/11155111/README.md` | ||||||||||
|
||||||||||
Note: The "data" field may be called "input". Additionally, if the input/data field already contains the leading `0000000000000000000000000000000000000000000000000000000000000000` prefix, simply copy this value over directly (no need to re-add the zeros prefix). | ||||||||||
|
||||||||||
## Troubleshooting | ||||||||||
#### 1. `make: *** [test] Error 137` | ||||||||||
|
||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.