fix intradoc links and add missing cargo metadata (#29)

This commit is contained in:
Georgios Konstantopoulos 2020-06-20 16:55:07 +03:00 committed by GitHub
parent 7ff8b8222c
commit 4ff466a593
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 311 additions and 250 deletions

21
Cargo.lock generated
View File

@ -241,9 +241,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "ethabi" name = "ethabi-next"
version = "12.0.0" version = "12.0.0"
source = "git+https://github.com/gakonst/ethabi#bd8214a5897f323b4832cd56430eb74bc6e06cda" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1190707a051f20d9d966b187da7eaa4fa3f2a293911cdcb8541e76724980ac1b"
dependencies = [ dependencies = [
"ethereum-types", "ethereum-types",
"rustc-hex", "rustc-hex",
@ -282,7 +283,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers" name = "ethers"
version = "0.1.0" version = "0.1.3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"ethers-contract", "ethers-contract",
@ -297,7 +298,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-contract" name = "ethers-contract"
version = "0.1.0" version = "0.1.3"
dependencies = [ dependencies = [
"ethers", "ethers",
"ethers-contract-abigen", "ethers-contract-abigen",
@ -317,7 +318,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-contract-abigen" name = "ethers-contract-abigen"
version = "0.1.0" version = "0.1.3"
dependencies = [ dependencies = [
"Inflector", "Inflector",
"anyhow", "anyhow",
@ -334,7 +335,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-contract-derive" name = "ethers-contract-derive"
version = "0.1.0" version = "0.1.3"
dependencies = [ dependencies = [
"ethers-contract-abigen", "ethers-contract-abigen",
"ethers-core", "ethers-core",
@ -346,11 +347,11 @@ dependencies = [
[[package]] [[package]]
name = "ethers-core" name = "ethers-core"
version = "0.1.0" version = "0.1.3"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"bincode", "bincode",
"ethabi", "ethabi-next",
"ethereum-types", "ethereum-types",
"ethers", "ethers",
"glob", "glob",
@ -366,7 +367,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-providers" name = "ethers-providers"
version = "0.1.0" version = "0.1.3"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"ethers", "ethers",
@ -385,7 +386,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-signers" name = "ethers-signers"
version = "0.1.0" version = "0.1.3"
dependencies = [ dependencies = [
"ethers", "ethers",
"ethers-core", "ethers-core",

View File

@ -1,17 +1,21 @@
[package] [package]
name = "ethers-contract" name = "ethers-contract"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.1.0" version = "0.1.3"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
description = "Smart contract bindings for the ethers-rs crate"
homepage = "https://docs.rs/ethers"
repository = "https://github.com/gakonst/ethers-rs"
keywords = ["ethereum", "web3", "celo", "ethers"]
[dependencies] [dependencies]
ethers-contract-abigen = { version = "0.1.0", path = "ethers-contract-abigen", optional = true } ethers-contract-abigen = { version = "0.1.3", path = "ethers-contract-abigen", optional = true }
ethers-contract-derive = { version = "0.1.0", path = "ethers-contract-derive", optional = true } ethers-contract-derive = { version = "0.1.3", path = "ethers-contract-derive", optional = true }
ethers-providers = { version = "0.1.0", path = "../ethers-providers" } ethers-providers = { version = "0.1.3", path = "../ethers-providers" }
ethers-signers = { version = "0.1.0", path = "../ethers-signers" } ethers-signers = { version = "0.1.3", path = "../ethers-signers" }
ethers-core = { version = "0.1.0", path = "../ethers-core" } ethers-core = { version = "0.1.3", path = "../ethers-core" }
serde = { version = "1.0.110", default-features = false } serde = { version = "1.0.110", default-features = false }
rustc-hex = { version = "2.1.0", default-features = false } rustc-hex = { version = "2.1.0", default-features = false }
@ -20,7 +24,7 @@ once_cell = { version = "1.3.1", default-features = false }
futures = "0.3.5" futures = "0.3.5"
[dev-dependencies] [dev-dependencies]
ethers = { version = "0.1.0", path = "../ethers" } ethers = { version = "0.1.3", path = "../ethers" }
tokio = { version = "0.2.21", default-features = false, features = ["macros"] } tokio = { version = "0.2.21", default-features = false, features = ["macros"] }
serde_json = "1.0.55" serde_json = "1.0.55"
serial_test = "0.4.0" serial_test = "0.4.0"
@ -28,3 +32,7 @@ serial_test = "0.4.0"
[features] [features]
abigen = ["ethers-contract-abigen", "ethers-contract-derive"] abigen = ["ethers-contract-abigen", "ethers-contract-derive"]
celo = ["ethers-core/celo", "ethers-core/celo", "ethers-providers/celo", "ethers-signers/celo"] celo = ["ethers-core/celo", "ethers-core/celo", "ethers-providers/celo", "ethers-signers/celo"]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

View File

@ -1,13 +1,16 @@
[package] [package]
name = "ethers-contract-abigen" name = "ethers-contract-abigen"
version = "0.1.0" version = "0.1.3"
authors = ["Nicholas Rodrigues Lordello <nlordell@gmail.com>", "Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Nicholas Rodrigues Lordello <nlordell@gmail.com>", "Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "Code generation for type-safe bindings to Ethereum smart contracts" description = "Code generation for type-safe bindings to Ethereum smart contracts"
homepage = "https://docs.rs/ethers"
repository = "https://github.com/gakonst/ethers-rs"
keywords = ["ethereum", "web3", "celo", "ethers"]
[dependencies] [dependencies]
ethers-core = { path = "../../ethers-core" } ethers-core = { version = "0.1.3", path = "../../ethers-core" }
anyhow = "1.0" anyhow = "1.0"
curl = "0.4" curl = "0.4"
@ -19,3 +22,7 @@ url = "2.1"
serde_json = "1.0.53" serde_json = "1.0.53"
once_cell = "1.3.1" once_cell = "1.3.1"
rustc-hex = { version = "2.1.0", default-features = false } rustc-hex = { version = "2.1.0", default-features = false }
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

View File

@ -1,20 +1,27 @@
[package] [package]
name = "ethers-contract-derive" name = "ethers-contract-derive"
version = "0.1.0" version = "0.1.3"
authors = ["Nicholas Rodrigues Lordello <nlordell@gmail.com>", "Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Nicholas Rodrigues Lordello <nlordell@gmail.com>", "Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "Proc macro for type-safe bindings generation to Ethereum smart contracts" description = "Proc macro for type-safe bindings generation to Ethereum and Celo smart contracts"
homepage = "https://docs.rs/ethers"
repository = "https://github.com/gakonst/ethers-rs"
keywords = ["ethereum", "web3", "celo", "ethers"]
[lib] [lib]
proc-macro = true proc-macro = true
[dependencies] [dependencies]
ethers-core = { path = "../../ethers-core" } ethers-core = { version = "0.1.3", path = "../../ethers-core" }
ethers-contract-abigen = { path = "../ethers-contract-abigen" } ethers-contract-abigen = { version = "0.1.3", path = "../ethers-contract-abigen" }
serde_json = "1.0.53" serde_json = "1.0.53"
proc-macro2 = "1.0" proc-macro2 = "1.0"
quote = "1.0" quote = "1.0"
syn = "1.0.12" syn = "1.0.12"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

View File

@ -19,7 +19,6 @@ use syn::{parse::Error, parse_macro_input};
/// ///
/// ```ignore /// ```ignore
/// # use ethers_contract_derive::abigen; /// # use ethers_contract_derive::abigen;
///
/// // ABI Path /// // ABI Path
/// abigen!(MyContract, "MyContract.json"); /// abigen!(MyContract, "MyContract.json");
/// ///

View File

@ -56,10 +56,14 @@ use std::{collections::HashMap, fmt::Debug, hash::Hash, marker::PhantomData};
/// interact with its methods and retrieve raw logs it has emitted. /// interact with its methods and retrieve raw logs it has emitted.
/// ///
/// ```no_run /// ```no_run
/// use ethers_core::{abi::Abi, utils::Solc, types::{Address, H256}}; /// use ethers::{
/// use ethers_contract::Contract; /// abi::Abi,
/// use ethers_providers::{Provider, Http}; /// utils::Solc,
/// use ethers_signers::Wallet; /// types::{Address, H256},
/// contract::Contract,
/// providers::{Provider, Http},
/// signers::Wallet,
/// };
/// use std::convert::TryFrom; /// use std::convert::TryFrom;
/// ///
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> { /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
@ -154,9 +158,9 @@ use std::{collections::HashMap, fmt::Debug, hash::Hash, marker::PhantomData};
/// _Disclaimer: these above docs have been adapted from the corresponding [ethers.js page](https://docs.ethers.io/ethers.js/html/api-contract.html)_ /// _Disclaimer: these above docs have been adapted from the corresponding [ethers.js page](https://docs.ethers.io/ethers.js/html/api-contract.html)_
/// ///
/// [`abigen`]: macro.abigen.html /// [`abigen`]: macro.abigen.html
/// [`Abigen` builder]: struct.Abigen.html /// [`Abigen` builder]: crate::Abigen
/// [`event`]: struct.Contract.html#method.event /// [`event`]: method@crate::Contract::event
/// [`method`]: struct.Contract.html#method.method /// [`method`]: method@crate::Contract::method
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Contract<'a, P, S> { pub struct Contract<'a, P, S> {
client: &'a Client<P, S>, client: &'a Client<P, S>,
@ -187,7 +191,7 @@ where
} }
} }
/// Returns an `Event` builder for the provided event name. /// Returns an [`Event`](crate::builders::Event) builder for the provided event name.
pub fn event<D: Detokenize>(&self, name: &str) -> Result<Event<P, D>, Error> { pub fn event<D: Detokenize>(&self, name: &str) -> Result<Event<P, D>, Error> {
// get the event's full name // get the event's full name
let event = self.abi.event(name)?; let event = self.abi.event(name)?;

View File

@ -29,7 +29,7 @@ where
} }
/// Broadcasts the contract deployment transaction and after waiting for it to /// Broadcasts the contract deployment transaction and after waiting for it to
/// be sufficiently confirmed (default: 1), it returns a [`Contract`](./struct.Contract.html) /// be sufficiently confirmed (default: 1), it returns a [`Contract`](crate::Contract)
/// struct at the deployed contract's address. /// struct at the deployed contract's address.
pub async fn send(self) -> Result<Contract<'a, P, S>, ContractError> { pub async fn send(self) -> Result<Contract<'a, P, S>, ContractError> {
let pending_tx = self.client.send_transaction(self.tx, None).await?; let pending_tx = self.client.send_transaction(self.tx, None).await?;
@ -61,15 +61,17 @@ where
/// (ABI), usually generated from the Solidity compiler. /// (ABI), usually generated from the Solidity compiler.
/// ///
/// Once the factory's deployment transaction is mined with sufficient confirmations, /// Once the factory's deployment transaction is mined with sufficient confirmations,
/// the [`Contract`](./struct.Contract.html) object is returned. /// the [`Contract`](crate::Contract) object is returned.
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```no_run
/// use ethers_core::utils::Solc; /// use ethers::{
/// use ethers_contract::ContractFactory; /// utils::Solc,
/// use ethers_providers::{Provider, Http}; /// contract::ContractFactory,
/// use ethers_signers::Wallet; /// providers::{Provider, Http},
/// signers::Wallet
/// };
/// use std::convert::TryFrom; /// use std::convert::TryFrom;
/// ///
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> { /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {

View File

@ -1,3 +1,18 @@
#![cfg_attr(docsrs, feature(doc_cfg))]
//! Type-safe abstractions for interacting with Ethereum smart contracts
//!
//! Interacting with a smart contract requires broadcasting carefully crafted
//! [transactions](ethers_core::types::TransactionRequest) where the `data` field contains
//! the [function's
//! selector](https://ethereum.stackexchange.com/questions/72363/what-is-a-function-selector)
//! along with the arguments of the called function. This module provides the
//! [`Contract`] and [`ContractFactory`] abstractions so that you do not have to worry about that.
//! It also provides typesafe bindings via the [`abigen`] macro and the [`Abigen` builder].
//!
//! [`ContractFactory`]: crate::ContractFactory
//! [`Contract`]: crate::Contract
//! [`abigen`]: ./macro.abigen.html
//! [`Abigen` builder]: crate::Abigen
mod contract; mod contract;
pub use contract::Contract; pub use contract::Contract;
@ -18,9 +33,11 @@ pub mod builders {
} }
#[cfg(feature = "abigen")] #[cfg(feature = "abigen")]
#[cfg_attr(docsrs, doc(cfg(feature = "abigen")))]
pub use ethers_contract_abigen::Abigen; pub use ethers_contract_abigen::Abigen;
#[cfg(feature = "abigen")] #[cfg(feature = "abigen")]
#[cfg_attr(docsrs, doc(cfg(feature = "abigen")))]
pub use ethers_contract_derive::abigen; pub use ethers_contract_derive::abigen;
// Hide the Lazy re-export, it's just for convenience // Hide the Lazy re-export, it's just for convenience

View File

@ -1,15 +1,20 @@
[package] [package]
name = "ethers-core" name = "ethers-core"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.1.0" version = "0.1.3"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
description = "Core structures for the ethers-rs crate"
homepage = "https://docs.rs/ethers"
repository = "https://github.com/gakonst/ethers-rs"
keywords = ["ethereum", "web3", "celo", "ethers"]
[dependencies] [dependencies]
# ethereum related # ethereum related
ethereum-types = { version = "0.9.2", default-features = false, features = ["serialize"] } ethereum-types = { version = "0.9.2", default-features = false, features = ["serialize"] }
rlp = { version = "0.4.5", default-features = false } rlp = { version = "0.4.5", default-features = false }
ethabi = { git = "https://github.com/gakonst/ethabi", version = "12.0.0", default-features = false, optional = true } ethabi = { package = "ethabi-next", version = "12.0.0", default-features = false }
arrayvec = { version = "0.5.1", default-features = false }
# crypto # crypto
secp256k1 = { package = "libsecp256k1", version = "0.3.5" } secp256k1 = { package = "libsecp256k1", version = "0.3.5" }
@ -22,15 +27,17 @@ serde = { version = "1.0.110", default-features = false, features = ["derive"] }
serde_json = { version = "1.0.53", default-features = false, features = ["alloc"] } serde_json = { version = "1.0.53", default-features = false, features = ["alloc"] }
rustc-hex = { version = "2.1.0", default-features = false } rustc-hex = { version = "2.1.0", default-features = false }
thiserror = { version = "1.0.15", default-features = false } thiserror = { version = "1.0.15", default-features = false }
arrayvec = { version = "0.5.1", default-features = false, optional = true }
glob = "0.3.0" glob = "0.3.0"
[dev-dependencies] [dev-dependencies]
ethers = { version = "0.1.0", path = "../ethers" } ethers = { version = "0.1.3", path = "../ethers" }
serde_json = { version = "1.0.53", default-features = false } serde_json = { version = "1.0.53", default-features = false }
bincode = "1.2.1" bincode = "1.2.1"
[features] [features]
default = ["abi"]
celo = [] # celo support extends the transaction format with extra fields celo = [] # celo support extends the transaction format with extra fields
abi = ["ethabi", "arrayvec"]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

View File

@ -1,7 +1,46 @@
/// Ethereum related datatypes #![cfg_attr(docsrs, feature(doc_cfg))]
//! Ethereum types, cryptography and utilities.
//! _It is recommended to use the `utils`, `types` and `abi` re-exports instead of
//! the `core` module to simplify your imports._
//!
//! This library provides type definitions for Ethereum's main datatypes along
//! with other utilities for interacting with the Ethereum ecosystem
//!
//! ## Signing an ethereum-prefixed message
//!
//! Signing in Ethereum is done by first prefixing the message with
//! `"\x19Ethereum Signed Message:\n" + message.length`, and then
//! signing the hash of the result.
//!
//! ```rust
//! use ethers::core::types::{PrivateKey, Address};
//!
//! let message = "Some data";
//! let key = PrivateKey::new(&mut rand::thread_rng());
//! let address = Address::from(&key);
//!
//! // Sign the message
//! let signature = key.sign(message);
//!
//! // Recover the signer from the message
//! let recovered = signature.recover(message).unwrap();
//!
//! assert_eq!(recovered, address);
//! ```
//!
//! ## Utilities
//!
//! The crate provides utilities for launching local Ethereum testnets by using `ganache-cli`
//! via the `GanacheBuilder` struct. In addition, you're able to compile contracts on the
//! filesystem by providing a glob to their path, using the `Solc` struct.
//!
//! # ABI Encoding and Decoding
//!
//! This crate re-exports the [`ethabi`](ethabi) crate's functions
//! under the `abi` module, as well as the [`secp256k1`](https://docs.rs/libsecp256k1)
//! and [`rand`](https://docs.rs/rand) crates for convenience.
pub mod types; pub mod types;
#[cfg(feature = "abi")]
pub mod abi; pub mod abi;
/// Various utilities /// Various utilities

View File

@ -14,7 +14,7 @@ pub struct Log {
/// topics: Array of 0 to 4 32 Bytes of indexed log arguments. /// topics: Array of 0 to 4 32 Bytes of indexed log arguments.
/// (In solidity: The first topic is the hash of the signature of the event /// (In solidity: The first topic is the hash of the signature of the event
/// (e.g. Deposit(address,bytes32,uint256)), except you declared the event /// (e.g. `Deposit(address,bytes32,uint256)`), except you declared the event
/// with the anonymous specifier.) /// with the anonymous specifier.)
pub topics: Vec<H256>, pub topics: Vec<H256>,

View File

@ -54,16 +54,19 @@ pub struct TransactionRequest {
///////////////// Celo-specific transaction fields ///////////////// ///////////////// Celo-specific transaction fields /////////////////
/// The currency fees are paid in (None for native currency) /// The currency fees are paid in (None for native currency)
#[cfg(feature = "celo")] #[cfg(feature = "celo")]
#[cfg_attr(docsrs, doc(cfg(feature = "celo")))]
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub fee_currency: Option<Address>, pub fee_currency: Option<Address>,
/// Gateway fee recipient (None for no gateway fee paid) /// Gateway fee recipient (None for no gateway fee paid)
#[cfg(feature = "celo")] #[cfg(feature = "celo")]
#[cfg_attr(docsrs, doc(cfg(feature = "celo")))]
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub gateway_fee_recipient: Option<Address>, pub gateway_fee_recipient: Option<Address>,
/// Gateway fee amount (None for no gateway fee paid) /// Gateway fee amount (None for no gateway fee paid)
#[cfg(feature = "celo")] #[cfg(feature = "celo")]
#[cfg_attr(docsrs, doc(cfg(feature = "celo")))]
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub gateway_fee: Option<U256>, pub gateway_fee: Option<U256>,
} }
@ -203,18 +206,21 @@ impl TransactionRequest {
} }
/// Sets the `fee_currency` field in the transaction to the provided value /// Sets the `fee_currency` field in the transaction to the provided value
#[cfg_attr(docsrs, doc(cfg(feature = "celo")))]
pub fn fee_currency<T: Into<Address>>(mut self, fee_currency: T) -> Self { pub fn fee_currency<T: Into<Address>>(mut self, fee_currency: T) -> Self {
self.fee_currency = Some(fee_currency.into()); self.fee_currency = Some(fee_currency.into());
self self
} }
/// Sets the `gateway_fee` field in the transaction to the provided value /// Sets the `gateway_fee` field in the transaction to the provided value
#[cfg_attr(docsrs, doc(cfg(feature = "celo")))]
pub fn gateway_fee<T: Into<U256>>(mut self, gateway_fee: T) -> Self { pub fn gateway_fee<T: Into<U256>>(mut self, gateway_fee: T) -> Self {
self.gateway_fee = Some(gateway_fee.into()); self.gateway_fee = Some(gateway_fee.into());
self self
} }
/// Sets the `gateway_fee_recipient` field in the transaction to the provided value /// Sets the `gateway_fee_recipient` field in the transaction to the provided value
#[cfg_attr(docsrs, doc(cfg(feature = "celo")))]
pub fn gateway_fee_recipient<T: Into<Address>>(mut self, gateway_fee_recipient: T) -> Self { pub fn gateway_fee_recipient<T: Into<Address>>(mut self, gateway_fee_recipient: T) -> Self {
self.gateway_fee_recipient = Some(gateway_fee_recipient.into()); self.gateway_fee_recipient = Some(gateway_fee_recipient.into());
self self
@ -285,11 +291,13 @@ pub struct Transaction {
///////////////// Celo-specific transaction fields ///////////////// ///////////////// Celo-specific transaction fields /////////////////
/// The currency fees are paid in (None for native currency) /// The currency fees are paid in (None for native currency)
#[cfg(feature = "celo")] #[cfg(feature = "celo")]
#[cfg_attr(docsrs, doc(cfg(feature = "celo")))]
#[serde(skip_serializing_if = "Option::is_none", rename = "feeCurrency")] #[serde(skip_serializing_if = "Option::is_none", rename = "feeCurrency")]
pub fee_currency: Option<Address>, pub fee_currency: Option<Address>,
/// Gateway fee recipient (None for no gateway fee paid) /// Gateway fee recipient (None for no gateway fee paid)
#[cfg(feature = "celo")] #[cfg(feature = "celo")]
#[cfg_attr(docsrs, doc(cfg(feature = "celo")))]
#[serde( #[serde(
skip_serializing_if = "Option::is_none", skip_serializing_if = "Option::is_none",
rename = "gatewayFeeRecipient" rename = "gatewayFeeRecipient"
@ -298,6 +306,7 @@ pub struct Transaction {
/// Gateway fee amount (None for no gateway fee paid) /// Gateway fee amount (None for no gateway fee paid)
#[cfg(feature = "celo")] #[cfg(feature = "celo")]
#[cfg_attr(docsrs, doc(cfg(feature = "celo")))]
#[serde(skip_serializing_if = "Option::is_none", rename = "gatewayFee")] #[serde(skip_serializing_if = "Option::is_none", rename = "gatewayFee")]
pub gateway_fee: Option<U256>, pub gateway_fee: Option<U256>,
} }

View File

@ -1,3 +1,4 @@
//! Ethereum related datatypes
mod crypto; mod crypto;
pub use crypto::*; pub use crypto::*;

View File

@ -7,7 +7,7 @@ const SLEEP_TIME: Duration = Duration::from_secs(3);
/// A ganache CLI instance. Will close the instance when dropped. /// A ganache CLI instance. Will close the instance when dropped.
/// ///
/// Construct this using [`Ganache`](./struct.Ganache.html) /// Construct this using [`Ganache`](crate::utils::Ganache)
pub struct GanacheInstance(Child); pub struct GanacheInstance(Child);
impl Drop for GanacheInstance { impl Drop for GanacheInstance {

View File

@ -1,12 +1,16 @@
[package] [package]
name = "ethers-providers" name = "ethers-providers"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.1.0" version = "0.1.3"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
description = "Provider implementations for the ethers-rs crate"
homepage = "https://docs.rs/ethers"
repository = "https://github.com/gakonst/ethers-rs"
keywords = ["ethereum", "web3", "celo", "ethers"]
[dependencies] [dependencies]
ethers-core = { version = "0.1.0", path = "../ethers-core" } ethers-core = { version = "0.1.3", path = "../ethers-core" }
async-trait = { version = "0.1.31", default-features = false } async-trait = { version = "0.1.31", default-features = false }
reqwest = { version = "0.10.4", default-features = false, features = ["json", "rustls-tls"] } reqwest = { version = "0.10.4", default-features = false, features = ["json", "rustls-tls"] }
@ -22,10 +26,14 @@ pin-project = { version = "0.4.20", default-features = false }
tokio = { version = "0.2.21", default-features = false, features = ["time"] } tokio = { version = "0.2.21", default-features = false, features = ["time"] }
[dev-dependencies] [dev-dependencies]
ethers = { version = "0.1.0", path = "../ethers" } ethers = { version = "0.1.3", path = "../ethers" }
rustc-hex = "2.1.0" rustc-hex = "2.1.0"
tokio = { version = "0.2.21", default-features = false, features = ["rt-core", "macros"] } tokio = { version = "0.2.21", default-features = false, features = ["rt-core", "macros"] }
[features] [features]
celo = ["ethers-core/celo"] celo = ["ethers-core/celo"]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

View File

@ -22,7 +22,7 @@ use url::Url;
/// ///
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> { /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// let provider = Http::from_str("http://localhost:8545")?; /// let provider = Http::from_str("http://localhost:8545")?;
/// let block_number: U64 = provider.request("eth_blockNumber", None::<()>).await?; /// let block_number: U64 = provider.request("eth_blockNumber", ()).await?;
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```

View File

@ -1,3 +1,55 @@
#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(intra_doc_link_resolution_failure)]
//! # Clients for interacting with Ethereum nodes
//!
//! This crate provides asynchronous [Ethereum JSON-RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC)
//! compliant clients.
//!
//! For more documentation on the available calls, refer to the [`Provider`](crate::Provider)
//! struct.
//!
//! # Examples
//!
//! ```no_run
//! use ethers::providers::{Provider, Http};
//! use std::convert::TryFrom;
//!
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
//! let provider = Provider::<Http>::try_from(
//! "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27"
//! )?;
//!
//! let block = provider.get_block(100u64).await?;
//! println!("Got block: {}", serde_json::to_string(&block)?);
//!
//! let code = provider.get_code("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359", None).await?;
//! println!("Got code: {}", serde_json::to_string(&code)?);
//! # Ok(())
//! # }
//! ```
//!
//! # Ethereum Name Service
//!
//! The provider may also be used to resolve [Ethereum Name Service](https://ens.domains) (ENS) names
//! to addresses (and vice versa). The default ENS address is [mainnet](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e) and can be overriden by calling the [`ens`](method@crate::Provider::ens) method on the provider.
//!
//! ```no_run
//! # use ethers::providers::{Provider, Http};
//! # use std::convert::TryFrom;
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
//! # let provider = Provider::<Http>::try_from(
//! # "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27"
//! # )?;
//! // Resolve ENS name to Address
//! let name = "vitalik.eth";
//! let address = provider.resolve_name(name).await?;
//!
//! // Lookup ENS name given Address
//! let resolved_name = provider.lookup_address(address).await?;
//! assert_eq!(name, resolved_name);
//! # Ok(())
//! # }
//! ```
mod http; mod http;
pub use http::Provider as Http; pub use http::Provider as Http;

View File

@ -22,8 +22,8 @@ use std::{convert::TryFrom, fmt::Debug};
/// An abstract provider for interacting with the [Ethereum JSON RPC /// An abstract provider for interacting with the [Ethereum JSON RPC
/// API](https://github.com/ethereum/wiki/wiki/JSON-RPC). Must be instantiated /// API](https://github.com/ethereum/wiki/wiki/JSON-RPC). Must be instantiated
/// with a data transport which implements the [`JsonRpcClient`](trait.JsonRpcClient.html) trait /// with a data transport which implements the [`JsonRpcClient`](trait@crate::JsonRpcClient) trait
/// (e.g. [HTTP](struct.Http.html), Websockets etc.) /// (e.g. [HTTP](crate::Http), Websockets etc.)
/// ///
/// # Example /// # Example
/// ///
@ -378,12 +378,15 @@ impl<P: JsonRpcClient> Provider<P> {
/// ///
/// This method must be called with one of the following return types, depending on the filter /// This method must be called with one of the following return types, depending on the filter
/// type: /// type:
/// - `eth_newBlockFilter`: `H256`, returns block hashes /// - `eth_newBlockFilter`: [`H256`], returns block hashes
/// - `eth_newPendingTransactionFilter`: `H256`, returns transaction hashes /// - `eth_newPendingTransactionFilter`: [`H256`], returns transaction hashes
/// - `eth_newFilter`: `Log`, returns raw logs /// - `eth_newFilter`: [`Log`], returns raw logs
/// ///
/// If one of these types is not used, decoding will fail and the method will /// If one of these types is not used, decoding will fail and the method will
/// return an error. /// return an error.
///
/// [`H256`]: ethers_core::types::H256
/// [`Log`]: ethers_core::types::Log
pub async fn get_filter_changes<T, R>(&self, id: T) -> Result<Vec<R>, ProviderError> pub async fn get_filter_changes<T, R>(&self, id: T) -> Result<Vec<R>, ProviderError>
where where
T: Into<U256>, T: Into<U256>,

View File

@ -17,7 +17,7 @@ use tokio::time::{interval, Interval};
const DEFAULT_POLL_DURATION: Duration = Duration::from_millis(7000); const DEFAULT_POLL_DURATION: Duration = Duration::from_millis(7000);
/// Trait for streaming filters. You can get the id. /// Trait for streaming filters.
pub trait FilterStream<R>: StreamExt + Stream<Item = R> pub trait FilterStream<R>: StreamExt + Stream<Item = R>
where where
R: for<'de> Deserialize<'de>, R: for<'de> Deserialize<'de>,

View File

@ -1,21 +1,30 @@
[package] [package]
name = "ethers-signers" name = "ethers-signers"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.1.0" version = "0.1.3"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
edition = "2018" edition = "2018"
description = "Signer implementations for the ethers-rs crate"
homepage = "https://docs.rs/ethers"
repository = "https://github.com/gakonst/ethers-rs"
keywords = ["ethereum", "web3", "celo", "ethers"]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[dependencies] [dependencies]
ethers-core = { version = "0.1.0", path = "../ethers-core" } ethers-core = { version = "0.1.3", path = "../ethers-core" }
ethers-providers = { version = "0.1.0", path = "../ethers-providers" } ethers-providers = { version = "0.1.3", path = "../ethers-providers" }
thiserror = { version = "1.0.15", default-features = false } thiserror = { version = "1.0.15", default-features = false }
futures-util = { version = "0.3.5", default-features = false } futures-util = { version = "0.3.5", default-features = false }
serde = "1.0.112" serde = "1.0.112"
[dev-dependencies] [dev-dependencies]
ethers = { version = "0.1.0", path = "../ethers" } ethers = { version = "0.1.3", path = "../ethers" }
tokio = { version = "0.2.21", features = ["macros"] } tokio = { version = "0.2.21", features = ["macros"] }
serde_json = "1.0.55"
[features] [features]
celo = ["ethers-core/celo", "ethers-providers/celo"] celo = ["ethers-core/celo", "ethers-providers/celo"]

View File

@ -68,7 +68,7 @@ use thiserror::Error;
/// ///
/// ``` /// ```
/// ///
/// [`Provider`]: ../ethers_providers/struct.Provider.html /// [`Provider`]: ethers_providers::Provider
pub struct Client<P, S> { pub struct Client<P, S> {
pub(crate) provider: Provider<P>, pub(crate) provider: Provider<P>,
pub(crate) signer: S, pub(crate) signer: S,

View File

@ -1,3 +1,42 @@
//! Provides a unified interface for locally signing transactions and interacting
//! with the Ethereum JSON-RPC. You can implement the `Signer` trait to extend
//! functionality to other signers such as Hardware Security Modules, KMS etc.
//!
//! ```no_run
//! # use ethers::{
//! providers::{Http, Provider},
//! signers::Wallet,
//! core::types::TransactionRequest
//! };
//! # use std::convert::TryFrom;
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
//! // connect to the network
//! let provider = Provider::<Http>::try_from("http://localhost:8545")?;
//!
//! // instantiate the wallet and connect it to the provider to get a client
//! let client = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7"
//! .parse::<Wallet>()?
//! .connect(provider);
//!
//! // create a transaction
//! let tx = TransactionRequest::new()
//! .to("vitalik.eth") // this will use ENS
//! .value(10000);
//!
//! // send it! (this will resolve the ENS name to an address under the hood)
//! let pending_tx = client.send_transaction(tx, None).await?;
//!
//! // get the receipt
//! let receipt = pending_tx.await?;
//!
//! // get the mined tx
//! let tx = client.get_transaction(receipt.transaction_hash).await?;
//!
//! println!("{}", serde_json::to_string(&tx)?);
//! println!("{}", serde_json::to_string(&receipt)?);
//!
//! # Ok(())
//! # }
mod wallet; mod wallet;
pub use wallet::Wallet; pub use wallet::Wallet;

View File

@ -59,10 +59,10 @@ use std::str::FromStr;
/// ``` /// ```
/// ///
/// ///
/// [`Client`]: ./struct.Client.html /// [`Client`]: crate::Client
/// [`connect`]: ./struct.Wallet.html#method.connect /// [`connect`]: method@crate::Wallet::connect
/// [`Signature`]: ../ethers_core/types/struct.Signature.html /// [`Signature`]: ethers_core::types::Signature
/// [`hash_message`]: ../ethers_core/utils/fn.hash_message.html /// [`hash_message`]: fn@ethers_core::utils::hash_message
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Wallet { pub struct Wallet {
/// The Wallet's private Key /// The Wallet's private Key

View File

@ -1,10 +1,10 @@
[package] [package]
name = "ethers" name = "ethers"
version = "0.1.0" version = "0.1.3"
authors = ["Georgios Konstantopoulos <me@gakonst.com>"] authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
edition = "2018" edition = "2018"
readme = "README.md" readme = "../README.md"
documentation = "https://docs.rs/ethers" documentation = "https://docs.rs/ethers"
repository = "https://github.com/gakonst/ethers-rs" repository = "https://github.com/gakonst/ethers-rs"
homepage = "https://docs.rs/ethers" homepage = "https://docs.rs/ethers"
@ -42,13 +42,13 @@ providers = ["ethers-providers"]
signers = ["ethers-signers"] signers = ["ethers-signers"]
[dependencies] [dependencies]
ethers-contract = { version = "0.1.0", path = "../ethers-contract", optional = true } ethers-contract = { version = "0.1.3", path = "../ethers-contract", optional = true }
ethers-core = { version = "0.1.0", path = "../ethers-core", optional = true } ethers-core = { version = "0.1.3", path = "../ethers-core", optional = true }
ethers-providers = { version = "0.1.0", path = "../ethers-providers", optional = true } ethers-providers = { version = "0.1.3", path = "../ethers-providers", optional = true }
ethers-signers = { version = "0.1.0", path = "../ethers-signers", optional = true } ethers-signers = { version = "0.1.3", path = "../ethers-signers", optional = true }
[dev-dependencies] [dev-dependencies]
ethers-contract = { version = "0.1.0", path = "../ethers-contract", features = ["abigen"] } ethers-contract = { version = "0.1.3", path = "../ethers-contract", features = ["abigen"] }
anyhow = "1.0.31" anyhow = "1.0.31"
rand = "0.7" rand = "0.7"

View File

@ -9,9 +9,8 @@
no_crate_inject, no_crate_inject,
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
))] ))]
#![cfg_attr(docsrs, feature(doc_cfg))]
//! # ethers-rs //! # Complete Ethereum & Celo library and wallet implementation.
//! //!
//! > ethers-rs is a port of [ethers-js](github.com/ethers-io/ethers.js) in Rust. //! > ethers-rs is a port of [ethers-js](github.com/ethers-io/ethers.js) in Rust.
//! //!
@ -24,20 +23,20 @@
//! A prelude is provided which imports all the important data types and traits for you. Use this //! A prelude is provided which imports all the important data types and traits for you. Use this
//! when you want to quickly bootstrap a new project. //! when you want to quickly bootstrap a new project.
//! //!
//! ``` //! ```no_run
//! # #[allow(unused)] //! # #[allow(unused)]
//! use ethers::prelude::*; //! use ethers::prelude::*;
//! ``` //! ```
//! //!
//! Examples on how you can use the types imported by the prelude can be found in //! Examples on how you can use the types imported by the prelude can be found in
//! the [`examples` directory of the repository](https://github.com/gakonst/ethers-rs) //! the [`examples` directory of the repository](https://github.com/gakonst/ethers-rs/tree/master/ethers/examples)
//! and in the `tests/` directories of each crate. //! and in the `tests/` directories of each crate.
//! //!
//! # Quick explanation of each module in ascending order of abstraction //! # Quick explanation of each module in ascending order of abstraction
//! //!
//! ## `core` //! ## `core`
//! //!
//! Contains all the [necessary data structures](core/types/index.html) for interacting //! Contains all the [necessary data structures](core::types) for interacting
//! with Ethereum, along with cryptographic utilities for signing and verifying //! with Ethereum, along with cryptographic utilities for signing and verifying
//! ECDSA signatures on `secp256k1`. Bindings to the solidity compiler and `ganache-cli` //! ECDSA signatures on `secp256k1`. Bindings to the solidity compiler and `ganache-cli`
//! are also provided as helpers. To simplify your imports, consider using the re-exported //! are also provided as helpers. To simplify your imports, consider using the re-exported
@ -67,204 +66,54 @@
//! using smart contracts, which can be thought of as programs with persistent storage. //! using smart contracts, which can be thought of as programs with persistent storage.
//! //!
//! Interacting with a smart contract requires broadcasting carefully crafted //! Interacting with a smart contract requires broadcasting carefully crafted
//! [transactions](core/types/struct.TransactionRequest.html) where the `data` field contains //! [transactions](core::types::TransactionRequest) where the `data` field contains
//! the [function's //! the [function's
//! selector](https://ethereum.stackexchange.com/questions/72363/what-is-a-function-selector) //! selector](https://ethereum.stackexchange.com/questions/72363/what-is-a-function-selector)
//! along with the arguments of the called function. This module provides the //! along with the arguments of the called function. This module provides the
//! [`Contract`] and [`ContractFactory`] abstractions so that you do not have to worry about that. //! [`Contract`] and [`ContractFactory`] abstractions so that you do not have to worry about that.
//! It also provides typesafe bindings via the [`abigen`] macro and the [`Abigen` builder]. //! It also provides typesafe bindings via the [`abigen`] macro and the [`Abigen` builder].
//! //!
//! [`Provider`]: providers/struct.Provider.html //! [`Provider`]: providers::Provider
//! //!
//! [`Wallet`]: signers/struct.Wallet.html //! [`Wallet`]: signers::Wallet
//! [`Client`]: signers/struct.Client.html //! [`Client`]: signers::Client
//! //!
//! [`ContractFactory`]: contract/struct.ContractFactory.html //! [`ContractFactory`]: contract::ContractFactory
//! [`Contract`]: contract/struct.Contract.html //! [`Contract`]: contract::Contract
//! [`abigen`]: contract/macro.abigen.html //! [`abigen`]: ./contract/macro.abigen.html
//! [`Abigen` builder]: contract/struct.Abigen.html //! [`Abigen` builder]: contract::Abigen
//! //!
//! [`utils`]: core/utils/index.html //! [`utils`]: core::utils
//! [`abi`]: core/abi/index.html //! [`abi`]: core::abi
//! [`types`]: core/types/index.html //! [`types`]: core::types
#[cfg(feature = "contract")] #[cfg(feature = "contract")]
#[cfg_attr(docsrs, doc(cfg(feature = "contract")))] pub use ethers_contract as contract;
// This is copied over from the crate-level docs, is there a better way to do this?
/// Type-safe abstractions for interacting with Ethereum smart contracts
///
/// Interacting with a smart contract requires broadcasting carefully crafted
/// [transactions](core/types/struct.TransactionRequest.html) where the `data` field contains
/// the [function's
/// selector](https://ethereum.stackexchange.com/questions/72363/what-is-a-function-selector)
/// along with the arguments of the called function. This module provides the
/// [`Contract`] and [`ContractFactory`] abstractions so that you do not have to worry about that.
/// It also provides typesafe bindings via the [`abigen`] macro and the [`Abigen` builder].
///
/// [`ContractFactory`]: struct.ContractFactory.html
/// [`Contract`]: struct.Contract.html
/// [`abigen`]: macro.abigen.html
/// [`Abigen` builder]: struct.Abigen.html
pub mod contract {
pub use ethers_contract::*;
}
#[cfg(feature = "providers")] #[cfg(feature = "providers")]
#[cfg_attr(docsrs, doc(cfg(feature = "providers")))] pub use ethers_providers as providers;
/// # Clients for interacting with Ethereum nodes
///
/// This crate provides asynchronous [Ethereum JSON-RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC)
/// compliant clients.
///
/// For more documentation on the available calls, refer to the [`Provider`](struct.Provider.html)
/// struct.
///
/// # Examples
///
/// ```no_run
/// use ethers::providers::{Provider, Http};
/// use std::convert::TryFrom;
///
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// let provider = Provider::<Http>::try_from(
/// "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27"
/// )?;
///
/// let block = provider.get_block(100u64).await?;
/// println!("Got block: {}", serde_json::to_string(&block)?);
///
/// let code = provider.get_code("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359", None).await?;
/// println!("Got code: {}", serde_json::to_string(&code)?);
/// # Ok(())
/// # }
/// ```
///
/// # Ethereum Name Service
///
/// The provider may also be used to resolve [Ethereum Name Service](https://ens.domains) (ENS) names
/// to addresses (and vice versa). The default ENS address is [mainnet](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e) and can be overriden by calling the [`ens`](struct.Provider.html#method.ens) method on the provider.
///
/// ```no_run
/// # use ethers::providers::{Provider, Http};
/// # use std::convert::TryFrom;
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// # let provider = Provider::<Http>::try_from(
/// # "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27"
/// # )?;
/// // Resolve ENS name to Address
/// let name = "vitalik.eth";
/// let address = provider.resolve_name(name).await?;
///
/// // Lookup ENS name given Address
/// let resolved_name = provider.lookup_address(address).await?;
/// assert_eq!(name, resolved_name);
/// # Ok(())
/// # }
/// ```
pub mod providers {
pub use ethers_providers::*;
}
#[cfg(feature = "signers")] #[cfg(feature = "signers")]
#[cfg_attr(docsrs, doc(cfg(feature = "signers")))] pub use ethers_signers as signers;
/// Provides a unified interface for locally signing transactions and interacting
/// with the Ethereum JSON-RPC. You can implement the `Signer` trait to extend
/// functionality to other signers such as Hardware Security Modules, KMS etc.
///
/// ```no_run
/// # use ethers::{
/// providers::{Http, Provider},
/// signers::Wallet,
/// core::types::TransactionRequest
/// };
/// # use std::convert::TryFrom;
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// // connect to the network
/// let provider = Provider::<Http>::try_from("http://localhost:8545")?;
///
/// // instantiate the wallet and connect it to the provider to get a client
/// let client = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7"
/// .parse::<Wallet>()?
/// .connect(provider);
///
/// // create a transaction
/// let tx = TransactionRequest::new()
/// .to("vitalik.eth") // this will use ENS
/// .value(10000);
///
/// // send it! (this will resolve the ENS name to an address under the hood)
/// let pending_tx = client.send_transaction(tx, None).await?;
///
/// // get the receipt
/// let receipt = pending_tx.await?;
///
/// // get the mined tx
/// let tx = client.get_transaction(receipt.transaction_hash).await?;
///
/// println!("{}", serde_json::to_string(&tx)?);
/// println!("{}", serde_json::to_string(&receipt)?);
///
/// # Ok(())
/// # }
pub mod signers {
pub use ethers_signers::*;
}
#[cfg(feature = "core")] #[cfg(feature = "core")]
#[cfg_attr(docsrs, doc(cfg(feature = "core")))] pub use ethers_core as core;
/// Ethereum types, cryptography and utilities.
/// _It is recommended to use the `utils`, `types` and `abi` re-exports instead of
/// the `core` module to simplify your imports._
///
/// This library provides type definitions for Ethereum's main datatypes along
/// with other utilities for interacting with the Ethereum ecosystem
///
/// ## Signing an ethereum-prefixed message
///
/// Signing in Ethereum is done by first prefixing the message with
/// `"\x19Ethereum Signed Message:\n" + message.length`, and then
/// signing the hash of the result.
///
/// ```rust
/// use ethers::core::types::{PrivateKey, Address};
///
/// let message = "Some data";
/// let key = PrivateKey::new(&mut rand::thread_rng());
/// let address = Address::from(&key);
///
/// // Sign the message
/// let signature = key.sign(message);
///
/// // Recover the signer from the message
/// let recovered = signature.recover(message).unwrap();
///
/// assert_eq!(recovered, address);
/// ```
///
/// ## Utilities
///
/// The crate provides utilities for launching local Ethereum testnets by using `ganache-cli`
/// via the `GanacheBuilder` struct. In addition, you're able to compile contracts on the
/// filesystem by providing a glob to their path, using the `Solc` struct.
///
/// # ABI Encoding and Decoding
///
/// This crate re-exports the [`ethabi`](http://docs.rs/ethabi) crate's functions
/// under the `abi` module, as well as the [`secp256k1`](https://docs.rs/libsecp256k1)
/// and [`rand`](https://docs.rs/rand) crates for convenience.
pub mod core {
pub use ethers_core::*;
}
// Re-export ethers_core::utils/types/abi // Re-export ethers_core::utils/types/abi
// We hide these docs so that the rustdoc links send the visitor
// to the corresponding crate, instead of the re-export
#[doc(hidden)]
#[cfg(feature = "core")] #[cfg(feature = "core")]
pub use ethers_core::abi; pub use ethers_core::abi;
#[doc(hidden)]
#[cfg(feature = "core")] #[cfg(feature = "core")]
pub use ethers_core::types; pub use ethers_core::types;
#[doc(hidden)]
#[cfg(feature = "core")] #[cfg(feature = "core")]
pub use ethers_core::utils; pub use ethers_core::utils;
/// Easy imports of frequently used type definitions and traits /// Easy imports of frequently used type definitions and traits
#[doc(hidden)]
pub mod prelude { pub mod prelude {
#[cfg(feature = "contract")] #[cfg(feature = "contract")]
pub use ethers_contract::*; pub use ethers_contract::*;