As per my understanding when I invoke a constant function without a transaction in a contract and if the function returns some result I am able to get it in EthereumJ or Go-Ethereum, But when a transaction is performed on a function it is returning a hex value. Please suggest how to get a return value from a function on which a transaction has been performed.
-
Possible duplicate of How to manipulate data in a Solidity smart contract? – Abhiram mishra Jun 21 '16 at 10:45
3 Answers
You need to use an Event, see example:
contract answer{
// ...
event VoteEvent(string ID, bool returnValue);
function vote(string ID, uint qNum, uint ans) returns (bool) {
// ...
VoteEvent(ID, true);
return true;
}
}
-
Here's an example of retrieving The DAO Voted events - http://ethereum.stackexchange.com/a/4553/1268 – BokkyPooBah Jun 21 '16 at 09:53
If you're using ethers.js, there's a feature called callStatic that allows you to call a non-constant function as if it were constant:
const result = await contract.callStatic.nonConstantFunction(…);
Related discussion in the ethers.js repository: How can I make a call and get the return values?
- 17,902
- 6
- 73
- 143
You can obtain the value returned from a transaction by calling debug_traceTransaction within Geth and looking at the final step in the trace. It is typically a RETURN opcode, so the top 2 stack values give the offset and length of the expected return data within the memory. You can then use the ABI to format this data accordingly.
Here is some sample code to achieve this in Python. step is the final step in the stack trace obtained by calling debug_traceTransaction, abi is the abi for the contract method being called.
from eth_abi import decode_abi
from hexbytes import HexBytes
def get_return_value(step, abi):
offset = int(step['stack'][-1], 16) * 2
length = int(step['stack'][-2], 16) * 2
memory = HexBytes("".join(step['memory'])[offset:offset+length])
return decode_abi([i['type'] for i in abi['outputs']], memory)
- 2,876
- 1
- 12
- 32