Repository: eth-brownie/brownie
Issue: Cannot `chain.get_transaction` for a transaction where the contract has self-destructed

### Environment information

* `brownie` Version: 1.14.4

### What was wrong?

```
>>> chain.get_transaction("0xc0d3e50f01e5345a76d5e902c41cad38bf98afa49b703e82ab05991a4d7a20ff")
  File "<console>", line 1, in <module>
  File "/Users/ski/code/brownie/brownie/network/state.py", line 335, in get_transaction
    return tx or TransactionReceipt(txid, silent=True, required_confs=0)
  File "/Users/ski/code/brownie/brownie/network/transaction.py", line 194, in init
    self._await_transaction(required_confs, is_blocking)
  File "/Users/ski/code/brownie/brownie/network/transaction.py", line 415, in _await_transaction
    self._set_from_tx(tx)
  File "/Users/ski/code/brownie/brownie/network/transaction.py", line 519, in _set_from_tx
    if not self.fn_name and state._find_contract(tx["to"]) is not None:
  File "/Users/ski/code/brownie/brownie/network/state.py", line 546, in _find_contract
    return Contract(address)
  File "/Users/ski/code/brownie/brownie/network/contract.py", line 939, in init
    contract = self.from_explorer(address, owner=owner, silent=True)
  File "/Users/ski/code/brownie/brownie/network/contract.py", line 1171, in from_explorer
    return cls.from_abi(name, address, abi, owner)
  File "/Users/ski/code/brownie/brownie/network/contract.py", line 1005, in from_abi
    _DeployedContractBase.__init__(self, address, owner, None)
  File "/Users/ski/code/brownie/brownie/network/contract.py", line 750, in init
    raise ContractNotFound(f"No contract deployed at {address}")
ContractNotFound: No contract deployed at 0x52903256dd18D85c2Dc4a6C999907c9793eA61E3
```

### How can it be fixed?

Maybe modify `get_transaction` to take the block identifier `get_transaction(txid, block_identifier=None)`.

I don't think that will work if the contract self destructed in the same block that it was created in (same transaction or not).

Even if we can't find the contract, the call should probably still return an incomplete transaction object.


Changed files:
brownie/network/transaction.py

diff --git a/brownie/network/transaction.py b/brownie/network/transaction.py
index 0f61acde..e72ee0c4 100644
--- a/brownie/network/transaction.py
+++ b/brownie/network/transaction.py
@@ -17,7 +17,7 @@ from web3.exceptions import TimeExhausted, TransactionNotFound
 
 from brownie._config import CONFIG
 from brownie.convert import EthAddress, Wei
-from brownie.exceptions import RPCRequestError
+from brownie.exceptions import ContractNotFound, RPCRequestError
 from brownie.project import build
 from brownie.project import main as project_main
 from brownie.project.compiler.solidity import SOLIDITY_ERROR_CODES
@@ -516,10 +516,18 @@ class TransactionReceipt:
         self.nonce = tx["nonce"]
 
         # if receiver is a known contract, set function name
-        if not self.fn_name and state._find_contract(tx["to"]) is not None:
+        if self.fn_name:
+            return
+        try:
             contract = state._find_contract(tx["to"])
-            self.contract_name = contract._name
-            self.fn_name = contract.get_method(tx["input"])
+            if contract is not None:
+                self.contract_name = contract._name
+                self.fn_name = contract.get_method(tx["input"])
+        except ContractNotFound:
+            # required in case the contract has self destructed
+            # other aspects of functionality will be broken, but this way we
+            # can at least return a receipt
+            pass
 
     def _set_from_receipt(self, receipt: Dict) -> None:
         """Sets object attributes based on the transaction reciept."""