Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add web3::contract::deploy::execute_no_unlock #252

Merged
merged 10 commits into from
Sep 15, 2019
73 changes: 63 additions & 10 deletions src/contract/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::api::{Eth, Namespace};
use crate::confirm;
use crate::contract::tokens::Tokenize;
use crate::contract::{Contract, Options};
use crate::types::{Address, Bytes, TransactionRequest};
use crate::types::{Address, Bytes, TransactionReceipt, TransactionRequest};
use crate::Transport;

pub use crate::contract::error::deploy::Error;
Expand Down Expand Up @@ -49,6 +49,61 @@ impl<T: Transport> Builder<T> {
where
P: Tokenize,
V: AsRef<str>,
{
let transport = self.eth.transport().clone();
let poll_interval = self.poll_interval;
let confirmations = self.confirmations;

self.do_execute(code, params, from, move |tx| {
confirm::send_transaction_with_confirmation(transport, tx, poll_interval, confirmations)
})
}
/// Execute deployment passing code and contructor parameters.
///
/// Unlike the above `execute`, this method uses
/// `sign_raw_transaction_with_confirmation` instead of
/// `sign_transaction_with_confirmation`, which requires the account from
/// which the transaction is sent to be unlocked.
pub fn sign_and_execute<P, V, Ft>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ft parameter is unused. This is problematic for calling code because the compiler cannot infer the instantiation of Ft. This leads to the calling code always requiring an explicit type annotation.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just remove it then. I guess I left it by mistake.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try this out.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it solve the issues you were having?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It did. I get other errors now, but as far as this PR goes, it has what we need.
Do you still want me to add a test before we merge?

self,
code: V,
params: P,
from: Address,
password: &str,
) -> Result<PendingContract<T, impl Future<Item = TransactionReceipt, Error = crate::error::Error>>, ethabi::Error>
where
P: Tokenize,
V: AsRef<str>,
{
let transport = self.eth.transport().clone();
let poll_interval = self.poll_interval;
let confirmations = self.confirmations;

self.do_execute(code, params, from, move |tx| {
crate::api::Personal::new(transport.clone())
.sign_transaction(tx, password)
.and_then(move |signed_tx| {
confirm::send_raw_transaction_with_confirmation(
transport,
signed_tx.raw,
poll_interval,
confirmations,
)
})
})
}

fn do_execute<P, V, Ft>(
self,
code: V,
params: P,
from: Address,
send: impl FnOnce(TransactionRequest) -> Ft,
) -> Result<PendingContract<T, Ft>, ethabi::Error>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
) -> Result<PendingContract<T, Ft>, ethabi::Error>
) -> Result<PendingContract<T, impl Future<...>>, ethabi::Error>

Drop Ft and try this.

where
P: Tokenize,
V: AsRef<str>,
Ft: Future<Item = TransactionReceipt, Error = crate::error::Error>,
{
let options = self.options;
let eth = self.eth;
Expand Down Expand Up @@ -89,12 +144,7 @@ impl<T: Transport> Builder<T> {
condition: options.condition,
};

let waiting = confirm::send_transaction_with_confirmation(
eth.transport().clone(),
tx,
self.poll_interval,
self.confirmations,
);
let waiting = send(tx);

Ok(PendingContract {
eth: Some(eth),
Expand All @@ -105,13 +155,16 @@ impl<T: Transport> Builder<T> {
}

/// Contract being deployed.
pub struct PendingContract<T: Transport> {
pub struct PendingContract<
T: Transport,
F: Future<Item = TransactionReceipt, Error = crate::error::Error> = confirm::SendTransactionWithConfirmation<T>,
> {
eth: Option<Eth<T>>,
abi: Option<ethabi::Contract>,
waiting: confirm::SendTransactionWithConfirmation<T>,
waiting: F,
}

impl<T: Transport> Future for PendingContract<T> {
impl<T: Transport, F: Future<Item = TransactionReceipt, Error = crate::error::Error>> Future for PendingContract<T, F> {
type Item = Contract<T>;
type Error = Error;

Expand Down