use crate::{ContractCall, Event}; use ethers_core::{ abi::{Abi, Detokenize, Error, EventExt, Function, FunctionExt, Tokenize}, types::{Address, Filter, NameOrAddress, Selector, TransactionRequest}, }; use ethers_providers::JsonRpcClient; use ethers_signers::{Client, Signer}; use rustc_hex::ToHex; use std::{collections::HashMap, fmt::Debug, hash::Hash, marker::PhantomData}; /// Represents a contract instance at an address. Provides methods for /// contract interaction. // TODO: Should we separate the lifetimes for the two references? // https://stackoverflow.com/a/29862184 #[derive(Debug, Clone)] pub struct Contract<'a, P, S> { client: &'a Client
,
abi: &'a Abi,
address: Address,
/// A mapping from method signature to a name-index pair for accessing
/// functions in the contract ABI. This is used to avoid allocation when
/// searching for matching functions by signature.
// Adapted from: https://github.com/gnosis/ethcontract-rs/blob/master/src/contract.rs
methods: HashMap ) -> Self {
let methods = create_mapping(&abi.functions, |function| function.selector());
Self {
client,
abi,
address,
methods,
}
}
/// Returns an `Event` builder for the provided event name. If there are
/// multiple functions with the same name due to overloading, consider using
/// the `method_hash` method instead, since this will use the first match.
pub fn event<'b, D: Detokenize>(&'a self, name: &str) -> Result
where
S: Hash + Eq,
F: Fn(&T) -> S,
{
let signature = &signature;
elements
.iter()
.flat_map(|(name, sub_elements)| {
sub_elements
.iter()
.enumerate()
.map(move |(index, element)| (signature(element), (name.to_owned(), index)))
})
.collect()
}