docs: fix broken links, update documentation (#2203)

* docs: fix broken links

* docs: update READMEs and module-level documentation
This commit is contained in:
DaniPopes 2023-02-27 21:03:17 +01:00 committed by GitHub
parent 620300f357
commit 203e350940
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 393 additions and 338 deletions

View File

@ -22,7 +22,7 @@ us!
The ethers-rs project adheres to the [Rust Code of Conduct][coc]. This describes
the _minimum_ behavior expected from all contributors. Instances of violations of the Code of Conduct can be reported by contacting the project team at [me@gakonst.com](mailto:me@gakonst.com).
[coc]: https://github.com/rust-lang/rust/blob/master/CODE_OF_CONDUCT.md
[coc]: https://www.rust-lang.org/policies/code-of-conduct
## Contributing in Issues

View File

@ -9,7 +9,7 @@ readme = "README.md"
documentation = "https://docs.rs/ethers"
repository = "https://github.com/gakonst/ethers-rs"
homepage = "https://docs.rs/ethers"
description = "Complete Ethereum library and wallet implementation in Rust."
description = "A complete Ethereum and Celo Rust library"
[workspace]
members = [

104
README.md
View File

@ -1,6 +1,6 @@
# <h1 align="center"> ethers.rs </h1>
# <h1 align="center"> ethers-rs </h1>
**Complete Ethereum and Celo wallet implementation and utilities in Rust**
**A complete Ethereum and Celo Rust library**
![Github Actions](https://github.com/gakonst/ethers-rs/workflows/Tests/badge.svg)
[![Telegram Chat](https://img.shields.io/endpoint?color=neon&style=flat-square&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fethers_rs)](https://t.me/ethers_rs)
@ -9,42 +9,34 @@
[crates-badge]: https://img.shields.io/crates/v/ethers.svg
[crates-url]: https://crates.io/crates/ethers
## Quickstart
Add this to your Cargo.toml:
```toml
[dependencies]
ethers = "1.0.2"
```
And this to your code:
```rust
use ethers::prelude::*;
```
## Documentation
Extensive documentation and examples are available [here](https://docs.rs/ethers).
Alternatively, you may clone the repository and run `cd ethers/ && cargo doc --open`
View the API reference [here](https://docs.rs/ethers) or the online book [here](https://gakonst.com/ethers-rs).
Examples are organized into individual crates under the `/examples` folder.
You can run any of the examples by executing:
You can run any of the examples by executing:
```bash
# cargo run -p <example-crate-name> --example <name>
cargo run -p examples-big-numbers --example math_operations
```
## Add ethers-rs to your repository
```toml
[dependencies]
ethers = "1.0.0"
```
</details>
## Running the tests
Tests require the following installed:
1. [`solc`](https://solidity.readthedocs.io/en/latest/installing-solidity.html) (>=0.8.10). We also recommend using [solc-select](https://github.com/crytic/solc-select) for more flexibility.
2. [`anvil`](https://github.com/foundry-rs/foundry/blob/master/anvil/README.md)
3. [`geth`](https://github.com/ethereum/go-ethereum)
In addition, it is recommended that you set the `ETHERSCAN_API_KEY` environment variable
for [the abigen via Etherscan](https://github.com/gakonst/ethers-rs/blob/master/ethers-contract/tests/it/abigen.rs) tests.
You can get one [here](https://etherscan.io/apis).
### EVM-compatible chains support
## EVM-compatible chains support
There are many chains live which are Ethereum JSON-RPC & EVM compatible, but do not yet have
support for [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) Typed Transactions. This means
@ -53,8 +45,7 @@ address that, you must use the `legacy` feature flag:
```toml
[dependencies]
ethers = { version = "1.0.0", features = ["legacy"] }
ethers = { version = "1.0.2", features = ["legacy"] }
```
### Polygon support
@ -73,8 +64,7 @@ You can get one [here](https://snowtrace.io/apis).
```toml
[dependencies]
ethers = { version = "1.0.0", features = ["celo"] }
ethers = { version = "1.0.2", features = ["celo"] }
```
Celo's transactions differ from Ethereum transactions by including 3 new fields:
@ -111,8 +101,7 @@ Websockets support is turned on via the feature-flag `ws`:
```toml
[dependencies]
ethers = { version = "1.0.0", features = ["ws"] }
ethers = { version = "1.0.2", features = ["ws"] }
```
### Interprocess Communication (IPC)
@ -121,8 +110,7 @@ IPC support is turned on via the feature-flag `ipc`:
```toml
[dependencies]
ethers = { version = "1.0.0", features = ["ipc"] }
ethers = { version = "1.0.2", features = ["ipc"] }
```
### HTTP Secure (HTTPS)
@ -134,16 +122,14 @@ To enable `rustls`:
```toml
[dependencies]
ethers = { version = "1.0.0", features = ["rustls"] }
ethers = { version = "1.0.2", features = ["rustls"] }
```
To enable `openssl`:
```toml
[dependencies]
ethers = { version = "1.0.0", features = ["openssl"] }
ethers = { version = "1.0.2", features = ["openssl"] }
```
## Note on WASM and FFI bindings
@ -171,24 +157,22 @@ Join the [ethers-rs telegram](https://t.me/ethers_rs) to chat with the community
## Contributing
Thanks for your help improving the project! We are so happy to have you! We have
[a contributing guide](https://github.com/gakonst/ethers-rs/blob/master/CONTRIBUTING.md) to
help you get involved in the ethers-rs project.
[a contributing guide](./CONTRIBUTING.md) to help you get involved in the ethers-rs project.
If you make a Pull Request, do not forget to add your changes in the [CHANGELOG](CHANGELOG.md) and ensure your code is
properly formatted with `cargo +nightly fmt` and clippy is happy `cargo clippy`, you can even try to let clippy fix simple
issues itself: `cargo +nightly clippy --fix -Z unstable-options`
If you open a Pull Request, do not forget to add your changes in the [CHANGELOG](./CHANGELOG.md), ensure your code is
properly formatted with `cargo +nightly fmt` and that Clippy is happy `cargo clippy`; you can even try to let clippy fix simple
issues itself: `cargo +nightly clippy --fix`
## Related Projects
### Running the tests
This library would not have been possible without the great work done in:
Tests require the following installed:
- [`ethers.js`](https://github.com/ethers-io/ethers.js/)
- [`rust-web3`](https://github.com/tomusdrw/rust-web3/)
- [`ethcontract-rs`](https://github.com/gnosis/ethcontract-rs/)
- [`guac_rs`](https://github.com/althea-net/guac_rs/tree/master/web3/src/jsonrpc)
1. [`solc`](https://docs.soliditylang.org/en/latest/installing-solidity.html) (>=0.8.0). We also recommend using [svm](https://github.com/roynalnaruto/svm-rs) for more flexibility.
2. [`anvil`](https://github.com/foundry-rs/foundry/blob/master/anvil/README.md)
3. [`geth`](https://github.com/ethereum/go-ethereum)
A lot of the code was inspired and adapted from them, to a unified and opinionated interface,
built with async/await and std futures from the ground up.
Additionally, the `ETHERSCAN_API_KEY` environment variable has to be set to run [`ethers-etherscan`](./ethers-etherscan) tests.
You can get one [here](https://etherscan.io/apis).
## Projects using ethers-rs
@ -199,3 +183,15 @@ built with async/await and std futures from the ground up.
- [Celo Threshold BLS DKG](https://github.com/celo-org/celo-threshold-bls-rs/): CLI for using Celo as a data availability network for the Joint-Feldman BLS DKG
- [Celo Plumo Prover](https://github.com/celo-org/plumo-prover): Creates Celo's ultralight client proof from on-chain data
- [Celo SNARK Setup Coordinator](https://github.com/celo-org/snark-setup-operator): Coordinator for executing a pipelined Groth16 SNARK setup
## Credits
This library would not have been possible without the great work done in:
- [`ethers.js`](https://github.com/ethers-io/ethers.js/)
- [`rust-web3`](https://github.com/tomusdrw/rust-web3/)
- [`ethcontract-rs`](https://github.com/gnosis/ethcontract-rs/)
- [`guac_rs`](https://github.com/althea-net/guac_rs/)
A lot of the code was inspired and adapted from them, to a unified and opinionated interface,
built with async/await and std futures from the ground up.

View File

@ -1 +0,0 @@
../ethers-contract/README.md

View File

@ -1 +0,0 @@
../ethers-core/README.md

View File

@ -1 +0,0 @@
../ethers-middleware/README.md

View File

@ -1 +0,0 @@
../ethers-providers/README.md

View File

@ -1 +0,0 @@
../ethers-signers/README.md

View File

@ -1 +0,0 @@
../ethers-solc/README.md

View File

@ -11,8 +11,8 @@ repository = "https://github.com/gakonst/ethers-rs"
keywords = ["ethereum", "web3", "celo", "ethers"]
[dependencies]
ethers-core = { version = "^1.0.0", path = "../ethers-core", default-features = false }
once_cell = "1.17.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
ethers-core = { path = "../ethers-core", version = "^1.0.0" }

View File

@ -0,0 +1,15 @@
# ethers-addressbook
A collection of commonly used smart contract addresses.
For more information, please refer to the [book](https://gakonst.com/ethers-rs).
## Examples
```rust
use ethers_addressbook::{contract, Chain};
let weth = contract("weth").unwrap();
let mainnet_address = weth.address(Chain::Mainnet).unwrap();
assert_eq!(mainnet_address, "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".parse().unwrap());
```

View File

@ -1,7 +1,10 @@
use ethers_core::types::{Address, Chain};
#![doc = include_str!("../README.md")]
#![deny(unsafe_code, rustdoc::broken_intra_doc_links)]
pub use ethers_core::types::{Address, Chain};
use once_cell::sync::Lazy;
use serde::Deserialize;
use std::collections::HashMap;
const CONTRACTS_JSON: &str = include_str!("./contracts/contracts.json");
@ -9,7 +12,7 @@ const CONTRACTS_JSON: &str = include_str!("./contracts/contracts.json");
static ADDRESSBOOK: Lazy<HashMap<String, Contract>> =
Lazy::new(|| serde_json::from_str(CONTRACTS_JSON).unwrap());
/// Wrapper around a hash map that maps a [chain](https://github.com/gakonst/ethers-rs/blob/master/ethers-core/src/types/chain.rs) to the contract's deployed address on that chain.
/// Wrapper around a hash map that maps a [Chain] to the contract's deployed address on that chain.
#[derive(Clone, Debug, Deserialize)]
pub struct Contract {
addresses: HashMap<Chain, Address>,

View File

@ -1,4 +1,6 @@
Type-safe abstractions for interacting with Ethereum smart contracts
# ethers-core
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
@ -10,6 +12,8 @@ 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].
For more information, please refer to the [book](https://gakonst.com/ethers-rs).
[`contractfactory`]: ./struct.ContractFactory.html
[`contract`]: ./struct.Contract.html
[`abigen`]: ./macro.abigen.html

View File

@ -371,8 +371,8 @@ impl Context {
/// convention of suffixing the function name with _with
///
/// The first function or the function with the least amount of arguments should
/// be named as in the ABI, the following functions suffixed with _with_ +
/// additional_params[0].name + (_and_(additional_params[1+i].name))*
/// be named as in the ABI, the following functions suffixed with:
/// `_with_ + additional_params[0].name + (_and_(additional_params[1+i].name))*`
fn get_method_aliases(&self) -> Result<BTreeMap<String, MethodAlias>> {
let mut aliases = self.method_aliases.clone();

View File

@ -119,7 +119,7 @@ impl Source {
/// Parse `s` as an explorer ("etherscan"), explorer domain ("etherscan.io") or a chain that has
/// an explorer ("mainnet").
///
/// The URL can be either <explorer>:<address> or <explorer_url>/.../<address>
/// The URL can be either `<explorer>:<address>` or `<explorer_url>/.../<address>`
fn from_explorer(s: &str, url: &Url) -> Result<Self> {
let explorer: Explorer = s.parse().or_else(|_| Explorer::from_chain(s.parse()?))?;
let address = last_segment_address(url).ok_or_else(|| eyre::eyre!("Invalid URL: {url}"))?;

View File

@ -1,4 +1,6 @@
# Ethereum types, cryptography and utilities.
# ethers-core
Ethereum data 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.
@ -6,43 +8,43 @@ 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
For more information, please refer to the [book](https://gakonst.com/ethers-rs).
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.
## Feature flags
```rust,ignore
# async fn foo() -> Result<(), Box<dyn std::error::Error>> {
use ethers::signers::{Signer, LocalWallet};
- `eip712`: Provides the `Eip712` trait and derive procedural macro for EIP-712 encoding of typed data.
let message = "Some data";
let wallet = LocalWallet::new(&mut rand::thread_rng());
## ABI
// Sign the message
let signature = wallet.sign_message(message).await?;
// Recover the signer from the message
let recovered = signature.recover(message)?;
assert_eq!(recovered, wallet.address());
# Ok(())
# }
```
This crate re-exports the [`ethabi`](https://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.
## Utilities
The crate provides utilities for launching local Ethereum testnets by using
`ganache-cli` via the `GanacheBuilder` struct.
# Features
## Examples
- ["eip712"] | Provides Eip712 trait for EIP-712 encoding of typed data for
derived structs
Calculate the UniswapV2 pair address for two ERC20 tokens:
# ABI Encoding and Decoding
```rust
# use ethers_core::abi::{self, Token};
# use ethers_core::types::{Address, H256};
# use ethers_core::utils;
let factory: Address = "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f".parse()?;
This crate re-exports the [`ethabi`](https://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.
let token_a: Address = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48".parse()?;
let token_b: Address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".parse()?;
let encoded = abi::encode_packed(&[Token::Address(token_a), Token::Address(token_b)])?;
let salt = utils::keccak256(encoded);
let init_code_hash: H256 = "0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f".parse()?;
let pair = utils::get_create2_address_from_hash(factory, salt, init_code_hash);
let weth_usdc = "0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc".parse()?;
assert_eq!(pair, weth_usdc);
# Ok::<(), Box<dyn std::error::Error>>(())
```

View File

@ -1,5 +1,7 @@
//! This module implements extensions to the [`ethabi`](https://docs.rs/ethabi) API.
// Adapted from [Gnosis' ethcontract](https://github.com/gnosis/ethcontract-rs/blob/master/common/src/abiext.rs)
//! Extensions to the [`ethabi`](https://docs.rs/ethabi) API.
//!
//! Adapted from [Gnosis' `ethcontract-rs`](https://github.com/gnosis/ethcontract-rs).
use crate::{
types::{Bytes, Selector, Uint8, H256, H512, I256, U128, U256, U64},
utils::id,

View File

@ -1,3 +1,5 @@
//! Ethereum data types.
pub type Selector = [u8; 4];
// Re-export common ethereum datatypes with more specific names

View File

@ -0,0 +1,22 @@
# ethers-etherscan
Bindings for the [etherscan.io web API](https://docs.etherscan.io).
For more information, please refer to the [book](https://gakonst.com/ethers-rs).
## Examples
```rust,no_run
# use ethers_core::types::Chain;
# use ethers_etherscan::Client;
# async fn foo() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new(Chain::Mainnet, "<your_api_key>")?;
// Or using environment variables
let client = Client::new_from_env(Chain::Mainnet)?;
let address = "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".parse()?;
let metadata = client.contract_source_code(address).await?;
assert_eq!(metadata.items[0].contract_name, "DAO");
# Ok(())
# }
```

View File

@ -363,14 +363,12 @@ impl Client {
/// ```no_run
/// # use ethers_etherscan::Client;
/// # use ethers_core::types::Chain;
///
/// # #[tokio::main]
/// # async fn main() {
/// let client = Client::new(Chain::Mainnet, "API_KEY").unwrap();
/// let meta = client
/// .contract_source_code("0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".parse().unwrap())
/// .await.unwrap();
/// let code = meta.source_code();
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// let client = Client::new(Chain::Mainnet, "<your_api_key>")?;
/// let address = "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".parse()?;
/// let metadata = client.contract_source_code(address).await?;
/// assert_eq!(metadata.items[0].contract_name, "DAO");
/// # Ok(())
/// # }
/// ```
pub async fn contract_source_code(&self, address: Address) -> Result<ContractMetadata> {

View File

@ -1,4 +1,5 @@
//! Bindings for [etherscan.io web api](https://docs.etherscan.io/)
#![doc = include_str!("../README.md")]
#![deny(unsafe_code, rustdoc::broken_intra_doc_links)]
use crate::errors::{is_blocked_by_cloudflare_response, is_cloudflare_security_challenge};
use contract::ContractMetadata;

View File

@ -1,93 +1,83 @@
# ethers-middleware
Your ethers application interacts with the blockchain through a [`Provider`](ethers_providers::Provider) abstraction. [`Provider`](ethers_providers::Provider) is a special type of [`Middleware`](ethers_providers::Middleware) that can be composed with others to obtain a layered architecture. This approach promotes "Open Closed Principle", "Single Responsibility" and composable patterns. The building process happens in a wrapping fashion, and starts from a [`Provider`](ethers_providers::Provider) being the first element in the stack. This process continues having new middlewares being pushed on top of a layered data structure.
For more information, please refer to the [book](https://gakonst.com/ethers-rs).
## Available Middleware
- [`Signer`](./signer/struct.SignerMiddleware.html): Signs transactions locally, with a private key or a hardware wallet.
- [`Nonce Manager`](./nonce_manager/struct.NonceManagerMiddleware.html): Manages nonces locally. Allows to sign multiple consecutive transactions without waiting for them to hit the mempool.
- [`Gas Escalator`](./gas_escalator/struct.GasEscalatorMiddleware.html): Bumps transactions gas price in the background to avoid getting them stuck in the memory pool. A [`GasEscalatorMiddleware`](crate::gas_escalator::GasEscalatorMiddleware) supports different escalation strategies (see [GasEscalator](crate::gas_escalator::GasEscalator)) and bump frequencies (see [Frequency](crate::gas_escalator::Frequency)).
- [`Gas Oracle`](./gas_oracle/struct.GasOracleMiddleware.html): Allows getting
your gas price estimates from places other than `eth_gasPrice`, including REST based gas stations (i.e. Etherscan, ETH Gas Station etc.).
- [`Transformer`](./transformer/trait.Transformer.html): Allows intercepting and
transforming a transaction to be broadcasted via a proxy wallet, e.g.
[`DSProxy`](./transformer/struct.DsProxy.html).
- [`Signer`](./signer/struct.SignerMiddleware.html): Signs transactions locally, with a private key or a hardware wallet.
- [`Nonce Manager`](./nonce_manager/struct.NonceManagerMiddleware.html): Manages nonces locally. Allows to sign multiple consecutive transactions without waiting for them to hit the mempool.
- [`Gas Escalator`](./gas_escalator/struct.GasEscalatorMiddleware.html): Bumps transactions gas price in the background to avoid getting them stuck in the memory pool. A [`GasEscalatorMiddleware`](crate::gas_escalator::GasEscalatorMiddleware) supports different escalation strategies (see [GasEscalator](crate::gas_escalator::GasEscalator)) and bump frequencies (see [Frequency](crate::gas_escalator::Frequency)).
- [`Gas Oracle`](./gas_oracle/struct.GasOracleMiddleware.html): Allows getting
your gas price estimates from places other than `eth_gasPrice`, including REST based gas stations (i.e. Etherscan, ETH Gas Station etc.).
- [`Transformer`](./transformer/trait.Transformer.html): Allows intercepting and
transforming a transaction to be broadcasted via a proxy wallet, e.g.
[`DSProxy`](./transformer/struct.DsProxy.html).
## Stacking middlewares using a builder
## Examples
Each [`Middleware`](ethers_providers::Middleware) implements the trait [MiddlewareBuilder](crate::MiddlewareBuilder). This trait helps a developer to compose a custom [`Middleware`](ethers_providers::Middleware) stack.
The following example shows how to build a composed [`Middleware`](ethers_providers::Middleware) starting from a [`Provider`](ethers_providers::Provider):
```rust
use ethers_providers::{Middleware, Provider, Http};
use std::sync::Arc;
use std::convert::TryFrom;
use ethers_signers::{LocalWallet, Signer};
use ethers_middleware::{gas_oracle::{GasOracle, GasNow}, MiddlewareBuilder};
# use ethers_providers::{Middleware, Provider, Http};
# use ethers_signers::{LocalWallet, Signer};
# use ethers_middleware::{gas_oracle::GasNow, MiddlewareBuilder};
let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
let signer = key.parse::<LocalWallet>()?;
let address = signer.address();
let gas_oracle = GasNow::new();
fn builder_example() {
let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
let signer = key.parse::<LocalWallet>().unwrap();
let address = signer.address();
let gas_oracle = GasNow::new();
let provider = Provider::<Http>::try_from("http://localhost:8545")
.unwrap()
.gas_oracle(gas_oracle)
.with_signer(signer)
.nonce_manager(address); // Outermost layer
}
let provider = Provider::<Http>::try_from("http://localhost:8545")?
.gas_oracle(gas_oracle)
.with_signer(signer)
.nonce_manager(address); // Outermost layer
# Ok::<_, Box<dyn std::error::Error>>(())
```
The [wrap_into](crate::MiddlewareBuilder::wrap_into) function can be used to wrap [`Middleware`](ethers_providers::Middleware) layers explicitly. This is useful when pushing [`Middleware`](ethers_providers::Middleware)s not directly handled by the builder interface.
```rust
use ethers_providers::{Middleware, Provider, Http};
use std::sync::Arc;
use std::convert::TryFrom;
use ethers_signers::{LocalWallet, Signer};
use ethers_middleware::{*,gas_escalator::*,gas_oracle::*};
```rust,no_run
# use ethers_providers::{Middleware, Provider, Http};
# use std::convert::TryFrom;
# use ethers_signers::{LocalWallet, Signer};
# use ethers_middleware::{*,gas_escalator::*,gas_oracle::*};
let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
let signer = key.parse::<LocalWallet>()?;
let address = signer.address();
let escalator = GeometricGasPrice::new(1.125, 60_u64, None::<u64>);
fn builder_example_wrap_into() {
let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
let signer = key.parse::<LocalWallet>().unwrap();
let address = signer.address();
let escalator = GeometricGasPrice::new(1.125, 60_u64, None::<u64>);
let provider = Provider::<Http>::try_from("http://localhost:8545")
.unwrap()
.wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock))
.wrap_into(|p| SignerMiddleware::new(p, signer))
.wrap_into(|p| GasOracleMiddleware::new(p, GasNow::new()))
.wrap_into(|p| NonceManagerMiddleware::new(p, address)); // Outermost layer
}
let provider = Provider::<Http>::try_from("http://localhost:8545")?
.wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock))
.wrap_into(|p| SignerMiddleware::new(p, signer))
.wrap_into(|p| GasOracleMiddleware::new(p, GasNow::new()))
.wrap_into(|p| NonceManagerMiddleware::new(p, address)); // Outermost layer
# Ok::<_, Box<dyn std::error::Error>>(())
```
## Stacking middlewares manually
A [`Middleware`](ethers_providers::Middleware) stack can be also constructed manually. This is achieved by explicitly wrapping layers.
```rust no_run
use ethers_providers::{Provider, Http};
use ethers_signers::{LocalWallet, Signer};
use ethers_middleware::{
gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency},
gas_oracle::{GasOracleMiddleware, GasCategory, GasNow},
signer::SignerMiddleware,
nonce_manager::NonceManagerMiddleware,
};
use ethers_core::rand;
use std::convert::TryFrom;
```rust,no_run
# use ethers_providers::{Provider, Http};
# use ethers_signers::{LocalWallet, Signer};
# use ethers_middleware::{
# gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency},
# gas_oracle::{GasOracleMiddleware, GasCategory, GasNow},
# signer::SignerMiddleware,
# nonce_manager::NonceManagerMiddleware,
# };
// Start the stack
let provider = Provider::<Http>::try_from("http://localhost:8545").unwrap();
let provider = Provider::<Http>::try_from("http://localhost:8545")?;
// Escalate gas prices
let escalator = GeometricGasPrice::new(1.125, 60u64, None::<u64>);
let provider = GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock);
// Sign transactions with a private key
let signer = LocalWallet::new(&mut rand::thread_rng());
let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
let signer = key.parse::<LocalWallet>()?;
let address = signer.address();
let provider = SignerMiddleware::new(provider, signer);
@ -97,6 +87,5 @@ let provider = GasOracleMiddleware::new(provider, gas_oracle);
// Manage nonces locally
let provider = NonceManagerMiddleware::new(provider, address);
// ... do something with the provider
# Ok::<_, Box<dyn std::error::Error>>(())
```

View File

@ -75,21 +75,20 @@ impl GasOracle for Median {
}
}
/// Weighted fractile by key
/// Weighted fractile by key.
///
/// Sort the values in place by key and return the weighted fractile value such
/// that `fractile` fraction of the values by weight are less than or equal to
/// the value.
/// Sort the values in place by key and return the weighted fractile value such that `fractile`
/// fraction of the values by weight are less than or equal to the value.
///
/// Returns None if the values are empty.
/// Returns `None` if the values are empty.
///
/// Note: it doesn't handle NaNs or other special float values.
///
/// See <https://en.wikipedia.org/wiki/Percentile#The_weighted_percentile_method>
/// See: <https://en.wikipedia.org/wiki/Percentile#The_weighted_percentile_method>
///
/// # Panics
///
/// Panics if [`fractile`] is not in the range $[0, 1]$.
/// Panics if `fractile` is not in the range `0.0..=1.0`.
fn weighted_fractile_by_key<'a, T, F, K>(
fractile: f32,
values: &'a mut [(f32, T)],

View File

@ -1,6 +1,5 @@
#![doc = include_str!("../README.md")]
#![deny(unsafe_code)]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(unsafe_code, rustdoc::broken_intra_doc_links)]
/// The [Gas Escalator middleware](crate::gas_escalator::GasEscalatorMiddleware)
/// is used to re-broadcast transactions with an increasing gas price to guarantee

View File

@ -1,24 +1,58 @@
# Clients for interacting with Ethereum nodes
# ethers-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.
For more information, please refer to the [book](https://gakonst.com/ethers-rs).
# Examples
## Websockets
```no_run
use ethers_core::types::Address;
use ethers_providers::{Provider, Http, Middleware};
use std::convert::TryFrom;
This crate supports for WebSockets via `tokio-tungstenite`.
Please ensure that you have the `ws` feature enabled if you wish to use WebSockets:
```toml
[dependencies]
ethers-providers = { version = "1.0.2", features = ["ws"] }
```
## Interprocess Communication (IPC)
This crate supports for Interprocess Communication via Unix sockets and Windows named pipes.
Please ensure that you have the `ipc` feature enabled if you wish to use IPC:
```toml
[dependencies]
ethers-providers = { version = "1.0.2", features = ["ipc"] }
```
## 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 [`0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e`][ens]
and can be overriden with the [`ens`](./struct.Provider.html#method.ens) method on the provider.
[ens]: https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
## Examples
```rust,no_run
# use ethers_core::types::Address;
# use ethers_providers::{Provider, Http, Middleware, Ws};
# async fn foo() -> Result<(), Box<dyn std::error::Error>> {
// HTTP Provider
let provider = Provider::<Http>::try_from(
"https://mainnet.infura.io/v3/YOUR_API_KEY"
)?;
// Websocket Provider
let provider = Provider::<Ws>::connect(
"wss://mainnet.infura.io/v3/YOUR_API_KEY"
).await?;
let block = provider.get_block(100u64).await?;
println!("Got block: {}", serde_json::to_string(&block)?);
@ -29,30 +63,10 @@ println!("Got code: {}", serde_json::to_string(&code)?);
# }
```
# Websockets
Using ENS:
The crate has support for WebSockets via Tokio. Please ensure that you have the "ws" and "rustls" / "openssl" features enabled if you wish to use WebSockets.
```
# async fn foo() -> Result<(), Box<dyn std::error::Error>> {
# use ethers_providers::Ws;
let ws = Ws::connect("ws://localhost:8545").await?;
# 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
```rust,no_run
# use ethers_providers::{Provider, Http, Middleware};
# use std::convert::TryFrom;
# async fn foo() -> Result<(), Box<dyn std::error::Error>> {
# let provider = Provider::<Http>::try_from(
# "https://mainnet.infura.io/v3/YOUR_API_KEY"

View File

@ -1,9 +1,8 @@
#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(unsafe_code)]
#![deny(rustdoc::broken_intra_doc_links)]
#![allow(clippy::type_complexity)]
#![doc = include_str!("../README.md")]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![allow(clippy::type_complexity)]
#![warn(missing_docs)]
#![deny(unsafe_code, rustdoc::broken_intra_doc_links)]
mod ext;
pub use ext::*;

View File

@ -24,9 +24,10 @@ pub struct JsonRpcError {
pub data: Option<Value>,
}
/// Recursively traverses the value, looking for hex data that it can extract
/// Recursively traverses the value, looking for hex data that it can extract.
///
/// Inspired by ethers-js logic:
/// https://github.com/ethers-io/ethers.js/blob/9f990c57f0486728902d4b8e049536f2bb3487ee/packages/providers/src.ts/json-rpc-provider.ts#L25-L53
/// <https://github.com/ethers-io/ethers.js/blob/9f990c57f0486728902d4b8e049536f2bb3487ee/packages/providers/src.ts/json-rpc-provider.ts#L25-L53>
fn spelunk_revert(value: &Value) -> Option<Bytes> {
match value {
Value::String(s) => s.parse().ok(),

View File

@ -1,3 +1,7 @@
# ethers-signers
A unified interface for locally signing transactions.
You can implement the `Signer` trait to extend functionality to other signers
such as Hardware Security Modules, KMS etc.
@ -13,10 +17,16 @@ Supported signers:
- [YubiHSM2](./src/wallet/yubi.rs)
- [AWS KMS](./src/aws)
```no_run
For more information, please refer to the [book](https://gakonst.com/ethers-rs).
[`transaction`]: ethers_core::types::Transaction
[`transactionrequest`]: ethers_core::types::TransactionRequest
## Examples
```rust,no_run
# use ethers_signers::{LocalWallet, Signer};
# use ethers_core::{k256::ecdsa::SigningKey, types::TransactionRequest};
# async fn foo() -> Result<(), Box<dyn std::error::Error>> {
// instantiate the wallet
let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7"
@ -37,5 +47,21 @@ signature.verify("hello world", wallet.address()).unwrap();
# }
```
[`transaction`]: ethers_core::types::Transaction
[`transactionrequest`]: ethers_core::types::TransactionRequest
Sign an Ethereum prefixed message ([eip-712](https://eips.ethereum.org/EIPS/eip-712)):
```rust,no_run
# use ethers_signers::{Signer, LocalWallet};
# async fn foo() -> Result<(), Box<dyn std::error::Error>> {
let message = "Some data";
let wallet = LocalWallet::new(&mut rand::thread_rng());
// Sign the message
let signature = wallet.sign_message(message).await?;
// Recover the signer from the message
let recovered = signature.recover(message)?;
assert_eq!(recovered, wallet.address());
# Ok(())
# }
```

View File

@ -1,6 +1,5 @@
//! Provides a unified interface for locally signing transactions.
#![deny(unsafe_code)]
#![deny(rustdoc::broken_intra_doc_links)]
#![doc = include_str!("../README.md")]
#![deny(unsafe_code, rustdoc::broken_intra_doc_links)]
mod wallet;
pub use wallet::{MnemonicBuilder, Wallet, WalletError};

View File

@ -463,7 +463,7 @@ impl CacheEntry {
/// Reads all artifact files associated with the `CacheEntry`
///
/// **Note:** all artifact file paths should be absolute, see [`Self::join`]
/// **Note:** all artifact file paths should be absolute.
fn read_artifact_files<Artifact: DeserializeOwned>(
&self,
) -> Result<BTreeMap<String, Vec<ArtifactFile<Artifact>>>> {
@ -579,27 +579,32 @@ impl CacheEntry {
/// and which `Artifacts` can be reused.
#[derive(Debug)]
pub(crate) struct ArtifactsCacheInner<'a, T: ArtifactOutput> {
/// preexisting cache file
/// The preexisting cache file.
pub cache: SolFilesCache,
/// all already existing artifacts
/// All already existing artifacts.
pub cached_artifacts: Artifacts<T::Artifact>,
/// relationship between all the files
/// Relationship between all the files.
pub edges: GraphEdges,
/// the project
/// The project.
pub project: &'a Project<T>,
/// all files that were filtered because they haven't changed
/// All the files that were filtered because they haven't changed.
pub filtered: HashMap<PathBuf, (Source, HashSet<Version>)>,
/// the corresponding cache entries for all sources that were deemed to be dirty
/// The corresponding cache entries for all sources that were deemed to be dirty.
///
/// `CacheEntry` are grouped by their solidity file.
/// `CacheEntry` are grouped by their Solidity file.
/// During preprocessing the `artifacts` field of a new `CacheEntry` is left blank, because in
/// order to determine the artifacts of the solidity file, the file needs to be compiled first.
/// Only after the `CompilerOutput` is received and all compiled contracts are handled, see
/// [`crate::ArtifactOutput::on_output()`] all artifacts, their disk paths, are determined and
/// can be populated before the updated [`crate::SolFilesCache`] is finally written to disk,
/// see [`Cache::finish()`]
/// [`crate::ArtifactOutput::on_output`] all artifacts, their disk paths, are determined and
/// can be populated before the updated [`crate::SolFilesCache`] is finally written to disk.
pub dirty_source_files: HashMap<PathBuf, (CacheEntry, HashSet<Version>)>,
/// the file hashes
/// The file hashes.
pub content_hashes: HashMap<PathBuf, String>,
}
@ -652,7 +657,7 @@ impl<'a, T: ArtifactOutput> ArtifactsCacheInner<'a, T> {
}
}
/// Returns the set of [Source]s that need to be included in the [CompilerOutput] in order to
/// Returns the set of [Source]s that need to be included in the `CompilerOutput` in order to
/// recompile the project.
///
/// We define _dirty_ sources as files that:
@ -661,12 +666,12 @@ impl<'a, T: ArtifactOutput> ArtifactsCacheInner<'a, T> {
/// - their imports were changed
/// - their artifact is missing
///
/// A _dirty_ file is always included in the [CompilerInput].
/// A _dirty_ file is always included in the `CompilerInput`.
/// A _dirty_ file can also include clean files - files that do not match any of the above
/// criteria - which solc also requires in order to compile a dirty file.
///
/// Therefore, these files will also be included in the filtered output but not marked as dirty,
/// so that their [OutputSelection] can be optimized in the [CompilerOutput] and their (empty)
/// so that their `OutputSelection` can be optimized in the `CompilerOutput` and their (empty)
/// artifacts ignored.
fn filter(&mut self, sources: Sources, version: &Version) -> FilteredSources {
// all files that are not dirty themselves, but are pulled from a dirty file
@ -906,7 +911,7 @@ impl<'a, T: ArtifactOutput> ArtifactsCache<'a, T> {
}
}
/// Consumes the `Cache`, rebuilds the [`SolFileCache`] by merging all artifacts that were
/// Consumes the `Cache`, rebuilds the `SolFileCache` by merging all artifacts that were
/// filtered out in the previous step (`Cache::filtered`) and the artifacts that were just
/// compiled and written to disk `written_artifacts`.
///

View File

@ -80,11 +80,10 @@
//! If caching is enabled in the [Project](crate::Project) a cache file will be created upon a
//! successful solc build. The [cache file](crate::cache::SolFilesCache) stores metadata for all the
//! files that were provided to solc.
//! For every file the cache file contains a dedicated [cache
//! entry](crate::cache::CacheEntry), which represents the state of the file. A solidity file can
//! contain several contracts, for every contract a separate [artifact](crate::Artifact) is emitted.
//! Therefor the entry also tracks all artifacts emitted by a file. A solidity file can also be
//! compiled with several solc versions.
//! For every file the cache file contains a dedicated [cache entry](crate::cache::CacheEntry),
//! which represents the state of the file. A solidity file can contain several contracts, for every
//! contract a separate [artifact](crate::Artifact) is emitted. Therefor the entry also tracks all
//! artifacts emitted by a file. A solidity file can also be compiled with several solc versions.
//!
//! For example in `A(<=0.8.10) imports C(>0.4.0)` and
//! `B(0.8.11) imports C(>0.4.0)`, both `A` and `B` import `C` but there's no solc version that's
@ -252,10 +251,12 @@ impl<'a, T: ArtifactOutput> ProjectCompiler<'a, T> {
/// The main reason is to debug all states individually
#[derive(Debug)]
struct PreprocessedState<'a, T: ArtifactOutput> {
/// contains all sources to compile
/// Contains all the sources to compile.
sources: FilteredCompilerSources,
/// cache that holds [CacheEntry] object if caching is enabled and the project is recompiled
/// Cache that holds `CacheEntry` objects if caching is enabled and the project is recompiled
cache: ArtifactsCache<'a, T>,
sparse_output: SparseOutputFilter,
}

View File

@ -76,8 +76,9 @@ impl ProjectPathsConfig {
}
}
/// Same as [Self::paths()] but strips the `root` form all paths,
/// [ProjectPaths::strip_prefix_all()]
/// Same as [`paths`][ProjectPathsConfig::paths] but strips the `root` form all paths.
///
/// See: [`ProjectPaths::strip_prefix_all`]
pub fn paths_relative(&self) -> ProjectPaths {
let mut paths = self.paths();
paths.strip_prefix_all(&self.root);
@ -790,7 +791,8 @@ impl SolcConfigBuilder {
}
}
/// Container for all `--include-path` arguments for Solc, se also [Solc docs](https://docs.soliditylang.org/en/v0.8.9/using-the-compiler.html#base-path-and-import-remapping
/// Container for all `--include-path` arguments for Solc, see also
/// [Solc docs](https://docs.soliditylang.org/en/v0.8.9/using-the-compiler.html#base-path-and-import-remapping).
///
/// The `--include--path` flag:
/// > Makes an additional source directory available to the default import callback. Use this option

View File

@ -287,14 +287,17 @@ impl FilteredSource {
/// Helper type that determines the state of a source file
#[derive(Debug)]
pub struct FilteredSourceInfo {
/// path to the source file
/// Path to the source file.
pub file: PathBuf,
/// contents of the file
/// Contents of the file.
pub source: Source,
/// idx in the [GraphEdges]
/// Index in the [GraphEdges].
pub idx: usize,
/// whether this file is actually dirty
/// Whether this file is actually dirty.
///
/// See also [ArtifactsCacheInner::is_dirty()]
/// See also `ArtifactsCacheInner::is_dirty`
pub dirty: bool,
}

View File

@ -1,5 +1,5 @@
#![doc = include_str!("../README.md")]
#![deny(rustdoc::broken_intra_doc_links)]
#![allow(rustdoc::private_intra_doc_links)]
pub mod artifacts;
pub mod sourcemap;
@ -24,7 +24,7 @@ pub use compile::{
};
mod config;
pub use config::{AllowedLibPaths, PathStyle, ProjectPathsConfig, SolcConfig};
pub use config::{AllowedLibPaths, PathStyle, ProjectPaths, ProjectPathsConfig, SolcConfig};
pub mod remappings;
use crate::artifacts::{Source, SourceFile, StandardJsonCompilerInput};
@ -280,7 +280,7 @@ impl<T: ArtifactOutput> Project<T> {
///
/// This will autodetect the appropriate `Solc` version(s) to use when compiling the provided
/// `Sources`. Solc auto-detection follows semver rules, see also
/// [`crate::resolver::Graph::get_input_node_versions()`]
/// `Graph::get_input_node_versions`
///
/// # Errors
///

View File

@ -179,7 +179,9 @@ impl GraphEdges {
///
/// This is a preprocess function that attempts to resolve those libraries that will the
/// solidity `file` will be required to link. And further restrict this list to libraries
/// that won't be inlined See also [SolLibrary](parse::SolLibrary)
/// that won't be inlined.
///
/// See also `parse::SolLibrary`.
pub fn get_link_references(&self, file: impl AsRef<Path>) -> HashSet<&PathBuf> {
let mut link_references = HashSet::new();
for import in self.all_imported_nodes(self.node_id(file)) {

View File

@ -1,56 +1,50 @@
#![warn(missing_debug_implementations, missing_docs, rust_2018_idioms, unreachable_pub)]
#![deny(rustdoc::broken_intra_doc_links)]
#![doc(test(
no_crate_inject,
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
))]
//! # Complete Ethereum & Celo library and wallet implementation.
//! # ethers-rs
//!
//! > ethers-rs is a port of [ethers-js](https://github.com/ethers-io/ethers.js) in Rust.
//! A complete Ethereum and Celo Rust library.
//!
//! ## Quickstart: `prelude`
//!
//! 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.
//!
//! ```no_run
//! # #[allow(unused)]
//! ```rust
//! use ethers::prelude::*;
//! ```
//!
//! 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/tree/master/examples)
//! 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/tree/master/examples)
//! and in the `tests/` directories of each crate.
//!
//! # Quick explanation of each module in ascending order of abstraction
//! ## Modules
//!
//! ## `core`
//! The following paragraphs are a quick explanation of each module in ascending order of
//! abstraction. More details can be found in [the book](https://gakonst.com/ethers-rs).
//!
//! Contains all the [necessary data structures](core::types) for interacting
//! with Ethereum, along with cryptographic utilities for signing and verifying
//! ECDSA signatures on `secp256k1`. Bindings to the Solidity compiler, Anvil and `ganache-cli`
//! are also provided as helpers. To simplify your imports, consider using the re-exported
//! modules described in the next subsection.
//! ### `core`
//!
//! ## `utils`, `types`, `abi`
//! Contains all the [necessary data structures](core::types) for interacting with Ethereum, along
//! with cryptographic utilities for signing and verifying ECDSA signatures on `secp256k1`. Bindings
//! to the Solidity compiler, Anvil and Ganace are also provided as helpers.
//! To simplify your imports, consider using the re-exported modules described in the next
//! subsection.
//!
//! These are re-exports of the [`utils`], [`types`] and [`abi`] modules from the `core` crate
//! ### `utils`, `types`, `abi`
//!
//! ## `providers`
//! These are re-exports of the [`utils`], [`types`] and [`abi`] modules from the [`core`] crate.
//!
//! Ethereum nodes expose RPC endpoints (by default at `localhost:8545`). You can connect
//! to them by using the [`Provider`]. The provider instance
//! allows you to issue requests to the node which involve querying the state of Ethereum or
//! broadcasting transactions with unlocked accounts on the node.
//! ### `providers`
//!
//! ## `signers`
//! Contains the [`Provider`] struct, an abstraction of a connection to the Ethereum network, which
//! alongside the [`Middleware`] trait provides a concise, consistent interface to standard Ethereum
//! node functionality,
//!
//! This module provides a [`Signer`] trait which can be used for signing messages
//! or transactions. A [`Wallet`] type is implemented which can be used with a
//! raw private key, or a YubiHSM2. We also provide Ledger support.
//! ### `signers`
//!
//! ## `contract`
//! Provides a [`Signer`] trait which can be used for signing messages or transactions. A [`Wallet`]
//! type is implemented which can be used with a raw private key or a YubiHSM2. Ledger and Trezor
//! support are also provided.
//!
//! ### `contract`
//!
//! Interacting with Ethereum is not restricted to sending or receiving funds. It also involves
//! using smart contracts, which can be thought of as programs with persistent storage.
@ -61,9 +55,10 @@
//! 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].
//!
//! ## `middleware`
//! It also provides typesafe bindings via the [`abigen`] macro and the [`Abigen`] builder.
//!
//! ### `middleware`
//!
//! In order to keep the ethers architecture as modular as possible, providers define a
//! [`Middleware`] trait which defines all the methods to interact with an Ethereum node. By
@ -78,56 +73,38 @@
//! [`Signer`]: signers::Signer
//! [`ContractFactory`]: contract::ContractFactory
//! [`Contract`]: contract::Contract
//! [`abigen`]: ./contract/macro.abigen.html
//! [`Abigen` builder]: contract::Abigen
//! [`abigen`]: contract::abigen
//! [`Abigen`]: contract::Abigen
//! [`utils`]: core::utils
//! [`abi`]: core::abi
//! [`types`]: core::types
/// Address book consisting of frequently used contracts
pub mod addressbook {
pub use ethers_addressbook::*;
}
#[doc = include_str!("../assets/CONTRACT_README.md")]
pub mod contract {
pub use ethers_contract::*;
}
#[doc = include_str!("../assets/CORE_README.md")]
pub mod core {
pub use ethers_core::*;
}
#[doc = include_str!("../assets/PROVIDERS_README.md")]
pub mod providers {
pub use ethers_providers::*;
}
#[doc = include_str!("../assets/MIDDLEWARE_README.md")]
pub mod middleware {
pub use ethers_middleware::*;
}
#[doc = include_str!("../assets/SIGNERS_README.md")]
pub mod signers {
pub use ethers_signers::*;
}
#![warn(missing_debug_implementations, missing_docs, rust_2018_idioms, unreachable_pub)]
#![deny(rustdoc::broken_intra_doc_links)]
#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms), allow(dead_code, unused_variables))))]
#[doc(inline)]
pub use ethers_addressbook as addressbook;
#[doc(inline)]
pub use ethers_contract as contract;
#[doc(inline)]
pub use ethers_core as core;
#[doc(inline)]
pub use ethers_etherscan as etherscan;
#[doc(inline)]
pub use ethers_middleware as middleware;
#[doc(inline)]
pub use ethers_providers as providers;
#[doc(inline)]
pub use ethers_signers as signers;
#[doc(inline)]
#[cfg(feature = "ethers-solc")]
#[doc = include_str!("../assets/SOLC_README.md")]
pub mod solc {
pub use ethers_solc::*;
}
pub use ethers_solc as solc;
/// Etherscan bindings
pub mod etherscan {
pub use ethers_etherscan::*;
}
#[doc(inline)]
pub use ethers_core::{abi, types, utils};
pub use crate::core::{abi, types, 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 use super::addressbook::*;
@ -136,6 +113,8 @@ pub mod prelude {
pub use super::core::{types::*, *};
pub use super::etherscan::*;
pub use super::middleware::*;
pub use super::providers::*;
@ -144,6 +123,4 @@ pub mod prelude {
#[cfg(feature = "ethers-solc")]
pub use super::solc::*;
pub use super::etherscan::*;
}