1

If you use Web3.py to deploy a Solidity contract to the blockchain, you can retrieve a transaction hash, like this:

tx_hash = w3.eth.sendRawTransaction(signed.rawTransaction)

Once you have that tx_hash, you can retrieve a transaction receipt, like this:

tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)

However, I haven't been able to find a straightforward way to retrieve that information for a contract that I didn't deploy (or that I deployed at some point in the past and didn't record).

Couple of notes:

  • There could be multiple transactions across multiple blocks for that contract.
  • I'm looking for a solution using Web3 -- I'd prefer not to traverse the entire blockchain or go to Etherscan and look up the information.

I would like to get an array of either:

  • all the block numbers that contain a transaction for a given contract
  • all the transaction receipts for a given contract

after the contract has been deployed. Is that possible?

For example, let's imagine that I wanted to find all of the transaction receipts for a smart contract deployed on the Ropsten test network.

Let's use the helloWorld contract deployed at this address: 0xb1Afb360F9ba99883166236a4b2DdAa9e3ff397a

This contract has been verified on Etherscan, so its ABI is available. You can see it on Etherscan here: https://ropsten.etherscan.io/address/0xb1afb360f9ba99883166236a4b2ddaa9e3ff397a#code

The following Python code will allow you to instantiate the contract, and call functions defined in the ABI:

abi = '''
[{"constant":false,"inputs":[{"name":"_wordsToSay","type":"string"}],"name":"sayAnything","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"sayHello","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]
'''

contract_address = "0xb1Afb360F9ba99883166236a4b2DdAa9e3ff397a"
contract = w3.eth.contract(address=contract_address, abi=abi)

pprint.pprint(contract.functions.sayHello().call())

The only other attributes I have been able to retrieve are the address and the ABI.

Is there any way to retrieve the block numbers or transaction hashes for an already deployed contract?

  • I think you're saying you want to see any transaction that interacts with a contract. Emitting events in the contract, and then using a filter, is a good way to do that kind of thing. Can you update the question with whether you've tried events, or if there is anything about events that don't meet your needs? – carver Oct 2 '18 at 23:52
  • Thank you for your reply Carver. For practical reasons (Infura, the host that I'm using to access the blockchain, doesn't support events) I didn't test events. However, as I understand, events and logs are optional, and Web3.py will return an empty hash if the programmer didn't emit them. I'm trying to access either the block number / block hash / transaction data about arbitrary contracts that I didn't write. So my impression (which may be wrong) is that events would not meet my needs. Thoughts? – Chris Brooks Oct 3 '18 at 13:37
0

Since you're interested in arbitrary contracts that don't emit events, you'll have to scan each block. Additionally, to capture scenarios where the contract you're interested in is called by another contract (instead of an Externally Owned Account), you'll likely have to run a trace on each transaction.

Traces are non-standard (client-specific) mechanisms for peeking inside the EVM mechanics of a transaction. Infura does not support traces, AFAIK. So you'll almost certainly have to run a local node.

Web3.py only supports parity traces, currently, so I'd probably start there. Unfortunately they're not documented in web3.py docs at the moment. You would roughly do something like:

from web3.auto import w3
from web3.parity import Parity
Parity.attach(w3, 'parity)
trace_results = w3.parity.traceReplayBlockTransactions('latest')

You can find more parity trace methods in the web3py source.

  • Thank you again Carver. The traces are interesting -- I'll definitely have to dig into those. It sounds like I'll need to start at one end of the blockchain and scan every block until I find the transaction I'm looking for. Thanks for the help. – Chris Brooks Oct 4 '18 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.