pipermerriam / ethereum-function-signature-registry Goto Github PK
View Code? Open in Web Editor NEWRegistry of 4byte function signatures and their human readable counterparts.
Registry of 4byte function signatures and their human readable counterparts.
ethereum-function-signature-registry/func_sig_registry/utils/solidity.py
Lines 127 to 135 in 99d5cbe
This caused me problems when trying to submit signatures with the function name mint
(which includes the string "int").
mint(uint256 nonce, bytes32 challenge_digest)
was misinterpreted as mint(int256,uint256,bytes32)
.
mint(address _to, uint256 _amount)
failed with a 500. (My guess is that it's already been submitted.)
I uploaded a big batch of signatures, but got quite a lot of http 500. These were the ones causing errors:
addDataPoint(uint256,bool,string)
addDSource(string,byte,uint256)
addOptionChain(uint256,string,uint256,uint256,bytes32,address,int[])
buildCity(string,uint[2],uint[2])
changeVotingRules(uint256,uint256,int)
CharlyLifeLog(string,int)
Congress(uint256,uint256,int,address)
demintTokens(address,uint8)
directionCount(int,int,int,int)
Etheropt(uint256,string,uint256,uint256,bytes32,address,int[])
get_address(string)
getBlockHeader(int)
getConfigUint(bytes32)
getDataPoint(uint256,uint256)
getFeeAmount(int)
getMaxLossAfterTrade(address,uint256,int,int)
getMaxLossAfterTrade(address,uint256,uint256,int,int)
getMoneyness(int,uint256,uint256)
getPrevHash(int)
getUint(bytes32,string)
hint(bytes32,string,bytes20)
hintURL(bytes32,string)
id(Token)
mint(address,string)
mint(address,uint256)
mintBadge(address,uint256)
mint(bytes32)
mintGreen(address,uint256)
mintGrey(address,uint256)
mintToken(address,uint256)
mint(uint256)
mint(uint256,string)
moneySumAtSettlement(address,uint256,int,uint256)
moneySumAtSettlement(address,uint256,uint256,int,uint256,uint256)
oraclize_setProof(byte)
orderMatchTest(uint256,uint256,int,uint256,uint256,address,address,uint256,int)
orderMatchTest(uint256,uint256,uint256,int,uint256,uint256,address,address,int)
orderMatch(uint256,uint256,int,uint256,uint256,address,uint8,bytes32,bytes32,int)
orderMatch(uint256,uint256,uint256,int,uint256,uint256,address,uint8,bytes32,bytes32,int)
personAdd(string,int,int,string)
personUpdateDOB(uint256,int)
personUpdateDOD(uint256,int)
setConfigUint(bytes32,uint256)
setNextID(uint256,int)
setPreviousID(uint256,int)
setProofType(byte)
setRowcol(uint256,uint[2])
setUint(bytes32,string,uint256)
_stringGas(string)
stringToBytes32(string)
unhint(bytes32)
mint(address,uint256)
mint(uint256)
hintURL(bytes32,string)
mintToken(address,uint256)
Hi, thanks for this useful project! Looks like the website at https://www.4byte.directory/ is currently down -- I get an SSL cert error when I try to access it, and a "no such app" error from heroku when I try to access it via HTTP instead of HTTPS.
Traceback (most recent call last):
File "/home/web/venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.7/contextlib.py", line 74, in inner
return func(*args, **kwds)
File "/home/web/venv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File "./func_sig_registry/registry/views.py", line 118, in post
import_results.extend(Signature.import_from_solidity_file(file_obj))
File "./func_sig_registry/registry/models.py", line 101, in import_from_solidity_file
return cls.import_from_solidity_code(code)
File "./func_sig_registry/registry/models.py", line 95, in import_from_solidity_code
for raw_signature in function_signatures
File "./func_sig_registry/registry/models.py", line 95, in <listcomp>
for raw_signature in function_signatures
File "./func_sig_registry/registry/models.py", line 81, in import_from_raw_text_signature
text_signature = normalize_function_signature(raw_function_signature)
File "./func_sig_registry/utils/solidity.py", line 190, in normalize_function_signature
arg_types = ','.join(get_arg_types(args))
File "./func_sig_registry/utils/solidity.py", line 170, in get_arg_types
types = [p.strip().split(maxsplit=1)[0] for p in parts]
File "./func_sig_registry/utils/solidity.py", line 170, in <listcomp>
types = [p.strip().split(maxsplit=1)[0] for p in parts]
IndexError: list index out of rangeTraceback (most recent call last):
File "./func_sig_registry/utils/solidity.py", line 186, in normalize_function_signature
args_tuple_type = parse_type(normalize_type(f'({args})'))
File "/home/web/venv/lib/python3.7/site-packages/eth_abi/grammar.py", line 125, in parse
raise ParseError(e.text, e.pos, e.expr)
ParseError: Parse error at ' )' (column 2) in type string '( )'Traceback (most recent call last):
File "/home/web/venv/lib/python3.7/site-packages/eth_abi/grammar.py", line 123, in parse
return super().parse(type_str)
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/nodes.py", line 254, in parse
return self._parse_or_match(text, pos, 'parse')
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/nodes.py", line 289, in _parse_or_match
return self.visit(getattr(self.grammar, method_name)(text, pos=pos))
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/grammar.py", line 115, in parse
return self.default_rule.parse(text, pos=pos)
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/expressions.py", line 120, in parse
node = self.match(text, pos=pos)
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/expressions.py", line 137, in match
raise error
ParseError: Rule 'type' didn't match at ' )' (line 1, column 2).
I'm not able to recover the original solidity source that was sent in, but I believe we simply need to catch the ParseError
at an appropriate place and present a friendly error to the user.
Something like rollbar.
Users should be able to make GET requests for individual retrieval and for list retrieval of Event Signatures. Thus, class EventSignatureSerializer()
and class EventSignatureFilter()
should be implemented
EventSignatureSerializer()
similar to
EventSignatureFilter()
similar to
{"repository":{"owner":{"name":["This field is required."]}},"head_commit":["This field is required."]}
Payload:
{
"zen": "It's not fully shipped until it's fast.",
"hook_id": 9852399,
"hook": {
"type": "Repository",
"id": 9852399,
"name": "web",
"active": true,
"events": [
"push"
],
"config": {
"content_type": "json",
"insecure_ssl": "0",
"url": "https://www.4byte.directory/api/v1/receive-github-webhook/"
},
"updated_at": "2016-09-10T02:36:16Z",
"created_at": "2016-09-10T02:36:16Z",
"url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/hooks/9852399",
"test_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/hooks/9852399/test",
"ping_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/hooks/9852399/pings",
"last_response": {
"code": null,
"status": "unused",
"message": null
}
},
"repository": {
"id": 46935750,
"name": "blobstore-ethereum",
"full_name": "bluedroplet/blobstore-ethereum",
"owner": {
"login": "bluedroplet",
"id": 1980379,
"avatar_url": "https://avatars.githubusercontent.com/u/1980379?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/bluedroplet",
"html_url": "https://github.com/bluedroplet",
"followers_url": "https://api.github.com/users/bluedroplet/followers",
"following_url": "https://api.github.com/users/bluedroplet/following{/other_user}",
"gists_url": "https://api.github.com/users/bluedroplet/gists{/gist_id}",
"starred_url": "https://api.github.com/users/bluedroplet/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/bluedroplet/subscriptions",
"organizations_url": "https://api.github.com/users/bluedroplet/orgs",
"repos_url": "https://api.github.com/users/bluedroplet/repos",
"events_url": "https://api.github.com/users/bluedroplet/events{/privacy}",
"received_events_url": "https://api.github.com/users/bluedroplet/received_events",
"type": "Organization",
"site_admin": false
},
"private": false,
"html_url": "https://github.com/bluedroplet/blobstore-ethereum",
"description": "Stores arbitrary-sizes blobs of data in Ethereum's transaction log.",
"fork": false,
"url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum",
"forks_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/forks",
"keys_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/teams",
"hooks_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/hooks",
"issue_events_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/issues/events{/number}",
"events_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/events",
"assignees_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/assignees{/user}",
"branches_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/branches{/branch}",
"tags_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/tags",
"blobs_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/statuses/{sha}",
"languages_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/languages",
"stargazers_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/stargazers",
"contributors_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/contributors",
"subscribers_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/subscribers",
"subscription_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/subscription",
"commits_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/contents/{+path}",
"compare_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/merges",
"archive_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/downloads",
"issues_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/issues{/number}",
"pulls_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/pulls{/number}",
"milestones_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/milestones{/number}",
"notifications_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/labels{/name}",
"releases_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/releases{/id}",
"deployments_url": "https://api.github.com/repos/bluedroplet/blobstore-ethereum/deployments",
"created_at": "2015-11-26T15:59:07Z",
"updated_at": "2016-05-30T19:58:53Z",
"pushed_at": "2016-09-08T15:01:30Z",
"git_url": "git://github.com/bluedroplet/blobstore-ethereum.git",
"ssh_url": "[email protected]:bluedroplet/blobstore-ethereum.git",
"clone_url": "https://github.com/bluedroplet/blobstore-ethereum.git",
"svn_url": "https://github.com/bluedroplet/blobstore-ethereum",
"homepage": null,
"size": 53,
"stargazers_count": 0,
"watchers_count": 0,
"language": "JavaScript",
"has_issues": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"forks_count": 0,
"mirror_url": null,
"open_issues_count": 0,
"forks": 0,
"open_issues": 0,
"watchers": 0,
"default_branch": "master"
},
"sender": {
"login": "ethernomad",
"id": 161566,
"avatar_url": "https://avatars.githubusercontent.com/u/161566?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/ethernomad",
"html_url": "https://github.com/ethernomad",
"followers_url": "https://api.github.com/users/ethernomad/followers",
"following_url": "https://api.github.com/users/ethernomad/following{/other_user}",
"gists_url": "https://api.github.com/users/ethernomad/gists{/gist_id}",
"starred_url": "https://api.github.com/users/ethernomad/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ethernomad/subscriptions",
"organizations_url": "https://api.github.com/users/ethernomad/orgs",
"repos_url": "https://api.github.com/users/ethernomad/repos",
"events_url": "https://api.github.com/users/ethernomad/events{/privacy}",
"received_events_url": "https://api.github.com/users/ethernomad/received_events",
"type": "User",
"site_admin": false
}
}
when trying to submit:
getOrdersInfo((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[])
the 4byte.direcory - I get a 500 server error
this is a valid signature
Can an example bash/curl script please be provided that shows how to download the entire database?
The following error was generated when submitting "withdrawal(addr _param1, uint256 _param2)"
Traceback (most recent call last):
File "/home/web/venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.7/contextlib.py", line 74, in inner
return func(*args, **kwds)
File "/home/web/venv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File "./func_sig_registry/registry/views.py", line 87, in post
if not serializer.is_valid():
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 213, in is_valid
self._validated_data = self.run_validation(self.initial_data)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 407, in run_validation
value = self.to_internal_value(data)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 439, in to_internal_value
validated_value = validate_method(validated_value)
File "./func_sig_registry/registry/forms.py", line 34, in validate_text_signature
return normalize_function_signature(value)
File "./func_sig_registry/utils/solidity.py", line 204, in normalize_function_signature
raise ValueError('function args contain non-standard types') from e
ValueError: function args contain non-standard typesTraceback (most recent call last):
File "./func_sig_registry/utils/solidity.py", line 200, in normalize_function_signature
validate_standard_type(args_tuple_type)
File "./func_sig_registry/utils/solidity.py", line 156, in validate_standard_type
validate_standard_type(t)
File "./func_sig_registry/utils/solidity.py", line 151, in validate_standard_type
f'type "{abi_type.to_type_str()}" '
ABITypeError: type "addr" has invalid base "addr"
This exception needs to be caught and handled during form validation.
http://www.4byte.directory/ seems to be defaulting to the standard nginx page.
The webserver is revealing its version nginx/1.14.2
which is quite dated (Dec 2018).
server_tokens off;
to not reveal it's version and prevent automated attacks.Traceback (most recent call last):
File "/home/web/venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.7/contextlib.py", line 74, in inner
return func(*args, **kwds)
File "/home/web/venv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File "./func_sig_registry/registry/views.py", line 87, in post
if not serializer.is_valid():
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 213, in is_valid
self._validated_data = self.run_validation(self.initial_data)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 407, in run_validation
value = self.to_internal_value(data)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 439, in to_internal_value
validated_value = validate_method(validated_value)
File "./func_sig_registry/registry/forms.py", line 34, in validate_text_signature
return normalize_function_signature(value)
File "./func_sig_registry/utils/solidity.py", line 204, in normalize_function_signature
raise ValueError('function args contain non-standard types') from e
ValueError: function args contain non-standard typesTraceback (most recent call last):
File "./func_sig_registry/utils/solidity.py", line 200, in normalize_function_signature
validate_standard_type(args_tuple_type)
File "./func_sig_registry/utils/solidity.py", line 156, in validate_standard_type
validate_standard_type(t)
File "./func_sig_registry/utils/solidity.py", line 151, in validate_standard_type
f'type "{abi_type.to_type_str()}" '
ABITypeError: type "byte32" has invalid base "byte"
Catch this exception and translate it into a friendly user facing error message on the form.
just a suggestion
It would be really cool if this registry lived on-chain!
I mentioned this to you, and you said there were some caveats we needed to overcome first, and you'd be happy to discuss it in an issue here, so here we go!
cc @kumavis
Users should be able to make GET requests for individual retrieval and for list retrieval. class EventSignatureViewSet()
is needed, so that it could be routed to '/event-signatures/' endpoint
class EventSignatureViewSet()
similar to
It should be easy to add support for events topics.
They are calculated identically to function signatures, except instead of chopping off the first four byte of the sha3 of the hex, you keep the entire 32 bytes.
You should probably have a separate area of the site to enter events (as opposed to a simple checkbox or something on the existing page for adding events) to make it less likely that people will enter events as functions. There is not way to distinguish the two, otherwise, especially when users are entering items by hand.
The API views provided by DRF can be sped up by about 2x with a few optimizations.
https://www.dabapps.com/blog/api-performance-profiling-django-rest-framework/
This article is a good place to start.
currently when you add an existing signature you press the submit button and nothing happens. This is confusing to users. Better would be SnackBar like thing similar to the success case - just with the extra info (already existed) instead of "Added"
When a user submits a signature using this page , it parses only for function signatures, ignoring the possibility of input being an event signature.
Implement the logic for parsing function and event signatures when SignatureForm is used. It should be quite similar to how it is done in Solidity and ABI import.
this is similar to #37 - but it does not crash like there - but the tuple gets removed
so when I submit setupDirectDebit(address,(uint256,uint256,uint256))
it ends up as a different signature:
Event Signatures model needs normalize_event_signature()
function to be implemented
normalize_event_signature()
normalize_event_signature()
Traceback (most recent call last):
File "/home/web/venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.7/contextlib.py", line 74, in inner
return func(*args, **kwds)
File "/home/web/venv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/viewsets.py", line 87, in view
return self.dispatch(request, *args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/mixins.py", line 42, in list
page = self.paginate_queryset(queryset)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/generics.py", line 172, in paginate_queryset
return self.paginator.paginate_queryset(queryset, self.request, view=self)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/pagination.py", line 206, in paginate_queryset
self.page = paginator.page(page_number)
File "/home/web/venv/lib/python3.7/site-packages/django/core/paginator.py", line 50, in page
number = self.validate_number(number)
File "/home/web/venv/lib/python3.7/site-packages/django/core/paginator.py", line 39, in validate_number
if number > self.num_pages:
File "/home/web/venv/lib/python3.7/site-packages/django/core/paginator.py", line 86, in _get_num_pages
if self.count == 0 and not self.allow_empty_first_page:
File "/home/web/venv/lib/python3.7/site-packages/django/core/paginator.py", line 72, in _get_count
self._count = self.object_list.count()
File "/home/web/venv/lib/python3.7/site-packages/django/db/models/query.py", line 371, in count
return self.query.get_count(using=self.db)
File "/home/web/venv/lib/python3.7/site-packages/django/db/models/sql/query.py", line 483, in get_count
number = obj.get_aggregation(using, ['__count'])['__count']
File "/home/web/venv/lib/python3.7/site-packages/django/db/models/sql/query.py", line 464, in get_aggregation
result = compiler.execute_sql(SINGLE)
File "/home/web/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 848, in execute_sql
cursor.execute(sql, params)
File "/home/web/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
ValueError: A string literal cannot contain NUL (0x00) characters.
This bubbled out of production causing a 500 error
Exception handling or maybe better database normalization.
Currently, the function signature is checked only if the function name is not "function". Ideally, it should check if the name is not a reserved word.
otherwise it is hard to report errors like #37 - @kolinko would have reported this error before - but he did not find the repo. I just knew from history it is from @pipermerriam so I browsed through your repos to report the error finally..
Hi @pipermerriam,
some time ago I created a script to dump contract sources from etherscan/etherchain that could be used to watch for new contract submissions in order to feed them into the 4bytes.directory, what do you think?
here's the scripts. should be easy to modify it to collect function signatures + hashes and submit them after deduping the signature_text. the repo also contains a good amount of published sources. I'll dedup the sources in that repo later but we could use that as a good starting point to submit new sigs.
cheers,
tin
Hi Piper, I was investigating some edge cases here alongside with Avsa.
It seems that signature's bytecode initiated in "0x00" ends up as only "0x", as seen in your Gist.
"0x": [
"setLowerFeePercentage(uint8)",
"setHand(uint256)",
"comparisonchr(string)",
"getTokenDivisor()",
"getFrontend()",
"triggerPayment()",
"setMinimumPassPercentage(uint8)"
],
I cannot ensure the "0x00~" is the root cause, but I'm tending to believe in that :)
00873367 => comparisonchr(string)
00c721ab => setHand(uint256)
003b9d88 => setLowerFeePercentage(uint8)
Opening for discussion, since I know there could a basic caveat; some functions with the same signature could name their parameters differently.
That said, if MetaMask had some way of knowing, for example, what the most popular names for those parameters were, or even just what the first registered one's parameters were named, we could experiment with the effectiveness of that strategy.
I suspect that for most cases, there would be no collisions. And in cases where there were, we could work around the issue in a variety of ways.
Related to MetaMask/metamask-extension#1142
Current incoming pull request contains a model for Event Signatures. But it does not have a creation option via parsing solidity source code. This functionality needs to be added.
Before pushing changes for this issue, the implementation of validators is expected to be present.
Tried to upload the following ABI via Submit ABI link:
[{"constant":false,"inputs":[{"name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newImplementation","type":"address"},{"name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_logic","type":"address"},{"name":"_admin","type":"address"},{"name":"_data","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"previousAdmin","type":"address"},{"indexed":false,"name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"implementation","type":"address"}],"name":"Upgraded","type":"event"}]
Nothing immediately jumps out at me as invalid in the ABI, I'm hoping that a more useful error is presented on the server. It would be nice if more verbose errors were available in the web interface when this happens so users (I) could work around the problem temporarily.
EventSignature should be able to import signature from ABI.
EventSignature model needs an implementation of event_definition_to_text_signature()
function in abi.py.
event_definition_to_text_signature()
for ABI should be implementedevent_definition_to_text_signature()
Can Ethereum function signature registry be enhanced so multiple signatures can be returned for multiple hex signatures?
There's a number of ways this could be done. For example, introduced a new hex_signatures
filter option that takes a comma separated list if hex signatures. eg
/api/v1/signatures/?hex_signatures=0xabcd1234,0x722713f7,0x20158c44,0x5c658165
For context, I'm writing a tool that will generate a sequence diagram of all the internal contract calls of a transaction. I need to resolve the function signatures of all the internal transactions hence I'd like to do that in one API call and not many.
Thanks
Nick
Please enable a page_size
parameter for the REST API so that all things can be fetched in one go if needed.
If filtering and ordering can be added too that would be great.
Traceback (most recent call last):
File "/home/web/venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.7/contextlib.py", line 74, in inner
return func(*args, **kwds)
File "/home/web/venv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File "./func_sig_registry/registry/views.py", line 87, in post
if not serializer.is_valid():
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 213, in is_valid
self._validated_data = self.run_validation(self.initial_data)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 407, in run_validation
value = self.to_internal_value(data)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 439, in to_internal_value
validated_value = validate_method(validated_value)
File "./func_sig_registry/registry/forms.py", line 34, in validate_text_signature
return normalize_function_signature(value)
File "./func_sig_registry/utils/solidity.py", line 194, in normalize_function_signature
raise ValueError('could not parse function args') from e
ValueError: could not parse function argsTraceback (most recent call last):
File "./func_sig_registry/utils/solidity.py", line 192, in normalize_function_signature
args_tuple_type = parse_type(normalize_type(f'({arg_types})'))
File "/home/web/venv/lib/python3.7/site-packages/eth_abi/grammar.py", line 125, in parse
raise ParseError(e.text, e.pos, e.expr)
ParseError: Parse error at ')' (column 3) in type string '())'Traceback (most recent call last):
File "/home/web/venv/lib/python3.7/site-packages/eth_abi/grammar.py", line 123, in parse
return super().parse(type_str)
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/nodes.py", line 254, in parse
return self._parse_or_match(text, pos, 'parse')
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/nodes.py", line 289, in _parse_or_match
return self.visit(getattr(self.grammar, method_name)(text, pos=pos))
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/grammar.py", line 115, in parse
return self.default_rule.parse(text, pos=pos)
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/expressions.py", line 122, in parse
raise IncompleteParseError(text, node.end, self)
IncompleteParseError: Rule 'type' matched in its entirety, but it didn't consume all the text. The non-matching portion of the text begins with ')' (line 1, column 3).Traceback (most recent call last):
File "./func_sig_registry/utils/solidity.py", line 186, in normalize_function_signature
args_tuple_type = parse_type(normalize_type(f'({args})'))
File "/home/web/venv/lib/python3.7/site-packages/eth_abi/grammar.py", line 125, in parse
raise ParseError(e.text, e.pos, e.expr)
ParseError: Parse error at ' inte' (column 3) in type string '() internal view virtual returns (address payable)'Traceback (most recent call last):
File "/home/web/venv/lib/python3.7/site-packages/eth_abi/grammar.py", line 123, in parse
return super().parse(type_str)
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/nodes.py", line 254, in parse
return self._parse_or_match(text, pos, 'parse')
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/nodes.py", line 289, in _parse_or_match
return self.visit(getattr(self.grammar, method_name)(text, pos=pos))
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/grammar.py", line 115, in parse
return self.default_rule.parse(text, pos=pos)
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/expressions.py", line 122, in parse
raise IncompleteParseError(text, node.end, self)
IncompleteParseError: Rule 'type' matched in its entirety, but it didn't consume all the text. The non-matching portion of the text begins with ' internal view virtu' (line 1, column 3).
This was triggered by the submission of:
"function _msgSender() internal view virtual returns (address payable)"
🤷 didn't investigate yet
While scanning the webserver logs today I noticed that there are a lot of queries to the API for signatures which are not found in the database. These queries potentially represent important gaps in the available signature data.
It may be interesting to occasionally gather these and see if we can uncover the corresponding plain text function signatures.
In theory, this data could also be gathered by simply scraping the entirety of the historical transactions and extracting the first four bytes, skipping over transactions that are contract creations. The bonus of doing it this way is that we would also have a contract address to investigate which may have verified source code attached to it on etherscan.
Server Error in https://www.4byte.directory/import-abi/, when normalizer function throws an exception.
When importing from Contract ABI, if json has error similar to following (type name error):
[{ "constant":false, "inputs":[ {"name":"some_id", "type":"ufint"}, {"name":"some_address", "type":"addrsess"}, {"name":"some_string", "type":"straing"} ], "outputs":[], "name":"SomeFunction", "type":"function" }]
Function import_from_contract_abi(cls, contract_abi)
returns array with None
;
Which is not iterable with zip, resulting in uncaught exception
Currenty the data returned from the API looks like this.
{
"id": 145,
"text_signature": "transfer(address,uint256)",
"hex_signature": "0xa9059cbb",
"bytes_signature": "©\u0005�»"
}
I think it would be more universally useful if it looked like this.
{
"id": 145,
"text_signature": "transfer(address,uint256)",
"hex_signature": "0xa9059cbb",
"bytes_signature": "©\u0005�»",
"function_name": "transfer",
"function_inputs": [
{
"type": "address"
},
{
"type": "uint256"
}
]
}
This error was reported in production:
Traceback (most recent call last):
File "/home/web/venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.7/contextlib.py", line 74, in inner
return func(*args, **kwds)
File "/home/web/venv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File "/home/web/venv/lib/python3.7/site-packages/rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File "./func_sig_registry/registry/views.py", line 216, in post
import_function_results.extend(Signature.import_from_solidity_file(file_obj))
File "./func_sig_registry/registry/models.py", line 109, in import_from_solidity_file
return cls.import_from_solidity_code(code)
File "./func_sig_registry/registry/models.py", line 102, in import_from_solidity_code
for raw_signature in function_signatures
File "./func_sig_registry/registry/models.py", line 102, in <listcomp>
for raw_signature in function_signatures
File "./func_sig_registry/registry/models.py", line 87, in import_from_raw_text_signature
text_signature = normalize_function_signature(raw_function_signature)
File "./func_sig_registry/utils/solidity.py", line 189, in normalize_function_signature
arg_types = ','.join(get_arg_types(args))
File "./func_sig_registry/utils/solidity.py", line 169, in get_arg_types
types = [p.strip().split(maxsplit=1)[0] for p in parts]
File "./func_sig_registry/utils/solidity.py", line 169, in <listcomp>
types = [p.strip().split(maxsplit=1)[0] for p in parts]
IndexError: list index out of rangeTraceback (most recent call last):
File "./func_sig_registry/utils/solidity.py", line 185, in normalize_function_signature
args_tuple_type = parse_type(normalize_type(f'({args})'))
File "/home/web/venv/lib/python3.7/site-packages/eth_abi/grammar.py", line 125, in parse
raise ParseError(e.text, e.pos, e.expr)
ParseError: Parse error at ' )' (column 2) in type string '( )'Traceback (most recent call last):
File "/home/web/venv/lib/python3.7/site-packages/eth_abi/grammar.py", line 123, in parse
return super().parse(type_str)
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/nodes.py", line 254, in parse
return self._parse_or_match(text, pos, 'parse')
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/nodes.py", line 289, in _parse_or_match
return self.visit(getattr(self.grammar, method_name)(text, pos=pos))
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/grammar.py", line 115, in parse
return self.default_rule.parse(text, pos=pos)
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/expressions.py", line 120, in parse
node = self.match(text, pos=pos)
File "/home/web/venv/lib/python3.7/site-packages/parsimonious/expressions.py", line 137, in match
raise error
ParseError: Rule 'type' didn't match at ' )' (line 1, column 2).
Looks like just exception handling that needs to be put in place
Currently, the app can extract and save only function signatures. The same needs to be done with event signatures as well. We can start by adding the necessary Django Model.
First, create a Django Model. The model should contain the following fields:
Ultimately, it should look similar to Function Signature Model
File ./func_sig_registry/registry/views.py line 87 in post
if not serializer.is_valid():
Show 3 non-project frames
File ./func_sig_registry/registry/forms.py line 34 in validate_text_signature
return normalize_function_signature(value)
File ./func_sig_registry/utils/solidity.py line 182 in normalize_function_signature
fn_name, args = extract_function_name(raw_signature)
File ./func_sig_registry/utils/solidity.py line 116 in extract_function_name args locals
raise ValueError("Could not parse function signature")
In the event that the submitted raw signature isn't valid the user will end up with a 500 error rather than an error message.
Add handling for this and return a friendly error to the user.
You should be able to send it either a four-byte code and it return either just the function name or the whole function signature, or send it a function name and have it return the four-byte code. I've hacked up a ABI function signature thing for myself in C++ as part of a larger project, and I found that I need both capabilities in almost every use case.
I inadvertently tried to enter a hex signature via https://www.4byte.directory/submit
(for example 0x12345678)
Then I got the error : Server Error (500)
Later i realized i should have entered the function, but i was confused for a while.
If would help if the description was more clear and/or an appropriate error message is given.
I just realized that Solidity also accepts functions/events with the missing parameter names (just like in C++). However, I am not sure if such a case should be taken into account, because it is quite rare.
The following code is an example that contains function and event that are accepted and compiled in Solidity, however, the import from the source code file ignores both of them.
pragma solidity >=0.4.22 <0.7.0;
contract Bar {
function fooFunction(uint) public { }
event fooEvent(uint);
}
Possibly, we would need to rewrite the regex that catches functions and events.
There is a browsable feature for function signatures, however, the same one is missing for event signatures.
Implement a browsable feature for Event Signatures.
Currently, the application has support for event signature extraction from solidity source code. However, it is not being extracted during the actual code submission.
Add event extraction call in SolidityImportView
Add a mini-application on the site that will decode a transaction.
EventSignature.import_from_contract_abi(contract_abi)
after importing functions"Found {0} function signatures. Imported {1}, Skipped {2} duplicates."
Hi @pipermerriam, i've got some entries from the API which doesn't seem to comply with the standard. I've omitted those on Mist embedded signature dictionary until further notice.
Thanks
"0xc72b4e60": [
"setIpfsHash(bytes ipfsHash)"
],
"0x27fbe7fe": [
"function setIpfsHash(bytes ipfsHash)"
],
"0x1e25c4a2": [
"0x337b1cf9"
],
Option 1:
EventSignature.import_from_github_repository(login_or_name, repository, branch)
to
Option 2:
Signature.import_from_solidity_file(file_obj)
and EventSignature.import_from_solidity_file(file_obj)
.A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.