From 4dc0d76da06453a2e0e9f7c201cb9521f3efe4b9 Mon Sep 17 00:00:00 2001 From: qd-qd Date: Thu, 30 Nov 2023 15:16:21 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A8=20make=20BaseScript=20more=20gener?= =?UTF-8?q?ic/powerful?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This light refactoring of BaseScript makes it more generic and powerful. Based on the flag you provide when running the script, it will either start the hardware wallet flow or use the private key you provide. In addition, I added new comments for each script to detail how to use them. --- script/AccountFactory/CreateAccount.s.sol | 22 ++++++++++++---- .../AccountFactory/CreateAndInitAccount.s.sol | 23 ++++++++++++----- script/AccountFactory/Deploy.s.sol | 19 ++++++++++++-- script/Base.s.sol | 25 ++++++------------- 4 files changed, 58 insertions(+), 31 deletions(-) diff --git a/script/AccountFactory/CreateAccount.s.sol b/script/AccountFactory/CreateAccount.s.sol index 863463f..1a99802 100644 --- a/script/AccountFactory/CreateAccount.s.sol +++ b/script/AccountFactory/CreateAccount.s.sol @@ -5,14 +5,26 @@ import { AccountFactory } from "src/AccountFactory.sol"; import { BaseScript } from "../Base.s.sol"; /// @title Create an Account using an already deployed AccountFactory -/** - * @notice - * forge script CreateAccount --sig "run(address,bytes32)" <...args> <...flags> - */ /// @dev If you need to deploy an AccountFactory, use the Deploy script in this directory contract CreateAccount is BaseScript { - function run(address factoryAddress, bytes32 loginHash) public broadcaster returns (address) { + function run(address factoryAddress, bytes32 loginHash) public broadcast returns (address) { AccountFactory factory = AccountFactory(factoryAddress); return factory.createAccount(loginHash); } } + +/* + + ℹ️ HOW TO USE THIS SCRIPT USING A LEDGER: + forge script CreateAccount --rpc-url --ledger --sender [--broadcast] + + + ℹ️ HOW TO USE THIS SCRIPT WITH AN ARBITRARY PRIVATE KEY (NOT RECOMMENDED): + PRIVATE_KEY= forge script CreateAccount --rpc-url [--broadcast] + + + ℹ️ HOW TO USE THIS SCRIPT ON ANVIL IN DEFAULT MODE: + forge script CreateAccount --rpc-url http://127.0.0.1:8545 --broadcast --sender \ + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --mnemonics "test test test test test test test test test test test junk" + +*/ diff --git a/script/AccountFactory/CreateAndInitAccount.s.sol b/script/AccountFactory/CreateAndInitAccount.s.sol index 6593894..632ff51 100644 --- a/script/AccountFactory/CreateAndInitAccount.s.sol +++ b/script/AccountFactory/CreateAndInitAccount.s.sol @@ -5,11 +5,6 @@ import { AccountFactory } from "src/AccountFactory.sol"; import { BaseScript } from "../Base.s.sol"; /// @title Create an Account using an already deployed AccountFactory and init it -/** - * @notice - * forge script CreateAndInitAccount --sig run(address,uint256,uint256,bytes32,bytes,bytes)" - * " <...args> <...flags> - */ /// @dev If you need to deploy an AccountFactory, use the Deploy script in this directory contract CreateAndInitAccount is BaseScript { function run( @@ -21,10 +16,26 @@ contract CreateAndInitAccount is BaseScript { bytes calldata nameServiceSignature // ℹ️ must be made by the nameServiceOwner of the AccountFactory ) public - broadcaster + broadcast returns (address) { AccountFactory factory = AccountFactory(factoryAddress); return factory.createAndInitAccount(pubKeyX, pubKeyY, loginHash, credId, nameServiceSignature); } } + +/* + + ℹ️ HOW TO USE THIS SCRIPT USING A LEDGER: + forge script CreateAndInitAccount --rpc-url --ledger --sender [--broadcast] + + + ℹ️ HOW TO USE THIS SCRIPT WITH AN ARBITRARY PRIVATE KEY (NOT RECOMMENDED): + PRIVATE_KEY= forge script CreateAndInitAccount --rpc-url [--broadcast] + + + ℹ️ HOW TO USE THIS SCRIPT ON ANVIL IN DEFAULT MODE: + forge script CreateAndInitAccount --rpc-url http://127.0.0.1:8545 --broadcast --sender \ + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --mnemonics "test test test test test test test test test test test junk" + +*/ diff --git a/script/AccountFactory/Deploy.s.sol b/script/AccountFactory/Deploy.s.sol index d365dd8..8b8bc88 100644 --- a/script/AccountFactory/Deploy.s.sol +++ b/script/AccountFactory/Deploy.s.sol @@ -5,7 +5,6 @@ import { AccountFactory } from "src/AccountFactory.sol"; import { BaseScript } from "../Base.s.sol"; /// @title Deploy an AccountFactory -/// @notice <...envs> forge script AccountFactoryDeploy /// @dev You can pass environment variables to this script to tailor the deployment. /// Do not deploy this script in production without changing the default values! contract AccountFactoryDeploy is BaseScript { @@ -14,7 +13,7 @@ contract AccountFactoryDeploy is BaseScript { // This is the first account exposed by Anvil address internal constant NAME_SERVICE_OWNER = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266; - function run() public broadcaster returns (AccountFactory) { + function run() public broadcast returns (AccountFactory) { address entrypoint = vm.envOr("ENTRYPOINT", ENTRYPOINT); address webAuthnVerifier = vm.envOr("WEBAUTHN_VERIFIER", address(0)); address nameServiceOwner = vm.envOr("NAME_SERVICE_OWNER", NAME_SERVICE_OWNER); @@ -22,3 +21,19 @@ contract AccountFactoryDeploy is BaseScript { return new AccountFactory(entrypoint, webAuthnVerifier, nameServiceOwner); } } + +/* + + ℹ️ HOW TO USE THIS SCRIPT USING A LEDGER: + forge script AccountFactoryDeploy --rpc-url --ledger --sender [--broadcast] + + + ℹ️ HOW TO USE THIS SCRIPT WITH AN ARBITRARY PRIVATE KEY (NOT RECOMMENDED): + PRIVATE_KEY= forge script AccountFactoryDeploy --rpc-url [--broadcast] + + + ℹ️ HOW TO USE THIS SCRIPT ON ANVIL IN DEFAULT MODE: + forge script AccountFactoryDeploy --rpc-url http://127.0.0.1:8545 --broadcast --sender \ + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --mnemonics "test test test test test test test test test test test junk" + +*/ diff --git a/script/Base.s.sol b/script/Base.s.sol index b9c6976..6a15eb2 100644 --- a/script/Base.s.sol +++ b/script/Base.s.sol @@ -4,26 +4,15 @@ pragma solidity >=0.8.19 <0.9.0; import { Script } from "forge-std/Script.sol"; abstract contract BaseScript is Script { - /// @dev Included to enable compilation of the script without a $MNEMONIC environment variable. - string internal constant TEST_MNEMONIC = "test test test test test test test test test test test junk"; + /// @notice this modifier can be used as a generic broadcast solution. It will automatically either: + /// - use the private key provided as an environment variable to broadcast + /// - or starts the hardware wallet flow if the correct flags are provided and the env variable is not set + modifier broadcast() { + uint256 privateKey = vm.envOr("PRIVATE_KEY", uint256(0)); + privateKey != 0 ? vm.startBroadcast(privateKey) : vm.startBroadcast(); - /// @dev Needed for the deterministic deployments. - bytes32 internal constant ZERO_SALT = bytes32(0); - - /// @dev The address of the contract deployer. - address internal deployer; - - /// @dev Used to derive the deployer's address. - string internal mnemonic; - - constructor() { - mnemonic = vm.envOr("MNEMONIC", TEST_MNEMONIC); - (deployer,) = deriveRememberKey({ mnemonic: mnemonic, index: 0 }); - } - - modifier broadcaster() { - vm.startBroadcast(deployer); _; + vm.stopBroadcast(); } }