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 <me@gakonst.com>
This commit is contained in:
Mark Tyneway 2022-02-05 06:37:09 -08:00 committed by GitHub
parent 75fbec0706
commit 100f121202
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 3 deletions

View File

@ -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

View File

@ -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<M: Middleware> Deployer<M> {
/// be sufficiently confirmed (default: 1), it returns a [`Contract`](crate::Contract)
/// struct at the deployed contract's address.
pub async fn send(self) -> Result<Contract<M>, ContractError<M>> {
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<M>, TransactionReceipt), ContractError<M>> {
let pending_tx = self
.client
.send_transaction(self.tx, Some(self.block.into()))
@ -81,7 +95,7 @@ impl<M: Middleware> Deployer<M> {
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

View File

@ -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();