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

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

Get contract return values from transaction recepts #1288

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

Comments

@ARitz-Cracker
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 <aritz@aritzcracker.ca> 
discussions-to: https://github.com/ethereum/EIPs/issues/1288
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.

Abstract

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

Motivation

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.

Specification

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.

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

// Result
{
	"id":1,
	"jsonrpc": "2.0",
	"result":{
		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'
	}
}

Rationale

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

Copyright and related rights waived via CC0.

@MicahZoltu
Copy link
Contributor

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.

@ARitz-Cracker
Copy link
Author

@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.

@Arachnid
Copy link
Contributor

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.

@Gerdinand
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).

@frangio
Copy link
Contributor

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.

@ARitz-Cracker
Copy link
Author

@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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants