From 100f1212025179d8e466f6b3feb7f588d57dcd89 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Sat, 5 Feb 2022 06:37:09 -0800 Subject: [PATCH] feat(ethers-contract): add `send_with_receipt` to `Deployer` (#865) * feat(ethers-contract): add `send_with_receipt` to `Deployer` The `Deployer` is used to deploy contracts and its `send` function returns an attached instance of a `Contract`. There is no way to know the transaction hash of the deployment transaction, so this commit adds another method `send_with_receipt` that returns an attached `Contract` as well as a `TransactionReceipt`. * changelog: update * tests: call `send_with_receipt` in tests Co-authored-by: Georgios Konstantopoulos --- CHANGELOG.md | 3 +++ ethers-contract/src/factory.rs | 18 ++++++++++++++++-- ethers-contract/tests/contract.rs | 3 ++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3327b8a..7379e9b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,9 @@ [#854](https://github.com/gakonst/ethers-rs/pull/852) - Refactor `ethers-contract-abigen` to use `eyre` instead of `anyhow` via [#858](https://github.com/gakonst/ethers-rs/pull/858) +- Add `Deployer.send_with_receipt -> Result<(Contract, Receipt), Error>` + so that the receipt can be returned to the called when deploying + a contract [#865](https://github.com/gakonst/ethers-rs/pull/865) - Add Arbitrum mainnet and testnet to the list of known chains ## ethers-contract-abigen diff --git a/ethers-contract/src/factory.rs b/ethers-contract/src/factory.rs index eee777bc..9e7103ca 100644 --- a/ethers-contract/src/factory.rs +++ b/ethers-contract/src/factory.rs @@ -2,7 +2,10 @@ use crate::{Contract, ContractError}; use ethers_core::{ abi::{Abi, Token, Tokenize}, - types::{transaction::eip2718::TypedTransaction, BlockNumber, Bytes, TransactionRequest}, + types::{ + transaction::eip2718::TypedTransaction, BlockNumber, Bytes, TransactionReceipt, + TransactionRequest, + }, }; use ethers_providers::Middleware; @@ -66,6 +69,17 @@ impl Deployer { /// be sufficiently confirmed (default: 1), it returns a [`Contract`](crate::Contract) /// struct at the deployed contract's address. pub async fn send(self) -> Result, ContractError> { + let (contract, _) = self.send_with_receipt().await?; + Ok(contract) + } + + /// Broadcasts the contract deployment transaction and after waiting for it to + /// be sufficiently confirmed (default: 1), it returns a tuple with + /// the [`Contract`](crate::Contract) struct at the deployed contract's address + /// and the corresponding [`TransactionReceipt`](ethers_core::types::TransactionReceipt). + pub async fn send_with_receipt( + self, + ) -> Result<(Contract, TransactionReceipt), ContractError> { let pending_tx = self .client .send_transaction(self.tx, Some(self.block.into())) @@ -81,7 +95,7 @@ impl Deployer { let address = receipt.contract_address.ok_or(ContractError::ContractNotDeployed)?; let contract = Contract::new(address, self.abi.clone(), self.client); - Ok(contract) + Ok((contract, receipt)) } /// Returns a reference to the deployer's ABI diff --git a/ethers-contract/tests/contract.rs b/ethers-contract/tests/contract.rs index 17bfe11e..09f82878 100644 --- a/ethers-contract/tests/contract.rs +++ b/ethers-contract/tests/contract.rs @@ -42,7 +42,8 @@ mod eth_tests { // dry runs the deployment of the contract. takes the deployer by reference, no need to // clone. assert!(deployer.call().await.is_ok()); - let contract = deployer.clone().send().await.unwrap(); + let (contract, receipt) = deployer.clone().send_with_receipt().await.unwrap(); + assert_eq!(receipt.contract_address.unwrap(), contract.address()); let get_value = contract.method::<_, String>("getValue", ()).unwrap(); let last_sender = contract.method::<_, Address>("lastSender", ()).unwrap();