diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56828b01..26a5226f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -158,4 +158,45 @@ jobs: - name: Wasm-pack test chrome run: | cd examples/ethers-wasm - wasm-pack test --headless --chrome \ No newline at end of file + wasm-pack test --headless --chrome + + examples: + name: Examples + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + - name: Install ganache-cli + uses: actions/setup-node@v1 + with: + node-version: 10 + - name: Install ganache + run: npm install -g ganache-cli + - name: Install Solc + run: | + mkdir -p "$HOME/bin" + wget -q https://github.com/ethereum/solidity/releases/download/v0.6.6/solc-static-linux -O $HOME/bin/solc + chmod u+x "$HOME/bin/solc" + export PATH=$HOME/bin:$PATH + solc --version + + - name: Install geth + run: | + mkdir -p "$HOME/bin" + wget -q https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.23-8c2f2715.tar.gz + tar -xvf geth-linux-amd64-1.9.23-8c2f2715.tar.gz + mv geth-linux-amd64-1.9.23-8c2f2715/geth $HOME/bin/geth + chmod u+x "$HOME/bin/geth" + export PATH=$HOME/bin:$PATH + geth version + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + components: rustfmt, clippy + - name: cargo test + run: | + export PATH=$HOME/bin:$PATH + ./scripts/examples.sh diff --git a/README.md b/README.md index 6f45e8d5..d5b22882 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ Extensive documentation and examples are available [here](https://docs.rs/ethers Alternatively, you may clone the repository and run `cd ethers/ && cargo doc --open` +You can also run any of the examples by executing: `cargo run -p ethers --example ` + ## Add ethers-rs to your repository ```toml diff --git a/ethers-providers/src/lib.rs b/ethers-providers/src/lib.rs index c08b8bd2..63486b14 100644 --- a/ethers-providers/src/lib.rs +++ b/ethers-providers/src/lib.rs @@ -215,7 +215,7 @@ pub trait Middleware: Sync + Send + Debug { tx: &mut TypedTransaction, block: Option, ) -> Result<(), Self::Error> { - let tx_clone = tx.clone(); + let mut tx_clone = tx.clone(); // TODO: Maybe deduplicate the code in a nice way match tx { @@ -223,6 +223,7 @@ pub trait Middleware: Sync + Send + Debug { if let Some(NameOrAddress::Name(ref ens_name)) = inner.to { let addr = self.resolve_name(ens_name).await?; inner.to = Some(addr.into()); + tx_clone.set_to(addr); }; if inner.from.is_none() { @@ -244,6 +245,7 @@ pub trait Middleware: Sync + Send + Debug { if let Some(NameOrAddress::Name(ref ens_name)) = inner.tx.to { let addr = self.resolve_name(ens_name).await?; inner.tx.to = Some(addr.into()); + tx_clone.set_to(addr); }; if inner.tx.from.is_none() { @@ -265,6 +267,7 @@ pub trait Middleware: Sync + Send + Debug { if let Some(NameOrAddress::Name(ref ens_name)) = inner.to { let addr = self.resolve_name(ens_name).await?; inner.to = Some(addr.into()); + tx_clone.set_to(addr); }; if inner.from.is_none() { diff --git a/examples/abigen.rs b/examples/abigen.rs index 4ea39bc6..3d29e0e5 100644 --- a/examples/abigen.rs +++ b/examples/abigen.rs @@ -4,8 +4,8 @@ fn main() -> anyhow::Result<()> { let mut args = std::env::args(); args.next().unwrap(); // skip program name - let contract_name = args.next().unwrap(); - let contract: String = args.next().unwrap(); + let contract_name = args.next().unwrap_or("SimpleStorage".to_owned()); + let contract: String = args.next().unwrap_or("examples/contract.sol".to_owned()); println!("Generating bindings for {}\n", contract); diff --git a/examples/contract_human_readable.rs b/examples/contract_human_readable.rs index fe519895..2d5ea03f 100644 --- a/examples/contract_human_readable.rs +++ b/examples/contract_human_readable.rs @@ -45,7 +45,11 @@ async fn main() -> Result<()> { ); // 6. deploy it with the constructor arguments - let contract = factory.deploy("initial value".to_string())?.send().await?; + let contract = factory + .deploy("initial value".to_string())? + .legacy() + .send() + .await?; // 7. get the contract's address let addr = contract.address(); @@ -55,7 +59,12 @@ async fn main() -> Result<()> { // 9. call the `setValue` method // (first `await` returns a PendingTransaction, second one waits for it to be mined) - let _receipt = contract.set_value("hi".to_owned()).send().await?.await?; + let _receipt = contract + .set_value("hi".to_owned()) + .legacy() + .send() + .await? + .await?; // 10. get all events let logs = contract diff --git a/examples/contract_with_abi.rs b/examples/contract_with_abi.rs index fa314e48..8038a0e3 100644 --- a/examples/contract_with_abi.rs +++ b/examples/contract_with_abi.rs @@ -43,7 +43,11 @@ async fn main() -> Result<()> { ); // 6. deploy it with the constructor arguments - let contract = factory.deploy("initial value".to_string())?.send().await?; + let contract = factory + .deploy("initial value".to_string())? + .legacy() + .send() + .await?; // 7. get the contract's address let addr = contract.address(); @@ -53,7 +57,12 @@ async fn main() -> Result<()> { // 9. call the `setValue` method // (first `await` returns a PendingTransaction, second one waits for it to be mined) - let _receipt = contract.set_value("hi".to_owned()).send().await?.await?; + let _receipt = contract + .set_value("hi".to_owned()) + .legacy() + .send() + .await? + .await?; // 10. get all events let logs = contract diff --git a/examples/ens.rs b/examples/ens.rs index c6bf8056..d8968733 100644 --- a/examples/ens.rs +++ b/examples/ens.rs @@ -1,29 +1,29 @@ use anyhow::Result; -use ethers::prelude::*; +use ethers::{prelude::*, utils::Ganache}; use std::convert::TryFrom; #[tokio::main] async fn main() -> Result<()> { + // fork mainnet + let ganache = Ganache::new() + .fork("https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27") + .spawn(); + let from = ganache.addresses()[0].clone(); // connect to the network - let provider = Provider::::try_from( - "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27", - )?; - - // create a wallet and connect it to the provider - let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7" - .parse::()?; - let client = SignerMiddleware::new(provider, wallet); + let provider = Provider::::try_from(ganache.endpoint()) + .unwrap() + .with_sender(from); // craft the transaction let tx = TransactionRequest::new().to("vitalik.eth").value(100_000); // send it! - let receipt = client + let receipt = provider .send_transaction(tx, None) .await? .await? .ok_or_else(|| anyhow::format_err!("tx dropped from mempool"))?; - let tx = client.get_transaction(receipt.transaction_hash).await?; + let tx = provider.get_transaction(receipt.transaction_hash).await?; println!("{}", serde_json::to_string(&tx)?); println!("{}", serde_json::to_string(&receipt)?); diff --git a/examples/ipc.rs b/examples/ipc.rs index 361c7f9c..5fa4f9ce 100644 --- a/examples/ipc.rs +++ b/examples/ipc.rs @@ -2,6 +2,7 @@ use ethers::prelude::*; use std::time::Duration; #[tokio::main] +#[cfg(feature = "ipc")] async fn main() -> anyhow::Result<()> { let provider = Provider::connect_ipc("~/.ethereum/geth.ipc") .await? @@ -15,3 +16,6 @@ async fn main() -> anyhow::Result<()> { Ok(()) } + +#[cfg(not(feature = "ipc"))] +fn main() {} diff --git a/examples/watch_blocks.rs b/examples/watch_blocks.rs index 97c2e008..8ee2cffb 100644 --- a/examples/watch_blocks.rs +++ b/examples/watch_blocks.rs @@ -1,11 +1,12 @@ -use ethers::prelude::*; +use ethers::{prelude::*, utils::Ganache}; use std::time::Duration; #[tokio::main] async fn main() -> anyhow::Result<()> { - let ws = Ws::connect("ws://localhost:8546").await?; + let ganache = Ganache::new().block_time(1u64).spawn(); + let ws = Ws::connect(ganache.ws_endpoint()).await?; let provider = Provider::new(ws).interval(Duration::from_millis(2000)); - let mut stream = provider.watch_blocks().await?.stream(); + let mut stream = provider.watch_blocks().await?.take(5); while let Some(block) = stream.next().await { dbg!(block); } diff --git a/scripts/examples.sh b/scripts/examples.sh new file mode 100755 index 00000000..9639af55 --- /dev/null +++ b/scripts/examples.sh @@ -0,0 +1,5 @@ +# run all examples +for file in examples/*.rs; do + name=`echo $file | cut -f 1 -d '.'` + cargo r -p ethers --example `basename $name` +done