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 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). 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 ## Contributing in Issues

View File

@ -9,7 +9,7 @@ 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"
description = "Complete Ethereum library and wallet implementation in Rust." description = "A complete Ethereum and Celo Rust library"
[workspace] [workspace]
members = [ 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) ![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) [![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-badge]: https://img.shields.io/crates/v/ethers.svg
[crates-url]: https://crates.io/crates/ethers [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 ## Documentation
Extensive documentation and examples are available [here](https://docs.rs/ethers). View the API reference [here](https://docs.rs/ethers) or the online book [here](https://gakonst.com/ethers-rs).
Alternatively, you may clone the repository and run `cd ethers/ && cargo doc --open`
Examples are organized into individual crates under the `/examples` folder. 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 ```bash
# cargo run -p <example-crate-name> --example <name> # cargo run -p <example-crate-name> --example <name>
cargo run -p examples-big-numbers --example math_operations cargo run -p examples-big-numbers --example math_operations
``` ```
## Add ethers-rs to your repository ## EVM-compatible chains support
```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
There are many chains live which are Ethereum JSON-RPC & EVM compatible, but do not yet have 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 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 ```toml
[dependencies] [dependencies]
ethers = { version = "1.0.2", features = ["legacy"] }
ethers = { version = "1.0.0", features = ["legacy"] }
``` ```
### Polygon support ### Polygon support
@ -73,8 +64,7 @@ You can get one [here](https://snowtrace.io/apis).
```toml ```toml
[dependencies] [dependencies]
ethers = { version = "1.0.2", features = ["celo"] }
ethers = { version = "1.0.0", features = ["celo"] }
``` ```
Celo's transactions differ from Ethereum transactions by including 3 new fields: 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 ```toml
[dependencies] [dependencies]
ethers = { version = "1.0.2", features = ["ws"] }
ethers = { version = "1.0.0", features = ["ws"] }
``` ```
### Interprocess Communication (IPC) ### Interprocess Communication (IPC)
@ -121,8 +110,7 @@ IPC support is turned on via the feature-flag `ipc`:
```toml ```toml
[dependencies] [dependencies]
ethers = { version = "1.0.2", features = ["ipc"] }
ethers = { version = "1.0.0", features = ["ipc"] }
``` ```
### HTTP Secure (HTTPS) ### HTTP Secure (HTTPS)
@ -134,16 +122,14 @@ To enable `rustls`:
```toml ```toml
[dependencies] [dependencies]
ethers = { version = "1.0.2", features = ["rustls"] }
ethers = { version = "1.0.0", features = ["rustls"] }
``` ```
To enable `openssl`: To enable `openssl`:
```toml ```toml
[dependencies] [dependencies]
ethers = { version = "1.0.2", features = ["openssl"] }
ethers = { version = "1.0.0", features = ["openssl"] }
``` ```
## Note on WASM and FFI bindings ## 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 ## Contributing
Thanks for your help improving the project! We are so happy to have you! We have 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 [a contributing guide](./CONTRIBUTING.md) to help you get involved in the ethers-rs project.
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 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 clippy is happy `cargo clippy`, you can even try to let clippy fix simple 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 -Z unstable-options` 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/) 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.
- [`rust-web3`](https://github.com/tomusdrw/rust-web3/) 2. [`anvil`](https://github.com/foundry-rs/foundry/blob/master/anvil/README.md)
- [`ethcontract-rs`](https://github.com/gnosis/ethcontract-rs/) 3. [`geth`](https://github.com/ethereum/go-ethereum)
- [`guac_rs`](https://github.com/althea-net/guac_rs/tree/master/web3/src/jsonrpc)
A lot of the code was inspired and adapted from them, to a unified and opinionated interface, Additionally, the `ETHERSCAN_API_KEY` environment variable has to be set to run [`ethers-etherscan`](./ethers-etherscan) tests.
built with async/await and std futures from the ground up. You can get one [here](https://etherscan.io/apis).
## Projects using ethers-rs ## 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 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 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 - [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"] keywords = ["ethereum", "web3", "celo", "ethers"]
[dependencies] [dependencies]
ethers-core = { version = "^1.0.0", path = "../ethers-core", default-features = false }
once_cell = "1.17.1" once_cell = "1.17.1"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" 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 once_cell::sync::Lazy;
use serde::Deserialize; use serde::Deserialize;
use std::collections::HashMap; use std::collections::HashMap;
const CONTRACTS_JSON: &str = include_str!("./contracts/contracts.json"); 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>> = static ADDRESSBOOK: Lazy<HashMap<String, Contract>> =
Lazy::new(|| serde_json::from_str(CONTRACTS_JSON).unwrap()); 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)] #[derive(Clone, Debug, Deserialize)]
pub struct Contract { pub struct Contract {
addresses: HashMap<Chain, Address>, 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 Interacting with a smart contract requires broadcasting carefully crafted
[transactions](ethers_core::types::TransactionRequest) where the `data` field [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 that you do not have to worry about that. It also provides typesafe bindings via
the [`abigen`] macro and the [`Abigen` builder]. the [`abigen`] macro and the [`Abigen` builder].
For more information, please refer to the [book](https://gakonst.com/ethers-rs).
[`contractfactory`]: ./struct.ContractFactory.html [`contractfactory`]: ./struct.ContractFactory.html
[`contract`]: ./struct.Contract.html [`contract`]: ./struct.Contract.html
[`abigen`]: ./macro.abigen.html [`abigen`]: ./macro.abigen.html

View File

@ -371,8 +371,8 @@ impl Context {
/// convention of suffixing the function name with _with /// convention of suffixing the function name with _with
/// ///
/// The first function or the function with the least amount of arguments should /// 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_ + /// be named as in the ABI, the following functions suffixed with:
/// additional_params[0].name + (_and_(additional_params[1+i].name))* /// `_with_ + additional_params[0].name + (_and_(additional_params[1+i].name))*`
fn get_method_aliases(&self) -> Result<BTreeMap<String, MethodAlias>> { fn get_method_aliases(&self) -> Result<BTreeMap<String, MethodAlias>> {
let mut aliases = self.method_aliases.clone(); 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 /// Parse `s` as an explorer ("etherscan"), explorer domain ("etherscan.io") or a chain that has
/// an explorer ("mainnet"). /// 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> { fn from_explorer(s: &str, url: &Url) -> Result<Self> {
let explorer: Explorer = s.parse().or_else(|_| Explorer::from_chain(s.parse()?))?; 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}"))?; 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 It is recommended to use the `utils`, `types` and `abi` re-exports instead of
the `core` module to simplify your imports. 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 This library provides type definitions for Ethereum's main datatypes along with
other utilities for interacting with the Ethereum ecosystem 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 ## Feature flags
`"\x19Ethereum Signed Message:\n" + message.length`, and then signing the hash
of the result.
```rust,ignore - `eip712`: Provides the `Eip712` trait and derive procedural macro for EIP-712 encoding of typed data.
# async fn foo() -> Result<(), Box<dyn std::error::Error>> {
use ethers::signers::{Signer, LocalWallet};
let message = "Some data"; ## ABI
let wallet = LocalWallet::new(&mut rand::thread_rng());
// Sign the message This crate re-exports the [`ethabi`](https://docs.rs/ethabi) crate's functions
let signature = wallet.sign_message(message).await?; under the `abi` module, as well as the
[`secp256k1`](https://docs.rs/libsecp256k1) and [`rand`](https://docs.rs/rand)
// Recover the signer from the message crates for convenience.
let recovered = signature.recover(message)?;
assert_eq!(recovered, wallet.address());
# Ok(())
# }
```
## Utilities ## Utilities
The crate provides utilities for launching local Ethereum testnets by using The crate provides utilities for launching local Ethereum testnets by using
`ganache-cli` via the `GanacheBuilder` struct. `ganache-cli` via the `GanacheBuilder` struct.
# Features ## Examples
- ["eip712"] | Provides Eip712 trait for EIP-712 encoding of typed data for Calculate the UniswapV2 pair address for two ERC20 tokens:
derived structs
# 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 let token_a: Address = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48".parse()?;
under the `abi` module, as well as the let token_b: Address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".parse()?;
[`secp256k1`](https://docs.rs/libsecp256k1) and [`rand`](https://docs.rs/rand) let encoded = abi::encode_packed(&[Token::Address(token_a), Token::Address(token_b)])?;
crates for convenience. 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. //! 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) //!
//! Adapted from [Gnosis' `ethcontract-rs`](https://github.com/gnosis/ethcontract-rs).
use crate::{ use crate::{
types::{Bytes, Selector, Uint8, H256, H512, I256, U128, U256, U64}, types::{Bytes, Selector, Uint8, H256, H512, I256, U128, U256, U64},
utils::id, utils::id,

View File

@ -1,3 +1,5 @@
//! Ethereum data types.
pub type Selector = [u8; 4]; pub type Selector = [u8; 4];
// Re-export common ethereum datatypes with more specific names // 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 /// ```no_run
/// # use ethers_etherscan::Client; /// # use ethers_etherscan::Client;
/// # use ethers_core::types::Chain; /// # use ethers_core::types::Chain;
/// /// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// # #[tokio::main] /// let client = Client::new(Chain::Mainnet, "<your_api_key>")?;
/// # async fn main() { /// let address = "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".parse()?;
/// let client = Client::new(Chain::Mainnet, "API_KEY").unwrap(); /// let metadata = client.contract_source_code(address).await?;
/// let meta = client /// assert_eq!(metadata.items[0].contract_name, "DAO");
/// .contract_source_code("0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".parse().unwrap()) /// # Ok(())
/// .await.unwrap();
/// let code = meta.source_code();
/// # } /// # }
/// ``` /// ```
pub async fn contract_source_code(&self, address: Address) -> Result<ContractMetadata> { 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 crate::errors::{is_blocked_by_cloudflare_response, is_cloudflare_security_challenge};
use contract::ContractMetadata; 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. 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 ## Available Middleware
- [`Signer`](./signer/struct.SignerMiddleware.html): Signs transactions locally, with a private key or a hardware wallet. - [`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. - [`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 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 - [`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.). 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 - [`Transformer`](./transformer/trait.Transformer.html): Allows intercepting and
transforming a transaction to be broadcasted via a proxy wallet, e.g. transforming a transaction to be broadcasted via a proxy wallet, e.g.
[`DSProxy`](./transformer/struct.DsProxy.html). [`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. 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): The following example shows how to build a composed [`Middleware`](ethers_providers::Middleware) starting from a [`Provider`](ethers_providers::Provider):
```rust ```rust
use ethers_providers::{Middleware, Provider, Http}; # use ethers_providers::{Middleware, Provider, Http};
use std::sync::Arc; # use ethers_signers::{LocalWallet, Signer};
use std::convert::TryFrom; # use ethers_middleware::{gas_oracle::GasNow, MiddlewareBuilder};
use ethers_signers::{LocalWallet, Signer}; let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
use ethers_middleware::{gas_oracle::{GasOracle, GasNow}, MiddlewareBuilder}; let signer = key.parse::<LocalWallet>()?;
let address = signer.address();
let gas_oracle = GasNow::new();
fn builder_example() { let provider = Provider::<Http>::try_from("http://localhost:8545")?
let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169"; .gas_oracle(gas_oracle)
let signer = key.parse::<LocalWallet>().unwrap(); .with_signer(signer)
let address = signer.address(); .nonce_manager(address); // Outermost layer
let gas_oracle = GasNow::new(); # Ok::<_, Box<dyn std::error::Error>>(())
let provider = Provider::<Http>::try_from("http://localhost:8545")
.unwrap()
.gas_oracle(gas_oracle)
.with_signer(signer)
.nonce_manager(address); // Outermost layer
}
``` ```
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. 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 ```rust,no_run
use ethers_providers::{Middleware, Provider, Http}; # use ethers_providers::{Middleware, Provider, Http};
use std::sync::Arc; # use std::convert::TryFrom;
use std::convert::TryFrom; # use ethers_signers::{LocalWallet, Signer};
use ethers_signers::{LocalWallet, Signer}; # use ethers_middleware::{*,gas_escalator::*,gas_oracle::*};
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 provider = Provider::<Http>::try_from("http://localhost:8545")?
let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169"; .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock))
let signer = key.parse::<LocalWallet>().unwrap(); .wrap_into(|p| SignerMiddleware::new(p, signer))
let address = signer.address(); .wrap_into(|p| GasOracleMiddleware::new(p, GasNow::new()))
let escalator = GeometricGasPrice::new(1.125, 60_u64, None::<u64>); .wrap_into(|p| NonceManagerMiddleware::new(p, address)); // Outermost layer
# Ok::<_, Box<dyn std::error::Error>>(())
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
}
``` ```
## Stacking middlewares manually
A [`Middleware`](ethers_providers::Middleware) stack can be also constructed manually. This is achieved by explicitly wrapping layers. A [`Middleware`](ethers_providers::Middleware) stack can be also constructed manually. This is achieved by explicitly wrapping layers.
```rust no_run ```rust,no_run
use ethers_providers::{Provider, Http}; # use ethers_providers::{Provider, Http};
use ethers_signers::{LocalWallet, Signer}; # use ethers_signers::{LocalWallet, Signer};
use ethers_middleware::{ # use ethers_middleware::{
gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency}, # gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency},
gas_oracle::{GasOracleMiddleware, GasCategory, GasNow}, # gas_oracle::{GasOracleMiddleware, GasCategory, GasNow},
signer::SignerMiddleware, # signer::SignerMiddleware,
nonce_manager::NonceManagerMiddleware, # nonce_manager::NonceManagerMiddleware,
}; # };
use ethers_core::rand;
use std::convert::TryFrom;
// Start the stack // 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 // Escalate gas prices
let escalator = GeometricGasPrice::new(1.125, 60u64, None::<u64>); let escalator = GeometricGasPrice::new(1.125, 60u64, None::<u64>);
let provider = GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock); let provider = GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock);
// Sign transactions with a private key // 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 address = signer.address();
let provider = SignerMiddleware::new(provider, signer); let provider = SignerMiddleware::new(provider, signer);
@ -97,6 +87,5 @@ let provider = GasOracleMiddleware::new(provider, gas_oracle);
// Manage nonces locally // Manage nonces locally
let provider = NonceManagerMiddleware::new(provider, address); let provider = NonceManagerMiddleware::new(provider, address);
# Ok::<_, Box<dyn std::error::Error>>(())
// ... do something with the provider
``` ```

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 /// Sort the values in place by key and return the weighted fractile value such that `fractile`
/// that `fractile` fraction of the values by weight are less than or equal to /// fraction of the values by weight are less than or equal to the value.
/// 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. /// 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
/// ///
/// 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>( fn weighted_fractile_by_key<'a, T, F, K>(
fractile: f32, fractile: f32,
values: &'a mut [(f32, T)], values: &'a mut [(f32, T)],

View File

@ -1,6 +1,5 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#![deny(unsafe_code)] #![deny(unsafe_code, rustdoc::broken_intra_doc_links)]
#![deny(rustdoc::broken_intra_doc_links)]
/// The [Gas Escalator middleware](crate::gas_escalator::GasEscalatorMiddleware) /// The [Gas Escalator middleware](crate::gas_escalator::GasEscalatorMiddleware)
/// is used to re-broadcast transactions with an increasing gas price to guarantee /// 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 This crate provides asynchronous
[Ethereum JSON-RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) compliant [Ethereum JSON-RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) compliant
clients. clients.
For more documentation on the available calls, refer to the For more information, please refer to the [book](https://gakonst.com/ethers-rs).
[`Provider`](./struct.Provider.html) struct.
# Examples ## Websockets
```no_run This crate supports for WebSockets via `tokio-tungstenite`.
use ethers_core::types::Address; Please ensure that you have the `ws` feature enabled if you wish to use WebSockets:
use ethers_providers::{Provider, Http, Middleware};
use std::convert::TryFrom;
```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>> { # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
// HTTP Provider
let provider = Provider::<Http>::try_from( let provider = Provider::<Http>::try_from(
"https://mainnet.infura.io/v3/YOUR_API_KEY" "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?; let block = provider.get_block(100u64).await?;
println!("Got block: {}", serde_json::to_string(&block)?); 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. ```rust,no_run
```
# 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
# use ethers_providers::{Provider, Http, Middleware}; # use ethers_providers::{Provider, Http, Middleware};
# use std::convert::TryFrom;
# async fn foo() -> Result<(), Box<dyn std::error::Error>> { # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
# let provider = Provider::<Http>::try_from( # let provider = Provider::<Http>::try_from(
# "https://mainnet.infura.io/v3/YOUR_API_KEY" # "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")] #![doc = include_str!("../README.md")]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![allow(clippy::type_complexity)]
#![warn(missing_docs)] #![warn(missing_docs)]
#![deny(unsafe_code, rustdoc::broken_intra_doc_links)]
mod ext; mod ext;
pub use ext::*; pub use ext::*;

View File

@ -24,9 +24,10 @@ pub struct JsonRpcError {
pub data: Option<Value>, 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: /// 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> { fn spelunk_revert(value: &Value) -> Option<Bytes> {
match value { match value {
Value::String(s) => s.parse().ok(), 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 You can implement the `Signer` trait to extend functionality to other signers
such as Hardware Security Modules, KMS etc. such as Hardware Security Modules, KMS etc.
@ -13,10 +17,16 @@ Supported signers:
- [YubiHSM2](./src/wallet/yubi.rs) - [YubiHSM2](./src/wallet/yubi.rs)
- [AWS KMS](./src/aws) - [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_signers::{LocalWallet, Signer};
# use ethers_core::{k256::ecdsa::SigningKey, types::TransactionRequest}; # use ethers_core::{k256::ecdsa::SigningKey, types::TransactionRequest};
# async fn foo() -> Result<(), Box<dyn std::error::Error>> { # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
// instantiate the wallet // instantiate the wallet
let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7" let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7"
@ -37,5 +47,21 @@ signature.verify("hello world", wallet.address()).unwrap();
# } # }
``` ```
[`transaction`]: ethers_core::types::Transaction Sign an Ethereum prefixed message ([eip-712](https://eips.ethereum.org/EIPS/eip-712)):
[`transactionrequest`]: ethers_core::types::TransactionRequest
```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. #![doc = include_str!("../README.md")]
#![deny(unsafe_code)] #![deny(unsafe_code, rustdoc::broken_intra_doc_links)]
#![deny(rustdoc::broken_intra_doc_links)]
mod wallet; mod wallet;
pub use wallet::{MnemonicBuilder, Wallet, WalletError}; pub use wallet::{MnemonicBuilder, Wallet, WalletError};

View File

@ -463,7 +463,7 @@ impl CacheEntry {
/// Reads all artifact files associated with the `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>( fn read_artifact_files<Artifact: DeserializeOwned>(
&self, &self,
) -> Result<BTreeMap<String, Vec<ArtifactFile<Artifact>>>> { ) -> Result<BTreeMap<String, Vec<ArtifactFile<Artifact>>>> {
@ -579,27 +579,32 @@ impl CacheEntry {
/// and which `Artifacts` can be reused. /// and which `Artifacts` can be reused.
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct ArtifactsCacheInner<'a, T: ArtifactOutput> { pub(crate) struct ArtifactsCacheInner<'a, T: ArtifactOutput> {
/// preexisting cache file /// The preexisting cache file.
pub cache: SolFilesCache, pub cache: SolFilesCache,
/// all already existing artifacts
/// All already existing artifacts.
pub cached_artifacts: Artifacts<T::Artifact>, pub cached_artifacts: Artifacts<T::Artifact>,
/// relationship between all the files
/// Relationship between all the files.
pub edges: GraphEdges, pub edges: GraphEdges,
/// the project
/// The project.
pub project: &'a Project<T>, 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>)>, 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 /// 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. /// 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 /// 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 /// [`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, /// can be populated before the updated [`crate::SolFilesCache`] is finally written to disk.
/// see [`Cache::finish()`]
pub dirty_source_files: HashMap<PathBuf, (CacheEntry, HashSet<Version>)>, pub dirty_source_files: HashMap<PathBuf, (CacheEntry, HashSet<Version>)>,
/// the file hashes
/// The file hashes.
pub content_hashes: HashMap<PathBuf, String>, 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. /// recompile the project.
/// ///
/// We define _dirty_ sources as files that: /// We define _dirty_ sources as files that:
@ -661,12 +666,12 @@ impl<'a, T: ArtifactOutput> ArtifactsCacheInner<'a, T> {
/// - their imports were changed /// - their imports were changed
/// - their artifact is missing /// - 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 /// 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. /// 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, /// 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. /// artifacts ignored.
fn filter(&mut self, sources: Sources, version: &Version) -> FilteredSources { fn filter(&mut self, sources: Sources, version: &Version) -> FilteredSources {
// all files that are not dirty themselves, but are pulled from a dirty file // 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 /// filtered out in the previous step (`Cache::filtered`) and the artifacts that were just
/// compiled and written to disk `written_artifacts`. /// 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 //! 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 //! successful solc build. The [cache file](crate::cache::SolFilesCache) stores metadata for all the
//! files that were provided to solc. //! files that were provided to solc.
//! For every file the cache file contains a dedicated [cache //! For every file the cache file contains a dedicated [cache entry](crate::cache::CacheEntry),
//! entry](crate::cache::CacheEntry), which represents the state of the file. A solidity file can //! which represents the state of the file. A solidity file can contain several contracts, for every
//! contain several contracts, for every contract a separate [artifact](crate::Artifact) is emitted. //! contract a separate [artifact](crate::Artifact) is emitted. Therefor the entry also tracks all
//! Therefor the entry also tracks all artifacts emitted by a file. A solidity file can also be //! artifacts emitted by a file. A solidity file can also be compiled with several solc versions.
//! compiled with several solc versions.
//! //!
//! For example in `A(<=0.8.10) imports C(>0.4.0)` and //! 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 //! `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 /// The main reason is to debug all states individually
#[derive(Debug)] #[derive(Debug)]
struct PreprocessedState<'a, T: ArtifactOutput> { struct PreprocessedState<'a, T: ArtifactOutput> {
/// contains all sources to compile /// Contains all the sources to compile.
sources: FilteredCompilerSources, 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>, cache: ArtifactsCache<'a, T>,
sparse_output: SparseOutputFilter, sparse_output: SparseOutputFilter,
} }

View File

@ -76,8 +76,9 @@ impl ProjectPathsConfig {
} }
} }
/// Same as [Self::paths()] but strips the `root` form all paths, /// Same as [`paths`][ProjectPathsConfig::paths] but strips the `root` form all paths.
/// [ProjectPaths::strip_prefix_all()] ///
/// See: [`ProjectPaths::strip_prefix_all`]
pub fn paths_relative(&self) -> ProjectPaths { pub fn paths_relative(&self) -> ProjectPaths {
let mut paths = self.paths(); let mut paths = self.paths();
paths.strip_prefix_all(&self.root); 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: /// The `--include--path` flag:
/// > Makes an additional source directory available to the default import callback. Use this option /// > 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 /// Helper type that determines the state of a source file
#[derive(Debug)] #[derive(Debug)]
pub struct FilteredSourceInfo { pub struct FilteredSourceInfo {
/// path to the source file /// Path to the source file.
pub file: PathBuf, pub file: PathBuf,
/// contents of the file
/// Contents of the file.
pub source: Source, pub source: Source,
/// idx in the [GraphEdges]
/// Index in the [GraphEdges].
pub idx: usize, 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, pub dirty: bool,
} }

View File

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

View File

@ -179,7 +179,9 @@ impl GraphEdges {
/// ///
/// This is a preprocess function that attempts to resolve those libraries that will the /// 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 /// 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> { pub fn get_link_references(&self, file: impl AsRef<Path>) -> HashSet<&PathBuf> {
let mut link_references = HashSet::new(); let mut link_references = HashSet::new();
for import in self.all_imported_nodes(self.node_id(file)) { 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)] //! # ethers-rs
#![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 is a port of [ethers-js](https://github.com/ethers-io/ethers.js) in Rust. //! A complete Ethereum and Celo Rust library.
//! //!
//! ## Quickstart: `prelude` //! ## Quickstart: `prelude`
//! //!
//! 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 //! ```rust
//! # #[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
//! the [`examples` directory of the repository](https://github.com/gakonst/ethers-rs/tree/master/examples) //! [`examples` directory of the repository](https://github.com/gakonst/ethers-rs/tree/master/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 //! ## 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 //! ### `core`
//! 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.
//! //!
//! ## `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 //! ### `providers`
//! 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.
//! //!
//! ## `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 //! ### `signers`
//! or transactions. A [`Wallet`] type is implemented which can be used with a
//! raw private key, or a YubiHSM2. We also provide Ledger support.
//! //!
//! ## `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 //! 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. //! 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) //! 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].
//! //!
//! ## `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 //! 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 //! [`Middleware`] trait which defines all the methods to interact with an Ethereum node. By
@ -78,56 +73,38 @@
//! [`Signer`]: signers::Signer //! [`Signer`]: signers::Signer
//! [`ContractFactory`]: contract::ContractFactory //! [`ContractFactory`]: contract::ContractFactory
//! [`Contract`]: contract::Contract //! [`Contract`]: contract::Contract
//! [`abigen`]: ./contract/macro.abigen.html //! [`abigen`]: contract::abigen
//! [`Abigen` builder]: contract::Abigen //! [`Abigen`]: contract::Abigen
//! [`utils`]: core::utils //! [`utils`]: core::utils
//! [`abi`]: core::abi //! [`abi`]: core::abi
//! [`types`]: core::types //! [`types`]: core::types
/// Address book consisting of frequently used contracts #![warn(missing_debug_implementations, missing_docs, rust_2018_idioms, unreachable_pub)]
pub mod addressbook { #![deny(rustdoc::broken_intra_doc_links)]
pub use ethers_addressbook::*; #![doc(test(no_crate_inject, attr(deny(rust_2018_idioms), allow(dead_code, unused_variables))))]
}
#[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::*;
}
#[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")] #[cfg(feature = "ethers-solc")]
#[doc = include_str!("../assets/SOLC_README.md")] pub use ethers_solc as solc;
pub mod solc {
pub use ethers_solc::*;
}
/// Etherscan bindings #[doc(inline)]
pub mod etherscan { pub use ethers_core::{abi, types, utils};
pub use ethers_etherscan::*;
}
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)] #[doc(hidden)]
pub mod prelude { pub mod prelude {
pub use super::addressbook::*; pub use super::addressbook::*;
@ -136,6 +113,8 @@ pub mod prelude {
pub use super::core::{types::*, *}; pub use super::core::{types::*, *};
pub use super::etherscan::*;
pub use super::middleware::*; pub use super::middleware::*;
pub use super::providers::*; pub use super::providers::*;
@ -144,6 +123,4 @@ pub mod prelude {
#[cfg(feature = "ethers-solc")] #[cfg(feature = "ethers-solc")]
pub use super::solc::*; pub use super::solc::*;
pub use super::etherscan::*;
} }