-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d11ee21
Showing
45 changed files
with
10,740 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
public/ | ||
*.pyc | ||
*.sqlite | ||
.env | ||
bower_components/ | ||
node_modules/ | ||
.cache/ | ||
tmp/ | ||
*.log | ||
build/ |
Binary file not shown.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from django.contrib import admin | ||
|
||
# Register your models here. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class RegistryConfig(AppConfig): | ||
name = 'registry' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.9.7 on 2016-07-06 22:20 | ||
from __future__ import unicode_literals | ||
|
||
import django.core.validators | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
import func_sig_registry.registry.validators | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='BytesSignature', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('bytes4_signature', models.CharField(max_length=4, unique=True, validators=[django.core.validators.MinLengthValidator(4)])), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name='Signature', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('created_at', models.DateTimeField(auto_now_add=True)), | ||
('updated_at', models.DateTimeField(auto_now=True)), | ||
('text_signature', models.TextField(unique=True, validators=[func_sig_registry.registry.validators.validate_text_signature, django.core.validators.MinLengthValidator(3)])), | ||
('bytes_signature', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='registry.BytesSignature')), | ||
], | ||
), | ||
migrations.AlterUniqueTogether( | ||
name='signature', | ||
unique_together=set([('text_signature', 'bytes_signature')]), | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
from django.db import models | ||
from django.core.validators import MinLengthValidator | ||
|
||
from .validators import ( | ||
validate_text_signature, | ||
) | ||
from .parsers import ( | ||
extract_function_signatures, | ||
normalize_function_signature, | ||
) | ||
from .utils import ( | ||
make_4byte_signature, | ||
encode_hex, | ||
force_text, | ||
force_bytes, | ||
) | ||
|
||
|
||
class Signature(models.Model): | ||
created_at = models.DateTimeField(auto_now_add=True) | ||
updated_at = models.DateTimeField(auto_now=True) | ||
|
||
text_signature = models.TextField(unique=True, | ||
validators=[ | ||
validate_text_signature, | ||
MinLengthValidator(3), | ||
]) | ||
bytes_signature = models.ForeignKey('registry.BytesSignature') | ||
|
||
class Meta: | ||
unique_together = ( | ||
('text_signature', 'bytes_signature'), | ||
) | ||
|
||
def save(self, *args, **kwargs): | ||
if self.bytes_signature_id is None: | ||
self.bytes_signature, _ = BytesSignature.objects.get_or_create( | ||
bytes4_signature=force_text(make_4byte_signature(self.text_signature)), | ||
) | ||
super(Signature, self).save() | ||
|
||
@classmethod | ||
def import_from_solidity_source(cls, file_obj): | ||
source_code = force_text(file_obj.read()) | ||
raw_function_signatures = extract_function_signatures(source_code) | ||
function_signatures = ( | ||
normalize_function_signature(sig) for sig in raw_function_signatures | ||
) | ||
for text_signature in function_signatures: | ||
Signature.objects.get_or_create(text_signature=text_signature) | ||
|
||
|
||
class BytesSignature(models.Model): | ||
bytes4_signature = models.CharField(max_length=4, | ||
unique=True, | ||
validators=[MinLengthValidator(4)]) | ||
|
||
def get_hex_display(self): | ||
return force_text(encode_hex(force_bytes(self.bytes4_signature))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import itertools | ||
import re | ||
|
||
|
||
DYNAMIC_TYPES = ['bytes', 'string'] | ||
|
||
STATIC_TYPE_ALIASES = ['uint', 'int', 'byte'] | ||
STATIC_TYPES = list(itertools.chain( | ||
['address', 'bool'], | ||
['uint{0}'.format(i) for i in range(8, 257, 8)], | ||
['int{0}'.format(i) for i in range(8, 257, 8)], | ||
['bytes{0}'.format(i) for i in range(1, 33)], | ||
)) | ||
|
||
TYPE_REGEX = '|'.join(itertools.chain( | ||
DYNAMIC_TYPES, | ||
STATIC_TYPES, | ||
STATIC_TYPE_ALIASES, | ||
)) | ||
|
||
NAME_REGEX = '[a-zA-Z_][a-zA-Z0-9_]*' | ||
|
||
ARGUMENT_REGEX = '(?:{type})(?:(?:\[[0-9]*\])*)?\s+[a-zA-Z_][a-zA-Z0-9_]*'.format( | ||
type=TYPE_REGEX, | ||
) | ||
|
||
|
||
FUNCTION_REGEX = ( | ||
'function\s+[a-zA-Z_][a-zA-Z0-9_]*\s*\(\s*(?:{arg}(?:(?:\s*,\s*{arg}\s*)*)?)?\s*\)'.format( | ||
arg=ARGUMENT_REGEX, | ||
) | ||
) | ||
|
||
|
||
def extract_function_signatures(code): | ||
matches = re.findall(FUNCTION_REGEX, code) | ||
return matches or [] | ||
|
||
|
||
EXTRACT_ARGUMENTS_REGEX = '(?P<type>{type})(?P<sub_type>(?:\[[0-9]*\])*)?\s+[a-zA-Z_][a-zA-Z0-9_]*'.format( | ||
type=TYPE_REGEX, | ||
) | ||
|
||
|
||
def to_canonical_type(value): | ||
if value == 'int': | ||
return 'int256' | ||
elif value == 'uint': | ||
return 'uint256' | ||
elif value == 'byte': | ||
return 'bytes1' | ||
else: | ||
return value | ||
|
||
|
||
def normalize_function_signature(raw_signature): | ||
fn_name_match = re.match('function\s+(?P<fn_name>[a-zA-Z_][a-zA-Z0-9_]*)', raw_signature) | ||
group_dict = fn_name_match.groupdict() | ||
fn_name = group_dict['fn_name'] | ||
raw_arguments = re.findall(EXTRACT_ARGUMENTS_REGEX, raw_signature) | ||
|
||
arguments = [ | ||
"".join((to_canonical_type(t), sub)) | ||
for t, sub in raw_arguments | ||
] | ||
return "{fn_name}({fn_args})".format(fn_name=fn_name, fn_args=','.join(arguments)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from rest_framework import serializers | ||
|
||
from .models import Signature | ||
|
||
from .utils import ( | ||
clean_text_signature, | ||
) | ||
|
||
|
||
class SignatureSearchSerializer(serializers.Serializer): | ||
bytes4_signature = serializers.CharField() | ||
|
||
|
||
class SignatureSerializer(serializers.ModelSerializer): | ||
bytes4_signature = serializers.CharField(read_only=True, | ||
source='bytes_signature.get_hex_display') | ||
|
||
class Meta: | ||
model = Signature | ||
fields = ('id', 'text_signature', 'bytes4_signature') | ||
read_only_fields = ('bytes4_signature',) | ||
|
||
def validate_signature(self, value): | ||
return clean_text_signature(value) | ||
|
||
|
||
class SolidityImportSerializer(serializers.Serializer): | ||
source_file = serializers.FileField() | ||
|
||
def create(self, validated_data): | ||
return validated_data['source_file'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import django_tables2 as tables | ||
|
||
from .models import ( | ||
Signature, | ||
) | ||
|
||
|
||
class SignatureTable(tables.Table): | ||
bytes_signature = tables.TemplateColumn( | ||
'<code>{{ record.bytes_signature.get_hex_display }}</code>', | ||
) | ||
|
||
class Meta: | ||
model = Signature | ||
fields = ( | ||
'id', | ||
'text_signature', | ||
'bytes_signature', | ||
) | ||
template = 'partials/table.html' | ||
attrs = { | ||
'class': 'table table-striped table-bordered', | ||
} |
15 changes: 15 additions & 0 deletions
15
func_sig_registry/registry/templates/registry/signature_create.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{% extends 'layout_full.html' %} | ||
{% load rest_framework %} | ||
|
||
|
||
{% block content %} | ||
<div class="row"> | ||
<div class="col-md-12"> | ||
<form class="form-inline" action="{% url 'signature-create' %}" method="post" novalidate> | ||
{% csrf_token %} | ||
{% render_form serializer template_pack='rest_framework/inline' %} | ||
<button type="submit" class="btn btn-default">Submit</button> | ||
</form> | ||
</div> | ||
</div> | ||
{% endblock content %} |
17 changes: 17 additions & 0 deletions
17
func_sig_registry/registry/templates/registry/signature_list.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{% extends 'layout_full.html' %} | ||
{% load render_table from django_tables2 %} | ||
{% load rest_framework %} | ||
|
||
|
||
{% block content %} | ||
<div class="row"> | ||
<div class="col-md-12"> | ||
<form class="form-inline" action="{% url 'site-index' %}" method="get" novalidate> | ||
<label for="bytes4_signature">Search Signatures</label> | ||
{% render_form serializer template_pack='rest_framework/inline' %} | ||
<button type="submit" class="btn btn-default">Search</button> | ||
</form> | ||
{% render_table table %} | ||
</div> | ||
</div> | ||
{% endblock %} |
15 changes: 15 additions & 0 deletions
15
func_sig_registry/registry/templates/registry/solidity_source_import.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{% extends 'layout_full.html' %} | ||
{% load rest_framework %} | ||
|
||
|
||
{% block content %} | ||
<div class="row"> | ||
<div class="col-md-12"> | ||
<form class="form-inline" action="{% url 'import-solidity' %}" method="post" enctype="multipart/form-data"> | ||
{% csrf_token %} | ||
{% render_form serializer template_pack='rest_framework/inline' %} | ||
<button type="submit" class="btn btn-default">Submit</button> | ||
</form> | ||
</div> | ||
</div> | ||
{% endblock content %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from django.test import TestCase | ||
|
||
# Create your tests here. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import codecs | ||
|
||
from sha3 import sha3_256 | ||
|
||
|
||
def force_bytes(value): | ||
if isinstance(value, bytes): | ||
return value | ||
elif isinstance(value, str): | ||
return bytes(value, 'latin1') | ||
else: | ||
raise TypeError("Unsupported type: {0}".format(type(value))) | ||
|
||
|
||
def force_text(value): | ||
if isinstance(value, str): | ||
return value | ||
elif isinstance(value, bytes): | ||
return str(value, 'latin1') | ||
else: | ||
raise TypeError("Unsupported type: {0}".format(type(value))) | ||
|
||
|
||
def remove_0x_prefix(value): | ||
if force_bytes(value).startswith(b'0x'): | ||
return value[2:] | ||
return value | ||
|
||
|
||
def encode_hex(value): | ||
return b'0x' + codecs.encode(force_bytes(value), 'hex') | ||
|
||
|
||
def decode_hex(value): | ||
return codecs.decode(remove_0x_prefix(force_bytes(value)), 'hex') | ||
|
||
|
||
def clean_text_signature(value): | ||
return value.strip().replace(' ', '').replace('\n', '').replace('\t', '') | ||
|
||
|
||
# sanity check we are using the right sha3 function | ||
assert sha3_256(b'').hexdigest() == 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', sha3_256(b'').hexdigest() | ||
|
||
|
||
def make_4byte_signature(text_signature): | ||
return sha3_256(force_bytes(text_signature)).digest()[:4] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from django.core.exceptions import ValidationError | ||
|
||
|
||
def validate_text_signature(value): | ||
# TODO | ||
pass |
Oops, something went wrong.