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