1use crate::{
2 Cast, SimpleCast,
3 opts::{Cast as CastArgs, CastSubcommand, ToBaseArgs},
4 traces::identifier::SignaturesIdentifier,
5};
6use alloy_consensus::transaction::{Recovered, SignerRecoverable};
7use alloy_dyn_abi::{DynSolValue, ErrorExt, EventExt};
8use alloy_eips::eip7702::SignedAuthorization;
9use alloy_ens::{ProviderEnsExt, namehash};
10use alloy_primitives::{Address, B256, eip191_hash_message, hex, keccak256};
11use alloy_provider::Provider;
12use alloy_rpc_types::{BlockId, BlockNumberOrTag::Latest};
13use clap::{CommandFactory, Parser};
14use clap_complete::generate;
15use eyre::Result;
16use foundry_cli::{utils, utils::LoadConfig};
17use foundry_common::{
18 abi::{get_error, get_event},
19 fmt::{format_tokens, format_uint_exp, serialize_value_as_json},
20 fs,
21 selectors::{
22 ParsedSignatures, SelectorImportData, SelectorKind, decode_calldata, decode_event_topic,
23 decode_function_selector, decode_selectors, import_selectors, parse_signatures,
24 pretty_calldata,
25 },
26 shell, stdin,
27};
28use std::time::Instant;
29
30pub fn run() -> Result<()> {
32 setup()?;
33
34 let args = CastArgs::parse();
35 args.global.init()?;
36 args.global.tokio_runtime().block_on(run_command(args))
37}
38
39pub fn setup() -> Result<()> {
41 utils::common_setup();
42 utils::subscriber();
43
44 Ok(())
45}
46
47pub async fn run_command(args: CastArgs) -> Result<()> {
49 match args.cmd {
50 CastSubcommand::MaxInt { r#type } => {
52 sh_println!("{}", SimpleCast::max_int(&r#type)?)?;
53 }
54 CastSubcommand::MinInt { r#type } => {
55 sh_println!("{}", SimpleCast::min_int(&r#type)?)?;
56 }
57 CastSubcommand::MaxUint { r#type } => {
58 sh_println!("{}", SimpleCast::max_int(&r#type)?)?;
59 }
60 CastSubcommand::AddressZero => {
61 sh_println!("{:?}", Address::ZERO)?;
62 }
63 CastSubcommand::HashZero => {
64 sh_println!("{:?}", B256::ZERO)?;
65 }
66
67 CastSubcommand::FromUtf8 { text } => {
69 let value = stdin::unwrap(text, false)?;
70 sh_println!("{}", SimpleCast::from_utf8(&value))?
71 }
72 CastSubcommand::ToAscii { hexdata } => {
73 let value = stdin::unwrap(hexdata, false)?;
74 sh_println!("{}", SimpleCast::to_ascii(value.trim())?)?
75 }
76 CastSubcommand::ToUtf8 { hexdata } => {
77 let value = stdin::unwrap(hexdata, false)?;
78 sh_println!("{}", SimpleCast::to_utf8(&value)?)?
79 }
80 CastSubcommand::FromFixedPoint { value, decimals } => {
81 let (value, decimals) = stdin::unwrap2(value, decimals)?;
82 sh_println!("{}", SimpleCast::from_fixed_point(&value, &decimals)?)?
83 }
84 CastSubcommand::ToFixedPoint { value, decimals } => {
85 let (value, decimals) = stdin::unwrap2(value, decimals)?;
86 sh_println!("{}", SimpleCast::to_fixed_point(&value, &decimals)?)?
87 }
88 CastSubcommand::ConcatHex { data } => {
89 if data.is_empty() {
90 let s = stdin::read(true)?;
91 sh_println!("{}", SimpleCast::concat_hex(s.split_whitespace()))?
92 } else {
93 sh_println!("{}", SimpleCast::concat_hex(data))?
94 }
95 }
96 CastSubcommand::FromBin => {
97 let hex = stdin::read_bytes(false)?;
98 sh_println!("{}", hex::encode_prefixed(hex))?
99 }
100 CastSubcommand::ToHexdata { input } => {
101 let value = stdin::unwrap_line(input)?;
102 let output = match value {
103 s if s.starts_with('@') => hex::encode(std::env::var(&s[1..])?),
104 s if s.starts_with('/') => hex::encode(fs::read(s)?),
105 s => s.split(':').map(|s| s.trim_start_matches("0x").to_lowercase()).collect(),
106 };
107 sh_println!("0x{output}")?
108 }
109 CastSubcommand::ToCheckSumAddress { address, chain_id } => {
110 let value = stdin::unwrap_line(address)?;
111 sh_println!("{}", value.to_checksum(chain_id))?
112 }
113 CastSubcommand::ToUint256 { value } => {
114 let value = stdin::unwrap_line(value)?;
115 sh_println!("{}", SimpleCast::to_uint256(&value)?)?
116 }
117 CastSubcommand::ToInt256 { value } => {
118 let value = stdin::unwrap_line(value)?;
119 sh_println!("{}", SimpleCast::to_int256(&value)?)?
120 }
121 CastSubcommand::ToUnit { value, unit } => {
122 let value = stdin::unwrap_line(value)?;
123 sh_println!("{}", SimpleCast::to_unit(&value, &unit)?)?
124 }
125 CastSubcommand::ParseUnits { value, unit } => {
126 let value = stdin::unwrap_line(value)?;
127 sh_println!("{}", SimpleCast::parse_units(&value, unit)?)?;
128 }
129 CastSubcommand::FormatUnits { value, unit } => {
130 let value = stdin::unwrap_line(value)?;
131 sh_println!("{}", SimpleCast::format_units(&value, unit)?)?;
132 }
133 CastSubcommand::FromWei { value, unit } => {
134 let value = stdin::unwrap_line(value)?;
135 sh_println!("{}", SimpleCast::from_wei(&value, &unit)?)?
136 }
137 CastSubcommand::ToWei { value, unit } => {
138 let value = stdin::unwrap_line(value)?;
139 sh_println!("{}", SimpleCast::to_wei(&value, &unit)?)?
140 }
141 CastSubcommand::FromRlp { value, as_int } => {
142 let value = stdin::unwrap_line(value)?;
143 sh_println!("{}", SimpleCast::from_rlp(value, as_int)?)?
144 }
145 CastSubcommand::ToRlp { value } => {
146 let value = stdin::unwrap_line(value)?;
147 sh_println!("{}", SimpleCast::to_rlp(&value)?)?
148 }
149 CastSubcommand::ToHex(ToBaseArgs { value, base_in }) => {
150 let value = stdin::unwrap_line(value)?;
151 sh_println!("{}", SimpleCast::to_base(&value, base_in.as_deref(), "hex")?)?
152 }
153 CastSubcommand::ToDec(ToBaseArgs { value, base_in }) => {
154 let value = stdin::unwrap_line(value)?;
155 sh_println!("{}", SimpleCast::to_base(&value, base_in.as_deref(), "dec")?)?
156 }
157 CastSubcommand::ToBase { base: ToBaseArgs { value, base_in }, base_out } => {
158 let (value, base_out) = stdin::unwrap2(value, base_out)?;
159 sh_println!("{}", SimpleCast::to_base(&value, base_in.as_deref(), &base_out)?)?
160 }
161 CastSubcommand::ToBytes32 { bytes } => {
162 let value = stdin::unwrap_line(bytes)?;
163 sh_println!("{}", SimpleCast::to_bytes32(&value)?)?
164 }
165 CastSubcommand::Pad { data, right, left: _, len } => {
166 let value = stdin::unwrap_line(data)?;
167 sh_println!("{}", SimpleCast::pad(&value, right, len)?)?
168 }
169 CastSubcommand::FormatBytes32String { string } => {
170 let value = stdin::unwrap_line(string)?;
171 sh_println!("{}", SimpleCast::format_bytes32_string(&value)?)?
172 }
173 CastSubcommand::ParseBytes32String { bytes } => {
174 let value = stdin::unwrap_line(bytes)?;
175 sh_println!("{}", SimpleCast::parse_bytes32_string(&value)?)?
176 }
177 CastSubcommand::ParseBytes32Address { bytes } => {
178 let value = stdin::unwrap_line(bytes)?;
179 sh_println!("{}", SimpleCast::parse_bytes32_address(&value)?)?
180 }
181
182 CastSubcommand::DecodeAbi { sig, calldata, input } => {
184 let tokens = SimpleCast::abi_decode(&sig, &calldata, input)?;
185 print_tokens(&tokens);
186 }
187 CastSubcommand::AbiEncode { sig, packed, args } => {
188 if !packed {
189 sh_println!("{}", SimpleCast::abi_encode(&sig, &args)?)?
190 } else {
191 sh_println!("{}", SimpleCast::abi_encode_packed(&sig, &args)?)?
192 }
193 }
194 CastSubcommand::AbiEncodeEvent { sig, args } => {
195 let log_data = SimpleCast::abi_encode_event(&sig, &args)?;
196 for (i, topic) in log_data.topics().iter().enumerate() {
197 sh_println!("[topic{}]: {}", i, topic)?;
198 }
199 if !log_data.data.is_empty() {
200 sh_println!("[data]: {}", hex::encode_prefixed(log_data.data))?;
201 }
202 }
203 CastSubcommand::DecodeCalldata { sig, calldata, file } => {
204 let raw_hex = if let Some(file_path) = file {
205 let contents = fs::read_to_string(&file_path)?;
206 contents.trim().to_string()
207 } else {
208 calldata.unwrap()
209 };
210
211 let tokens = SimpleCast::calldata_decode(&sig, &raw_hex, true)?;
212 print_tokens(&tokens);
213 }
214 CastSubcommand::CalldataEncode { sig, args, file } => {
215 let final_args = if let Some(file_path) = file {
216 let contents = fs::read_to_string(file_path)?;
217 contents
218 .lines()
219 .map(str::trim)
220 .filter(|line| !line.is_empty())
221 .map(String::from)
222 .collect()
223 } else {
224 args
225 };
226 sh_println!("{}", SimpleCast::calldata_encode(sig, &final_args)?)?;
227 }
228 CastSubcommand::DecodeString { data } => {
229 let tokens = SimpleCast::calldata_decode("Any(string)", &data, true)?;
230 print_tokens(&tokens);
231 }
232 CastSubcommand::DecodeEvent { sig, data } => {
233 let decoded_event = if let Some(event_sig) = sig {
234 let event = get_event(event_sig.as_str())?;
235 event.decode_log_parts(core::iter::once(event.selector()), &hex::decode(data)?)?
236 } else {
237 let data = data.strip_prefix("0x").unwrap_or(data.as_str());
238 let selector = data.get(..64).unwrap_or_default();
239 let selector = selector.parse()?;
240 let identified_event =
241 SignaturesIdentifier::new(false)?.identify_event(selector).await;
242 if let Some(event) = identified_event {
243 let _ = sh_println!("{}", event.signature());
244 let data = data.get(64..).unwrap_or_default();
245 get_event(event.signature().as_str())?
246 .decode_log_parts(core::iter::once(selector), &hex::decode(data)?)?
247 } else {
248 eyre::bail!("No matching event signature found for selector `{selector}`")
249 }
250 };
251 print_tokens(&decoded_event.body);
252 }
253 CastSubcommand::DecodeError { sig, data } => {
254 let error = if let Some(err_sig) = sig {
255 get_error(err_sig.as_str())?
256 } else {
257 let data = data.strip_prefix("0x").unwrap_or(data.as_str());
258 let selector = data.get(..8).unwrap_or_default();
259 let identified_error =
260 SignaturesIdentifier::new(false)?.identify_error(selector.parse()?).await;
261 if let Some(error) = identified_error {
262 let _ = sh_println!("{}", error.signature());
263 error
264 } else {
265 eyre::bail!("No matching error signature found for selector `{selector}`")
266 }
267 };
268 let decoded_error = error.decode_error(&hex::decode(data)?)?;
269 print_tokens(&decoded_error.body);
270 }
271 CastSubcommand::Interface(cmd) => cmd.run().await?,
272 CastSubcommand::CreationCode(cmd) => cmd.run().await?,
273 CastSubcommand::ConstructorArgs(cmd) => cmd.run().await?,
274 CastSubcommand::Artifact(cmd) => cmd.run().await?,
275 CastSubcommand::Bind(cmd) => cmd.run().await?,
276 CastSubcommand::PrettyCalldata { calldata, offline } => {
277 let calldata = stdin::unwrap_line(calldata)?;
278 sh_println!("{}", pretty_calldata(&calldata, offline).await?)?;
279 }
280 CastSubcommand::Sig { sig, optimize } => {
281 let sig = stdin::unwrap_line(sig)?;
282 match optimize {
283 Some(opt) => {
284 sh_println!("Starting to optimize signature...")?;
285 let start_time = Instant::now();
286 let (selector, signature) = SimpleCast::get_selector(&sig, opt)?;
287 sh_println!("Successfully generated in {:?}", start_time.elapsed())?;
288 sh_println!("Selector: {selector}")?;
289 sh_println!("Optimized signature: {signature}")?;
290 }
291 None => sh_println!("{}", SimpleCast::get_selector(&sig, 0)?.0)?,
292 }
293 }
294
295 CastSubcommand::AccessList(cmd) => cmd.run().await?,
297 CastSubcommand::Age { block, rpc } => {
298 let config = rpc.load_config()?;
299 let provider = utils::get_provider(&config)?;
300 sh_println!(
301 "{} UTC",
302 Cast::new(provider).age(block.unwrap_or(BlockId::Number(Latest))).await?
303 )?
304 }
305 CastSubcommand::Balance { block, who, ether, rpc, erc20 } => {
306 let config = rpc.load_config()?;
307 let provider = utils::get_provider(&config)?;
308 let account_addr = who.resolve(&provider).await?;
309
310 match erc20 {
311 Some(token) => {
312 let balance =
313 Cast::new(&provider).erc20_balance(token, account_addr, block).await?;
314 sh_println!("{}", format_uint_exp(balance))?
315 }
316 None => {
317 let value = Cast::new(&provider).balance(account_addr, block).await?;
318 if ether {
319 sh_println!("{}", SimpleCast::from_wei(&value.to_string(), "eth")?)?
320 } else {
321 sh_println!("{value}")?
322 }
323 }
324 }
325 }
326 CastSubcommand::BaseFee { block, rpc } => {
327 let config = rpc.load_config()?;
328 let provider = utils::get_provider(&config)?;
329 sh_println!(
330 "{}",
331 Cast::new(provider).base_fee(block.unwrap_or(BlockId::Number(Latest))).await?
332 )?
333 }
334 CastSubcommand::Block { block, full, field, raw, rpc } => {
335 let config = rpc.load_config()?;
336 let provider = utils::get_provider(&config)?;
337
338 let raw = raw || field.as_ref().is_some_and(|f| f == "raw");
340
341 sh_println!(
342 "{}",
343 Cast::new(provider)
344 .block(block.unwrap_or(BlockId::Number(Latest)), full, field, raw)
345 .await?
346 )?
347 }
348 CastSubcommand::BlockNumber { rpc, block } => {
349 let config = rpc.load_config()?;
350 let provider = utils::get_provider(&config)?;
351 let number = match block {
352 Some(id) => {
353 provider
354 .get_block(id)
355 .await?
356 .ok_or_else(|| eyre::eyre!("block {id:?} not found"))?
357 .header
358 .number
359 }
360 None => Cast::new(provider).block_number().await?,
361 };
362 sh_println!("{number}")?
363 }
364 CastSubcommand::Chain { rpc } => {
365 let config = rpc.load_config()?;
366 let provider = utils::get_provider(&config)?;
367 sh_println!("{}", Cast::new(provider).chain().await?)?
368 }
369 CastSubcommand::ChainId { rpc } => {
370 let config = rpc.load_config()?;
371 let provider = utils::get_provider(&config)?;
372 sh_println!("{}", Cast::new(provider).chain_id().await?)?
373 }
374 CastSubcommand::Client { rpc } => {
375 let config = rpc.load_config()?;
376 let provider = utils::get_provider(&config)?;
377 sh_println!("{}", provider.get_client_version().await?)?
378 }
379 CastSubcommand::Code { block, who, disassemble, rpc } => {
380 let config = rpc.load_config()?;
381 let provider = utils::get_provider(&config)?;
382 let who = who.resolve(&provider).await?;
383 sh_println!("{}", Cast::new(provider).code(who, block, disassemble).await?)?
384 }
385 CastSubcommand::Codesize { block, who, rpc } => {
386 let config = rpc.load_config()?;
387 let provider = utils::get_provider(&config)?;
388 let who = who.resolve(&provider).await?;
389 sh_println!("{}", Cast::new(provider).codesize(who, block).await?)?
390 }
391 CastSubcommand::ComputeAddress { address, nonce, salt, init_code, init_code_hash, rpc } => {
392 let address = stdin::unwrap_line(address)?;
393 let computed = {
394 if let Some(init_code_hash) = init_code_hash {
396 address.create2(salt.unwrap_or(B256::ZERO), init_code_hash)
397 } else if let Some(init_code) = init_code {
398 address.create2(salt.unwrap_or(B256::ZERO), keccak256(hex::decode(init_code)?))
399 } else {
400 let config = rpc.load_config()?;
402 let provider = utils::get_provider(&config)?;
403 Cast::new(provider).compute_address(address, nonce).await?
404 }
405 };
406 sh_println!("Computed Address: {}", computed.to_checksum(None))?
407 }
408 CastSubcommand::Disassemble { bytecode } => {
409 let bytecode = stdin::unwrap_line(bytecode)?;
410 sh_println!("{}", SimpleCast::disassemble(&hex::decode(bytecode)?)?)?
411 }
412 CastSubcommand::Selectors { bytecode, resolve } => {
413 let bytecode = stdin::unwrap_line(bytecode)?;
414 let functions = SimpleCast::extract_functions(&bytecode)?;
415 let max_args_len = functions.iter().map(|r| r.1.len()).max().unwrap_or(0);
416 let max_mutability_len = functions.iter().map(|r| r.2.len()).max().unwrap_or(0);
417
418 let resolve_results = if resolve {
419 let selectors = functions
420 .iter()
421 .map(|&(selector, ..)| SelectorKind::Function(selector))
422 .collect::<Vec<_>>();
423 let ds = decode_selectors(&selectors).await?;
424 ds.into_iter().map(|v| v.join("|")).collect()
425 } else {
426 vec![]
427 };
428 for (pos, (selector, arguments, state_mutability)) in functions.into_iter().enumerate()
429 {
430 if resolve {
431 let resolved = &resolve_results[pos];
432 sh_println!(
433 "{selector}\t{arguments:max_args_len$}\t{state_mutability:max_mutability_len$}\t{resolved}"
434 )?
435 } else {
436 sh_println!("{selector}\t{arguments:max_args_len$}\t{state_mutability}")?
437 }
438 }
439 }
440 CastSubcommand::FindBlock(cmd) => cmd.run().await?,
441 CastSubcommand::GasPrice { rpc } => {
442 let config = rpc.load_config()?;
443 let provider = utils::get_provider(&config)?;
444 sh_println!("{}", Cast::new(provider).gas_price().await?)?;
445 }
446 CastSubcommand::Index { key_type, key, slot_number } => {
447 sh_println!("{}", SimpleCast::index(&key_type, &key, &slot_number)?)?;
448 }
449 CastSubcommand::IndexErc7201 { id, formula_id } => {
450 eyre::ensure!(formula_id == "erc7201", "unsupported formula ID: {formula_id}");
451 let id = stdin::unwrap_line(id)?;
452 sh_println!("{}", foundry_common::erc7201(&id))?;
453 }
454 CastSubcommand::Implementation { block, beacon, who, rpc } => {
455 let config = rpc.load_config()?;
456 let provider = utils::get_provider(&config)?;
457 let who = who.resolve(&provider).await?;
458 sh_println!("{}", Cast::new(provider).implementation(who, beacon, block).await?)?;
459 }
460 CastSubcommand::Admin { block, who, rpc } => {
461 let config = rpc.load_config()?;
462 let provider = utils::get_provider(&config)?;
463 let who = who.resolve(&provider).await?;
464 sh_println!("{}", Cast::new(provider).admin(who, block).await?)?;
465 }
466 CastSubcommand::Nonce { block, who, rpc } => {
467 let config = rpc.load_config()?;
468 let provider = utils::get_provider(&config)?;
469 let who = who.resolve(&provider).await?;
470 sh_println!("{}", Cast::new(provider).nonce(who, block).await?)?;
471 }
472 CastSubcommand::Codehash { block, who, slots, rpc } => {
473 let config = rpc.load_config()?;
474 let provider = utils::get_provider(&config)?;
475 let who = who.resolve(&provider).await?;
476 sh_println!("{}", Cast::new(provider).codehash(who, slots, block).await?)?;
477 }
478 CastSubcommand::StorageRoot { block, who, slots, rpc } => {
479 let config = rpc.load_config()?;
480 let provider = utils::get_provider(&config)?;
481 let who = who.resolve(&provider).await?;
482 sh_println!("{}", Cast::new(provider).storage_root(who, slots, block).await?)?;
483 }
484 CastSubcommand::Proof { address, slots, rpc, block } => {
485 let config = rpc.load_config()?;
486 let provider = utils::get_provider(&config)?;
487 let address = address.resolve(&provider).await?;
488 let value = provider
489 .get_proof(address, slots.into_iter().collect())
490 .block_id(block.unwrap_or_default())
491 .await?;
492 sh_println!("{}", serde_json::to_string(&value)?)?;
493 }
494 CastSubcommand::Rpc(cmd) => cmd.run().await?,
495 CastSubcommand::Storage(cmd) => cmd.run().await?,
496
497 CastSubcommand::Call(cmd) => cmd.run().await?,
499 CastSubcommand::Estimate(cmd) => cmd.run().await?,
500 CastSubcommand::MakeTx(cmd) => cmd.run().await?,
501 CastSubcommand::PublishTx { raw_tx, cast_async, rpc } => {
502 let config = rpc.load_config()?;
503 let provider = utils::get_provider(&config)?;
504 let cast = Cast::new(&provider);
505 let pending_tx = cast.publish(raw_tx).await?;
506 let tx_hash = pending_tx.inner().tx_hash();
507
508 if cast_async {
509 sh_println!("{tx_hash:#x}")?;
510 } else {
511 let receipt = pending_tx.get_receipt().await?;
512 sh_println!("{}", serde_json::json!(receipt))?;
513 }
514 }
515 CastSubcommand::Receipt { tx_hash, field, cast_async, confirmations, rpc } => {
516 let config = rpc.load_config()?;
517 let provider = utils::get_provider(&config)?;
518 sh_println!(
519 "{}",
520 Cast::new(provider)
521 .receipt(tx_hash, field, confirmations, None, cast_async)
522 .await?
523 )?
524 }
525 CastSubcommand::Run(cmd) => cmd.run().await?,
526 CastSubcommand::SendTx(cmd) => cmd.run().await?,
527 CastSubcommand::Tx { tx_hash, from, nonce, field, raw, rpc, to_request } => {
528 let config = rpc.load_config()?;
529 let provider = utils::get_provider(&config)?;
530
531 let raw = raw || field.as_ref().is_some_and(|f| f == "raw");
533
534 sh_println!(
535 "{}",
536 Cast::new(&provider)
537 .transaction(tx_hash, from, nonce, field, raw, to_request)
538 .await?
539 )?
540 }
541
542 CastSubcommand::FourByte { selector } => {
544 let selector = stdin::unwrap_line(selector)?;
545 let sigs = decode_function_selector(selector).await?;
546 if sigs.is_empty() {
547 eyre::bail!("No matching function signatures found for selector `{selector}`");
548 }
549 for sig in sigs {
550 sh_println!("{sig}")?
551 }
552 }
553
554 CastSubcommand::FourByteCalldata { calldata } => {
555 let calldata = stdin::unwrap_line(calldata)?;
556
557 if calldata.len() == 10 {
558 let sigs = decode_function_selector(calldata.parse()?).await?;
559 if sigs.is_empty() {
560 eyre::bail!("No matching function signatures found for calldata `{calldata}`");
561 }
562 for sig in sigs {
563 sh_println!("{sig}")?
564 }
565 return Ok(());
566 }
567
568 let sigs = decode_calldata(&calldata).await?;
569 sigs.iter().enumerate().for_each(|(i, sig)| {
570 let _ = sh_println!("{}) \"{sig}\"", i + 1);
571 });
572
573 let sig = match sigs.len() {
574 0 => eyre::bail!("No signatures found"),
575 1 => sigs.first().unwrap(),
576 _ => {
577 let i: usize = prompt!("Select a function signature by number: ")?;
578 sigs.get(i - 1).ok_or_else(|| eyre::eyre!("Invalid signature index"))?
579 }
580 };
581
582 let tokens = SimpleCast::calldata_decode(sig, &calldata, true)?;
583 print_tokens(&tokens);
584 }
585
586 CastSubcommand::FourByteEvent { topic } => {
587 let topic = stdin::unwrap_line(topic)?;
588 let sigs = decode_event_topic(topic).await?;
589 if sigs.is_empty() {
590 eyre::bail!("No matching event signatures found for topic `{topic}`");
591 }
592 for sig in sigs {
593 sh_println!("{sig}")?
594 }
595 }
596 CastSubcommand::UploadSignature { signatures } => {
597 let signatures = stdin::unwrap_vec(signatures)?;
598 let ParsedSignatures { signatures, abis } = parse_signatures(signatures);
599 if !abis.is_empty() {
600 import_selectors(SelectorImportData::Abi(abis)).await?.describe();
601 }
602 if !signatures.is_empty() {
603 import_selectors(SelectorImportData::Raw(signatures)).await?.describe();
604 }
605 }
606
607 CastSubcommand::Namehash { name } => {
609 let name = stdin::unwrap_line(name)?;
610 sh_println!("{}", namehash(&name))?
611 }
612 CastSubcommand::LookupAddress { who, rpc, verify } => {
613 let config = rpc.load_config()?;
614 let provider = utils::get_provider(&config)?;
615
616 let who = stdin::unwrap_line(who)?;
617 let name = provider.lookup_address(&who).await?;
618 if verify {
619 let address = provider.resolve_name(&name).await?;
620 eyre::ensure!(
621 address == who,
622 "Reverse lookup verification failed: got `{address}`, expected `{who}`"
623 );
624 }
625 sh_println!("{name}")?
626 }
627 CastSubcommand::ResolveName { who, rpc, verify } => {
628 let config = rpc.load_config()?;
629 let provider = utils::get_provider(&config)?;
630
631 let who = stdin::unwrap_line(who)?;
632 let address = provider.resolve_name(&who).await?;
633 if verify {
634 let name = provider.lookup_address(&address).await?;
635 eyre::ensure!(
636 name == who,
637 "Forward lookup verification failed: got `{name}`, expected `{who}`"
638 );
639 }
640 sh_println!("{address}")?
641 }
642
643 CastSubcommand::Keccak { data } => {
645 let bytes = match data {
646 Some(data) => data.into_bytes(),
647 None => stdin::read_bytes(false)?,
648 };
649 match String::from_utf8(bytes) {
650 Ok(s) => {
651 let s = SimpleCast::keccak(&s)?;
652 sh_println!("{s}")?
653 }
654 Err(e) => {
655 let hash = keccak256(e.as_bytes());
656 let s = hex::encode(hash);
657 sh_println!("0x{s}")?
658 }
659 };
660 }
661 CastSubcommand::HashMessage { message } => {
662 let message = stdin::unwrap(message, false)?;
663 sh_println!("{}", eip191_hash_message(message))?
664 }
665 CastSubcommand::SigEvent { event_string } => {
666 let event_string = stdin::unwrap_line(event_string)?;
667 let parsed_event = get_event(&event_string)?;
668 sh_println!("{:?}", parsed_event.selector())?
669 }
670 CastSubcommand::LeftShift { value, bits, base_in, base_out } => sh_println!(
671 "{}",
672 SimpleCast::left_shift(&value, &bits, base_in.as_deref(), &base_out)?
673 )?,
674 CastSubcommand::RightShift { value, bits, base_in, base_out } => sh_println!(
675 "{}",
676 SimpleCast::right_shift(&value, &bits, base_in.as_deref(), &base_out)?
677 )?,
678 CastSubcommand::Source {
679 address,
680 directory,
681 explorer_api_url,
682 explorer_url,
683 etherscan,
684 flatten,
685 } => {
686 let config = etherscan.load_config()?;
687 let chain = config.chain.unwrap_or_default();
688 let api_key = config.get_etherscan_api_key(Some(chain));
689 match (directory, flatten) {
690 (Some(dir), false) => {
691 SimpleCast::expand_etherscan_source_to_directory(
692 chain,
693 address,
694 api_key,
695 dir,
696 explorer_api_url,
697 explorer_url,
698 )
699 .await?
700 }
701 (None, false) => sh_println!(
702 "{}",
703 SimpleCast::etherscan_source(
704 chain,
705 address,
706 api_key,
707 explorer_api_url,
708 explorer_url
709 )
710 .await?
711 )?,
712 (dir, true) => {
713 SimpleCast::etherscan_source_flatten(
714 chain,
715 address,
716 api_key,
717 dir,
718 explorer_api_url,
719 explorer_url,
720 )
721 .await?;
722 }
723 }
724 }
725 CastSubcommand::Create2(cmd) => {
726 cmd.run()?;
727 }
728 CastSubcommand::Wallet { command } => command.run().await?,
729 CastSubcommand::Completions { shell } => {
730 generate(shell, &mut CastArgs::command(), "cast", &mut std::io::stdout())
731 }
732 CastSubcommand::GenerateFigSpec => clap_complete::generate(
733 clap_complete_fig::Fig,
734 &mut CastArgs::command(),
735 "cast",
736 &mut std::io::stdout(),
737 ),
738 CastSubcommand::Logs(cmd) => cmd.run().await?,
739 CastSubcommand::DecodeTransaction { tx } => {
740 let tx = stdin::unwrap_line(tx)?;
741 let tx = SimpleCast::decode_raw_transaction(&tx)?;
742
743 if let Ok(signer) = tx.recover_signer() {
744 let recovered = Recovered::new_unchecked(tx, signer);
745 sh_println!("{}", serde_json::to_string_pretty(&recovered)?)?;
746 } else {
747 sh_println!("{}", serde_json::to_string_pretty(&tx)?)?;
748 }
749 }
750 CastSubcommand::RecoverAuthority { auth } => {
751 let auth: SignedAuthorization = serde_json::from_str(&auth)?;
752 sh_println!("{}", auth.recover_authority()?)?;
753 }
754 CastSubcommand::TxPool { command } => command.run().await?,
755 CastSubcommand::DAEstimate(cmd) => {
756 cmd.run().await?;
757 }
758 };
759
760 fn print_tokens(tokens: &[DynSolValue]) {
765 if shell::is_json() {
766 let tokens: Vec<serde_json::Value> = tokens
767 .iter()
768 .cloned()
769 .map(serialize_value_as_json)
770 .collect::<Result<Vec<_>>>()
771 .unwrap();
772 let _ = sh_println!("{}", serde_json::to_string_pretty(&tokens).unwrap());
773 } else {
774 let tokens = format_tokens(tokens);
775 tokens.for_each(|t| {
776 let _ = sh_println!("{t}");
777 });
778 }
779 }
780
781 Ok(())
782}