docs: fix broken links, update documentation (#2203)
* docs: fix broken links * docs: update READMEs and module-level documentation
This commit is contained in:
parent
620300f357
commit
203e350940
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 = [
|
||||||
|
|
102
README.md
102
README.md
|
@ -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.
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../ethers-contract/README.md
|
|
|
@ -1 +0,0 @@
|
||||||
../ethers-core/README.md
|
|
|
@ -1 +0,0 @@
|
||||||
../ethers-middleware/README.md
|
|
|
@ -1 +0,0 @@
|
||||||
../ethers-providers/README.md
|
|
|
@ -1 +0,0 @@
|
||||||
../ethers-signers/README.md
|
|
|
@ -1 +0,0 @@
|
||||||
../ethers-solc/README.md
|
|
|
@ -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" }
|
|
||||||
|
|
|
@ -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());
|
||||||
|
```
|
|
@ -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>,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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}"))?;
|
||||||
|
|
|
@ -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>>(())
|
||||||
|
```
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(())
|
||||||
|
# }
|
||||||
|
```
|
|
@ -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> {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
@ -12,82 +15,69 @@ Your ethers application interacts with the blockchain through a [`Provider`](eth
|
||||||
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};
|
|
||||||
use ethers_middleware::{gas_oracle::{GasOracle, GasNow}, MiddlewareBuilder};
|
|
||||||
|
|
||||||
fn builder_example() {
|
|
||||||
let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
|
let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
|
||||||
let signer = key.parse::<LocalWallet>().unwrap();
|
let signer = key.parse::<LocalWallet>()?;
|
||||||
let address = signer.address();
|
let address = signer.address();
|
||||||
let gas_oracle = GasNow::new();
|
let gas_oracle = GasNow::new();
|
||||||
|
|
||||||
let provider = Provider::<Http>::try_from("http://localhost:8545")
|
let provider = Provider::<Http>::try_from("http://localhost:8545")?
|
||||||
.unwrap()
|
|
||||||
.gas_oracle(gas_oracle)
|
.gas_oracle(gas_oracle)
|
||||||
.with_signer(signer)
|
.with_signer(signer)
|
||||||
.nonce_manager(address); // Outermost layer
|
.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.
|
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::*};
|
|
||||||
|
|
||||||
fn builder_example_wrap_into() {
|
|
||||||
let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
|
let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169";
|
||||||
let signer = key.parse::<LocalWallet>().unwrap();
|
let signer = key.parse::<LocalWallet>()?;
|
||||||
let address = signer.address();
|
let address = signer.address();
|
||||||
let escalator = GeometricGasPrice::new(1.125, 60_u64, None::<u64>);
|
let escalator = GeometricGasPrice::new(1.125, 60_u64, None::<u64>);
|
||||||
|
|
||||||
let provider = Provider::<Http>::try_from("http://localhost:8545")
|
let provider = Provider::<Http>::try_from("http://localhost:8545")?
|
||||||
.unwrap()
|
|
||||||
.wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock))
|
.wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock))
|
||||||
.wrap_into(|p| SignerMiddleware::new(p, signer))
|
.wrap_into(|p| SignerMiddleware::new(p, signer))
|
||||||
.wrap_into(|p| GasOracleMiddleware::new(p, GasNow::new()))
|
.wrap_into(|p| GasOracleMiddleware::new(p, GasNow::new()))
|
||||||
.wrap_into(|p| NonceManagerMiddleware::new(p, address)); // Outermost layer
|
.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.
|
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
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -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)],
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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(())
|
||||||
|
# }
|
||||||
|
```
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
///
|
///
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
133
src/lib.rs
133
src/lib.rs
|
@ -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::*;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue