Rufen Sie den Wert ab, der von einer Funktion zurückgegeben wurde, die mit „transact“ aufgerufen wurde

Ich verwende Python web3, um einen Solidity-Vertrag bereitzustellen und zu testen.

Hier sind meine ersten Schritte:

from web3 import Web3
from web3 import RPCProvider
from json import loads

eth = Web3(RPCProvider()).eth
abi = open(ABI_FILE_NAME).read()
bin = open(BIN_FILE_NAME).read()
transaction = {'from':eth.accounts[0]}

contract = eth.contract(abi=loads(abi),bytecode=bin)
tx_hash  = contract.deploy(transaction=transaction)
address  = eth.getTransactionReceipt(tx_hash)['contractAddress']
handle   = contract(address).transact(transaction)

An dieser Stelle rufe ich eine Funktion im Vertrag auf:

tx_hash = handle.some_func()

Und das bekomme ich, wenn ich anrufe eth.getTransactionReceipt(tx_hash):

{
    'transactionHash'   : '0x...',
    'transactionIndex'  : 0,
    'blockHash'         : '0x...',
    'blockNumber'       : 3710,
    'gasUsed'           : 72597,
    'cumulativeGasUsed' : 72597,
    'contractAddress'   : None,
    'logs'              : [],
    'status'            : 1
}

some_funcWie kann ich den tatsächlich zurückgegebenen Wert abrufen ?

Ich habe eine sehr detaillierte Antwort gefunden , die sich auf dieses Problem zu beziehen scheint, aber ich konnte die tatsächlich erforderlichen Schritte nicht abschließen.

Danke schön.

Antworten (2)

Leider gibt es bei einer Transaktion keinen „Rückgabewert“. Es gibt zwei typische Muster, um einen Rückgabewert zu simulieren:

  1. Mutieren Sie den Zustand über eine Transaktion und lesen Sie dann den resultierenden Zustand, indem Sie eine viewFunktion aufrufen. (Beachten Sie, dass Sie dadurch den Status zum Zeitpunkt des Aufrufs der viewFunktion erhalten, nicht unbedingt den Status unmittelbar nach der Transaktion, da möglicherweise andere Transaktionen dazwischen gekommen sind.)
  2. Mutieren Sie den Zustand über eine Transaktion und geben Sie eine aus, eventdie vom Aufrufer beobachtet wird.

Abhängig von Ihrem Szenario kann das eine oder andere die natürlichere Passform sein.

Ja, ich habe diese Informationen bereits mehr oder weniger gesammelt. Die erste Option ist aus dem Grund, den Sie ausdrücklich erwähnen, nicht akzeptabel. Ich muss mich mit der zweiten Option befassen. Hast du ein gutes Codierungsbeispiel? Beide Seiten (Solidity und Python-web3) wären großartig. Wenn nicht, dann zumindest auf der Solidity-Seite. Danke.
solidity.readthedocs.io/en/develop/contracts.html#events ist ziemlich gut, obwohl es Solidity+JavaScript ist, nicht Solidity+Python.
Danke, ich konnte dieses Ziel endlich erreichen. Praktische Antwort unter Ihrer gegeben.

So konnte ich dieses Problem lösen:

  1. Im Solidity-Vertrag generiere ich kurz vor der Rückgabe eine, eventdie den zurückzugebenden Wert enthält.
  2. Im Python-Code extrahiere ich den zurückgegebenen Wert mit:

    retVal = eth.getTransactionReceipt(tx_hash)['logs'][0]['data']

Dieser Wert ist in meinem Fall eine hexadezimale Zeichenfolge, daher verwende ich, int(retVal,16)um den entsprechenden ganzzahligen Wert zu erhalten.