diff --git a/examples/local_signer.rs b/examples/local_signer.rs index 2d1d2d5c..f0d96ba4 100644 --- a/examples/local_signer.rs +++ b/examples/local_signer.rs @@ -4,16 +4,21 @@ use std::str::FromStr; #[tokio::main] async fn main() -> Result<(), failure::Error> { + // connect to the network let provider = HttpProvider::try_from("http://localhost:8545")?; + + // create a wallet and connect it to the provider let client = MainnetWallet::from_str( "d8ebe1e50cfea1f9961908d9df28e64bb163fee9ee48320361b2eb0a54974269", )? .connect(&provider); + // get the account's nonce let nonce = provider .get_transaction_count(client.signer.address, None) .await?; + // craft the transaction let tx = UnsignedTransaction { to: Some("986eE0C8B91A58e490Ee59718Cca41056Cf55f24".parse().unwrap()), gas: 21000.into(), @@ -23,8 +28,10 @@ async fn main() -> Result<(), failure::Error> { nonce, }; + // send it! let tx = client.send_transaction(tx).await?; + // get the mined tx let tx = client.get_transaction(tx.hash).await?; println!("{}", serde_json::to_string(&tx)?); diff --git a/examples/sign.rs b/examples/sign.rs new file mode 100644 index 00000000..69ec04b6 --- /dev/null +++ b/examples/sign.rs @@ -0,0 +1,17 @@ +use ethers::{MainnetWallet as Wallet, Signer}; + +fn main() { + let message = "Some data"; + let wallet = Wallet::new(&mut rand::thread_rng()); + + // sign a message + let signature = wallet.sign_message(message); + println!("Produced signature {}", signature); + + // recover the address that signed it + let recovered = signature.recover(message).unwrap(); + + assert_eq!(recovered, wallet.address); + + println!("Verified signature produced by {:?}!", wallet.address); +} diff --git a/examples/transfer_eth.rs b/examples/transfer_eth.rs index 4a9b0e7e..45cab594 100644 --- a/examples/transfer_eth.rs +++ b/examples/transfer_eth.rs @@ -6,20 +6,23 @@ use std::convert::TryFrom; #[tokio::main] async fn main() -> Result<(), failure::Error> { + // connect to the network let provider = HttpProvider::try_from("http://localhost:8545")?; let from = "4916064D2E9C1b2ccC466EEc3d30B2b08F1C130D".parse()?; - let tx_hash = provider - .send_transaction(TransactionRequest { - from, - to: Some("9A7e5d4bcA656182e66e33340d776D1542143006".parse()?), - value: Some(1000u64.into()), - gas: None, - gas_price: None, - data: None, - nonce: None, - }) - .await?; + // craft the tx + let tx = TransactionRequest { + from, + to: Some("9A7e5d4bcA656182e66e33340d776D1542143006".parse()?), + value: Some(1000u64.into()), + gas: None, + gas_price: None, + data: None, + nonce: None, + }; + + // broadcast it via the eth_sendTransaction API + let tx_hash = provider.send_transaction(tx).await?; let tx = provider.get_transaction(tx_hash).await?; diff --git a/src/lib.rs b/src/lib.rs index b4a0a5fe..88e66770 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,7 @@ pub mod providers; pub use providers::HttpProvider; pub mod signers; -pub use signers::{AnyWallet, MainnetWallet}; +pub use signers::{AnyWallet, MainnetWallet, Signer}; /// Ethereum related datatypes pub mod types; diff --git a/src/providers/mod.rs b/src/providers/mod.rs index 2af270b9..edab5267 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -6,6 +6,7 @@ mod http; use crate::{ + signers::{Client, Signer}, types::{Address, BlockNumber, Bytes, Transaction, TransactionRequest, TxHash, U256}, utils, }; @@ -37,6 +38,14 @@ pub struct Provider
(P);
// JSON RPC bindings
impl {
+ /// Connects to a signer and returns a client
+ pub fn connect ,
+ pub provider: &'a Provider ,
pub signer: S,
}
diff --git a/src/signers/mod.rs b/src/signers/mod.rs
index 0c42c4f4..abe38c97 100644
--- a/src/signers/mod.rs
+++ b/src/signers/mod.rs
@@ -1,3 +1,4 @@
+//! Sign and broadcast transactions
mod networks;
pub use networks::instantiated::*;
use networks::Network;
@@ -6,7 +7,7 @@ mod wallet;
pub use wallet::Wallet;
mod client;
-use client::Client;
+pub(crate) use client::Client;
use crate::types::{Signature, Transaction, UnsignedTransaction};
diff --git a/src/types/signature.rs b/src/types/signature.rs
index 60a5aa48..6676194e 100644
--- a/src/types/signature.rs
+++ b/src/types/signature.rs
@@ -4,12 +4,13 @@ use crate::{
utils::hash_message,
};
+use rustc_hex::ToHex;
use secp256k1::{
recovery::{RecoverableSignature, RecoveryId},
Error as Secp256k1Error, Message, Secp256k1,
};
use serde::{Deserialize, Serialize};
-use std::convert::TryFrom;
+use std::{convert::TryFrom, fmt};
use thiserror::Error;
/// An error involving a signature.
@@ -47,6 +48,13 @@ pub struct Signature {
pub v: u8,
}
+impl fmt::Display for Signature {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let sig = <[u8; 65]>::from(self);
+ write!(f, "{}", sig.to_hex:: {
+ Client {
+ signer,
+ provider: self,
+ }
+ }
+
pub async fn get_block_number(&self) -> Result