ethers_etherscan/
transaction.rs

1use std::collections::HashMap;
2
3use serde::Deserialize;
4
5use crate::{Client, EtherscanError, Response, Result};
6
7#[derive(Deserialize, Clone, Debug)]
8#[serde(rename_all = "camelCase")]
9struct ContractExecutionStatus {
10    is_error: String,
11    err_description: String,
12}
13
14#[derive(Deserialize, Clone, Debug)]
15struct TransactionReceiptStatus {
16    status: String,
17}
18
19impl Client {
20    /// Returns the status of a contract execution
21    pub async fn check_contract_execution_status(&self, tx_hash: impl AsRef<str>) -> Result<()> {
22        let query = self.create_query(
23            "transaction",
24            "getstatus",
25            HashMap::from([("txhash", tx_hash.as_ref())]),
26        );
27        let response: Response<ContractExecutionStatus> = self.get_json(&query).await?;
28
29        if response.result.is_error == "0" {
30            Ok(())
31        } else {
32            Err(EtherscanError::ExecutionFailed(response.result.err_description))
33        }
34    }
35
36    /// Returns the status of a transaction execution: `false` for failed and `true` for successful
37    pub async fn check_transaction_receipt_status(&self, tx_hash: impl AsRef<str>) -> Result<()> {
38        let query = self.create_query(
39            "transaction",
40            "gettxreceiptstatus",
41            HashMap::from([("txhash", tx_hash.as_ref())]),
42        );
43        let response: Response<TransactionReceiptStatus> = self.get_json(&query).await?;
44
45        match response.result.status.as_str() {
46            "0" => Err(EtherscanError::TransactionReceiptFailed),
47            "1" => Ok(()),
48            err => Err(EtherscanError::BadStatusCode(err.to_string())),
49        }
50    }
51}