Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get contract return values from transaction recepts #1288

ARitz-Cracker opened this issue Aug 1, 2018 · 6 comments

Get contract return values from transaction recepts #1288

ARitz-Cracker opened this issue Aug 1, 2018 · 6 comments


Copy link

ARitz-Cracker commented Aug 1, 2018

Here's the pull request

eip: 1288
title: Get contract return values from transaction recepts
author: Aritz Beobide-Cardinal <> 
status: Draft
type: Standards Track
category: Interface
created: 2018-08-01

Simple Summary

This is a proposal to give clients the ability to easily get contract return values and revert reasons from already completed transactions.


This EIP proposes to allow eth_getTransactionReceipt to show return values from a smart contract executon, similarly to eth_call.


Clients have no reliable way to get why a transaction has failed when mined, nor can they get the return value from a successful smart contract execution. A workaround would be to use eth_call before or after the transaction is mined, but that is unreliable since the state of a smart contract can change multiple times within the same block.

For example, any eth_call checks or gas estimations may return OK before the transaction is submitted to the mempool, but your transaction may be reverted due to the actions of one that got in just before you.

Expanding on this example, your transaction may have been between 2 other transactions which affected yours, so any eth_call checks on that block or the previous block return an unexpected value, resulting in much frustration. and confusion.


Take the result of eth_call and put it in eth_getTransactionReceipt's returning object; using a field called contractResult.

The return values can be interpreted using the ABI if status == 1, or as a string when status == 0.

curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0x62ec664057fe15405de42d1711e270b8b90ea2b6f32ae4ab7b8d417eb348ac5b"],"id":1}'

// Result
	"jsonrpc": "2.0",
		transactionHash: '0x62ec664057fe15405de42d1711e270b8b90ea2b6f32ae4ab7b8d417eb348ac5b',
		transactionIndex: '0x9',
		blockHash: '0x268920a0bb83f1bd66e6a1c8228119ef4db38c24c84d22c160e8e660aa204a56',
		blockNumber: '0x5ca0ee',
		from: '0x8c070c3c66f62e34bae561951450f15f3256f67c',
		to: '0xc0c001140319c5f114f8467295b1f22f86929ad0',
		cumulativeGasUsed: '0x33b60',
		gasUsed: '0x5914',
		contractAddress: null,
		logs: [],
		logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
		status: '0x0',
		// Here's the new thing:
		contractResult: '0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000026706c65617365207069636b20612070657263656e74206265747765656e203120616e642039390000000000000000000000000000000000000000000000000000'


This implementation proposal kills 2 birds with one stone, allowing for revert reasons and successful return values to be accessable by the client. This proposal was designed to require minimal work for implementation, and to take advantage of already existing infrastructure.

Backwards Compatibility

This proposal will not break anything that relies on existing behaviour.


Copyright and related rights waived via CC0.

Copy link

I believe in the past this has been punted on because of the unbounded size of a contract's result. For example, if a contract returns a string or an array of values the size of the receipt is now unbounded. Since receipts are part of consensus, they need to be kept small/constrained.

One option would be to only return the first 32 bytes of the result. This greatly limits what you can usefully return, but would solve the problem for a lot of people. 32 bytes is enough to give an exit code result, a number result, an address result, etc.

Copy link

@MicahZoltu a contracts result isn't unbounded as the stack size is pretty shallow. (at least in solidity, correct me if I'm wrong) Strings don't exist in the EVM, just a bunch of uint256s. If you push a "string" on the stack which is greater than 32 chars long, it pushes multiple uint256s internally.

Copy link

Arachnid commented Aug 2, 2018

@ARitz-Cracker The return value of a contract call is a section of memory, not stack elements. It can be as large as the contract's memory space.

As @MicahZoltu observes, we punted on this before because of the issue of determining what a fair qas cost would be.

Copy link

Gerdinand commented Aug 3, 2018

I think it would be fair to return only the first 32 bytes. Any critical information should be able to be conveyed this way.

Getting return values of contracts would be convenient, but what would really help me as a developer is if I can get the revert reason through the transaction receipt (preventing out-commenting/logging/redeploying thousands of times).

Copy link

frangio commented Aug 3, 2018

@ARitz-Cracker Have you seen EIP 758? It is an alternative proposal to retrieve the return value of a mined transaction. I believe it should be mentioned in this ERC as well. There was some discussion about receipts in the associated issue #758.

Copy link

@frangio I swear I looked through all the EIPs before submitting this one 😅 looks like I missed it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
None yet

No branches or pull requests

5 participants