-
Notifications
You must be signed in to change notification settings - Fork 6k
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
Add .selector member on function types #2473
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strictly, this is about the first four bytes of the hash of the signature, not the signature itself. I know we have msg.sig
, but I wonder whether it would make sense to call it identifier
or id
instead.
On the other hand, this could also be just confusing and sig
is an accepted - even if wrong - name for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
@chriseth |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the documentation. Also, there is a test failure:
Invalid error: "Internal compiler error (/home/travis/build/ethereum/solidity/libsolidity/ast/Types.cpp:2513): External signature of function needs declaration
"
scripts/../test/cmdlineTests.sh: line 80: 12148 Aborted (core dumped) "$REPO_ROOT"/build/test/solfuzzer --quiet < "$f"
Fuzzer failed on:
contract C {
function h() external {
}
function f() external returns (uint) {
function () external g = this.h;
return g.sig;
}
}
The ABI specification calls this thing "Function Selector". Also Perhaps we should deprecate
|
We can then talk about the function signature as the plain-text representation that is hashed to obtain the function selector. |
It is called as |
This works:
This doesn't:
(Calling The code fails here:
|
Probably |
Something is weird. On Linux it reports:
But on Windows there is only one failure:
What Linux reports is correct, but why is it missing on Windows? |
@chriseth any idea why the Windows vs. Linux tests differ? |
No, we have to investigate. |
libsolidity/ast/Types.cpp
Outdated
if (m_kind == Kind::External && hasDeclaration()) | ||
members.push_back(MemberList::Member( | ||
"selector", | ||
make_shared<IntegerType>(32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be bytes4
or uint32
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bytes4
.
Difference is: the other compilation failure is part of the end-to-end tests, which is not run on Windows. |
5703e70
to
2cd25bd
Compare
@chriseth @pirapira @federicobond Added documentation changes so this should be ready. |
8ab9ca2
to
38e0b1a
Compare
} | ||
function f() external returns (bytes4) { | ||
var g = this.h; | ||
return g.selector; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is not detected yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chriseth if you know a quick way to solve this, please do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@chriseth the reason we wanted to disable them on variables is most of them don't have a name so the signature cannot be established. Tha question remains: should we allow it for |
e45d046
to
2ab217c
Compare
@chriseth rebased (man, that was annoying) and I think this is as far as we can go without spending way too much time on it. It just checks if the declaration is available (e.g. has an external signature). That means |
if (member == "selector") | ||
{ | ||
FunctionType const& type = dynamic_cast<FunctionType const&>(*_memberAccess.expression().annotation().type); | ||
utils().popStackElement(type); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not m_context << Instruction::SWAP1 << Instruction::POP;
? (and then perhaps a shift left, not sure about that)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the stack should have <address> <signature>
.
Test bound functions. Perhaps for function types the stack also contains the first argument either before or after the function type. |
2ab217c
to
cce5083
Compare
@chriseth please review (but don't merge yet, will squash some commits) |
libsolidity/ast/Types.cpp
Outdated
@@ -2436,6 +2436,11 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con | |||
case Kind::BareDelegateCall: | |||
{ | |||
MemberList::MemberMap members; | |||
if (m_kind == Kind::External && hasDeclaration()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't we say that the hasDeclaration()
condition is not required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to give it a try.
aeee758
to
0fe2d04
Compare
return fun.selector; | ||
} | ||
function h() returns (bytes4) { | ||
function () external returns (bytes4) fun = this.f; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works now, but not sure we are doing the right thing, since the function signature of this function type can be different depending on what function was assigned to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but the correct type signature has to be there, since we also have to know it when we want to call the function. What are your worries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never mind.
0fe2d04
to
8b166c3
Compare
@chriseth should be ready now |
Fixes #1435.