From 425b88425b6d3ddf75f32973184e032d6c44dcfd Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Sun, 19 Sep 2021 17:10:44 -0400 Subject: [PATCH 01/17] Seth: --to-fix --- dapptools/src/seth.rs | 3 +++ dapptools/src/seth_opts.rs | 3 +++ seth/src/lib.rs | 25 +++++++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index 8da45e42f2af..6d898c54ea53 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -28,6 +28,9 @@ async fn main() -> eyre::Result<()> { Subcommands::ToBytes32 { bytes } => { println!("{}", SimpleSeth::to_bytes32(&bytes)?); } + Subcommands::ToFix { decimals, value } => { + println!("{}", SimpleSeth::to_fix(unwrap_or_stdin(decimals)?, unwrap_or_stdin(value)?)); + } Subcommands::Block { rpc_url, block, diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index c3b6871c6cd9..e897a7b2d051 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -23,6 +23,9 @@ pub enum Subcommands { #[structopt(name = "--to-bytes32")] #[structopt(about = "left-pads a hex bytes string to 32 bytes)")] ToBytes32 { bytes: String }, + #[structopt(name = "--to-fix")] + #[structopt(about = "convert integers into fixed point with specified decimals")] + ToFix { decimals: Option, value: Option }, #[structopt(name = "block")] #[structopt( about = "Prints information about . If is given, print only the value of that field" diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 815220ce8dcd..94a7848bdc5f 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -211,6 +211,31 @@ impl SimpleSeth { let s: String = s.as_bytes().to_hex(); format!("0x{}", s) } + + /// Converts integers with specified decimals into fixed point numbers + /// + /// ``` + /// use seth::SimpleSeth as Seth; + /// + /// assert_eq!(Seth::to_fix(0, 10), "10."); + /// assert_eq!(Seth::to_fix(1, 10), "1.0"); + /// assert_eq!(Seth::to_fix(2, 10), "0.10"); + /// assert_eq!(Seth::to_fix(3, 10), "0.010"); + /// ``` + pub fn to_fix(decimals: u128, value: u128) -> String { + let mut value: String = value.to_string(); + let decimals = decimals as usize; + + if decimals >= value.len() { + // {0}.{0 * (number_of_decimals - value.len())}{value} + format!("0.{:0>1$}", value, decimals) + } else { + // Insert decimal at -idx (i.e 1 => decimal idx = -1) + value.insert(value.len() - decimals, '.'); + value + } + } + /// Converts decimal input to hex /// /// ``` From 072670a48a67004f342df5e73f87c97b3bc98d75 Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Sun, 19 Sep 2021 17:31:11 -0400 Subject: [PATCH 02/17] Seth: block-number --- dapptools/src/seth.rs | 4 ++++ dapptools/src/seth_opts.rs | 6 ++++++ seth/src/lib.rs | 17 +++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index 6d898c54ea53..c4a3ec7a17d3 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -46,6 +46,10 @@ async fn main() -> eyre::Result<()> { .await? ); } + Subcommands::BlockNumber { rpc_url } => { + let provider = Provider::try_from(rpc_url)?; + println!("{}", Seth::new(provider).block_number().await?); + } Subcommands::Call { rpc_url, address, diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index e897a7b2d051..121c2007f669 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -41,6 +41,12 @@ pub enum Subcommands { #[structopt(long, env = "ETH_RPC_URL")] rpc_url: String, }, + #[structopt(name = "block-number")] + #[structopt(about = "returns latest block number")] + BlockNumber { + #[structopt(long, env = "ETH_RPC_URL")] + rpc_url: String, + }, #[structopt(name = "call")] #[structopt(about = "Perform a local call to without publishing a transaction.")] Call { diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 94a7848bdc5f..549f22666931 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -195,6 +195,23 @@ where Ok(block) } + + /// ```no_run + /// use seth::Seth; + /// use ethers_providers::{Provider, Http}; + /// use std::convert::TryFrom; + /// + /// # async fn foo() -> eyre::Result<()> { + /// let provider = Provider::::try_from("http://localhost:8545")?; + /// let seth = Seth::new(provider); + /// let latest_block_number = seth.block_number().await?; + /// println!("{}", latest_block_number); + /// # Ok(()) + /// # } + /// ``` + pub async fn block_number(&self) -> Result { + self.provider.get_block_number().await + } } pub struct SimpleSeth; From 08a856a87388febb3d4771ce9d34ebd94d74016d Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Sun, 19 Sep 2021 20:06:12 -0400 Subject: [PATCH 03/17] Seth: basefee --- dapptools/src/seth.rs | 16 +++++++++------- dapptools/src/seth_opts.rs | 8 ++++++++ seth/src/lib.rs | 31 +++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index c4a3ec7a17d3..4743ff5eeaf1 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -2,13 +2,7 @@ mod seth_opts; use seth_opts::{Opts, Subcommands}; use seth::{Seth, SimpleSeth}; - -use ethers::{ - middleware::SignerMiddleware, - providers::{Middleware, Provider}, - signers::Signer, - types::NameOrAddress, -}; +use ethers::{core::types::{BlockId, BlockNumber::{Latest}}, middleware::SignerMiddleware, providers::{Middleware, Provider}, signers::Signer, types::NameOrAddress}; use std::{convert::TryFrom, str::FromStr}; use structopt::StructOpt; @@ -78,6 +72,14 @@ async fn main() -> eyre::Result<()> { let provider = Provider::try_from(rpc_url)?; println!("{}", Seth::new(provider).balance(who, block).await?); } + Subcommands::BaseFee { + block, + rpc_url, + } => { + let provider = Provider::try_from(rpc_url)?; + println!("{}", Seth::new(provider).base_fee(block.unwrap_or(BlockId::Number(Latest))).await?); + } + Subcommands::ResolveName { who, rpc_url, diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index 121c2007f669..e3f701833caa 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -79,6 +79,14 @@ pub enum Subcommands { #[structopt(short, long, env = "ETH_RPC_URL")] rpc_url: String, }, + #[structopt(name = "basefee")] + #[structopt(about = "Print the block basefee")] + BaseFee { + #[structopt(global = true, help = "the block you want to query, can also be earliest/latest/pending", parse(try_from_str = parse_block_id))] + block: Option, + #[structopt(short, long, env = "ETH_RPC_URL")] + rpc_url: String, + }, #[structopt(name = "resolve-name")] #[structopt(about = "Returns the address the provided ENS name resolves to")] ResolveName { diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 549f22666931..3754c72b960c 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -134,6 +134,37 @@ where Ok::<_, eyre::Error>(res) } + /// ```no_run + /// use seth::Seth; + /// use ethers_providers::{Provider, Http}; + /// use std::convert::TryFrom; + /// + /// # async fn foo() -> eyre::Result<()> { + /// let provider = Provider::::try_from("http://localhost:8545")?; + /// let seth = Seth::new(provider); + /// let base_fee = seth.base_fee(13_000_000).await?; + /// println!("{}", base_fee); + /// # Ok(()) + /// # } + /// ``` + pub async fn base_fee>(&self, block: T) -> Result { + let block = block.into(); + let base_fee_hex = Seth::block( + &self, + block, + false, + // Select only baseFee field + Some(String::from("baseFeePerGas")), + false + ).await?; + let base_fee_num = U256::from_str_radix( + strip_0x(&base_fee_hex), + 16 + ).expect("Unable to convert baseFee hexadecimal to U256"); + + Ok(base_fee_num) + } + /// ```no_run /// use seth::Seth; /// use ethers_providers::{Provider, Http}; From 5470aadc6cf3a2e2b1f2e3f7e30f595a781730e1 Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Sun, 19 Sep 2021 20:19:07 -0400 Subject: [PATCH 04/17] Seth: chain-id --- dapptools/src/seth.rs | 4 ++++ dapptools/src/seth_opts.rs | 6 ++++++ seth/src/lib.rs | 21 ++++++--------------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index 4743ff5eeaf1..a0ab252b8f5a 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -53,6 +53,10 @@ async fn main() -> eyre::Result<()> { let provider = Provider::try_from(rpc_url)?; println!("{}", Seth::new(provider).call(address, &sig, args).await?); } + Subcommands::ChainId { rpc_url } => { + let provider = Provider::try_from(rpc_url)?; + println!("{}", Seth::new(provider).chain_id().await?); + } Subcommands::SendTx { eth, to, sig, args } => { let provider = Provider::try_from(eth.rpc_url.as_str())?; if let Some(signer) = eth.signer()? { diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index e3f701833caa..eaa87859479c 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -57,6 +57,12 @@ pub enum Subcommands { #[structopt(long, env = "ETH_RPC_URL")] rpc_url: String, }, + #[structopt(name = "chain-id")] + #[structopt(about = "returns ethereum chain id")] + ChainId { + #[structopt(long, env = "ETH_RPC_URL")] + rpc_url: String, + }, #[structopt(name = "send")] #[structopt(about = "Publish a transaction signed by to call with ")] SendTx { diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 3754c72b960c..52fc5ef9a4f8 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -227,21 +227,12 @@ where Ok(block) } - /// ```no_run - /// use seth::Seth; - /// use ethers_providers::{Provider, Http}; - /// use std::convert::TryFrom; - /// - /// # async fn foo() -> eyre::Result<()> { - /// let provider = Provider::::try_from("http://localhost:8545")?; - /// let seth = Seth::new(provider); - /// let latest_block_number = seth.block_number().await?; - /// println!("{}", latest_block_number); - /// # Ok(()) - /// # } - /// ``` - pub async fn block_number(&self) -> Result { - self.provider.get_block_number().await + pub async fn chain_id(&self) -> Result { + Ok(self.provider.get_chainid().await?) + } + + pub async fn block_number(&self) -> Result { + Ok(self.provider.get_block_number().await?) } } From 91000f7b537a3cc6be6c25af9e460a01fa98b504 Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Sun, 19 Sep 2021 20:51:51 -0400 Subject: [PATCH 05/17] Seth: age --- Cargo.lock | 47 +++++++++++++++++++++++-- dapptools/src/seth.rs | 4 +++ dapptools/src/seth_opts.rs | 8 +++++ seth/Cargo.toml | 1 + seth/src/lib.rs | 72 ++++++++++++++++++++++---------------- 5 files changed, 99 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73332895c992..dfc3d0c30ce1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -327,6 +327,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00" +dependencies = [ + "num", + "time 0.1.43", +] + [[package]] name = "chrono" version = "0.4.19" @@ -1441,7 +1451,7 @@ checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" dependencies = [ "cfg-if", "js-sys", - "time", + "time 0.2.27", "wasm-bindgen", "web-sys", ] @@ -1601,6 +1611,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "num" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +dependencies = [ + "num-integer", + "num-iter", + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.44" @@ -1611,6 +1632,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.14" @@ -2339,6 +2371,7 @@ dependencies = [ name = "seth" version = "0.1.0" dependencies = [ + "chrono 0.2.25", "dapp-utils", "ethers-core", "ethers-providers", @@ -2672,6 +2705,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "time" version = "0.2.27" @@ -2885,7 +2928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62af966210b88ad5776ee3ba12d5f35b8d6a2b2a12168f3080cf02b814d7376b" dependencies = [ "ansi_term 0.12.1", - "chrono", + "chrono 0.4.19", "lazy_static", "matchers", "regex", diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index a0ab252b8f5a..d032f5c32320 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -68,6 +68,10 @@ async fn main() -> eyre::Result<()> { seth_send(provider, from, to, sig, args, eth.seth_async).await?; } } + Subcommands::Age { block, rpc_url } => { + let provider = Provider::try_from(rpc_url)?; + println!("{}", Seth::new(provider).age(block.unwrap_or(BlockId::Number(Latest))).await?); + } Subcommands::Balance { block, who, diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index eaa87859479c..d9ea7a88257a 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -75,6 +75,14 @@ pub enum Subcommands { #[structopt(flatten)] eth: EthereumOpts, }, + #[structopt(name = "age")] + #[structopt(about = "Print the timestamp of a block")] + Age { + #[structopt(global = true, help = "the block you want to query, can also be earliest/latest/pending", parse(try_from_str = parse_block_id))] + block: Option, + #[structopt(short, long, env = "ETH_RPC_URL")] + rpc_url: String, + }, #[structopt(name = "balance")] #[structopt(about = "Print the balance of in wei")] Balance { diff --git a/seth/Cargo.toml b/seth/Cargo.toml index 0deebe06b83b..cdbed789924c 100644 --- a/seth/Cargo.toml +++ b/seth/Cargo.toml @@ -13,3 +13,4 @@ ethers-providers = { git = "https://github.com/gakonst/ethers-rs", branch = "mas eyre = "0.6.5" rustc-hex = "2.1.0" serde_json = "1.0.67" +chrono = "0.2" diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 52fc5ef9a4f8..20c0ae23aabc 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -6,6 +6,7 @@ use ethers_providers::{Middleware, PendingTransaction}; use eyre::Result; use rustc_hex::ToHex; use std::str::FromStr; +use chrono::NaiveDateTime; use dapp_utils::{encode_args, get_func, to_table}; @@ -134,37 +135,6 @@ where Ok::<_, eyre::Error>(res) } - /// ```no_run - /// use seth::Seth; - /// use ethers_providers::{Provider, Http}; - /// use std::convert::TryFrom; - /// - /// # async fn foo() -> eyre::Result<()> { - /// let provider = Provider::::try_from("http://localhost:8545")?; - /// let seth = Seth::new(provider); - /// let base_fee = seth.base_fee(13_000_000).await?; - /// println!("{}", base_fee); - /// # Ok(()) - /// # } - /// ``` - pub async fn base_fee>(&self, block: T) -> Result { - let block = block.into(); - let base_fee_hex = Seth::block( - &self, - block, - false, - // Select only baseFee field - Some(String::from("baseFeePerGas")), - false - ).await?; - let base_fee_num = U256::from_str_radix( - strip_0x(&base_fee_hex), - 16 - ).expect("Unable to convert baseFee hexadecimal to U256"); - - Ok(base_fee_num) - } - /// ```no_run /// use seth::Seth; /// use ethers_providers::{Provider, Http}; @@ -227,6 +197,46 @@ where Ok(block) } + async fn block_field_as_num>( + &self, block: T, + field: String + ) -> Result { + let block = block.into(); + let base_fee_hex = Seth::block( + &self, + block, + false, + // Select only select field + Some(field), + false + ).await?; + Ok(U256::from_str_radix( + strip_0x(&base_fee_hex), + 16 + ).expect("Unable to convert hexadecimal to U256")) + } + + pub async fn base_fee>(&self, block: T) -> Result { + Ok(Seth::block_field_as_num( + &self, + block, + String::from("baseFeePerGas") + ).await?) + } + + pub async fn age>(&self, block: T) -> Result { + let timestamp_str = Seth::block_field_as_num( + &self, + block, + String::from("timestamp") + ).await?.to_string(); + let datetime = NaiveDateTime::from_timestamp( + timestamp_str.parse::().unwrap(), + 0 + ); + Ok(datetime.format("%a %b %e %H:%M:%S %Y").to_string()) + } + pub async fn chain_id(&self) -> Result { Ok(self.provider.get_chainid().await?) } From 734ae4190264b0a7c34825316c561caac0321a6b Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Sun, 19 Sep 2021 22:31:28 -0400 Subject: [PATCH 06/17] Seth: namehash --- dapptools/src/seth.rs | 3 +++ dapptools/src/seth_opts.rs | 3 +++ seth/src/lib.rs | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index d032f5c32320..e9d3403fa97b 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -57,6 +57,9 @@ async fn main() -> eyre::Result<()> { let provider = Provider::try_from(rpc_url)?; println!("{}", Seth::new(provider).chain_id().await?); } + Subcommands::Namehash { name } => { + println!("{}", SimpleSeth::namehash(&name)); + } Subcommands::SendTx { eth, to, sig, args } => { let provider = Provider::try_from(eth.rpc_url.as_str())?; if let Some(signer) = eth.signer()? { diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index d9ea7a88257a..b35e8321a75d 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -63,6 +63,9 @@ pub enum Subcommands { #[structopt(long, env = "ETH_RPC_URL")] rpc_url: String, }, + #[structopt(name = "namehash")] + #[structopt(about = "returns ENS namehash of provided name")] + Namehash { name: String }, #[structopt(name = "send")] #[structopt(about = "Publish a transaction signed by to call with ")] SendTx { diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 20c0ae23aabc..0e4305eceea5 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -1,7 +1,7 @@ //! Seth //! //! TODO -use ethers_core::{types::*, utils}; +use ethers_core::{types::*, utils::{self, keccak256}}; use ethers_providers::{Middleware, PendingTransaction}; use eyre::Result; use rustc_hex::ToHex; @@ -343,6 +343,39 @@ impl SimpleSeth { // need to use the Debug implementation Ok(format!("{:?}", H256::from_str(&padded)?)) } + + /// Converts ENS names to their namehash representation + /// [Namehash reference](https://docs.ens.domains/contract-api-reference/name-processing#hashing-names) + /// [namehash-rust reference](https://github.com/InstateDev/namehash-rust/blob/master/src/lib.rs) + /// + /// ``` + /// use seth::SimpleSeth as Seth; + /// + /// assert_eq!(Seth::namehash(""), "0x0000000000000000000000000000000000000000000000000000000000000000"); + /// assert_eq!(Seth::namehash("eth"), "0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae"); + /// assert_eq!(Seth::namehash("foo.eth"), "0xde9b09fd7c5f901e23a3f19fecc54828e9c848539801e86591bd9801b019f84f"); + /// assert_eq!(Seth::namehash("sub.foo.eth"), "0x500d86f9e663479e5aaa6e99276e55fc139c597211ee47d17e1e92da16a83402"); + /// ``` + pub fn namehash(ens: &str) -> String { + let mut node = vec![0u8; 32]; + + if !ens.is_empty() { + let ens_lower = ens.to_lowercase(); + let mut labels: Vec<&str> = ens_lower.split(".").collect(); + labels.reverse(); + + for label in labels { + let mut label_hash = keccak256(label.as_bytes()); + node.append(&mut label_hash.to_vec()); + + label_hash = keccak256(node.as_slice()); + node = label_hash.to_vec(); + } + } + + let namehash: String = node.to_hex(); + format!("0x{}", namehash) + } } fn strip_0x(s: &str) -> &str { From a2b43af3f29b8e70cd63db28deb8623ac7fbe616 Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Sun, 19 Sep 2021 22:41:53 -0400 Subject: [PATCH 07/17] Seth: keccak --- dapptools/src/seth.rs | 4 +++- dapptools/src/seth_opts.rs | 3 +++ seth/src/lib.rs | 13 +++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index e9d3403fa97b..8a3b97430723 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -90,7 +90,9 @@ async fn main() -> eyre::Result<()> { let provider = Provider::try_from(rpc_url)?; println!("{}", Seth::new(provider).base_fee(block.unwrap_or(BlockId::Number(Latest))).await?); } - + Subcommands::Keccak { data } => { + println!("{}", SimpleSeth::keccak(&data)); + } Subcommands::ResolveName { who, rpc_url, diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index b35e8321a75d..cc9caa31b5d5 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -104,6 +104,9 @@ pub enum Subcommands { #[structopt(short, long, env = "ETH_RPC_URL")] rpc_url: String, }, + #[structopt(name = "keccak")] + #[structopt(about = "Keccak-256 hash arbitrary data")] + Keccak { data: String }, #[structopt(name = "resolve-name")] #[structopt(about = "Returns the address the provided ENS name resolves to")] ResolveName { diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 0e4305eceea5..cd759fc43fba 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -344,6 +344,19 @@ impl SimpleSeth { Ok(format!("{:?}", H256::from_str(&padded)?)) } + /// Keccak-256 hashes arbitrary data + /// + /// ``` + /// use seth::SimpleSeth as Seth; + /// + /// assert_eq!(Seth::keccak("foo"), "0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d"); + /// assert_eq!(Seth::keccak("123abc"), "0xb1f1c74a1ba56f07a892ea1110a39349d40f66ca01d245e704621033cb7046a4"); + /// ``` + pub fn keccak(d: &str) -> String { + let hash: String = keccak256(d.as_bytes()).to_hex(); + format!("0x{}", hash) + } + /// Converts ENS names to their namehash representation /// [Namehash reference](https://docs.ens.domains/contract-api-reference/name-processing#hashing-names) /// [namehash-rust reference](https://github.com/InstateDev/namehash-rust/blob/master/src/lib.rs) From 8efb2161fe83f7d934aabba413d36fa7214537aa Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Sun, 19 Sep 2021 22:46:02 -0400 Subject: [PATCH 08/17] Seth: gas-price --- dapptools/src/seth.rs | 4 ++++ dapptools/src/seth_opts.rs | 6 ++++++ seth/src/lib.rs | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index 8a3b97430723..70ee71f905ed 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -90,6 +90,10 @@ async fn main() -> eyre::Result<()> { let provider = Provider::try_from(rpc_url)?; println!("{}", Seth::new(provider).base_fee(block.unwrap_or(BlockId::Number(Latest))).await?); } + Subcommands::GasPrice { rpc_url } => { + let provider = Provider::try_from(rpc_url)?; + println!("{}", Seth::new(provider).gas_price().await?); + } Subcommands::Keccak { data } => { println!("{}", SimpleSeth::keccak(&data)); } diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index cc9caa31b5d5..62dee2761bd7 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -104,6 +104,12 @@ pub enum Subcommands { #[structopt(short, long, env = "ETH_RPC_URL")] rpc_url: String, }, + #[structopt(name = "gas-price")] + #[structopt(about = "current gas price of target chain")] + GasPrice { + #[structopt(short, long, env = "ETH_RPC_URL")] + rpc_url: String, + }, #[structopt(name = "keccak")] #[structopt(about = "Keccak-256 hash arbitrary data")] Keccak { data: String }, diff --git a/seth/src/lib.rs b/seth/src/lib.rs index cd759fc43fba..8cb11ffe96f3 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -244,6 +244,10 @@ where pub async fn block_number(&self) -> Result { Ok(self.provider.get_block_number().await?) } + + pub async fn gas_price(&self) -> Result { + Ok(self.provider.get_gas_price().await?) + } } pub struct SimpleSeth; From b6b5953efdb49c3838cfae6c18352fcad281e076 Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Sun, 19 Sep 2021 22:58:59 -0400 Subject: [PATCH 09/17] Seth: chain --- dapptools/src/seth.rs | 4 ++++ dapptools/src/seth_opts.rs | 6 ++++++ seth/src/lib.rs | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index 70ee71f905ed..e1f1941abae3 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -53,6 +53,10 @@ async fn main() -> eyre::Result<()> { let provider = Provider::try_from(rpc_url)?; println!("{}", Seth::new(provider).call(address, &sig, args).await?); } + Subcommands::Chain { rpc_url } => { + let provider = Provider::try_from(rpc_url)?; + println!("{}", Seth::new(provider).chain().await?); + } Subcommands::ChainId { rpc_url } => { let provider = Provider::try_from(rpc_url)?; println!("{}", Seth::new(provider).chain_id().await?); diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index 62dee2761bd7..02b447c459f4 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -57,6 +57,12 @@ pub enum Subcommands { #[structopt(long, env = "ETH_RPC_URL")] rpc_url: String, }, + #[structopt(name = "chain")] + #[structopt(about = "Prints symbolic name of current blockchain by checking genesis hash")] + Chain { + #[structopt(long, env = "ETH_RPC_URL")] + rpc_url: String, + }, #[structopt(name = "chain-id")] #[structopt(about = "returns ethereum chain id")] ChainId { diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 8cb11ffe96f3..65bf4066a95b 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -237,6 +237,44 @@ where Ok(datetime.format("%a %b %e %H:%M:%S %Y").to_string()) } + pub async fn chain(&self) -> Result<&str> { + let genesis_hash = Seth::block( + &self, + 0, + false, + // Select only block hash + Some(String::from("hash")), + false + ).await?; + + Ok(match &genesis_hash[..] { + "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" => { + match &(Seth::block( + &self, + 1920000, + false, + Some(String::from("hash")), + false + ).await?)[..] { + "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f" => "etclive", + _ => "ethlive", + } + }, + "0xa3c565fc15c7478862d50ccd6561e3c06b24cc509bf388941c25ea985ce32cb9" => "kovan", + "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d" => "ropsten", + "0x39e1b9259598b65c8c71d1ea153de17e89222e64e8b271213dfb92c231f7fb88" => "optimism-mainnet", + "0x2510549c5c30f15472b55dbae139122e2e593f824217eefc7a53f78698ac5c1e" => "optimism-kovan", + "0x7ee576b35482195fc49205cec9af72ce14f003b9ae69f6ba0faef4514be8b442" => "arbitrum-mainnet", + "0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303" => "morden", + "0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177" => "rinkeby", + "0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a" => "goerli", + "0x14c2283285a88fe5fce9bf5c573ab03d6616695d717b12a127188bcacfc743c4" => "kotti", + "0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34" => "bsctest", + "0x0d21840abff46b96c84b2ac9e10e4f5cdaeb5693cb665db62a2f3b02d2d57b5b" => "bsc", + _ => "unknown", + }) + } + pub async fn chain_id(&self) -> Result { Ok(self.provider.get_chainid().await?) } From 3314129dcea26de92a94cf2b2283d8b00802e7c9 Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Sun, 19 Sep 2021 23:40:34 -0400 Subject: [PATCH 10/17] Seth: --to-wei --- dapptools/src/seth.rs | 3 +++ dapptools/src/seth_opts.rs | 3 +++ seth/src/lib.rs | 23 +++++++++++++++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index e1f1941abae3..11aff3e05ec9 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -25,6 +25,9 @@ async fn main() -> eyre::Result<()> { Subcommands::ToFix { decimals, value } => { println!("{}", SimpleSeth::to_fix(unwrap_or_stdin(decimals)?, unwrap_or_stdin(value)?)); } + Subcommands::ToWei { value, unit } => { + println!("{}", SimpleSeth::to_wei(unwrap_or_stdin(value)?, unit.unwrap_or(String::from("wei")))); + } Subcommands::Block { rpc_url, block, diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index 02b447c459f4..d1357292bd40 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -26,6 +26,9 @@ pub enum Subcommands { #[structopt(name = "--to-fix")] #[structopt(about = "convert integers into fixed point with specified decimals")] ToFix { decimals: Option, value: Option }, + #[structopt(name = "--to-wei")] + #[structopt(about = "convert an ETH amount into wei")] + ToWei { value: Option, unit: Option }, #[structopt(name = "block")] #[structopt( about = "Prints information about . If is given, print only the value of that field" diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 65bf4066a95b..fbe8269baa60 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -202,7 +202,7 @@ where field: String ) -> Result { let block = block.into(); - let base_fee_hex = Seth::block( + let block_field = Seth::block( &self, block, false, @@ -211,7 +211,7 @@ where false ).await?; Ok(U256::from_str_radix( - strip_0x(&base_fee_hex), + strip_0x(&block_field), 16 ).expect("Unable to convert hexadecimal to U256")) } @@ -339,6 +339,25 @@ impl SimpleSeth { format!("{:#x}", u) } + /// Converts an eth amount into wei + /// + /// ``` + /// use seth::SimpleSeth as Seth; + /// + /// assert_eq!(Seth::to_wei(1, "".to_string()), "1"); + /// assert_eq!(Seth::to_wei(100, "gwei".to_string()), "100000000000"); + /// assert_eq!(Seth::to_wei(100, "eth".to_string()), "100000000000000000000"); + /// assert_eq!(Seth::to_wei(1000, "ether".to_string()), "1000000000000000000000"); + /// ``` + pub fn to_wei(value: u128, unit: String) -> String { + let value = value.to_string(); + match &unit[..] { + "gwei" => format!("{:0<1$}", value, 9 + value.len()), + "eth" | "ether" => format!("{:0<1$}", value, 18 + value.len()), + _ => value, + } + } + /// Converts an Ethereum address to its checksum format /// according to [EIP-55](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md) /// From 4cf8b59f2365240dad566473fb0fe0e354b13d6f Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Mon, 20 Sep 2021 00:50:47 -0400 Subject: [PATCH 11/17] Seth: --to-uint256 rough --- dapptools/src/seth.rs | 3 +++ dapptools/src/seth_opts.rs | 3 +++ seth/src/lib.rs | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index 11aff3e05ec9..6d847fadbabe 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -25,6 +25,9 @@ async fn main() -> eyre::Result<()> { Subcommands::ToFix { decimals, value } => { println!("{}", SimpleSeth::to_fix(unwrap_or_stdin(decimals)?, unwrap_or_stdin(value)?)); } + Subcommands::ToUint256 { value } => { + println!("{}", SimpleSeth::to_uint256(value)); + } Subcommands::ToWei { value, unit } => { println!("{}", SimpleSeth::to_wei(unwrap_or_stdin(value)?, unit.unwrap_or(String::from("wei")))); } diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index d1357292bd40..b542a2cfbe34 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -26,6 +26,9 @@ pub enum Subcommands { #[structopt(name = "--to-fix")] #[structopt(about = "convert integers into fixed point with specified decimals")] ToFix { decimals: Option, value: Option }, + #[structopt(name = "--to-uint256")] + #[structopt(about = "convert a number into uint256 hex string with 0x prefix")] + ToUint256 { value: String }, #[structopt(name = "--to-wei")] #[structopt(about = "convert an ETH amount into wei")] ToWei { value: Option, unit: Option }, diff --git a/seth/src/lib.rs b/seth/src/lib.rs index fbe8269baa60..8506f0533678 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -339,6 +339,24 @@ impl SimpleSeth { format!("{:#x}", u) } + /// Converts a number into uint256 hex string with 0x prefix + /// + /// ``` + /// use seth::SimpleSeth as Seth; + /// + /// assert_eq!(Seth::to_uint256("100".to_string()), "0x0000000000000000000000000000000000000000000000000000000000000064"); + /// assert_eq!(Seth::to_uint256("192038293923".to_string()), "0x0000000000000000000000000000000000000000000000000000002cb65fd1a3"); + /// assert_eq!( + /// Seth::to_uint256("115792089237316195423570985008687907853269984665640564039457584007913129639935".to_string()), + /// "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + /// ); + /// ``` + pub fn to_uint256(value: String) -> String { + let num_u256 = U256::from_str_radix(&value, 10).expect("Could not parse string"); + let num_hex = format!("{:x}", num_u256); + format!("0x{}{}", "0".repeat(64 - num_hex.len()), num_hex) + } + /// Converts an eth amount into wei /// /// ``` From 4364e44c318c3deb3ce20d579721d8831288afca Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Mon, 20 Sep 2021 01:04:26 -0400 Subject: [PATCH 12/17] Seth: --to-dec --- dapptools/src/seth.rs | 3 +++ dapptools/src/seth_opts.rs | 3 +++ seth/src/lib.rs | 13 +++++++++++++ 3 files changed, 19 insertions(+) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index 6d847fadbabe..5e318eb9f7b2 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -22,6 +22,9 @@ async fn main() -> eyre::Result<()> { Subcommands::ToBytes32 { bytes } => { println!("{}", SimpleSeth::to_bytes32(&bytes)?); } + Subcommands::ToDec { hexvalue } => { + println!("{}", SimpleSeth::to_dec(hexvalue)); + } Subcommands::ToFix { decimals, value } => { println!("{}", SimpleSeth::to_fix(unwrap_or_stdin(decimals)?, unwrap_or_stdin(value)?)); } diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index b542a2cfbe34..0e98e54f5e28 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -23,6 +23,9 @@ pub enum Subcommands { #[structopt(name = "--to-bytes32")] #[structopt(about = "left-pads a hex bytes string to 32 bytes)")] ToBytes32 { bytes: String }, + #[structopt(name = "--to-dec")] + #[structopt(about = "convert hex value into a decimal number")] + ToDec { hexvalue: String }, #[structopt(name = "--to-fix")] #[structopt(about = "convert integers into fixed point with specified decimals")] ToFix { decimals: Option, value: Option }, diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 8506f0533678..01a1b06c975a 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -303,6 +303,19 @@ impl SimpleSeth { format!("0x{}", s) } + /// Converts hex input to decimal + /// + /// ``` + /// use seth::SimpleSeth as Seth; + /// + /// assert_eq!(424242, Seth::to_dec("0x67932")); + /// assert_eq!(1234, Seth::to_dec("0x4d2")); + /// ``` + pub fn to_dec(hex: String) -> u128 { + let hex_trimmed = hex.trim_start_matches("0x"); + u128::from_str_radix(&hex_trimmed, 16).expect("Could not parse hex") + } + /// Converts integers with specified decimals into fixed point numbers /// /// ``` From fb310dfa664e4be7a88c7539bce5cdc2139a7163 Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Mon, 20 Sep 2021 01:22:47 -0400 Subject: [PATCH 13/17] Seth: --to-ascii --- dapptools/src/seth.rs | 5 ++++- dapptools/src/seth_opts.rs | 3 +++ seth/src/lib.rs | 23 +++++++++++++++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index 5e318eb9f7b2..1eb3cca7efc7 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -19,11 +19,14 @@ async fn main() -> eyre::Result<()> { Subcommands::ToCheckSumAddress { address } => { println!("{}", SimpleSeth::to_checksum_address(&address)?); } + Subcommands::ToAscii { hexdata } => { + println!("{}", SimpleSeth::to_ascii(&hexdata)); + } Subcommands::ToBytes32 { bytes } => { println!("{}", SimpleSeth::to_bytes32(&bytes)?); } Subcommands::ToDec { hexvalue } => { - println!("{}", SimpleSeth::to_dec(hexvalue)); + println!("{}", SimpleSeth::to_dec(&hexvalue)); } Subcommands::ToFix { decimals, value } => { println!("{}", SimpleSeth::to_fix(unwrap_or_stdin(decimals)?, unwrap_or_stdin(value)?)); diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index 0e98e54f5e28..a376d7f36c76 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -20,6 +20,9 @@ pub enum Subcommands { #[structopt(name = "--to-checksum-address")] #[structopt(about = "convert an address to a checksummed format (EIP-55)")] ToCheckSumAddress { address: Address }, + #[structopt(name = "--to-ascii")] + #[structopt(about = "convert hex data to text data")] + ToAscii { hexdata: String }, #[structopt(name = "--to-bytes32")] #[structopt(about = "left-pads a hex bytes string to 32 bytes)")] ToBytes32 { bytes: String }, diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 01a1b06c975a..96cbab7fa072 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -4,7 +4,7 @@ use ethers_core::{types::*, utils::{self, keccak256}}; use ethers_providers::{Middleware, PendingTransaction}; use eyre::Result; -use rustc_hex::ToHex; +use rustc_hex::{ToHex, FromHexIter}; use std::str::FromStr; use chrono::NaiveDateTime; @@ -303,6 +303,25 @@ impl SimpleSeth { format!("0x{}", s) } + + /// Converts hex data into text data + /// + /// ``` + /// use seth::SimpleSeth as Seth; + /// + /// assert_eq!("Hello, World!", Seth::to_ascii("48656c6c6f2c20576f726c6421".to_string())); + /// assert_eq!("TurboDappTools", Seth::to_ascii("0x547572626f44617070546f6f6c73".to_string())); + /// ``` + pub fn to_ascii(hex: &str) -> String { + let hex_trimmed = hex.trim_start_matches("0x"); + let iter = FromHexIter::new(hex_trimmed); + let mut ascii = String::new(); + for letter in iter.collect::>() { + ascii.push(letter.unwrap() as char); + } + ascii + } + /// Converts hex input to decimal /// /// ``` @@ -311,7 +330,7 @@ impl SimpleSeth { /// assert_eq!(424242, Seth::to_dec("0x67932")); /// assert_eq!(1234, Seth::to_dec("0x4d2")); /// ``` - pub fn to_dec(hex: String) -> u128 { + pub fn to_dec(hex: &str) -> u128 { let hex_trimmed = hex.trim_start_matches("0x"); u128::from_str_radix(&hex_trimmed, 16).expect("Could not parse hex") } From de1ae4436c3f03d9bac6e1ee5b49258e290e13a9 Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Mon, 20 Sep 2021 01:27:30 -0400 Subject: [PATCH 14/17] Quickfix: fixing test types --- seth/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 96cbab7fa072..80009c705ff5 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -309,8 +309,8 @@ impl SimpleSeth { /// ``` /// use seth::SimpleSeth as Seth; /// - /// assert_eq!("Hello, World!", Seth::to_ascii("48656c6c6f2c20576f726c6421".to_string())); - /// assert_eq!("TurboDappTools", Seth::to_ascii("0x547572626f44617070546f6f6c73".to_string())); + /// assert_eq!("Hello, World!", Seth::to_ascii("48656c6c6f2c20576f726c6421")); + /// assert_eq!("TurboDappTools", Seth::to_ascii("0x547572626f44617070546f6f6c73")); /// ``` pub fn to_ascii(hex: &str) -> String { let hex_trimmed = hex.trim_start_matches("0x"); From 086ec0c813c4c4b00085379fea3180db0f236fc1 Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Mon, 20 Sep 2021 11:12:42 -0400 Subject: [PATCH 15/17] Cleanup PR --- dapptools/src/seth.rs | 38 +++++++++++++++++++++++++++++++++----- dapptools/src/seth_opts.rs | 12 ++++++------ seth/src/lib.rs | 11 ++++++----- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index 1eb3cca7efc7..4287cab6e107 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -2,7 +2,13 @@ mod seth_opts; use seth_opts::{Opts, Subcommands}; use seth::{Seth, SimpleSeth}; -use ethers::{core::types::{BlockId, BlockNumber::{Latest}}, middleware::SignerMiddleware, providers::{Middleware, Provider}, signers::Signer, types::NameOrAddress}; +use ethers::{ + core::types::{BlockId, BlockNumber::{Latest}}, + middleware::SignerMiddleware, + providers::{Middleware, Provider}, + signers::Signer, + types::NameOrAddress +}; use std::{convert::TryFrom, str::FromStr}; use structopt::StructOpt; @@ -29,13 +35,25 @@ async fn main() -> eyre::Result<()> { println!("{}", SimpleSeth::to_dec(&hexvalue)); } Subcommands::ToFix { decimals, value } => { - println!("{}", SimpleSeth::to_fix(unwrap_or_stdin(decimals)?, unwrap_or_stdin(value)?)); + println!( + "{}", + SimpleSeth::to_fix( + unwrap_or_stdin(decimals)?, + unwrap_or_stdin(value)? + ) + ); } Subcommands::ToUint256 { value } => { println!("{}", SimpleSeth::to_uint256(value)); } Subcommands::ToWei { value, unit } => { - println!("{}", SimpleSeth::to_wei(unwrap_or_stdin(value)?, unit.unwrap_or(String::from("wei")))); + println!( + "{}", + SimpleSeth::to_wei( + unwrap_or_stdin(value)?, + unit.unwrap_or(String::from("wei")) + ) + ); } Subcommands::Block { rpc_url, @@ -89,7 +107,12 @@ async fn main() -> eyre::Result<()> { } Subcommands::Age { block, rpc_url } => { let provider = Provider::try_from(rpc_url)?; - println!("{}", Seth::new(provider).age(block.unwrap_or(BlockId::Number(Latest))).await?); + println!( + "{}", + Seth::new(provider) + .age(block.unwrap_or(BlockId::Number(Latest))) + .await? + ); } Subcommands::Balance { block, @@ -104,7 +127,12 @@ async fn main() -> eyre::Result<()> { rpc_url, } => { let provider = Provider::try_from(rpc_url)?; - println!("{}", Seth::new(provider).base_fee(block.unwrap_or(BlockId::Number(Latest))).await?); + println!( + "{}", + Seth::new(provider) + .base_fee(block.unwrap_or(BlockId::Number(Latest))) + .await? + ); } Subcommands::GasPrice { rpc_url } => { let provider = Provider::try_from(rpc_url)?; diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index a376d7f36c76..ec87f66df2db 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -27,7 +27,7 @@ pub enum Subcommands { #[structopt(about = "left-pads a hex bytes string to 32 bytes)")] ToBytes32 { bytes: String }, #[structopt(name = "--to-dec")] - #[structopt(about = "convert hex value into a decimal number")] + #[structopt(about = "convert hex value into decimal number")] ToDec { hexvalue: String }, #[structopt(name = "--to-fix")] #[structopt(about = "convert integers into fixed point with specified decimals")] @@ -54,7 +54,7 @@ pub enum Subcommands { rpc_url: String, }, #[structopt(name = "block-number")] - #[structopt(about = "returns latest block number")] + #[structopt(about = "Prints latest block number")] BlockNumber { #[structopt(long, env = "ETH_RPC_URL")] rpc_url: String, @@ -97,7 +97,7 @@ pub enum Subcommands { eth: EthereumOpts, }, #[structopt(name = "age")] - #[structopt(about = "Print the timestamp of a block")] + #[structopt(about = "Prints the timestamp of a block")] Age { #[structopt(global = true, help = "the block you want to query, can also be earliest/latest/pending", parse(try_from_str = parse_block_id))] block: Option, @@ -115,7 +115,7 @@ pub enum Subcommands { rpc_url: String, }, #[structopt(name = "basefee")] - #[structopt(about = "Print the block basefee")] + #[structopt(about = "Print the basefee of a block")] BaseFee { #[structopt(global = true, help = "the block you want to query, can also be earliest/latest/pending", parse(try_from_str = parse_block_id))] block: Option, @@ -123,13 +123,13 @@ pub enum Subcommands { rpc_url: String, }, #[structopt(name = "gas-price")] - #[structopt(about = "current gas price of target chain")] + #[structopt(about = "Prints current gas price of target chain")] GasPrice { #[structopt(short, long, env = "ETH_RPC_URL")] rpc_url: String, }, #[structopt(name = "keccak")] - #[structopt(about = "Keccak-256 hash arbitrary data")] + #[structopt(about = "Keccak-256 hashes arbitrary data")] Keccak { data: String }, #[structopt(name = "resolve-name")] #[structopt(about = "Returns the address the provided ENS name resolves to")] diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 80009c705ff5..cab3872b23be 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -198,7 +198,8 @@ where } async fn block_field_as_num>( - &self, block: T, + &self, + block: T, field: String ) -> Result { let block = block.into(); @@ -218,8 +219,8 @@ where pub async fn base_fee>(&self, block: T) -> Result { Ok(Seth::block_field_as_num( - &self, - block, + &self, + block, String::from("baseFeePerGas") ).await?) } @@ -463,8 +464,8 @@ impl SimpleSeth { /// assert_eq!(Seth::keccak("foo"), "0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d"); /// assert_eq!(Seth::keccak("123abc"), "0xb1f1c74a1ba56f07a892ea1110a39349d40f66ca01d245e704621033cb7046a4"); /// ``` - pub fn keccak(d: &str) -> String { - let hash: String = keccak256(d.as_bytes()).to_hex(); + pub fn keccak(data: &str) -> String { + let hash: String = keccak256(data.as_bytes()).to_hex(); format!("0x{}", hash) } From 3d4fc605347bd339329071f6405485224e72bfae Mon Sep 17 00:00:00 2001 From: Anish Agnihotri Date: Mon, 20 Sep 2021 11:22:37 -0400 Subject: [PATCH 16/17] Fix return types as Result --- dapptools/src/seth.rs | 14 +++--- seth/src/lib.rs | 111 ++++++++++++++++++++++++++---------------- 2 files changed, 76 insertions(+), 49 deletions(-) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index 4287cab6e107..90b920c87e9f 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -26,13 +26,13 @@ async fn main() -> eyre::Result<()> { println!("{}", SimpleSeth::to_checksum_address(&address)?); } Subcommands::ToAscii { hexdata } => { - println!("{}", SimpleSeth::to_ascii(&hexdata)); + println!("{}", SimpleSeth::to_ascii(&hexdata)?); } Subcommands::ToBytes32 { bytes } => { println!("{}", SimpleSeth::to_bytes32(&bytes)?); } Subcommands::ToDec { hexvalue } => { - println!("{}", SimpleSeth::to_dec(&hexvalue)); + println!("{}", SimpleSeth::to_dec(&hexvalue)?); } Subcommands::ToFix { decimals, value } => { println!( @@ -40,11 +40,11 @@ async fn main() -> eyre::Result<()> { SimpleSeth::to_fix( unwrap_or_stdin(decimals)?, unwrap_or_stdin(value)? - ) + )? ); } Subcommands::ToUint256 { value } => { - println!("{}", SimpleSeth::to_uint256(value)); + println!("{}", SimpleSeth::to_uint256(value)?); } Subcommands::ToWei { value, unit } => { println!( @@ -52,7 +52,7 @@ async fn main() -> eyre::Result<()> { SimpleSeth::to_wei( unwrap_or_stdin(value)?, unit.unwrap_or(String::from("wei")) - ) + )? ); } Subcommands::Block { @@ -92,7 +92,7 @@ async fn main() -> eyre::Result<()> { println!("{}", Seth::new(provider).chain_id().await?); } Subcommands::Namehash { name } => { - println!("{}", SimpleSeth::namehash(&name)); + println!("{}", SimpleSeth::namehash(&name)?); } Subcommands::SendTx { eth, to, sig, args } => { let provider = Provider::try_from(eth.rpc_url.as_str())?; @@ -139,7 +139,7 @@ async fn main() -> eyre::Result<()> { println!("{}", Seth::new(provider).gas_price().await?); } Subcommands::Keccak { data } => { - println!("{}", SimpleSeth::keccak(&data)); + println!("{}", SimpleSeth::keccak(&data)?); } Subcommands::ResolveName { who, diff --git a/seth/src/lib.rs b/seth/src/lib.rs index cab3872b23be..928348580372 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -310,17 +310,21 @@ impl SimpleSeth { /// ``` /// use seth::SimpleSeth as Seth; /// - /// assert_eq!("Hello, World!", Seth::to_ascii("48656c6c6f2c20576f726c6421")); - /// assert_eq!("TurboDappTools", Seth::to_ascii("0x547572626f44617070546f6f6c73")); + /// fn main() -> eyre::Result<()> { + /// assert_eq!("Hello, World!", Seth::to_ascii("48656c6c6f2c20576f726c6421")?); + /// assert_eq!("TurboDappTools", Seth::to_ascii("0x547572626f44617070546f6f6c73")?); + /// + /// Ok(()) + /// } /// ``` - pub fn to_ascii(hex: &str) -> String { + pub fn to_ascii(hex: &str) -> Result { let hex_trimmed = hex.trim_start_matches("0x"); let iter = FromHexIter::new(hex_trimmed); let mut ascii = String::new(); for letter in iter.collect::>() { ascii.push(letter.unwrap() as char); } - ascii + Ok(ascii) } /// Converts hex input to decimal @@ -328,12 +332,15 @@ impl SimpleSeth { /// ``` /// use seth::SimpleSeth as Seth; /// - /// assert_eq!(424242, Seth::to_dec("0x67932")); - /// assert_eq!(1234, Seth::to_dec("0x4d2")); - /// ``` - pub fn to_dec(hex: &str) -> u128 { + /// fn main() -> eyre::Result<()> { + /// assert_eq!(424242, Seth::to_dec("0x67932")?); + /// assert_eq!(1234, Seth::to_dec("0x4d2")?); + /// + /// Ok(()) + /// } + pub fn to_dec(hex: &str) -> Result { let hex_trimmed = hex.trim_start_matches("0x"); - u128::from_str_radix(&hex_trimmed, 16).expect("Could not parse hex") + Ok(u128::from_str_radix(&hex_trimmed, 16)?) } /// Converts integers with specified decimals into fixed point numbers @@ -341,22 +348,26 @@ impl SimpleSeth { /// ``` /// use seth::SimpleSeth as Seth; /// - /// assert_eq!(Seth::to_fix(0, 10), "10."); - /// assert_eq!(Seth::to_fix(1, 10), "1.0"); - /// assert_eq!(Seth::to_fix(2, 10), "0.10"); - /// assert_eq!(Seth::to_fix(3, 10), "0.010"); + /// fn main() -> eyre::Result<()> { + /// assert_eq!(Seth::to_fix(0, 10)?, "10."); + /// assert_eq!(Seth::to_fix(1, 10)?, "1.0"); + /// assert_eq!(Seth::to_fix(2, 10)?, "0.10"); + /// assert_eq!(Seth::to_fix(3, 10)?, "0.010"); + /// + /// Ok(()) + /// } /// ``` - pub fn to_fix(decimals: u128, value: u128) -> String { + pub fn to_fix(decimals: u128, value: u128) -> Result { let mut value: String = value.to_string(); let decimals = decimals as usize; if decimals >= value.len() { // {0}.{0 * (number_of_decimals - value.len())}{value} - format!("0.{:0>1$}", value, decimals) + Ok(format!("0.{:0>1$}", value, decimals)) } else { // Insert decimal at -idx (i.e 1 => decimal idx = -1) value.insert(value.len() - decimals, '.'); - value + Ok(value) } } @@ -377,17 +388,21 @@ impl SimpleSeth { /// ``` /// use seth::SimpleSeth as Seth; /// - /// assert_eq!(Seth::to_uint256("100".to_string()), "0x0000000000000000000000000000000000000000000000000000000000000064"); - /// assert_eq!(Seth::to_uint256("192038293923".to_string()), "0x0000000000000000000000000000000000000000000000000000002cb65fd1a3"); - /// assert_eq!( - /// Seth::to_uint256("115792089237316195423570985008687907853269984665640564039457584007913129639935".to_string()), - /// "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - /// ); + /// fn main() -> eyre::Result<()> { + /// assert_eq!(Seth::to_uint256("100".to_string())?, "0x0000000000000000000000000000000000000000000000000000000000000064"); + /// assert_eq!(Seth::to_uint256("192038293923".to_string())?, "0x0000000000000000000000000000000000000000000000000000002cb65fd1a3"); + /// assert_eq!( + /// Seth::to_uint256("115792089237316195423570985008687907853269984665640564039457584007913129639935".to_string())?, + /// "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + /// ); + /// + /// Ok(()) + /// } /// ``` - pub fn to_uint256(value: String) -> String { - let num_u256 = U256::from_str_radix(&value, 10).expect("Could not parse string"); + pub fn to_uint256(value: String) -> Result { + let num_u256 = U256::from_str_radix(&value, 10)?; let num_hex = format!("{:x}", num_u256); - format!("0x{}{}", "0".repeat(64 - num_hex.len()), num_hex) + Ok(format!("0x{}{}", "0".repeat(64 - num_hex.len()), num_hex)) } /// Converts an eth amount into wei @@ -395,18 +410,22 @@ impl SimpleSeth { /// ``` /// use seth::SimpleSeth as Seth; /// - /// assert_eq!(Seth::to_wei(1, "".to_string()), "1"); - /// assert_eq!(Seth::to_wei(100, "gwei".to_string()), "100000000000"); - /// assert_eq!(Seth::to_wei(100, "eth".to_string()), "100000000000000000000"); - /// assert_eq!(Seth::to_wei(1000, "ether".to_string()), "1000000000000000000000"); + /// fn main() -> eyre::Result<()> { + /// assert_eq!(Seth::to_wei(1, "".to_string())?, "1"); + /// assert_eq!(Seth::to_wei(100, "gwei".to_string())?, "100000000000"); + /// assert_eq!(Seth::to_wei(100, "eth".to_string())?, "100000000000000000000"); + /// assert_eq!(Seth::to_wei(1000, "ether".to_string())?, "1000000000000000000000"); + /// + /// Ok(()) + /// } /// ``` - pub fn to_wei(value: u128, unit: String) -> String { + pub fn to_wei(value: u128, unit: String) -> Result { let value = value.to_string(); - match &unit[..] { + Ok(match &unit[..] { "gwei" => format!("{:0<1$}", value, 9 + value.len()), "eth" | "ether" => format!("{:0<1$}", value, 18 + value.len()), _ => value, - } + }) } /// Converts an Ethereum address to its checksum format @@ -461,12 +480,16 @@ impl SimpleSeth { /// ``` /// use seth::SimpleSeth as Seth; /// - /// assert_eq!(Seth::keccak("foo"), "0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d"); - /// assert_eq!(Seth::keccak("123abc"), "0xb1f1c74a1ba56f07a892ea1110a39349d40f66ca01d245e704621033cb7046a4"); + /// fn main() -> eyre::Result<()> { + /// assert_eq!(Seth::keccak("foo")?, "0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d"); + /// assert_eq!(Seth::keccak("123abc")?, "0xb1f1c74a1ba56f07a892ea1110a39349d40f66ca01d245e704621033cb7046a4"); + /// + /// Ok(()) + /// } /// ``` - pub fn keccak(data: &str) -> String { + pub fn keccak(data: &str) -> Result { let hash: String = keccak256(data.as_bytes()).to_hex(); - format!("0x{}", hash) + Ok(format!("0x{}", hash)) } /// Converts ENS names to their namehash representation @@ -476,12 +499,16 @@ impl SimpleSeth { /// ``` /// use seth::SimpleSeth as Seth; /// - /// assert_eq!(Seth::namehash(""), "0x0000000000000000000000000000000000000000000000000000000000000000"); - /// assert_eq!(Seth::namehash("eth"), "0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae"); - /// assert_eq!(Seth::namehash("foo.eth"), "0xde9b09fd7c5f901e23a3f19fecc54828e9c848539801e86591bd9801b019f84f"); - /// assert_eq!(Seth::namehash("sub.foo.eth"), "0x500d86f9e663479e5aaa6e99276e55fc139c597211ee47d17e1e92da16a83402"); + /// fn main() -> eyre::Result<()> { + /// assert_eq!(Seth::namehash("")?, "0x0000000000000000000000000000000000000000000000000000000000000000"); + /// assert_eq!(Seth::namehash("eth")?, "0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae"); + /// assert_eq!(Seth::namehash("foo.eth")?, "0xde9b09fd7c5f901e23a3f19fecc54828e9c848539801e86591bd9801b019f84f"); + /// assert_eq!(Seth::namehash("sub.foo.eth")?, "0x500d86f9e663479e5aaa6e99276e55fc139c597211ee47d17e1e92da16a83402"); + /// + /// Ok(()) + /// } /// ``` - pub fn namehash(ens: &str) -> String { + pub fn namehash(ens: &str) -> Result { let mut node = vec![0u8; 32]; if !ens.is_empty() { @@ -499,7 +526,7 @@ impl SimpleSeth { } let namehash: String = node.to_hex(); - format!("0x{}", namehash) + Ok(format!("0x{}", namehash)) } } From db3687b996aaecf7bb745d6be50a77039994bbb4 Mon Sep 17 00:00:00 2001 From: Georgios Konstantopoulos Date: Tue, 21 Sep 2021 00:22:32 -0500 Subject: [PATCH 17/17] chore: cargo fmt / clippy --- dapptools/src/seth.rs | 28 +++++------- dapptools/src/seth_opts.rs | 12 +++-- seth/src/lib.rs | 89 ++++++++++++++++++-------------------- 3 files changed, 61 insertions(+), 68 deletions(-) diff --git a/dapptools/src/seth.rs b/dapptools/src/seth.rs index 90b920c87e9f..c2199dd37dae 100644 --- a/dapptools/src/seth.rs +++ b/dapptools/src/seth.rs @@ -1,14 +1,14 @@ mod seth_opts; use seth_opts::{Opts, Subcommands}; -use seth::{Seth, SimpleSeth}; use ethers::{ - core::types::{BlockId, BlockNumber::{Latest}}, + core::types::{BlockId, BlockNumber::Latest}, middleware::SignerMiddleware, providers::{Middleware, Provider}, signers::Signer, - types::NameOrAddress + types::NameOrAddress, }; +use seth::{Seth, SimpleSeth}; use std::{convert::TryFrom, str::FromStr}; use structopt::StructOpt; @@ -36,11 +36,8 @@ async fn main() -> eyre::Result<()> { } Subcommands::ToFix { decimals, value } => { println!( - "{}", - SimpleSeth::to_fix( - unwrap_or_stdin(decimals)?, - unwrap_or_stdin(value)? - )? + "{}", + SimpleSeth::to_fix(unwrap_or_stdin(decimals)?, unwrap_or_stdin(value)?)? ); } Subcommands::ToUint256 { value } => { @@ -48,10 +45,10 @@ async fn main() -> eyre::Result<()> { } Subcommands::ToWei { value, unit } => { println!( - "{}", + "{}", SimpleSeth::to_wei( - unwrap_or_stdin(value)?, - unit.unwrap_or(String::from("wei")) + unwrap_or_stdin(value)?, + unit.unwrap_or_else(|| String::from("wei")) )? ); } @@ -108,7 +105,7 @@ async fn main() -> eyre::Result<()> { Subcommands::Age { block, rpc_url } => { let provider = Provider::try_from(rpc_url)?; println!( - "{}", + "{}", Seth::new(provider) .age(block.unwrap_or(BlockId::Number(Latest))) .await? @@ -122,13 +119,10 @@ async fn main() -> eyre::Result<()> { let provider = Provider::try_from(rpc_url)?; println!("{}", Seth::new(provider).balance(who, block).await?); } - Subcommands::BaseFee { - block, - rpc_url, - } => { + Subcommands::BaseFee { block, rpc_url } => { let provider = Provider::try_from(rpc_url)?; println!( - "{}", + "{}", Seth::new(provider) .base_fee(block.unwrap_or(BlockId::Number(Latest))) .await? diff --git a/dapptools/src/seth_opts.rs b/dapptools/src/seth_opts.rs index ec87f66df2db..3b5f3300c713 100644 --- a/dapptools/src/seth_opts.rs +++ b/dapptools/src/seth_opts.rs @@ -31,13 +31,19 @@ pub enum Subcommands { ToDec { hexvalue: String }, #[structopt(name = "--to-fix")] #[structopt(about = "convert integers into fixed point with specified decimals")] - ToFix { decimals: Option, value: Option }, + ToFix { + decimals: Option, + value: Option, + }, #[structopt(name = "--to-uint256")] #[structopt(about = "convert a number into uint256 hex string with 0x prefix")] ToUint256 { value: String }, #[structopt(name = "--to-wei")] #[structopt(about = "convert an ETH amount into wei")] - ToWei { value: Option, unit: Option }, + ToWei { + value: Option, + unit: Option, + }, #[structopt(name = "block")] #[structopt( about = "Prints information about . If is given, print only the value of that field" @@ -124,7 +130,7 @@ pub enum Subcommands { }, #[structopt(name = "gas-price")] #[structopt(about = "Prints current gas price of target chain")] - GasPrice { + GasPrice { #[structopt(short, long, env = "ETH_RPC_URL")] rpc_url: String, }, diff --git a/seth/src/lib.rs b/seth/src/lib.rs index 928348580372..621307ecab96 100644 --- a/seth/src/lib.rs +++ b/seth/src/lib.rs @@ -1,12 +1,15 @@ //! Seth //! //! TODO -use ethers_core::{types::*, utils::{self, keccak256}}; +use chrono::NaiveDateTime; +use ethers_core::{ + types::*, + utils::{self, keccak256}, +}; use ethers_providers::{Middleware, PendingTransaction}; use eyre::Result; -use rustc_hex::{ToHex, FromHexIter}; +use rustc_hex::{FromHexIter, ToHex}; use std::str::FromStr; -use chrono::NaiveDateTime; use dapp_utils::{encode_args, get_func, to_table}; @@ -197,75 +200,66 @@ where Ok(block) } - async fn block_field_as_num>( - &self, - block: T, - field: String - ) -> Result { + async fn block_field_as_num>(&self, block: T, field: String) -> Result { let block = block.into(); let block_field = Seth::block( - &self, + self, block, false, // Select only select field Some(field), - false - ).await?; - Ok(U256::from_str_radix( - strip_0x(&block_field), - 16 - ).expect("Unable to convert hexadecimal to U256")) + false, + ) + .await?; + Ok(U256::from_str_radix(strip_0x(&block_field), 16) + .expect("Unable to convert hexadecimal to U256")) } pub async fn base_fee>(&self, block: T) -> Result { - Ok(Seth::block_field_as_num( - &self, - block, - String::from("baseFeePerGas") - ).await?) + Ok(Seth::block_field_as_num(self, block, String::from("baseFeePerGas")).await?) } pub async fn age>(&self, block: T) -> Result { - let timestamp_str = Seth::block_field_as_num( - &self, - block, - String::from("timestamp") - ).await?.to_string(); - let datetime = NaiveDateTime::from_timestamp( - timestamp_str.parse::().unwrap(), - 0 - ); + let timestamp_str = Seth::block_field_as_num(self, block, String::from("timestamp")) + .await? + .to_string(); + let datetime = NaiveDateTime::from_timestamp(timestamp_str.parse::().unwrap(), 0); Ok(datetime.format("%a %b %e %H:%M:%S %Y").to_string()) } pub async fn chain(&self) -> Result<&str> { let genesis_hash = Seth::block( - &self, + self, 0, false, // Select only block hash Some(String::from("hash")), - false - ).await?; + false, + ) + .await?; Ok(match &genesis_hash[..] { "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" => { - match &(Seth::block( - &self, - 1920000, - false, - Some(String::from("hash")), - false - ).await?)[..] { - "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f" => "etclive", + match &(Seth::block(self, 1920000, false, Some(String::from("hash")), false) + .await?)[..] + { + "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f" => { + "etclive" + } _ => "ethlive", } - }, + } "0xa3c565fc15c7478862d50ccd6561e3c06b24cc509bf388941c25ea985ce32cb9" => "kovan", "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d" => "ropsten", - "0x39e1b9259598b65c8c71d1ea153de17e89222e64e8b271213dfb92c231f7fb88" => "optimism-mainnet", - "0x2510549c5c30f15472b55dbae139122e2e593f824217eefc7a53f78698ac5c1e" => "optimism-kovan", - "0x7ee576b35482195fc49205cec9af72ce14f003b9ae69f6ba0faef4514be8b442" => "arbitrum-mainnet", + "0x39e1b9259598b65c8c71d1ea153de17e89222e64e8b271213dfb92c231f7fb88" => { + "optimism-mainnet" + } + "0x2510549c5c30f15472b55dbae139122e2e593f824217eefc7a53f78698ac5c1e" => { + "optimism-kovan" + } + "0x7ee576b35482195fc49205cec9af72ce14f003b9ae69f6ba0faef4514be8b442" => { + "arbitrum-mainnet" + } "0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303" => "morden", "0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177" => "rinkeby", "0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a" => "goerli", @@ -304,7 +298,6 @@ impl SimpleSeth { format!("0x{}", s) } - /// Converts hex data into text data /// /// ``` @@ -340,7 +333,7 @@ impl SimpleSeth { /// } pub fn to_dec(hex: &str) -> Result { let hex_trimmed = hex.trim_start_matches("0x"); - Ok(u128::from_str_radix(&hex_trimmed, 16)?) + Ok(u128::from_str_radix(hex_trimmed, 16)?) } /// Converts integers with specified decimals into fixed point numbers @@ -392,7 +385,7 @@ impl SimpleSeth { /// assert_eq!(Seth::to_uint256("100".to_string())?, "0x0000000000000000000000000000000000000000000000000000000000000064"); /// assert_eq!(Seth::to_uint256("192038293923".to_string())?, "0x0000000000000000000000000000000000000000000000000000002cb65fd1a3"); /// assert_eq!( - /// Seth::to_uint256("115792089237316195423570985008687907853269984665640564039457584007913129639935".to_string())?, + /// Seth::to_uint256("115792089237316195423570985008687907853269984665640564039457584007913129639935".to_string())?, /// "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" /// ); /// @@ -513,7 +506,7 @@ impl SimpleSeth { if !ens.is_empty() { let ens_lower = ens.to_lowercase(); - let mut labels: Vec<&str> = ens_lower.split(".").collect(); + let mut labels: Vec<&str> = ens_lower.split('.').collect(); labels.reverse(); for label in labels {