2

I am using Python web3 in order to deploy and test a Solidity contract.

Here are my initial steps:

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)

At this point, I invoke a function in the contract:

tx_hash = handle.some_func()

And this is what I get when I call eth.getTransactionReceipt(tx_hash):

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

How can I retrieve the actual value that some_func has returned?

I found a very detailed answer which seems to refer to this issue, but I have not been able to conclude the actual steps required.

Thank you.

2 Answers 2

6

Unfortunately, there is no "return value" for a transaction. There are two typical patterns to simulate a return value:

  1. Mutate the state via a transaction and then read the resulting state by calling a view function. (Note that this gives you the state at the time you call the view function, not necessarily the state right after the transaction, since other transactions may have come between.)
  2. Mutate the state via a transaction and emit an event that's observed by the caller.

Depending on your scenario, one or the other may be a more natural fit.

3
  • Yes, I've already gathered this information more or less. The first option is not acceptable, due to the reason that you mention explicitly. I need to dive into the second option. Do you have a good coding example? Both sides (Solidity and Python-web3) would be great. If not, then at least on the Solidity side. Thanks. Commented Dec 25, 2017 at 20:03
  • solidity.readthedocs.io/en/develop/contracts.html#events is pretty good, though it's Solidity+JavaScript, not Solidity+Python.
    – user19510
    Commented Dec 25, 2017 at 20:06
  • Thanks, I was finally able to achieve this purpose. Practical answer given below yours. Commented Dec 26, 2017 at 14:55
5

Here is how I was able to resolve this problem:

  1. In the Solidity contract, just before returning, I generate an event which contains the value about to be returned.
  2. In the Python code, I extract the returned value with:

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

This value happens to be an hexadecimal string in my case, so I use int(retVal,16) in order to obtain the corresponding integer value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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