cast/opts.rs
1use crate::cmd::{
2 access_list::AccessListArgs,
3 artifact::ArtifactArgs,
4 b2e_payload::B2EPayloadArgs,
5 bal::BalArgs,
6 batch_mktx::BatchMakeTxArgs,
7 batch_send::BatchSendArgs,
8 bind::BindArgs,
9 call::CallArgs,
10 call_overrides::CallOverrideOpts,
11 constructor_args::ConstructorArgsArgs,
12 create2::Create2Args,
13 creation_code::CreationCodeArgs,
14 erc20::Erc20Subcommand,
15 erc4626::Erc4626Subcommand,
16 estimate::EstimateArgs,
17 events::EventsArgs,
18 find_block::FindBlockArgs,
19 interface::InterfaceArgs,
20 keychain::{KeyAuthorizationSubcommand, KeychainSubcommand},
21 logs::LogsArgs,
22 mktx::MakeTxArgs,
23 receive_policy::ReceivePolicySubcommand,
24 rpc::RpcArgs,
25 run::RunArgs,
26 safe::SafeSubcommand,
27 send::SendTxArgs,
28 storage::StorageArgs,
29 storage_credits::StorageCreditsSubcommand,
30 tempo::TempoArgs,
31 tip20::Tip20Subcommand,
32 tip403::Tip403Subcommand,
33 trace::TraceArgs,
34 txpool::TxPoolSubcommands,
35 vaddr::VaddrSubcommand,
36 wallet::WalletSubcommands,
37};
38use alloy_ens::NameOrAddress;
39use alloy_primitives::{Address, B256, Selector, U256};
40use alloy_rpc_types::BlockId;
41use clap::{ArgAction, Parser, Subcommand, ValueHint};
42use eyre::Result;
43use foundry_cli::opts::{EtherscanOpts, GlobalArgs, RpcOpts};
44use foundry_common::version::{LONG_VERSION, SHORT_VERSION};
45use foundry_evm_networks::NetworkVariant;
46use std::{path::PathBuf, str::FromStr};
47
48#[cfg(any(feature = "base", feature = "optimism"))]
49use crate::cmd::da_estimate::DAEstimateArgs;
50
51/// A Swiss Army knife for interacting with Ethereum applications from the command line.
52#[derive(Parser)]
53#[command(
54 name = "cast",
55 version = SHORT_VERSION,
56 long_version = LONG_VERSION,
57 after_help = "Find more information in the book: https://getfoundry.sh/cast/overview",
58 next_display_order = None,
59)]
60pub struct Cast {
61 /// Include the global arguments.
62 #[command(flatten)]
63 pub global: GlobalArgs,
64
65 #[command(subcommand)]
66 pub cmd: CastSubcommand,
67}
68
69/// The `cast` subcommands.
70///
71/// Subcommands are declared across several flattened enums because clap's derive generates one
72/// `augment_subcommands` function per enum, and in debug builds a single enum holding every
73/// subcommand produced a stack frame that overflowed the 2 MiB stack of test threads.
74#[derive(Subcommand)]
75#[allow(clippy::large_enum_variant, reason = "parsed once per process")]
76pub enum CastSubcommand {
77 #[command(flatten)]
78 Conversion(ConversionSubcommand),
79
80 #[command(flatten)]
81 Transaction(TransactionSubcommand),
82
83 #[command(flatten)]
84 Abi(AbiSubcommand),
85
86 #[command(flatten)]
87 Query(QuerySubcommand),
88
89 #[command(flatten)]
90 Misc(MiscSubcommand),
91}
92
93/// Constant and conversion subcommands.
94#[derive(Subcommand)]
95pub enum ConversionSubcommand {
96 /// Prints the maximum value of the given integer type.
97 #[command(visible_aliases = &["--max-int", "maxi"])]
98 MaxInt {
99 /// The integer type to get the maximum value of.
100 #[arg(default_value = "int256")]
101 r#type: String,
102 },
103
104 /// Prints the minimum value of the given integer type.
105 #[command(visible_aliases = &["--min-int", "mini"])]
106 MinInt {
107 /// The integer type to get the minimum value of.
108 #[arg(default_value = "int256")]
109 r#type: String,
110 },
111
112 /// Prints the maximum value of the given integer type.
113 #[command(visible_aliases = &["--max-uint", "maxu"])]
114 MaxUint {
115 /// The unsigned integer type to get the maximum value of.
116 #[arg(default_value = "uint256")]
117 r#type: String,
118 },
119
120 /// Prints the zero address.
121 #[command(visible_aliases = &["--address-zero", "az"])]
122 AddressZero,
123
124 /// Prints the zero hash.
125 #[command(visible_aliases = &["--hash-zero", "hz"])]
126 HashZero,
127
128 /// Convert UTF8 text to hex.
129 #[command(
130 visible_aliases = &[
131 "--from-ascii",
132 "--from-utf8",
133 "from-ascii",
134 "fu",
135 "fa"]
136 )]
137 FromUtf8 {
138 /// The text to convert.
139 text: Option<String>,
140 },
141
142 /// Concatenate hex strings.
143 #[command(visible_aliases = &["--concat-hex", "ch"])]
144 ConcatHex {
145 /// The data to concatenate.
146 data: Vec<String>,
147 },
148
149 /// Convert binary data into hex data.
150 #[command(visible_aliases = &["--from-bin", "from-binx", "fb"])]
151 FromBin,
152
153 /// Normalize the input to lowercase, 0x-prefixed hex.
154 ///
155 /// The input can be:
156 /// - mixed case hex with or without 0x prefix
157 /// - 0x prefixed hex, concatenated with a ':'
158 /// - an absolute path to file
159 /// - @tag, where the tag is defined in an environment variable
160 #[command(visible_aliases = &["--to-hexdata", "thd", "2hd"])]
161 ToHexdata {
162 /// The input to normalize.
163 input: Option<String>,
164 },
165
166 /// Convert an address to a checksummed format (EIP-55).
167 #[command(
168 visible_aliases = &["--to-checksum-address",
169 "--to-checksum",
170 "to-checksum",
171 "ta",
172 "2a"]
173 )]
174 ToCheckSumAddress {
175 /// The address to convert.
176 address: Option<Address>,
177 /// EIP-155 chain ID to encode the address using EIP-1191.
178 chain_id: Option<u64>,
179 },
180
181 /// Convert hex data to an ASCII string.
182 #[command(visible_aliases = &["--to-ascii", "tas", "2as"])]
183 ToAscii {
184 /// The hex data to convert.
185 hexdata: Option<String>,
186 },
187
188 /// Convert hex data to a utf-8 string.
189 #[command(visible_aliases = &["--to-utf8", "tu8", "2u8"])]
190 ToUtf8 {
191 /// The hex data to convert.
192 hexdata: Option<String>,
193 },
194
195 /// Convert a fixed point number into an integer.
196 #[command(visible_aliases = &["--from-fix", "ff"])]
197 FromFixedPoint {
198 /// The number of decimals to use.
199 decimals: Option<String>,
200
201 /// The value to convert.
202 #[arg(allow_hyphen_values = true)]
203 value: Option<String>,
204 },
205
206 /// Right-pads hex data to 32 bytes.
207 #[command(visible_aliases = &["--to-bytes32", "tb", "2b"])]
208 ToBytes32 {
209 /// The hex data to convert.
210 bytes: Option<String>,
211 },
212
213 /// Convert hex data to the word-aligned layout of a Solidity `bytes memory` value.
214 ///
215 /// The output contains a 32-byte length prefix followed by the data, right-padded with zeros
216 /// to a whole number of 32-byte words.
217 #[command(visible_alias = "tbm")]
218 ToBytesMemory {
219 /// The hex data to convert.
220 data: Option<String>,
221 },
222
223 /// Pads hex data to a specified length.
224 #[command(visible_aliases = &["pd"])]
225 Pad {
226 /// The hex data to pad.
227 data: Option<String>,
228
229 /// Right-pad the data (instead of left-pad).
230 #[arg(long)]
231 right: bool,
232
233 /// Left-pad the data (default).
234 #[arg(long, conflicts_with = "right")]
235 left: bool,
236
237 /// Target length in bytes (default: 32).
238 #[arg(long, default_value = "32")]
239 len: usize,
240 },
241
242 /// Convert an integer into a fixed point number.
243 #[command(visible_aliases = &["--to-fix", "tf", "2f"])]
244 ToFixedPoint {
245 /// The number of decimals to use.
246 decimals: Option<String>,
247
248 /// The value to convert.
249 #[arg(allow_hyphen_values = true)]
250 value: Option<String>,
251 },
252
253 /// Convert a number to a hex-encoded uint256.
254 #[command(name = "to-uint256", visible_aliases = &["--to-uint256", "tu", "2u"])]
255 ToUint256 {
256 /// The value to convert.
257 value: Option<String>,
258 },
259
260 /// Convert a number to a hex-encoded int256.
261 #[command(name = "to-int256", visible_aliases = &["--to-int256", "ti", "2i"])]
262 ToInt256 {
263 /// The value to convert.
264 value: Option<String>,
265 },
266
267 /// Convert an ETH amount into another unit (ether, gwei or wei)
268 ///
269 /// Examples:
270 /// - 1ether wei
271 /// - "1 ether" wei
272 /// - 1ether
273 /// - 1 gwei
274 /// - 1gwei ether
275 #[command(verbatim_doc_comment, visible_aliases = &["--to-unit", "tun", "2un"])]
276 ToUnit {
277 /// The value to convert.
278 value: Option<String>,
279
280 /// The unit to convert to (ether, gwei, wei).
281 #[arg(default_value = "wei")]
282 unit: String,
283 },
284
285 /// Convert a number from decimal to smallest unit with arbitrary decimals
286 ///
287 /// Examples:
288 /// - 1.0 6 (for USDC, result: 1000000)
289 /// - 2.5 12 (for 12 decimals token, result: 2500000000000)
290 /// - 1.23 3 (for 3 decimals token, result: 1230)
291 #[command(verbatim_doc_comment, visible_aliases = &["--parse-units", "pun"])]
292 ParseUnits {
293 /// The value to convert.
294 value: Option<String>,
295
296 /// The unit to convert to.
297 #[arg(default_value = "18")]
298 unit: u8,
299 },
300
301 /// Format a number from smallest unit to decimal with arbitrary decimals
302 ///
303 /// Examples:
304 /// - 1000000 6 (for USDC, result: 1.0)
305 /// - 2500000000000 12 (for 12 decimals, result: 2.5)
306 /// - 1230 3 (for 3 decimals, result: 1.23)
307 #[command(verbatim_doc_comment, visible_aliases = &["--format-units", "fun"])]
308 FormatUnits {
309 /// The value to format.
310 value: Option<String>,
311
312 /// The unit to format to.
313 #[arg(default_value = "18")]
314 unit: u8,
315 },
316
317 /// Convert an ETH amount to wei.
318 ///
319 /// Consider using --to-unit.
320 #[command(visible_aliases = &["--to-wei", "tw", "2w"])]
321 ToWei {
322 /// The value to convert.
323 #[arg(allow_hyphen_values = true)]
324 value: Option<String>,
325
326 /// The unit to convert from (ether, gwei, wei).
327 #[arg(default_value = "eth")]
328 unit: String,
329 },
330
331 /// Convert wei into an ETH amount.
332 ///
333 /// Consider using --to-unit.
334 #[command(visible_aliases = &["--from-wei", "fw"])]
335 FromWei {
336 /// The value to convert.
337 #[arg(allow_hyphen_values = true)]
338 value: Option<String>,
339
340 /// The unit to convert from (ether, gwei, wei).
341 #[arg(default_value = "eth")]
342 unit: String,
343 },
344
345 /// RLP encodes hex data, or an array of hex data
346 ///
347 /// Accepts a hex-encoded string, or an array of hex-encoded strings.
348 /// Can be arbitrarily recursive.
349 ///
350 /// Examples:
351 /// - `cast to-rlp "[]"` -> `0xc0`
352 /// - `cast to-rlp "0x22"` -> `0x22`
353 /// - `cast to-rlp "[\"0x61\"]"` -> `0xc161`
354 /// - `cast to-rlp "[\"0xf1\", \"f2\"]"` -> `0xc481f181f2`
355 #[command(verbatim_doc_comment, visible_aliases = &["--to-rlp"])]
356 ToRlp {
357 /// The value to convert.
358 ///
359 /// This is a hex-encoded string, or an array of hex-encoded strings.
360 /// Can be arbitrarily recursive.
361 value: Option<String>,
362 },
363
364 /// Decodes RLP hex-encoded data.
365 #[command(visible_aliases = &["--from-rlp"])]
366 FromRlp {
367 /// The RLP hex-encoded data.
368 value: Option<String>,
369
370 /// Decode the RLP data as int
371 #[arg(long, alias = "int")]
372 as_int: bool,
373 },
374
375 /// Converts a number of one base to another
376 #[command(visible_aliases = &["--to-hex", "th", "2h"])]
377 ToHex(ToBaseArgs),
378
379 /// Converts a number of one base to decimal
380 #[command(visible_aliases = &["--to-dec", "td", "2d"])]
381 ToDec(ToBaseArgs),
382
383 /// Converts a number of one base to another
384 #[command(
385 visible_aliases = &["--to-base",
386 "--to-radix",
387 "to-radix",
388 "tr",
389 "2r"]
390 )]
391 ToBase {
392 #[command(flatten)]
393 base: ToBaseArgs,
394
395 /// The output base.
396 #[arg(value_name = "BASE")]
397 base_out: Option<String>,
398 },
399
400 /// Formats a string into bytes32 encoding.
401 #[command(name = "format-bytes32-string", visible_aliases = &["--format-bytes32-string"])]
402 FormatBytes32String {
403 /// The string to format.
404 string: Option<String>,
405 },
406
407 /// Parses a string from bytes32 encoding.
408 #[command(name = "parse-bytes32-string", visible_aliases = &["--parse-bytes32-string"])]
409 ParseBytes32String {
410 /// The string to parse.
411 bytes: Option<String>,
412 },
413
414 #[command(name = "parse-bytes32-address", visible_aliases = &["--parse-bytes32-address"])]
415 #[command(about = "Parses a checksummed address from bytes32 encoding.")]
416 ParseBytes32Address {
417 #[arg(value_name = "BYTES")]
418 bytes: Option<String>,
419 },
420}
421
422/// Call and transaction subcommands.
423#[derive(Subcommand)]
424pub enum TransactionSubcommand {
425 /// Perform a call on an account without publishing a transaction
426 ///
427 /// Examples:
428 /// - cast call $TOKEN "balanceOf(address)(uint256)" vitalik.eth
429 /// - cast call $TOKEN "transfer(address,uint256)" vitalik.eth 100 --trace
430 #[command(verbatim_doc_comment, visible_alias = "c")]
431 Call(CallArgs),
432
433 /// Build and sign a transaction
434 ///
435 /// Examples:
436 /// - cast mktx vitalik.eth --value 0.1ether --private-key $PK
437 /// - cast mktx $TOKEN "transfer(address,uint256)" vitalik.eth 100 --account dev
438 #[command(verbatim_doc_comment, name = "mktx", visible_alias = "m")]
439 MakeTx(MakeTxArgs),
440
441 /// Classify a raw transaction as Tempo T5 payment/general lane.
442 Classify {
443 /// The raw signed transaction.
444 raw_tx: Option<String>,
445 },
446
447 /// Get information about a transaction
448 ///
449 /// Examples:
450 /// - cast tx $TX_HASH
451 /// - cast tx $TX_HASH blockNumber (only print the blockNumber field)
452 /// - cast tx $TX_HASH --raw
453 #[command(verbatim_doc_comment, visible_alias = "t")]
454 Tx {
455 /// The transaction hash.
456 tx_hash: Option<String>,
457
458 /// The sender of the transaction.
459 #[arg(long, value_parser = NameOrAddress::from_str)]
460 from: Option<NameOrAddress>,
461
462 /// Nonce of the transaction.
463 #[arg(long)]
464 nonce: Option<u64>,
465
466 /// If specified, only get the given field of the transaction. If "raw", the RLP encoded
467 /// transaction will be printed.
468 field: Option<String>,
469
470 /// Print the raw RLP encoded transaction.
471 #[arg(long, conflicts_with = "field")]
472 raw: bool,
473
474 /// Classify the transaction as Tempo T5 payment/general lane.
475 #[arg(long, conflicts_with_all = ["field", "raw", "to_request"])]
476 lane: bool,
477
478 #[command(flatten)]
479 rpc: RpcOpts,
480
481 /// If specified, the transaction will be converted to a TransactionRequest JSON format.
482 #[arg(long)]
483 to_request: bool,
484
485 /// Specify the Network for correct encoding.
486 #[arg(long, short, num_args = 1, value_name = "NETWORK")]
487 network: Option<NetworkVariant>,
488 },
489
490 /// Get the transaction receipt for a transaction
491 ///
492 /// Examples:
493 /// - cast receipt $TX_HASH
494 /// - cast receipt $TX_HASH status (only print the status field)
495 #[command(verbatim_doc_comment, visible_alias = "re")]
496 Receipt {
497 /// The transaction hash.
498 tx_hash: String,
499
500 /// If specified, only get the given field of the transaction.
501 field: Option<String>,
502
503 /// The number of confirmations until the receipt is fetched
504 #[arg(long, default_value = "1")]
505 confirmations: u64,
506
507 /// Exit immediately if the transaction was not found.
508 #[arg(id = "async", long = "async", env = "CAST_ASYNC", alias = "cast-async")]
509 cast_async: bool,
510
511 #[command(flatten)]
512 rpc: RpcOpts,
513 },
514
515 /// Sign and publish a transaction
516 ///
517 /// Examples:
518 /// - cast send vitalik.eth --value 0.1ether --private-key $PK (transfer ETH)
519 /// - cast send $TOKEN "transfer(address,uint256)" vitalik.eth 100 --account dev
520 /// - cast send --private-key $PK --create $BYTECODE (deploy a contract)
521 #[command(verbatim_doc_comment, name = "send", visible_alias = "s")]
522 SendTx(SendTxArgs),
523
524 /// Build and sign a batch transaction (Tempo).
525 #[command(name = "batch-mktx", visible_alias = "bm")]
526 BatchMakeTx(BatchMakeTxArgs),
527
528 /// Sign and publish a batch transaction (Tempo).
529 #[command(name = "batch-send", visible_alias = "bs")]
530 BatchSend(BatchSendArgs),
531
532 /// Publish a raw transaction to the network.
533 #[command(name = "publish", visible_alias = "p")]
534 PublishTx {
535 /// The raw transaction
536 raw_tx: String,
537
538 /// Only print the transaction hash and exit immediately.
539 #[arg(id = "async", long = "async", env = "CAST_ASYNC", alias = "cast-async")]
540 cast_async: bool,
541
542 #[command(flatten)]
543 rpc: RpcOpts,
544 },
545
546 /// Estimate the gas cost of a transaction
547 ///
548 /// Examples:
549 /// - cast estimate vitalik.eth --value 0.1ether
550 /// - cast estimate $CONTRACT "deposit()" --value 1ether
551 #[command(verbatim_doc_comment, visible_alias = "e")]
552 Estimate(EstimateArgs),
553
554 /// Runs a published transaction in a local environment and prints the trace
555 ///
556 /// If the node serves an EIP-7928 block access list (BAL) for the transaction's block, the
557 /// transaction's prestate is read from it instead of replaying the earlier transactions of
558 /// the block. Pass `--no-bal` to always replay the block.
559 ///
560 /// Examples:
561 /// - cast run $TX_HASH
562 /// - cast run $TX_HASH --quick (only use the state from the previous block)
563 /// - cast run $TX_HASH --debug (open the transaction in the debugger)
564 #[command(verbatim_doc_comment, visible_alias = "r")]
565 Run(RunArgs),
566}
567
568/// ABI encoding and decoding, selector and contract artifact subcommands.
569#[derive(Subcommand)]
570pub enum AbiSubcommand {
571 /// ABI-encode a function with arguments.
572 #[command(name = "calldata", visible_alias = "cd")]
573 CalldataEncode {
574 /// The function signature in the format `<name>(<in-types>)(<out-types>)`
575 sig: String,
576
577 /// The arguments to encode.
578 #[arg(allow_hyphen_values = true)]
579 args: Vec<String>,
580
581 // Path to file containing arguments to encode.
582 #[arg(long, value_name = "PATH")]
583 file: Option<PathBuf>,
584 },
585
586 /// Decode ABI-encoded input data
587 ///
588 /// Similar to `abi-decode --input`, but function selector MUST be prefixed in `calldata`.
589 ///
590 /// Examples:
591 /// - cast decode-calldata "transfer(address,uint256)" $CALLDATA
592 /// - cast decode-calldata --json "transfer(address,uint256)" $CALLDATA
593 #[command(verbatim_doc_comment, visible_aliases = &["calldata-decode", "--calldata-decode", "cdd"])]
594 DecodeCalldata {
595 /// The function signature in the format `<name>(<in-types>)(<out-types>)`.
596 sig: String,
597
598 /// The ABI-encoded calldata.
599 #[arg(required_unless_present = "file", index = 2)]
600 calldata: Option<String>,
601
602 /// Load ABI-encoded calldata from a file instead.
603 #[arg(long = "file", short = 'f', conflicts_with = "calldata")]
604 file: Option<PathBuf>,
605 },
606
607 /// Decode ABI-encoded string.
608 ///
609 /// Similar to `calldata-decode --input`, but the function argument is a `string`
610 #[command(visible_aliases = &["string-decode", "--string-decode", "sd"])]
611 DecodeString {
612 /// The ABI-encoded string.
613 data: String,
614 },
615
616 /// Decode event data
617 ///
618 /// With `--sig`, DATA contains only the encoded non-indexed event data, without topics.
619 /// Pass `--topics` to also decode indexed parameters and print all parameters in declaration
620 /// order. Without topics, indexed parameters are skipped. Indexed arrays, tuples, strings,
621 /// and bytes are returned as hashes; their original values cannot be recovered.
622 ///
623 /// Examples:
624 /// - cast decode-event --sig "Transfer(address indexed from, address indexed to, uint256
625 /// value)" $DATA
626 /// - cast decode-event --sig "Transfer(address indexed from, address indexed to, uint256
627 /// value)" --topics $TOPIC0,$TOPIC1,$TOPIC2 $DATA
628 /// - cast decode-event $DATA (topic0-prefixed data; looks up the signature)
629 #[command(verbatim_doc_comment, visible_aliases = &["event-decode", "--event-decode", "ed"])]
630 DecodeEvent {
631 /// The event signature. If none provided then tries to decode from local cache or <https://4byte.sourcify.dev>.
632 #[arg(long, visible_alias = "event-sig")]
633 sig: Option<String>,
634 /// The event data to decode. Use 0x for events with only indexed parameters.
635 data: String,
636
637 /// The log topics, including topic0 for non-anonymous events, in log order.
638 ///
639 /// Repeat the flag or separate topics with commas. Requires --sig with indexed parameters
640 /// marked explicitly. Anonymous events do not have a signature topic.
641 #[arg(long, short = 't', value_delimiter = ',', requires = "sig")]
642 topics: Vec<B256>,
643 },
644
645 /// Decode custom error data.
646 #[command(visible_aliases = &["error-decode", "--error-decode", "erd"])]
647 DecodeError {
648 /// The error signature. If none provided then tries to decode from local cache or <https://4byte.sourcify.dev>.
649 #[arg(long, visible_alias = "error-sig")]
650 sig: Option<String>,
651 /// The error data to decode.
652 data: String,
653 },
654
655 /// Decode ABI-encoded input or output data
656 ///
657 /// Defaults to decoding output data. To decode input data pass --input.
658 ///
659 /// When passing `--input`, function selector must NOT be prefixed in `calldata` string.
660 ///
661 /// Examples:
662 /// - cast decode-abi "balanceOf(address)(uint256)" $DATA
663 /// - cast decode-abi --input "transfer(address,uint256)" $CALLDATA
664 #[command(verbatim_doc_comment, name = "decode-abi", visible_aliases = &["abi-decode", "--abi-decode", "ad"])]
665 DecodeAbi {
666 /// The function signature in the format `<name>(<in-types>)(<out-types>)`.
667 sig: String,
668
669 /// The ABI-encoded calldata.
670 calldata: String,
671
672 /// Whether to decode the input or output data.
673 #[arg(long, short, help_heading = "Decode input data instead of output data")]
674 input: bool,
675 },
676
677 /// ABI encode the given function argument, excluding the selector
678 ///
679 /// Examples:
680 /// - cast abi-encode "transfer(address,uint256)" $ADDRESS 100
681 /// - cast abi-encode --packed "f(string,uint64)" hello 100
682 #[command(verbatim_doc_comment, visible_alias = "ae")]
683 AbiEncode {
684 /// The function signature.
685 sig: String,
686
687 /// Whether to use packed encoding.
688 #[arg(long)]
689 packed: bool,
690
691 /// The arguments of the function.
692 #[arg(allow_hyphen_values = true)]
693 args: Vec<String>,
694 },
695
696 /// ABI encode an event and its arguments to generate topics and data.
697 #[command(visible_alias = "aee")]
698 AbiEncodeEvent {
699 /// The event signature.
700 sig: String,
701
702 /// The arguments of the event.
703 #[arg(allow_hyphen_values = true)]
704 args: Vec<String>,
705 },
706
707 /// Get the function signatures for the given selector from <https://4byte.sourcify.dev>.
708 #[command(name = "4byte", visible_aliases = &["4", "4b"])]
709 FourByte {
710 /// The function selector.
711 selector: Option<Selector>,
712 },
713
714 /// Decode ABI-encoded calldata using <https://4byte.sourcify.dev>.
715 #[command(name = "4byte-calldata", aliases = &["4byte-decode", "4d", "4bd"], visible_aliases = &["4c", "4bc"])]
716 FourByteCalldata {
717 /// The ABI-encoded calldata.
718 calldata: Option<String>,
719 },
720
721 /// Get the event signature for a given topic 0 from <https://4byte.sourcify.dev>.
722 #[command(name = "4byte-event", visible_aliases = &["4e", "4be", "topic0-event", "t0e"])]
723 FourByteEvent {
724 /// Topic 0
725 #[arg(value_name = "TOPIC_0")]
726 topic: Option<B256>,
727 },
728
729 /// Upload the given signatures to <https://4byte.sourcify.dev>.
730 ///
731 /// Example inputs:
732 /// - "transfer(address,uint256)"
733 /// - "function transfer(address,uint256)"
734 /// - "function transfer(address,uint256)" "event Transfer(address,address,uint256)"
735 /// - "./out/Contract.sol/Contract.json"
736 #[command(visible_aliases = &["ups"])]
737 UploadSignature {
738 /// The signatures to upload.
739 ///
740 /// Prefix with 'function', 'event', or 'error'. Defaults to function if no prefix given.
741 /// Can also take paths to contract artifact JSON.
742 signatures: Vec<String>,
743 },
744
745 /// Pretty print calldata.
746 ///
747 /// Tries to decode the calldata using <https://4byte.sourcify.dev> unless --offline is passed.
748 #[command(visible_alias = "pc")]
749 PrettyCalldata {
750 /// The calldata.
751 calldata: Option<String>,
752
753 /// Skip the <https://4byte.sourcify.dev> lookup.
754 #[arg(long, short)]
755 offline: bool,
756 },
757
758 /// Download a contract creation code from Etherscan and RPC.
759 #[command(visible_alias = "cc")]
760 CreationCode(CreationCodeArgs),
761
762 /// Generate an artifact file, that can be used to deploy a contract locally.
763 #[command(visible_alias = "ar")]
764 Artifact(ArtifactArgs),
765
766 /// Display constructor arguments used for the contract initialization.
767 #[command(visible_alias = "cra")]
768 ConstructorArgs(ConstructorArgsArgs),
769
770 /// Generate a Solidity interface from a given ABI
771 ///
772 /// Currently does not support ABI encoder v2.
773 ///
774 /// Examples:
775 /// - cast interface $TOKEN --etherscan-api-key $KEY (fetch the ABI from Etherscan)
776 /// - cast interface ./out/Counter.sol/Counter.json (load a local ABI file)
777 #[command(verbatim_doc_comment, visible_alias = "i")]
778 Interface(InterfaceArgs),
779
780 /// Generate a rust binding from a given ABI.
781 #[command(visible_alias = "bi")]
782 Bind(BindArgs),
783
784 /// Convert Beacon payload to execution payload.
785 #[command(visible_alias = "b2e")]
786 B2EPayload(B2EPayloadArgs),
787
788 /// Get the selector for a function
789 ///
790 /// Examples:
791 /// - cast sig "transfer(address,uint256)"
792 /// - cast sig "deposit(uint256)" 2 (optimize for 2 leading zero bytes)
793 #[command(verbatim_doc_comment, visible_alias = "si")]
794 Sig {
795 /// The function signature, e.g. transfer(address,uint256).
796 sig: Option<String>,
797
798 /// Optimize signature to contain provided amount of leading zeroes in selector.
799 #[arg(conflicts_with = "json")]
800 optimize: Option<usize>,
801 },
802}
803
804/// Blockchain, RPC and ENS query subcommands.
805#[derive(Subcommand)]
806#[allow(clippy::large_enum_variant, reason = "parsed once per process")]
807pub enum QuerySubcommand {
808 /// Create an access list for a transaction
809 ///
810 /// Examples:
811 /// - cast access-list vitalik.eth --value 0.1ether
812 /// - cast access-list $TOKEN "transfer(address,uint256)" vitalik.eth 100
813 #[command(verbatim_doc_comment, visible_aliases = &["ac", "acl"])]
814 AccessList(AccessListArgs),
815
816 /// Get information about a block
817 ///
818 /// Examples:
819 /// - cast block latest
820 /// - cast block 21000000 --field timestamp
821 /// - cast block latest --json
822 #[command(verbatim_doc_comment, visible_alias = "bl")]
823 Block {
824 /// The block height to query at.
825 ///
826 /// Can also be the tags earliest, finalized, safe, latest, or pending.
827 block: Option<BlockId>,
828
829 /// If specified, only get the given field of the block.
830 #[arg(short, long = "field", aliases = ["fields"], num_args = 0.., action = ArgAction::Append, value_delimiter = ',')]
831 fields: Vec<String>,
832
833 /// Print the raw RLP encoded block header.
834 #[arg(long, conflicts_with = "fields")]
835 raw: bool,
836
837 #[arg(long, env = "CAST_FULL_BLOCK")]
838 full: bool,
839
840 #[command(flatten)]
841 rpc: RpcOpts,
842
843 /// Specify the Network for correct encoding.
844 #[arg(long, short, num_args = 1, value_name = "NETWORK")]
845 network: Option<NetworkVariant>,
846 },
847
848 /// Get the latest block number.
849 #[command(visible_alias = "bn")]
850 BlockNumber {
851 /// The hash or tag to query. If not specified, the latest number is returned.
852 block: Option<BlockId>,
853 #[command(flatten)]
854 rpc: RpcOpts,
855 },
856
857 /// Get the EIP-7928 block access list of a block
858 ///
859 /// Examples:
860 /// - cast bal latest
861 /// - cast bal 21000000 --raw
862 #[command(verbatim_doc_comment, visible_alias = "block-access-list")]
863 Bal(BalArgs),
864
865 /// Get the symbolic name of the current chain.
866 Chain {
867 #[command(flatten)]
868 rpc: RpcOpts,
869 },
870
871 /// Get the Ethereum chain ID.
872 #[command(visible_aliases = &["ci", "cid"])]
873 ChainId {
874 #[command(flatten)]
875 rpc: RpcOpts,
876 },
877
878 /// Get the current client version.
879 #[command(visible_alias = "cl")]
880 Client {
881 #[command(flatten)]
882 rpc: RpcOpts,
883 },
884
885 /// Compute the contract address from a given nonce and deployer address.
886 #[command(visible_alias = "ca")]
887 ComputeAddress {
888 /// The deployer address.
889 address: Option<Address>,
890
891 /// The nonce of the deployer address.
892 #[arg(
893 long,
894 conflicts_with = "salt",
895 conflicts_with = "init_code",
896 conflicts_with = "init_code_hash"
897 )]
898 nonce: Option<u64>,
899
900 /// The salt for CREATE2 address computation.
901 #[arg(long, conflicts_with = "nonce")]
902 salt: Option<B256>,
903
904 /// The init code for CREATE2 address computation.
905 #[arg(
906 long,
907 requires = "salt",
908 conflicts_with = "init_code_hash",
909 conflicts_with = "nonce"
910 )]
911 init_code: Option<String>,
912
913 /// The init code hash for CREATE2 address computation.
914 #[arg(long, requires = "salt", conflicts_with = "init_code", conflicts_with = "nonce")]
915 init_code_hash: Option<B256>,
916
917 #[command(flatten)]
918 rpc: RpcOpts,
919 },
920
921 /// Disassembles a hex-encoded bytecode into a human-readable representation.
922 #[command(visible_alias = "da")]
923 Disassemble {
924 /// The hex-encoded bytecode.
925 bytecode: Option<String>,
926 },
927
928 /// Calculate the ENS namehash of a name.
929 #[command(visible_aliases = &["na", "nh"])]
930 Namehash { name: Option<String> },
931
932 /// Compute the storage slot for an entry in a mapping.
933 #[command(visible_alias = "in")]
934 Index {
935 /// The mapping key type.
936 key_type: String,
937
938 /// The mapping key.
939 key: String,
940
941 /// The storage slot of the mapping.
942 slot_number: String,
943 },
944
945 /// Compute storage slots as specified by `ERC-7201: Namespaced Storage Layout`.
946 #[command(name = "index-erc7201", alias = "index-erc-7201", visible_aliases = &["index7201", "in7201"])]
947 IndexErc7201 {
948 /// The arbitrary identifier.
949 id: Option<String>,
950 /// The formula ID. Currently the only supported formula is `erc7201`.
951 #[arg(long, default_value = "erc7201")]
952 formula_id: String,
953 },
954
955 /// Fetch the EIP-1967 implementation for a contract
956 /// Can read from the implementation slot or the beacon slot.
957 #[command(visible_alias = "impl")]
958 Implementation {
959 /// The block height to query at.
960 ///
961 /// Can also be the tags earliest, finalized, safe, latest, or pending.
962 #[arg(long, short = 'B')]
963 block: Option<BlockId>,
964
965 /// Fetch the implementation from the beacon slot.
966 ///
967 /// If not specified, the implementation slot is used.
968 #[arg(long)]
969 beacon: bool,
970
971 /// The address for which the implementation will be fetched.
972 #[arg(value_parser = NameOrAddress::from_str)]
973 who: NameOrAddress,
974
975 #[command(flatten)]
976 rpc: RpcOpts,
977 },
978
979 /// Fetch the EIP-1967 admin account
980 #[command(visible_alias = "adm")]
981 Admin {
982 /// The block height to query at.
983 ///
984 /// Can also be the tags earliest, finalized, safe, latest, or pending.
985 #[arg(long, short = 'B')]
986 block: Option<BlockId>,
987
988 /// The address from which the admin account will be fetched.
989 #[arg(value_parser = NameOrAddress::from_str)]
990 who: NameOrAddress,
991
992 #[command(flatten)]
993 rpc: RpcOpts,
994 },
995
996 /// Get the timestamp of a block.
997 #[command(visible_alias = "a")]
998 Age {
999 /// The block height to query at.
1000 ///
1001 /// Can also be the tags earliest, finalized, safe, latest, or pending.
1002 block: Option<BlockId>,
1003
1004 #[command(flatten)]
1005 rpc: RpcOpts,
1006 },
1007
1008 /// Get the balance of an account in wei
1009 ///
1010 /// Examples:
1011 /// - cast balance vitalik.eth --ether
1012 /// - cast balance vitalik.eth --erc20 0x6B175474E89094C44Da98b954EedeAC495271d0F
1013 #[command(verbatim_doc_comment, visible_alias = "b")]
1014 Balance {
1015 /// The block height to query at.
1016 ///
1017 /// Can also be the tags earliest, finalized, safe, latest, or pending.
1018 #[arg(long, short = 'B')]
1019 block: Option<BlockId>,
1020
1021 /// The account to query.
1022 #[arg(value_parser = NameOrAddress::from_str)]
1023 who: NameOrAddress,
1024
1025 /// Format the balance in ether.
1026 #[arg(long, short)]
1027 ether: bool,
1028
1029 #[command(flatten)]
1030 rpc: RpcOpts,
1031
1032 /// erc20 address to query, with the method `balanceOf(address) return (uint256)`, alias
1033 /// with '--erc721'
1034 #[arg(long, alias = "erc721")]
1035 erc20: Option<Address>,
1036
1037 #[command(flatten)]
1038 overrides: CallOverrideOpts,
1039 },
1040
1041 /// Get the basefee of a block.
1042 #[command(visible_aliases = &["ba", "fee", "basefee"])]
1043 BaseFee {
1044 /// The block height to query at.
1045 ///
1046 /// Can also be the tags earliest, finalized, safe, latest, or pending.
1047 block: Option<BlockId>,
1048
1049 #[command(flatten)]
1050 rpc: RpcOpts,
1051 },
1052
1053 /// Get the runtime bytecode of a contract
1054 ///
1055 /// Examples:
1056 /// - cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
1057 /// - cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --disassemble
1058 #[command(verbatim_doc_comment, visible_alias = "co")]
1059 Code {
1060 /// The block height to query at.
1061 ///
1062 /// Can also be the tags earliest, finalized, safe, latest, or pending.
1063 #[arg(long, short = 'B')]
1064 block: Option<BlockId>,
1065
1066 /// The contract address.
1067 #[arg(value_parser = NameOrAddress::from_str)]
1068 who: NameOrAddress,
1069
1070 /// Disassemble bytecodes.
1071 #[arg(long, short)]
1072 disassemble: bool,
1073
1074 #[command(flatten)]
1075 rpc: RpcOpts,
1076 },
1077
1078 /// Get the runtime bytecode size of a contract.
1079 #[command(visible_alias = "cs")]
1080 Codesize {
1081 /// The block height to query at.
1082 ///
1083 /// Can also be the tags earliest, finalized, safe, latest, or pending.
1084 #[arg(long, short = 'B')]
1085 block: Option<BlockId>,
1086
1087 /// The contract address.
1088 #[arg(value_parser = NameOrAddress::from_str)]
1089 who: NameOrAddress,
1090
1091 #[command(flatten)]
1092 rpc: RpcOpts,
1093 },
1094
1095 /// Get the current gas price.
1096 #[command(visible_alias = "g")]
1097 GasPrice {
1098 #[command(flatten)]
1099 rpc: RpcOpts,
1100 },
1101
1102 /// Perform an ENS lookup.
1103 #[command(visible_alias = "rn")]
1104 ResolveName {
1105 /// The name to lookup.
1106 who: Option<String>,
1107
1108 /// Perform a reverse lookup to verify that the name is correct.
1109 #[arg(long)]
1110 verify: bool,
1111
1112 #[command(flatten)]
1113 rpc: RpcOpts,
1114 },
1115
1116 /// Perform an ENS reverse lookup.
1117 #[command(visible_alias = "la")]
1118 LookupAddress {
1119 /// The account to perform the lookup for.
1120 who: Option<Address>,
1121
1122 /// Perform a normal lookup to verify that the address is correct.
1123 #[arg(long)]
1124 verify: bool,
1125
1126 #[command(flatten)]
1127 rpc: RpcOpts,
1128 },
1129
1130 /// Get the raw value of a contract's storage slot
1131 ///
1132 /// Examples:
1133 /// - cast storage 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 0
1134 /// - cast storage $TOKEN --etherscan-api-key $KEY (decode the full storage layout)
1135 #[command(verbatim_doc_comment, visible_alias = "st")]
1136 Storage(StorageArgs),
1137
1138 /// Generate a storage proof for a given storage slot.
1139 #[command(visible_alias = "pr")]
1140 Proof {
1141 /// The contract address.
1142 #[arg(value_parser = NameOrAddress::from_str)]
1143 address: NameOrAddress,
1144
1145 /// The storage slot numbers (hex or decimal).
1146 #[arg(value_parser = parse_slot)]
1147 slots: Vec<B256>,
1148
1149 /// The block height to query at.
1150 ///
1151 /// Can also be the tags earliest, finalized, safe, latest, or pending.
1152 #[arg(long, short = 'B')]
1153 block: Option<BlockId>,
1154
1155 #[command(flatten)]
1156 rpc: RpcOpts,
1157 },
1158
1159 /// Get the nonce for an account.
1160 #[command(visible_alias = "n")]
1161 Nonce {
1162 /// The block height to query at.
1163 ///
1164 /// Can also be the tags earliest, finalized, safe, latest, or pending.
1165 #[arg(long, short = 'B')]
1166 block: Option<BlockId>,
1167
1168 /// The address to get the nonce for.
1169 #[arg(value_parser = NameOrAddress::from_str)]
1170 who: NameOrAddress,
1171
1172 #[command(flatten)]
1173 rpc: RpcOpts,
1174 },
1175
1176 /// Get the codehash for an account.
1177 #[command()]
1178 Codehash {
1179 /// The block height to query at.
1180 ///
1181 /// Can also be the tags earliest, finalized, safe, latest, or pending.
1182 #[arg(long, short = 'B')]
1183 block: Option<BlockId>,
1184
1185 /// The address to get the codehash for.
1186 #[arg(value_parser = NameOrAddress::from_str)]
1187 who: NameOrAddress,
1188
1189 /// The storage slot numbers (hex or decimal).
1190 #[arg(value_parser = parse_slot)]
1191 slots: Vec<B256>,
1192
1193 #[command(flatten)]
1194 rpc: RpcOpts,
1195 },
1196
1197 /// Get the storage root for an account.
1198 #[command(visible_alias = "sr")]
1199 StorageRoot {
1200 /// The block height to query at.
1201 ///
1202 /// Can also be the tags earliest, finalized, safe, latest, or pending.
1203 #[arg(long, short = 'B')]
1204 block: Option<BlockId>,
1205
1206 /// The address to get the storage root for.
1207 #[arg(value_parser = NameOrAddress::from_str)]
1208 who: NameOrAddress,
1209
1210 /// The storage slot numbers (hex or decimal).
1211 #[arg(value_parser = parse_slot)]
1212 slots: Vec<B256>,
1213
1214 #[command(flatten)]
1215 rpc: RpcOpts,
1216 },
1217
1218 /// Compute a Tempo TIP-20 channel reserve channel ID.
1219 #[command(name = "channel-id")]
1220 ChannelId {
1221 /// Channel payer address.
1222 #[arg(value_parser = NameOrAddress::from_str)]
1223 payer: NameOrAddress,
1224
1225 /// Channel payee address.
1226 #[arg(value_parser = NameOrAddress::from_str)]
1227 payee: NameOrAddress,
1228
1229 /// TIP-20 token address locked by the channel.
1230 #[arg(value_parser = NameOrAddress::from_str)]
1231 token: NameOrAddress,
1232
1233 /// User-supplied channel salt.
1234 salt: B256,
1235
1236 /// Optional relayer allowed to submit settlements for the payee.
1237 #[arg(long, value_parser = NameOrAddress::from_str)]
1238 operator: Option<NameOrAddress>,
1239
1240 /// Optional voucher signer. Defaults to the zero address, meaning the payer signs.
1241 #[arg(long, value_parser = NameOrAddress::from_str)]
1242 authorized_signer: Option<NameOrAddress>,
1243
1244 /// Transaction-derived expiring nonce hash from ChannelOpened.
1245 #[arg(long, default_value_t = B256::ZERO)]
1246 expiring_nonce_hash: B256,
1247
1248 /// Channel reserve precompile address.
1249 #[arg(long, value_parser = NameOrAddress::from_str)]
1250 reserve: Option<NameOrAddress>,
1251
1252 /// The block height to query at.
1253 ///
1254 /// Can also be the tags earliest, finalized, safe, latest, or pending.
1255 #[arg(long, short = 'B')]
1256 block: Option<BlockId>,
1257
1258 #[command(flatten)]
1259 rpc: RpcOpts,
1260 },
1261
1262 /// Get the block number closest to the provided timestamp.
1263 #[command(visible_alias = "f")]
1264 FindBlock(FindBlockArgs),
1265
1266 /// Perform a raw JSON-RPC request
1267 ///
1268 /// Examples:
1269 /// - cast rpc eth_blockNumber
1270 /// - cast rpc eth_getBlockByNumber 0x123 false
1271 /// - cast rpc eth_getBlockByNumber '["0x123", false]' --raw
1272 #[command(verbatim_doc_comment, visible_alias = "rp")]
1273 Rpc(RpcArgs),
1274
1275 /// Extracts function selectors and arguments from bytecode
1276 #[command(visible_alias = "sel")]
1277 Selectors {
1278 /// The hex-encoded bytecode.
1279 bytecode: Option<String>,
1280
1281 /// Resolve the function signatures for the extracted selectors using <https://4byte.sourcify.dev>
1282 #[arg(long, short)]
1283 resolve: bool,
1284 },
1285}
1286
1287/// Miscellaneous subcommands.
1288#[derive(Subcommand)]
1289pub enum MiscSubcommand {
1290 /// Perform a left shifting operation
1291 #[command(name = "shl")]
1292 LeftShift {
1293 /// The value to shift.
1294 value: String,
1295
1296 /// The number of bits to shift.
1297 bits: String,
1298
1299 /// The input base.
1300 #[arg(long)]
1301 base_in: Option<String>,
1302
1303 /// The output base.
1304 #[arg(long, default_value = "16")]
1305 base_out: String,
1306 },
1307
1308 /// Perform a right shifting operation
1309 #[command(name = "shr")]
1310 RightShift {
1311 /// The value to shift.
1312 value: String,
1313
1314 /// The number of bits to shift.
1315 bits: String,
1316
1317 /// The input base,
1318 #[arg(long)]
1319 base_in: Option<String>,
1320
1321 /// The output base,
1322 #[arg(long, default_value = "16")]
1323 base_out: String,
1324 },
1325
1326 /// Get logs by signature or topic
1327 ///
1328 /// Event declarations decode matching logs in text output. Indexed parameters must be marked
1329 /// `indexed` in the declaration. JSON output remains raw.
1330 ///
1331 /// Examples:
1332 /// - cast logs "Transfer(address indexed from, address indexed to, uint256 value)"
1333 /// - cast logs --address $TOKEN --from-block 21000000 --to-block latest $TOPIC_0
1334 #[command(verbatim_doc_comment, visible_alias = "l")]
1335 Logs(LogsArgs),
1336
1337 /// Fetch and decode events from a transaction receipt or log filter.
1338 ///
1339 /// Examples:
1340 /// - cast events $TX_HASH
1341 /// - cast events --tx-hash $TX_HASH
1342 /// - cast events --address $TOKEN --from-block 21000000 --to-block latest
1343 /// - cast events --address $TOKEN "Transfer(address indexed,address indexed,uint256)"
1344 ///
1345 /// A lone 32-byte positional value is treated as a transaction hash. Qualify a raw topic with
1346 /// an address, block range, additional topic, or query size.
1347 #[command(verbatim_doc_comment, visible_alias = "ev")]
1348 Events(EventsArgs),
1349
1350 /// Generate event signatures from event string.
1351 #[command(visible_alias = "se")]
1352 SigEvent {
1353 /// The event string.
1354 event_string: Option<String>,
1355 },
1356
1357 /// Hash arbitrary data using Keccak-256
1358 ///
1359 /// Examples:
1360 /// - cast keccak "hello world"
1361 /// - cast keccak 0xdeadbeef
1362 /// - echo -n "some data" | cast keccak (hash data from stdin)
1363 #[command(verbatim_doc_comment, visible_aliases = &["k", "keccak256"])]
1364 Keccak {
1365 /// The data to hash.
1366 data: Option<String>,
1367 },
1368
1369 /// Hash a message according to EIP-191.
1370 #[command(visible_aliases = &["--hash-message", "hm"])]
1371 HashMessage {
1372 /// The message to hash.
1373 message: Option<String>,
1374 },
1375
1376 /// Get the source code of a contract from a block explorer.
1377 #[command(visible_aliases = &["et", "src"])]
1378 Source {
1379 /// The contract's address.
1380 address: String,
1381
1382 /// Whether to flatten the source code.
1383 #[arg(long, short)]
1384 flatten: bool,
1385
1386 /// The output directory/file to expand source tree into.
1387 #[arg(short, value_hint = ValueHint::DirPath, alias = "path")]
1388 directory: Option<PathBuf>,
1389
1390 #[command(flatten)]
1391 etherscan: EtherscanOpts,
1392
1393 /// Alternative explorer API URL to use that adheres to the Etherscan API. If not provided,
1394 /// defaults to Etherscan.
1395 #[arg(long, env = "EXPLORER_API_URL")]
1396 explorer_api_url: Option<String>,
1397
1398 /// Alternative explorer browser URL.
1399 #[arg(long, env = "EXPLORER_URL")]
1400 explorer_url: Option<String>,
1401 },
1402
1403 /// Wallet management utilities.
1404 #[command(visible_alias = "w")]
1405 Wallet {
1406 #[command(subcommand)]
1407 command: WalletSubcommands,
1408 },
1409
1410 /// Create, propose, and sign Safe transactions.
1411 Safe {
1412 #[command(subcommand)]
1413 command: SafeSubcommand,
1414 },
1415
1416 /// Generate a deterministic contract address using CREATE2.
1417 #[command(visible_alias = "c2")]
1418 Create2(Create2Args),
1419
1420 /// Generate shell completions script.
1421 #[command(visible_alias = "com")]
1422 Completions {
1423 #[arg(value_enum)]
1424 shell: foundry_cli::clap::Shell,
1425 },
1426
1427 /// Decodes a raw signed EIP 2718 typed transaction
1428 #[command(visible_aliases = &["dt", "decode-tx"])]
1429 DecodeTransaction {
1430 /// Encoded transaction
1431 tx: Option<String>,
1432
1433 /// Override the network used to decode the transaction.
1434 ///
1435 /// By default, cast decodes with Foundry's transaction envelope, which recognizes
1436 /// standard Ethereum txs and Foundry-supported network-specific tx types such as Tempo.
1437 #[arg(long, short, num_args = 1, value_name = "NETWORK")]
1438 network: Option<NetworkVariant>,
1439 },
1440
1441 /// Recovery an EIP-7702 authority from a Authorization JSON string.
1442 #[command(visible_aliases = &["decode-auth"])]
1443 RecoverAuthority { auth: String },
1444
1445 /// Inspect the TxPool of a node.
1446 #[command(visible_alias = "tp")]
1447 TxPool {
1448 #[command(subcommand)]
1449 command: TxPoolSubcommands,
1450 },
1451
1452 /// Estimates the data availability size of a given opstack block.
1453 #[cfg(any(feature = "base", feature = "optimism"))]
1454 #[command(name = "da-estimate")]
1455 DAEstimate(DAEstimateArgs),
1456
1457 /// ERC20 token operations.
1458 #[command(visible_alias = "erc20")]
1459 Erc20Token {
1460 #[command(subcommand)]
1461 command: Erc20Subcommand,
1462 },
1463
1464 /// ERC-4626 tokenized vault operations.
1465 #[command(name = "erc4626", visible_alias = "vault")]
1466 Erc4626 {
1467 #[command(subcommand)]
1468 command: Erc4626Subcommand,
1469 },
1470
1471 /// TIP-20 token operations (Tempo).
1472 #[command(visible_alias = "tip20")]
1473 Tip20Token {
1474 #[command(subcommand)]
1475 command: Tip20Subcommand,
1476 },
1477
1478 /// Account-level receive policy operations (Tempo).
1479 #[command(name = "receive-policy")]
1480 ReceivePolicy {
1481 #[command(subcommand)]
1482 command: ReceivePolicySubcommand,
1483 },
1484
1485 /// TIP-403 policy registry operations (Tempo).
1486 #[command(name = "tip403")]
1487 Tip403 {
1488 #[command(subcommand)]
1489 command: Tip403Subcommand,
1490 },
1491
1492 /// T7 storage credits operations (Tempo).
1493 #[command(name = "storage-credits", visible_alias = "sc")]
1494 StorageCredits {
1495 #[command(subcommand)]
1496 command: StorageCreditsSubcommand,
1497 },
1498
1499 /// Tempo keychain (access key) management.
1500 #[command(visible_alias = "kc")]
1501 Keychain {
1502 #[command(subcommand)]
1503 command: KeychainSubcommand,
1504 },
1505
1506 /// Tempo key authorization RLP helpers.
1507 #[command(name = "key-authorization", visible_alias = "key-auth")]
1508 KeyAuthorization {
1509 #[command(subcommand)]
1510 command: KeyAuthorizationSubcommand,
1511 },
1512
1513 /// Tempo wallet and zone operations.
1514 Tempo(TempoArgs),
1515
1516 /// TIP-1022 virtual address registry operations (Tempo).
1517 #[command(visible_alias = "vaddr")]
1518 VirtualAddress {
1519 #[command(subcommand)]
1520 command: VaddrSubcommand,
1521 },
1522
1523 #[command(name = "trace")]
1524 Trace(TraceArgs),
1525}
1526
1527/// CLI arguments for `cast --to-base`.
1528#[derive(Debug, Parser)]
1529pub struct ToBaseArgs {
1530 /// The value to convert.
1531 #[arg(allow_hyphen_values = true)]
1532 pub value: Option<String>,
1533
1534 /// The input base.
1535 #[arg(long, short = 'i')]
1536 pub base_in: Option<String>,
1537}
1538
1539pub fn parse_slot(s: &str) -> Result<B256> {
1540 let slot = U256::from_str(s).map_err(|e| eyre::eyre!("Could not parse slot number: {e}"))?;
1541 Ok(B256::from(slot))
1542}
1543
1544#[cfg(test)]
1545mod tests {
1546 use super::*;
1547 use clap::CommandFactory;
1548
1549 #[test]
1550 fn verify_cli() {
1551 Cast::command().debug_assert();
1552 }
1553
1554 #[test]
1555 fn parse_proof_slot() {
1556 let args: Cast = Cast::parse_from([
1557 "foundry-cli",
1558 "proof",
1559 "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
1560 "0",
1561 "1",
1562 "0x0000000000000000000000000000000000000000000000000000000000000000",
1563 "0x1",
1564 "0x01",
1565 ]);
1566 match args.cmd {
1567 CastSubcommand::Query(QuerySubcommand::Proof { slots, .. }) => {
1568 assert_eq!(
1569 slots,
1570 vec![
1571 B256::ZERO,
1572 U256::ONE.into(),
1573 B256::ZERO,
1574 U256::ONE.into(),
1575 U256::ONE.into()
1576 ]
1577 );
1578 }
1579 _ => unreachable!(),
1580 };
1581 }
1582
1583 #[test]
1584 fn parse_call_data() {
1585 let args: Cast = Cast::parse_from([
1586 "foundry-cli",
1587 "calldata",
1588 "f()",
1589 "5c9d55b78febcc2061715ba4f57ecf8ea2711f2c",
1590 "2",
1591 ]);
1592 match args.cmd {
1593 CastSubcommand::Abi(AbiSubcommand::CalldataEncode { args, .. }) => {
1594 assert_eq!(
1595 args,
1596 vec!["5c9d55b78febcc2061715ba4f57ecf8ea2711f2c".to_string(), "2".to_string()]
1597 )
1598 }
1599 _ => unreachable!(),
1600 };
1601 }
1602
1603 #[test]
1604 fn parse_call_data_with_file() {
1605 let args: Cast = Cast::parse_from(["foundry-cli", "calldata", "f()", "--file", "test.txt"]);
1606 match args.cmd {
1607 CastSubcommand::Abi(AbiSubcommand::CalldataEncode { sig, file, args }) => {
1608 assert_eq!(sig, "f()".to_string());
1609 assert_eq!(file, Some(PathBuf::from("test.txt")));
1610 assert!(args.is_empty());
1611 }
1612 _ => unreachable!(),
1613 };
1614 }
1615
1616 // <https://github.com/foundry-rs/book/issues/1019>
1617 #[test]
1618 fn parse_signature() {
1619 let args: Cast = Cast::parse_from([
1620 "foundry-cli",
1621 "sig",
1622 "__$_$__$$$$$__$$_$$$_$$__$$___$$(address,address,uint256)",
1623 ]);
1624 match args.cmd {
1625 CastSubcommand::Abi(AbiSubcommand::Sig { sig, .. }) => {
1626 let sig = sig.unwrap();
1627 assert_eq!(
1628 sig,
1629 "__$_$__$$$$$__$$_$$$_$$__$$___$$(address,address,uint256)".to_string()
1630 );
1631
1632 let selector = foundry_common::abi::get_func(&sig).unwrap().selector();
1633 assert_eq!(selector.to_string(), "0x23b872dd");
1634 }
1635 _ => unreachable!(),
1636 };
1637 }
1638}