diff --git a/.gitignore b/.gitignore index ded91645..33d110eb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ target Cargo.lock *.swp .idea/ +*.DS_Store diff --git a/Cargo.toml b/Cargo.toml index 7ca8a6f0..cbf98df4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,13 @@ [package] -name = "web3" -version = "0.19.0" -description = "Ethereum JSON-RPC client." -homepage = "https://github.com/tomusdrw/rust-web3" -repository = "https://github.com/tomusdrw/rust-web3" -documentation = "https://docs.rs/web3" +name = "web3_fe" +version = "0.1.0" +description = "Ethereum JSON-RPC client. Fathom Edition" +homepage = "https://github.com/Into-the-Fathom/rust-web3" +repository = "https://github.com/Into-the-Fathom/rust-web3" +documentation = "https://docs.rs/web3_fe" license = "MIT" keywords = ["jsonrpc", "web3", "ethereum", "rpc", "client"] -authors = ["Tomasz Drwięga "] +authors = ["Tomasz Drwięga ", "Zachary Short ", "Anton Grigorev "] readme = "README.md" edition = "2018" diff --git a/LICENSE b/LICENSE index 64fd35b0..76f84d1b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ MIT License -Copyright (c) 2019 Tomasz Drwięga +Original Copyright (c) 2019 Tomasz Drwięga +Modified Copyright (c) 2022 Fathom Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index a2b59643..e13891c3 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ -# web3 +# web3 FE Ethereum JSON-RPC multi-transport client. Rust implementation of Web3.js library. +Fathom Edition. -[![Build Status][ci-image]][ci-url] [![Crates.io](https://img.shields.io/crates/v/web3)](https://crates.io/crates/web3) +[![Build Status][ci-image]][ci-url] [![Crates.io](https://img.shields.io/crates/v/web3_fe)](https://crates.io/crates/web3_fe) -[ci-image]: https://github.com/tomusdrw/rust-web3/workflows/Compilation%20and%20Testing%20Suite/badge.svg -[ci-url]: https://github.com/tomusdrw/rust-web3/actions?query=workflow%3A%22Compilation+and+Testing+Suite%22 -[docs-rs-badge]: https://docs.rs/web3/badge.svg -[docs-rs-url]: https://docs.rs/web3 +[ci-image]: https://github.com/Into-the-Fathom/rust-web3/workflows/Compilation%20and%20Testing%20Suite/badge.svg +[ci-url]: https://github.com/Into-the-Fathom/rust-web3/actions?query=workflow%3A%22Compilation+and+Testing+Suite%22 +[docs-rs-badge]: https://docs.rs/web3_fe/badge.svg +[docs-rs-url]: https://docs.rs/web3_fe Documentation: [crates.io][docs-rs-url] @@ -18,15 +19,15 @@ First, add this to your `Cargo.toml`: ```toml [dependencies] -web3 = "0.17.0" +web3_fe = "0.1.0" ``` ## Example ```rust #[tokio::main] -async fn main() -> web3::Result<()> { - let transport = web3::transports::Http::new("http://localhost:8545")?; - let web3 = web3::Web3::new(transport); +async fn main() -> web3_fe::Result<()> { + let transport = web3_fe::transports::Http::new("http://localhost:8545")?; + let web3 = web3_fe::Web3::new(transport); println!("Calling accounts."); let mut accounts = web3.eth().accounts().await?; @@ -104,7 +105,7 @@ web3.api::().custom_method().wait().unwrap() Currently, Windows does not support IPC, which is enabled in the library by default. To compile, you need to disable the IPC feature: ``` -web3 = { version = "0.17.0", default-features = false, features = ["http"] } +web3_fe = { version = "0.1.0", default-features = false, features = ["http"] } ``` # Avoiding OpenSSL dependency @@ -112,7 +113,7 @@ web3 = { version = "0.17.0", default-features = false, features = ["http"] } On Linux, `native-tls` is implemented using OpenSSL. To avoid that dependency for HTTPS use the corresponding feature. ``` -web3 = { version = "0.17.0", default-features = false, features = ["http-rustls-tls"] } +web3_fe = { version = "0.1.0", default-features = false, features = ["http-rustls-tls"] } ``` # Cargo Features diff --git a/examples/bench.rs b/examples/bench.rs index 78dc2d83..95b7f087 100644 --- a/examples/bench.rs +++ b/examples/bench.rs @@ -5,26 +5,26 @@ use std::{ }; #[tokio::main] -async fn main() -> web3::Result { +async fn main() -> web3_fe::Result { let _ = env_logger::try_init(); let requests = 200_000; - let http = web3::transports::Http::new("http://localhost:8545/")?; + let http = web3_fe::transports::Http::new("http://localhost:8545/")?; bench("http", http, requests); - let ipc = web3::transports::WebSocket::new("./jsonrpc.ipc").await?; + let ipc = web3_fe::transports::WebSocket::new("./jsonrpc.ipc").await?; bench(" ipc", ipc, requests); Ok(()) } -fn bench(id: &str, transport: T, max: usize) +fn bench(id: &str, transport: T, max: usize) where T::Out: Send + 'static, { use futures::FutureExt; - let web3 = web3::Web3::new(transport); + let web3 = web3_fe::Web3::new(transport); let ticker = Arc::new(Ticker::new(id)); for _ in 0..max { diff --git a/examples/contract.rs b/examples/contract.rs index c45e7aa0..653fc8c8 100644 --- a/examples/contract.rs +++ b/examples/contract.rs @@ -1,14 +1,14 @@ use hex_literal::hex; -use web3::{ +use web3_fe::{ contract::{Contract, Options}, types::U256, }; #[tokio::main] -async fn main() -> web3::contract::Result<()> { +async fn main() -> web3_fe::contract::Result<()> { let _ = env_logger::try_init(); - let http = web3::transports::Http::new("http://localhost:8545")?; - let web3 = web3::Web3::new(http); + let http = web3_fe::transports::Http::new("http://localhost:8545")?; + let web3 = web3_fe::Web3::new(http); let my_account = hex!("d028d24f16a8893bd078259d413372ac01580769").into(); // Get the contract bytecode for instance from Solidity compiler diff --git a/examples/contract_log_filter.rs b/examples/contract_log_filter.rs index dff3ab8b..16249eec 100644 --- a/examples/contract_log_filter.rs +++ b/examples/contract_log_filter.rs @@ -1,15 +1,15 @@ use hex_literal::hex; use std::time; -use web3::{ +use web3_fe::{ contract::{Contract, Options}, futures::StreamExt, types::FilterBuilder, }; #[tokio::main] -async fn main() -> web3::contract::Result<()> { +async fn main() -> web3_fe::contract::Result<()> { let _ = env_logger::try_init(); - let web3 = web3::Web3::new(web3::transports::Http::new("http://localhost:8545")?); + let web3 = web3_fe::Web3::new(web3_fe::transports::Http::new("http://localhost:8545")?); // Get the contract bytecode for instance from Solidity compiler let bytecode = include_str!("./res/SimpleEvent.bin"); diff --git a/examples/contract_log_pubsub.rs b/examples/contract_log_pubsub.rs index 29133185..145cdcb3 100644 --- a/examples/contract_log_pubsub.rs +++ b/examples/contract_log_pubsub.rs @@ -1,15 +1,15 @@ use hex_literal::hex; use std::time; -use web3::{ +use web3_fe::{ contract::{Contract, Options}, futures::{future, StreamExt}, types::FilterBuilder, }; #[tokio::main] -async fn main() -> web3::contract::Result<()> { +async fn main() -> web3_fe::contract::Result<()> { let _ = env_logger::try_init(); - let web3 = web3::Web3::new(web3::transports::WebSocket::new("ws://localhost:8546").await?); + let web3 = web3_fe::Web3::new(web3_fe::transports::WebSocket::new("ws://localhost:8546").await?); // Get the contract bytecode for instance from Solidity compiler let bytecode = include_str!("./res/SimpleEvent.bin"); diff --git a/examples/contract_storage.rs b/examples/contract_storage.rs index 9b27d0c3..8411d4fd 100644 --- a/examples/contract_storage.rs +++ b/examples/contract_storage.rs @@ -1,16 +1,16 @@ //based on examples/contract.rs use std::time; -use web3::{ +use web3_fe::{ contract::{Contract, Options}, types::U256, }; #[tokio::main] -async fn main() -> web3::contract::Result<()> { +async fn main() -> web3_fe::contract::Result<()> { let _ = env_logger::try_init(); - let transport = web3::transports::Http::new("http://localhost:8545")?; - let web3 = web3::Web3::new(transport); + let transport = web3_fe::transports::Http::new("http://localhost:8545")?; + let web3 = web3_fe::Web3::new(transport); let accounts = web3.eth().accounts().await?; // Get current balance diff --git a/examples/pubsub.rs b/examples/pubsub.rs index 8c95e2b6..240c46da 100644 --- a/examples/pubsub.rs +++ b/examples/pubsub.rs @@ -1,9 +1,9 @@ -use web3::futures::{future, StreamExt}; +use web3_fe::futures::{future, StreamExt}; #[tokio::main] -async fn main() -> web3::Result { - let ws = web3::transports::WebSocket::new("ws://localhost:8546").await?; - let web3 = web3::Web3::new(ws.clone()); +async fn main() -> web3_fe::Result { + let ws = web3_fe::transports::WebSocket::new("ws://localhost:8546").await?; + let web3 = web3_fe::Web3::new(ws.clone()); let mut sub = web3.eth_subscribe().subscribe_new_heads().await?; println!("Got subscription id: {:?}", sub.id()); diff --git a/examples/transaction_private.rs b/examples/transaction_private.rs index 8df238c0..cc5fa52c 100644 --- a/examples/transaction_private.rs +++ b/examples/transaction_private.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use web3::{ +use web3_fe::{ ethabi::ethereum_types::U256, types::{Address, TransactionRequest}, }; @@ -8,9 +8,9 @@ use web3::{ /// Below sends a transaction to a local node that stores private keys (eg Ganache) /// For generating and signing a transaction offline, before transmitting it to a public node (eg Infura) see transaction_public #[tokio::main] -async fn main() -> web3::Result { - let transport = web3::transports::Http::new("http://localhost:7545")?; - let web3 = web3::Web3::new(transport); +async fn main() -> web3_fe::Result { + let transport = web3_fe::transports::Http::new("http://localhost:7545")?; + let web3 = web3_fe::Web3::new(transport); // Insert the 20-byte "from" address in hex format (prefix with 0x) let from = Address::from_str("0xC48ad5fd060e1400a41bcf51db755251AD5A2475").unwrap(); diff --git a/examples/transaction_public.rs b/examples/transaction_public.rs index cc0ea337..8609b7ce 100644 --- a/examples/transaction_public.rs +++ b/examples/transaction_public.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use secp256k1::SecretKey; -use web3::{ +use web3_fe::{ ethabi::ethereum_types::U256, types::{Address, TransactionParameters}, }; @@ -10,11 +10,11 @@ use web3::{ /// Below generates and signs a transaction offline, before transmitting it to a public node (eg Infura) /// For sending a transaction to a local node that stores private keys (eg Ganache) see transaction_private #[tokio::main] -async fn main() -> web3::Result { +async fn main() -> web3_fe::Result { // Sign up at infura > choose the desired network (eg Rinkeby) > copy the endpoint url into the below // If you need test ether use a faucet, eg https://faucet.rinkeby.io/ - let transport = web3::transports::Http::new("https://rinkeby.infura.io/v3/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")?; - let web3 = web3::Web3::new(transport); + let transport = web3_fe::transports::Http::new("https://rinkeby.infura.io/v3/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")?; + let web3 = web3_fe::Web3::new(transport); // Insert the 20-byte "to" address in hex format (prefix with 0x) let to = Address::from_str("0xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX").unwrap(); diff --git a/examples/transport_batch.rs b/examples/transport_batch.rs index b210bd81..dd1b050e 100644 --- a/examples/transport_batch.rs +++ b/examples/transport_batch.rs @@ -1,8 +1,8 @@ #[tokio::main] -async fn main() -> web3::Result { +async fn main() -> web3_fe::Result { let _ = env_logger::try_init(); - let http = web3::transports::Http::new("http://localhost:8545")?; - let web3 = web3::Web3::new(web3::transports::Batch::new(http)); + let http = web3_fe::transports::Http::new("http://localhost:8545")?; + let web3 = web3_fe::Web3::new(web3_fe::transports::Batch::new(http)); let accounts = web3.eth().accounts(); let block = web3.eth().block_number(); diff --git a/examples/transport_either.rs b/examples/transport_either.rs index 2173aee0..0e9def0d 100644 --- a/examples/transport_either.rs +++ b/examples/transport_either.rs @@ -1,17 +1,17 @@ use hex_literal::hex; -pub type Transport = web3::transports::Either; +pub type Transport = web3_fe::transports::Either; #[tokio::main] -async fn main() -> web3::Result { +async fn main() -> web3_fe::Result { let _ = env_logger::try_init(); - let transport = web3::transports::Http::new("http://localhost:8545")?; + let transport = web3_fe::transports::Http::new("http://localhost:8545")?; - run(web3::transports::Either::Right(transport)).await + run(web3_fe::transports::Either::Right(transport)).await } -async fn run(transport: Transport) -> web3::Result { - let web3 = web3::Web3::new(transport); +async fn run(transport: Transport) -> web3_fe::Result { + let web3 = web3_fe::Web3::new(transport); println!("Calling accounts."); let mut accounts = web3.eth().accounts().await?; diff --git a/examples/transport_http.rs b/examples/transport_http.rs index eb81b47b..179e4f09 100644 --- a/examples/transport_http.rs +++ b/examples/transport_http.rs @@ -1,10 +1,10 @@ use hex_literal::hex; #[tokio::main] -async fn main() -> web3::Result<()> { +async fn main() -> web3_fe::Result<()> { let _ = env_logger::try_init(); - let transport = web3::transports::Http::new("http://localhost:8545")?; - let web3 = web3::Web3::new(transport); + let transport = web3_fe::transports::Http::new("http://localhost:8545")?; + let web3 = web3_fe::Web3::new(transport); println!("Calling accounts."); let mut accounts = web3.eth().accounts().await?; diff --git a/examples/transport_ws.rs b/examples/transport_ws.rs index 4eaa178c..8c7fc4f0 100644 --- a/examples/transport_ws.rs +++ b/examples/transport_ws.rs @@ -1,10 +1,10 @@ use hex_literal::hex; #[tokio::main] -async fn main() -> web3::Result<()> { +async fn main() -> web3_fe::Result<()> { let _ = env_logger::try_init(); - let transport = web3::transports::WebSocket::new("ws://localhost:8546").await?; - let web3 = web3::Web3::new(transport); + let transport = web3_fe::transports::WebSocket::new("ws://localhost:8546").await?; + let web3 = web3_fe::Web3::new(transport); println!("Calling accounts."); let mut accounts = web3.eth().accounts().await?; diff --git a/src/types/block.rs b/src/types/block.rs index f67f7266..6bb93c9d 100644 --- a/src/types/block.rs +++ b/src/types/block.rs @@ -1,3 +1,8 @@ +use std::{ + fmt::{self, Debug}, + str::FromStr, +}; + use crate::types::{Bytes, H160, H2048, H256, H64, U256, U64}; use serde::{de::Error, ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer}; @@ -118,11 +123,27 @@ pub struct Block { fn null_to_default<'de, D, T>(deserializer: D) -> Result where - T: Default + Deserialize<'de>, + T: Default + Deserialize<'de> + FromStr + Debug, D: Deserializer<'de>, + ::Err: fmt::Debug, { - let option = Option::deserialize(deserializer)?; - Ok(option.unwrap_or_default()) + let option = String::deserialize(deserializer); + match option { + Ok(string) => { + if string.len() > 40 { + // Remove address prefix + let len = string.len(); + let author: &str = &string[len - 40..]; + let author = author.clone().to_string(); + let result: Option = Some(author.parse().unwrap()); + Ok(result.unwrap_or_default()) + } else { + let result: Option = Some(string.parse().unwrap()); + Ok(result.unwrap_or_default()) + } + } + Err(err) => Err(err), + } } /// Block Number diff --git a/src/types/log.rs b/src/types/log.rs index 9a1f5087..9a0abb12 100644 --- a/src/types/log.rs +++ b/src/types/log.rs @@ -1,10 +1,15 @@ use crate::types::{BlockNumber, Bytes, Index, H160, H256, U256, U64}; -use serde::{Deserialize, Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::{ + fmt::{self, Debug}, + str::FromStr, +}; /// A log produced by a transaction. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Log { /// H160 + #[serde(default, deserialize_with = "null_to_default")] pub address: H160, /// Topics pub topics: Vec, @@ -73,6 +78,31 @@ where } } +fn null_to_default<'de, D, T>(deserializer: D) -> Result +where + T: Default + Deserialize<'de> + FromStr + Debug, + D: Deserializer<'de>, + ::Err: fmt::Debug, +{ + let option = String::deserialize(deserializer); + match option { + Ok(string) => { + if string.len() > 40 { + // Remove address prefix + let len = string.len(); + let author: &str = &string[len - 40..]; + let author = author.clone().to_string(); + let result: Option = Some(author.parse().unwrap()); + Ok(result.unwrap_or_default()) + } else { + let result: Option = Some(string.parse().unwrap()); + Ok(result.unwrap_or_default()) + } + } + Err(err) => Err(err), + } +} + /// Filter #[derive(Default, Debug, PartialEq, Clone, Serialize)] pub struct Filter {