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

Function signatures do not take return type into account #3131

Closed
Qqwy opened this issue Oct 26, 2017 · 6 comments
Closed

Function signatures do not take return type into account #3131

Qqwy opened this issue Oct 26, 2017 · 6 comments

Comments

@Qqwy
Copy link

Qqwy commented Oct 26, 2017

From the Solidity documentation

The first four bytes of the call data for a function call specifies the function to be called. It is the first (left, high-order in big-endian) four bytes of the Keccak (SHA-3) hash of the signature of the function. The signature is defined as the canonical expression of the basic prototype, i.e. the function name with the parenthesised list of parameter types. Parameter types are split by a single comma - no spaces are used.

It seems that the return type of the function is not taken into account. Does this mean that a contract that returns something that the caller contract does not expect is able to exploit problems with implicit type conversions?

I have not yet had the time to create a test case to try what happens in practice, but it seems very odd to
not have the return type be part of the function signature/function selector that is used to decide what function is called (and if it is possible at all to call a function on a certain contract).

Am I missing something?

@chriseth
Copy link
Contributor

The function selector only has four bytes, so there is no bijection between function selector and the type of the function anyway. If you call functions on contracts that are not compiled from the source code you assume they are compiled from, such attacks are also possible if you take the return parameters into the selector.

@VoR0220
Copy link
Member

VoR0220 commented Oct 26, 2017

...you know I never thought about this, but why weren't outputs included in the original function signature sha3?

@axic
Copy link
Member

axic commented Oct 26, 2017

Function overloading can have a hard time determining what expressions are valid (function as right hand side vs. lvalue) and more importantly if the return value is not assigned to anything which one to take from a return-overloaded case?

Thus many languages (such as C++) doesn't support it. I assume Solidity took a good chunk of early decisions from C++.

@axic
Copy link
Member

axic commented Dec 22, 2017

@elenadimitrova do you want to incorporate this last comment in to the documentation?

@Qqwy
Copy link
Author

Qqwy commented Dec 22, 2017

@axic I do believe that there is an important difference between supporting 'parametric return types' (which is what your C++ comment is hinting at and which indeed requires a quite powerful compiler) vs incorporating the return type in the resulting function signature's SHA3-hash (since this is a separate step that happens after the compilation itself, right?)

@axic
Copy link
Member

axic commented Dec 22, 2017

I agree that it would have been more consistent with the ABI to include the return types in the signature and other languages may utilise that feature.

The function selector on its own is not supposed to be used though, but in rather a JSON description of the ABI exists of which the clients calculate the hash themselves. This contains both inputs and outputs. See https://solidity.readthedocs.io/en/develop/abi-spec.html#json

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

No branches or pull requests

4 participants