Wie kann ich den Transaktions-Hash / Block-Hash eines bereits bereitgestellten Vertrags abrufen?

Wenn Sie Web3.py verwenden, um einen Solidity-Vertrag in der Blockchain bereitzustellen, können Sie einen Transaktions-Hash wie folgt abrufen:

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

Sobald Sie diesen tx_hash haben, können Sie einen Transaktionsbeleg wie folgt abrufen:

tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)

Ich konnte jedoch keine einfache Möglichkeit finden, diese Informationen für einen Vertrag abzurufen, den ich nicht bereitgestellt habe (oder den ich irgendwann in der Vergangenheit bereitgestellt und nicht aufgezeichnet habe).

Paar Anmerkungen:

  • Es könnte mehrere Transaktionen über mehrere Blöcke für diesen Vertrag geben.
  • Ich suche nach einer Lösung mit Web3 - ich würde es vorziehen, nicht die gesamte Blockchain zu durchlaufen oder zu Etherscan zu gehen und die Informationen nachzuschlagen.

Ich möchte entweder ein Array erhalten:

  • alle Blocknummern, die eine Transaktion für einen bestimmten Vertrag enthalten
  • alle Transaktionsbelege für einen bestimmten Vertrag

nachdem der Vertrag bereitgestellt wurde. Ist das möglich?

Stellen wir uns zum Beispiel vor, ich möchte alle Transaktionsbelege für einen Smart Contract finden, der im Ropsten-Testnetzwerk bereitgestellt wird.

Verwenden wir den helloWorld-Vertrag, der unter dieser Adresse bereitgestellt wird: 0xb1Afb360F9ba99883166236a4b2DdAa9e3ff397a

Dieser Vertrag wurde auf Etherscan verifiziert, daher ist sein ABI verfügbar. Sie können es hier auf Etherscan sehen: https://ropsten.etherscan.io/address/0xb1afb360f9ba99883166236a4b2ddaa9e3ff397a#code

Mit dem folgenden Python-Code können Sie den Vertrag instanziieren und in der ABI definierte Funktionen aufrufen:

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

Die einzigen anderen Attribute, die ich abrufen konnte, sind die Adresse und die ABI.

Gibt es eine Möglichkeit, die Blocknummern oder Transaktions-Hashes für einen bereits bereitgestellten Vertrag abzurufen?

Ich denke, Sie sagen, dass Sie jede Transaktion sehen möchten, die mit einem Vertrag interagiert. Ereignisse im Vertrag auszugeben und dann einen Filter zu verwenden, ist eine gute Möglichkeit, so etwas zu tun. Können Sie die Frage dahingehend aktualisieren, ob Sie Veranstaltungen ausprobiert haben oder ob etwas an Veranstaltungen Ihren Anforderungen nicht entspricht?
Vielen Dank für Ihre Antwort Carver. Aus praktischen Gründen (Infura, der Host, den ich für den Zugriff auf die Blockchain verwende, unterstützt keine Ereignisse) habe ich keine Ereignisse getestet. Soweit ich weiß, sind Ereignisse und Protokolle jedoch optional, und Web3.py gibt einen leeren Hash zurück, wenn der Programmierer sie nicht ausgegeben hat. Ich versuche, entweder auf die Blocknummer / den Blockhash / die Transaktionsdaten über beliebige Verträge zuzugreifen, die ich nicht geschrieben habe. Mein (möglicherweise falscher) Eindruck ist also, dass Veranstaltungen nicht meinen Bedürfnissen entsprechen würden. Gedanken?

Antworten (1)

Da Sie an beliebigen Verträgen interessiert sind, die keine Ereignisse ausgeben, müssen Sie jeden Block scannen. Um Szenarien zu erfassen, in denen der Vertrag, an dem Sie interessiert sind, von einem anderen Vertrag aufgerufen wird (anstelle eines externen Kontos), müssen Sie außerdem wahrscheinlich eine Ablaufverfolgung für jede Transaktion ausführen.

Ablaufverfolgungen sind nicht standardmäßige (clientspezifische) Mechanismen, um einen Blick in die EVM-Mechanik einer Transaktion zu werfen. Infura unterstützt keine Traces, AFAIK. Sie müssen also mit ziemlicher Sicherheit einen lokalen Knoten ausführen.

Web3.py unterstützt derzeit nur paritytraces , also würde ich wahrscheinlich dort anfangen. Leider sind sie derzeit nicht in web3.py-Dokumenten dokumentiert. Sie würden ungefähr so ​​etwas tun:

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

Weitere Parity-Trace-Methoden finden Sie in der web3py-Quelle .

Nochmals vielen Dank Carver. Die Spuren sind interessant – da muss ich definitiv nachforschen. Es hört sich so an, als müsste ich an einem Ende der Blockchain beginnen und jeden Block scannen, bis ich die gesuchte Transaktion finde. Danke für die Hilfe.