diff --git a/crates/cast/src/cmd/call.rs b/crates/cast/src/cmd/call.rs index 315410b8db3cb..f6f80f7a09af9 100644 --- a/crates/cast/src/cmd/call.rs +++ b/crates/cast/src/cmd/call.rs @@ -42,72 +42,64 @@ use super::run::fetch_contracts_bytecode_from_trace; static OVERRIDE_PATTERN: LazyLock = LazyLock::new(|| Regex::new(r"^([^:]+):([^:]+):([^:]+)$").unwrap()); -/// CLI arguments for `cast call`. +/// Call a contract function locally (eth_call) and print the result. /// -/// ## State Override Flags +/// Example: /// -/// The following flags can be used to override the state for the call: -/// -/// * `--override-balance
:` - Override the balance of an account -/// * `--override-nonce
:` - Override the nonce of an account -/// * `--override-code
:` - Override the code of an account -/// * `--override-state
::` - Override a storage slot of an account -/// -/// Multiple overrides can be specified for the same account. For example: -/// -/// ```bash -/// cast call 0x... "transfer(address,uint256)" 0x... 100 \ -/// --override-balance 0x123:0x1234 \ -/// --override-nonce 0x123:1 \ -/// --override-code 0x123:0x1234 \ -/// --override-state 0x123:0x1:0x1234 -/// --override-state-diff 0x123:0x1:0x1234 -/// ``` +/// cast call 0xAbC... "balanceOf(address)" 0x123... --rpc-url <URL> #[derive(Debug, Parser)] +#[command( + about = "Call a contract function locally (eth_call) and print the result.", + long_about = "Call a contract function locally (eth_call) and print the result.\n\ +EXAMPLES:\n\ + cast call 0xAbC... 'balanceOf(address)' 0x123... --rpc-url \n\ + cast call 0xAbC... --data 0xabcdef... --rpc-url \n\ + cast call 0xAbC... 'transfer(address,uint256)' 0x123... 100 --override-balance 0x123:1000\n\ +See more: https://book.getfoundry.sh/reference/cast/cast-call.html" +)] pub struct CallArgs { - /// The destination of the transaction. - #[arg(value_parser = NameOrAddress::from_str)] + /// Destination address of the contract to call. + #[arg(value_name = "TO", value_parser = NameOrAddress::from_str)] to: Option, - /// The signature of the function to call. + /// Function signature to call, e.g. `balanceOf(address)`. + #[arg(value_name = "SIG")] sig: Option, - /// The arguments of the function to call. + /// Arguments for the function call. + #[arg(value_name = "ARGS")] args: Vec, /// Raw hex-encoded data for the transaction. Used instead of \[SIG\] and \[ARGS\]. #[arg( long, - conflicts_with_all = &["sig", "args"] + conflicts_with_all = &["sig", "args"], + value_name = "DATA", )] data: Option, - /// Forks the remote rpc, executes the transaction locally and prints a trace + /// Forks the remote rpc, executes the transaction locally and prints a trace. #[arg(long, default_value_t = false)] trace: bool, - /// Opens an interactive debugger. - /// Can only be used with `--trace`. + /// Opens an interactive debugger (requires --trace). #[arg(long, requires = "trace")] debug: bool, + /// Decode internal calls in traces (requires --trace). #[arg(long, requires = "trace")] decode_internal: bool, - /// Labels to apply to the traces; format: `address:label`. - /// Can only be used with `--trace`. + /// Labels to apply to the traces; format: `address:label` (requires --trace). #[arg(long, requires = "trace")] labels: Vec, - /// The EVM Version to use. - /// Can only be used with `--trace`. - #[arg(long, requires = "trace")] + /// EVM Version to use (requires --trace). + #[arg(long, requires = "trace", value_name = "EVM_VERSION")] evm_version: Option, - /// The block height to query at. - /// - /// Can also be the tags earliest, finalized, safe, latest, or pending. - #[arg(long, short)] + /// Block height to query at (number or tag: earliest, latest, pending, etc). + #[arg(long, short, value_name = "BLOCK")] block: Option, /// Enable Odyssey features. @@ -127,28 +119,23 @@ pub struct CallArgs { #[arg(long, visible_alias = "la")] pub with_local_artifacts: bool, - /// Override the balance of an account. - /// Format: address:balance + /// Override the balance of an account. Format: address:balance #[arg(long = "override-balance", value_name = "ADDRESS:BALANCE")] pub balance_overrides: Option>, - /// Override the nonce of an account. - /// Format: address:nonce + /// Override the nonce of an account. Format: address:nonce #[arg(long = "override-nonce", value_name = "ADDRESS:NONCE")] pub nonce_overrides: Option>, - /// Override the code of an account. - /// Format: address:code + /// Override the code of an account. Format: address:code #[arg(long = "override-code", value_name = "ADDRESS:CODE")] pub code_overrides: Option>, - /// Override the state of an account. - /// Format: address:slot:value + /// Override the state of an account. Format: address:slot:value #[arg(long = "override-state", value_name = "ADDRESS:SLOT:VALUE")] pub state_overrides: Option>, - /// Override the state diff of an account. - /// Format: address:slot:value + /// Override the state diff of an account. Format: address:slot:value #[arg(long = "override-state-diff", value_name = "ADDRESS:SLOT:VALUE")] pub state_diff_overrides: Option>, @@ -163,24 +150,23 @@ pub struct CallArgs { #[derive(Debug, Parser)] pub enum CallSubcommands { - /// ignores the address field and simulates creating a contract + /// Simulate contract creation (ignores the address field). #[command(name = "--create")] Create { - /// Bytecode of contract. + /// Bytecode of contract to deploy. + #[arg(value_name = "BYTECODE")] code: String, - /// The signature of the constructor. + /// Constructor signature, e.g. `constructor(uint256)`. + #[arg(value_name = "SIG")] sig: Option, - /// The arguments of the constructor. + /// Arguments for the constructor. + #[arg(value_name = "ARGS")] args: Vec, - /// Ether to send in the transaction. - /// - /// Either specified in wei, or as a string with a unit type. - /// - /// Examples: 1ether, 10gwei, 0.01ether - #[arg(long, value_parser = parse_ether_value)] + /// Ether to send in the transaction (e.g. 1ether, 10gwei, 0.01ether). + #[arg(long, value_parser = parse_ether_value, value_name = "VALUE")] value: Option, }, } diff --git a/crates/cast/src/cmd/send.rs b/crates/cast/src/cmd/send.rs index 35ec92f737e0e..fce367a4e48c2 100644 --- a/crates/cast/src/cmd/send.rs +++ b/crates/cast/src/cmd/send.rs @@ -17,38 +17,53 @@ use foundry_cli::{ }; use std::{path::PathBuf, str::FromStr}; -/// CLI arguments for `cast send`. +/// Send a transaction to a contract or deploy a new contract. +/// +/// Example: +/// +/// cast send 0xAbC... "transfer(address,uint256)" 0x123... 100 --private-key <KEY> --rpc-url +/// <URL> cast send --create <BYTECODE> --private-key <KEY> --rpc-url <URL> #[derive(Debug, Parser)] +#[command( + about = "Send a transaction to a contract or deploy a new contract.", + long_about = "Send a transaction to a contract or deploy a new contract.\n\ +EXAMPLES:\n\ + cast send 0xAbC... 'transfer(address,uint256)' 0x123... 100 --private-key <KEY> --rpc-url <URL>\n\ + cast send --create <BYTECODE> --private-key <KEY> --rpc-url <URL>\n\ +See more: https://book.getfoundry.sh/reference/cast/cast-send.html" +)] pub struct SendTxArgs { - /// The destination of the transaction. + /// Destination address of the transaction (contract or EOA). /// - /// If not provided, you must use cast send --create. - #[arg(value_parser = NameOrAddress::from_str)] + /// If not provided, you must use `cast send --create`. + #[arg(value_name = "TO", value_parser = NameOrAddress::from_str)] to: Option, - /// The signature of the function to call. + /// Function signature to call, e.g. `transfer(address,uint256)`. + #[arg(value_name = "SIG")] sig: Option, - /// The arguments of the function to call. + /// Arguments for the function call. + #[arg(value_name = "ARGS")] args: Vec, /// Only print the transaction hash and exit immediately. #[arg(id = "async", long = "async", alias = "cast-async", env = "CAST_ASYNC")] cast_async: bool, - /// The number of confirmations until the receipt is fetched. - #[arg(long, default_value = "1")] + /// Number of confirmations to wait for the receipt. + #[arg(long, default_value = "1", value_name = "NUM")] confirmations: u64, #[command(subcommand)] command: Option, - /// Send via `eth_sendTransaction` using the `--from` argument or $ETH_FROM as sender + /// Use `eth_sendTransaction` with an unlocked account (requires --from or $ETH_FROM). #[arg(long, requires = "from")] unlocked: bool, - /// Timeout for sending the transaction. - #[arg(long, env = "ETH_TIMEOUT")] + /// Timeout (in seconds) for sending the transaction. + #[arg(long, env = "ETH_TIMEOUT", value_name = "SECONDS")] pub timeout: Option, #[command(flatten)] @@ -57,7 +72,7 @@ pub struct SendTxArgs { #[command(flatten)] eth: EthereumOpts, - /// The path of blob data to be sent. + /// Path to a file containing blob data to be sent. #[arg( long, value_name = "BLOB_DATA_PATH", @@ -70,16 +85,19 @@ pub struct SendTxArgs { #[derive(Debug, Parser)] pub enum SendTxSubcommands { - /// Use to deploy raw contract bytecode. + /// Deploy raw contract bytecode as a new contract. #[command(name = "--create")] Create { - /// The bytecode of the contract to deploy. + /// Bytecode of the contract to deploy. + #[arg(value_name = "BYTECODE")] code: String, - /// The signature of the function to call. + /// Constructor signature, e.g. `constructor(uint256)`. + #[arg(value_name = "SIG")] sig: Option, - /// The arguments of the function to call. + /// Arguments for the constructor. + #[arg(value_name = "ARGS")] args: Vec, }, } diff --git a/crates/forge/src/cmd/create.rs b/crates/forge/src/cmd/create.rs index 6768b43829836..ab5329aba4723 100644 --- a/crates/forge/src/cmd/create.rs +++ b/crates/forge/src/cmd/create.rs @@ -37,13 +37,31 @@ use std::{borrow::Borrow, marker::PhantomData, path::PathBuf, sync::Arc, time::D merge_impl_figment_convert!(CreateArgs, build, eth); -/// CLI arguments for `forge create`. +/// Deploy a smart contract to the specified network. +/// +/// This command compiles the contract, encodes constructor arguments, and sends a deployment +/// transaction. +/// +/// Example: +/// +/// forge create src/Counter.sol:Counter --constructor-args 42 --rpc-url <URL> --private-key +/// <KEY> --broadcast #[derive(Clone, Debug, Parser)] +#[command( + about = "Deploy a smart contract to the specified network.", + long_about = "Deploy a smart contract to the specified network.\n\ +Compiles the contract, encodes constructor arguments, and sends a deployment transaction.\n\ +EXAMPLES:\n\ + forge create src/Counter.sol:Counter --constructor-args 42 --rpc-url <URL> --private-key <KEY> --broadcast\n\ +Use --verify to automatically verify the contract after deployment.\n\ +See more: https://book.getfoundry.sh/reference/forge/forge-create.html" +)] pub struct CreateArgs { - /// The contract identifier in the form `:`. + /// Contract identifier in the form `:`, e.g. `src/Counter.sol:Counter`. + #[arg(value_name = "CONTRACT")] contract: ContractInfo, - /// The constructor arguments. + /// Constructor arguments as a space-separated list, e.g. `42 \"hello\"`. #[arg( long, num_args(1..), @@ -53,7 +71,7 @@ pub struct CreateArgs { )] constructor_args: Vec, - /// The path to a file containing the constructor arguments. + /// Path to a file containing constructor arguments (one per line or as JSON array). #[arg( long, value_hint = ValueHint::FilePath, @@ -61,27 +79,24 @@ pub struct CreateArgs { )] constructor_args_path: Option, - /// Broadcast the transaction. + /// Broadcast the transaction to the network (otherwise, dry-run only). #[arg(long)] pub broadcast: bool, - /// Verify contract after creation. + /// Verify contract after creation (using the selected block explorer). #[arg(long)] verify: bool, - /// Send via `eth_sendTransaction` using the `--from` argument or `$ETH_FROM` as sender + /// Use `eth_sendTransaction` with an unlocked account (requires --from or $ETH_FROM). #[arg(long, requires = "from")] unlocked: bool, - /// Prints the standard json compiler input if `--verify` is provided. - /// - /// The standard json compiler input can be used to manually submit contract verification in - /// the browser. + /// Print the standard JSON compiler input (for manual verification in a browser). #[arg(long, requires = "verify")] show_standard_json_input: bool, - /// Timeout to use for broadcasting transactions. - #[arg(long, env = "ETH_TIMEOUT")] + /// Timeout (in seconds) for broadcasting transactions. + #[arg(long, env = "ETH_TIMEOUT", value_name = "SECONDS")] pub timeout: Option, #[command(flatten)] diff --git a/crates/verify/src/verify.rs b/crates/verify/src/verify.rs index 804813c7a96e7..ad417c2075b49 100644 --- a/crates/verify/src/verify.rs +++ b/crates/verify/src/verify.rs @@ -54,16 +54,31 @@ impl Default for VerifierArgs { } } -/// CLI arguments for `forge verify-contract`. +/// Submit a contract's source code for verification on a block explorer (e.g. Etherscan, Sourcify). +/// +/// Example: +/// +/// forge verify-contract 0x123... src/Counter.sol:Counter --compiler-version 0.8.20 +/// --etherscan-api-key <KEY> #[derive(Clone, Debug, Parser)] +#[command( + about = "Verify a deployed contract's source code on a block explorer.", + long_about = "Submit a contract's source code for verification on a block explorer (e.g. Etherscan, Sourcify).\n\ +EXAMPLES:\n\ + forge verify-contract 0x123... src/Counter.sol:Counter --compiler-version 0.8.20 --etherscan-api-key <KEY>\n\ + forge verify-contract 0x123... src/Counter.sol:Counter --constructor-args 42 --compiler-version 0.8.20\n\ +See more: https://book.getfoundry.sh/reference/forge/forge-verify-contract.html" +)] pub struct VerifyArgs { - /// The address of the contract to verify. + /// Address of the deployed contract to verify. + #[arg(value_name = "ADDRESS")] pub address: Address, - /// The contract identifier in the form `:`. + /// Contract identifier in the form `:`, e.g. `src/Counter.sol:Counter`. + #[arg(value_name = "CONTRACT")] pub contract: Option, - /// The ABI-encoded constructor arguments. + /// ABI-encoded constructor arguments (hex string, e.g. 000000...) #[arg( long, conflicts_with = "constructor_args_path", @@ -72,7 +87,7 @@ pub struct VerifyArgs { )] pub constructor_args: Option, - /// The path to a file containing the constructor arguments. + /// Path to a file containing constructor arguments (one per line or as JSON array). #[arg(long, value_hint = ValueHint::FilePath, value_name = "PATH")] pub constructor_args_path: Option, @@ -80,15 +95,15 @@ pub struct VerifyArgs { #[arg(long)] pub guess_constructor_args: bool, - /// The `solc` version to use to build the smart contract. + /// Solidity compiler version to use (e.g. 0.8.20). #[arg(long, value_name = "VERSION")] pub compiler_version: Option, - /// The compilation profile to use to build the smart contract. + /// Compilation profile to use (e.g. default, release). #[arg(long, value_name = "PROFILE_NAME")] pub compilation_profile: Option, - /// The number of optimization runs used to build the smart contract. + /// Number of optimizer runs used to build the contract. #[arg(long, visible_alias = "optimizer-runs", value_name = "NUM")] pub num_of_optimizations: Option, @@ -96,7 +111,7 @@ pub struct VerifyArgs { #[arg(long)] pub flatten: bool, - /// Do not compile the flattened smart contract before verifying (if --flatten is passed). + /// Do not compile the flattened contract before verifying (if --flatten is passed). #[arg(short, long)] pub force: bool, @@ -108,21 +123,15 @@ pub struct VerifyArgs { #[arg(long)] pub watch: bool, - /// Set pre-linked libraries. - #[arg(long, help_heading = "Linker options", env = "DAPP_LIBRARIES")] + /// Pre-linked libraries in the format <file>:<lib>=<address> (repeatable). + #[arg(long, help_heading = "Linker options", env = "DAPP_LIBRARIES", value_name = "LIBRARIES")] pub libraries: Vec, - /// The project's root path. - /// - /// By default root of the Git repository, if in one, - /// or the current working directory. + /// Project's root path (default: git root or current directory). #[arg(long, value_hint = ValueHint::DirPath, value_name = "PATH")] pub root: Option, - /// Prints the standard json compiler input. - /// - /// The standard json compiler input can be used to manually submit contract verification in - /// the browser. + /// Print the standard JSON compiler input (for manual verification in a browser). #[arg(long, conflicts_with = "flatten")] pub show_standard_json_input: bool, @@ -130,10 +139,8 @@ pub struct VerifyArgs { #[arg(long)] pub via_ir: bool, - /// The EVM version to use. - /// - /// Overrides the version specified in the config. - #[arg(long)] + /// EVM version to use (overrides config). + #[arg(long, value_name = "EVM_VERSION")] pub evm_version: Option, #[command(flatten)] @@ -223,7 +230,7 @@ impl VerifyArgs { .create_verify_request(&self, &context) .await?; sh_println!("{}", args.source)?; - return Ok(()) + return Ok(()); } let verifier_url = self.verifier.verifier_url.clone();