Skip to content

Commit

Permalink
feat(cast): add cast --to-int256 (gakonst#677)
Browse files Browse the repository at this point in the history
* feat: to_int256 function + doctests

* fix: handle larger int256 values

* chore: remove import

* feat: add to cli

* refactor: use more idiomatic rust

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
  • Loading branch information
0xTomoyo and gakonst authored Feb 5, 2022
1 parent 2bb8896 commit 9c69b49
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 1 deletion.
2 changes: 1 addition & 1 deletion cast/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
- [x] `--to-fix`
- [x] `--to-hex`
- [x] `--to-hexdata`
- [ ] `--to-int256`
- [x] `--to-int256`
- [x] `--to-uint256`
- [x] `--to-wei`
- [x] `4byte`
Expand Down
38 changes: 38 additions & 0 deletions cast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,44 @@ impl SimpleCast {
Ok(format!("0x{}{}", "0".repeat(64 - num_hex.len()), num_hex))
}

/// Converts a number into int256 hex string with 0x prefix
///
/// ```
/// use cast::SimpleCast as Cast;
///
/// fn main() -> eyre::Result<()> {
/// assert_eq!(Cast::to_int256("0")?, "0x0000000000000000000000000000000000000000000000000000000000000000");
/// assert_eq!(Cast::to_int256("100")?, "0x0000000000000000000000000000000000000000000000000000000000000064");
/// assert_eq!(Cast::to_int256("-100")?, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c");
/// assert_eq!(Cast::to_int256("192038293923")?, "0x0000000000000000000000000000000000000000000000000000002cb65fd1a3");
/// assert_eq!(Cast::to_int256("-192038293923")?, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffd349a02e5d");
/// assert_eq!(
/// Cast::to_int256("57896044618658097711785492504343953926634992332820282019728792003956564819967")?,
/// "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
/// );
/// assert_eq!(
/// Cast::to_int256("-57896044618658097711785492504343953926634992332820282019728792003956564819968")?,
/// "0x8000000000000000000000000000000000000000000000000000000000000000"
/// );
///
/// Ok(())
/// }
/// ```
pub fn to_int256(value: &str) -> Result<String> {
let (sign, value) = match value.as_bytes().get(0) {
Some(b'+') => (Sign::Positive, &value[1..]),
Some(b'-') => (Sign::Negative, &value[1..]),
_ => (Sign::Positive, value),
};

let mut num = U256::from_str_radix(value, 10)?;
if matches!(sign, Sign::Negative) {
num = (!num).overflowing_add(U256::one()).0;
}
let num_hex = format!("{:x}", num);
Ok(format!("0x{}{}", "0".repeat(64 - num_hex.len()), num_hex))
}

/// Converts an eth amount into a specified unit
///
/// ```
Expand Down
1 change: 1 addition & 0 deletions cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ SUBCOMMANDS:
- absolute path to file
- @tag, where $TAG is defined in environment variables
--to-uint256 convert a number into uint256 hex string with 0x prefix
--to-int256 convert a number into int256 hex string with 0x prefix
--to-wei convert an ETH amount into wei
4byte Fetches function signatures given the selector from 4byte.directory
4byte-decode Decodes transaction calldata by fetching the signature using 4byte.directory
Expand Down
4 changes: 4 additions & 0 deletions cli/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ async fn main() -> eyre::Result<()> {
let val = unwrap_or_stdin(value)?;
println!("{}", SimpleCast::to_uint256(&val)?);
}
Subcommands::ToInt256 { value } => {
let val = unwrap_or_stdin(value)?;
println!("{}", SimpleCast::to_int256(&val)?);
}
Subcommands::ToUnit { value, unit } => {
let val = unwrap_or_stdin(value)?;
println!("{}", SimpleCast::to_unit(val, unit.unwrap_or_else(|| String::from("wei")))?);
Expand Down
3 changes: 3 additions & 0 deletions cli/src/opts/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ pub enum Subcommands {
#[clap(name = "--to-uint256")]
#[clap(about = "convert a number into uint256 hex string with 0x prefix")]
ToUint256 { value: Option<String> },
#[clap(name = "--to-int256")]
#[clap(about = "convert a number into int256 hex string with 0x prefix")]
ToInt256 { value: Option<String> },
#[clap(name = "--to-unit")]
#[clap(
about = r#"convert an ETH amount into a specified unit: ether, gwei or wei (default: wei).
Expand Down

0 comments on commit 9c69b49

Please sign in to comment.