Skip to content
Snippets Groups Projects
Commit 4d1d7545 authored by Patricio Kumagae's avatar Patricio Kumagae
Browse files

Se agrega utils.py

parent d6cacd5e
No related branches found
No related tags found
No related merge requests found
from TsaApi.settings import CONTRACTS, CURRENT_CONTRACT_VERSION, ACCOUNT_ADDRESS
from django.db import models from django.db import models
from web3 import Web3, HTTPProvider from web3 import Web3, HTTPProvider
from web3.exceptions import CannotHandleRequest, UnhandledRequest from web3.exceptions import CannotHandleRequest, UnhandledRequest
from TsaApi.settings import HOST_ADDRESS from TsaApi.settings import HOST_ADDRESS
from web3.middleware import geth_poa_middleware from web3.middleware import geth_poa_middleware
from bitcoin.core.serialize import uint256_from_str
class TimestampManager(models.Manager): class TimestampManager(models.Manager):
...@@ -21,3 +24,43 @@ class TimestampManager(models.Manager): ...@@ -21,3 +24,43 @@ class TimestampManager(models.Manager):
return web3 return web3
except UnhandledRequest: except UnhandledRequest:
raise raise
@classmethod
def get_current_contract(cls):
return TimestampManager.get_contract(CURRENT_CONTRACT_VERSION)
@classmethod
def get_contract(cls, contract_version):
web3 = TimestampManager.get_provider()
return web3.eth.contract(abi=CONTRACTS[contract_version]['abi'], address=Web3.toChecksumAddress(CONTRACTS[contract_version]['address']))
@classmethod
def get_block(cls, block_number):
web3 = TimestampManager.get_provider()
return web3.eth.getBlock(block_number)
@classmethod
def get_transaction(cls, tx_hash):
web3 = TimestampManager.get_provider()
return web3.eth.getTransaction(tx_hash)
@classmethod
def stamp(cls, proof_hash, file_hash):
contract = TimestampManager.get_current_contract()
return contract.functions.stamp(uint256_from_str(proof_hash.encode('utf-8')), uint256_from_str(file_hash.encode('utf-8'))).transact({'from': Web3.toChecksumAddress(ACCOUNT_ADDRESS)})
@classmethod
def verify(cls, contract_version, proof_hash, file_hash):
contract = TimestampManager.get_contract(contract_version)
return contract.functions.verify(uint256_from_str(proof_hash.encode('utf-8')),uint256_from_str(file_hash.encode('utf-8'))).call()
@classmethod
def get_block_number(cls, contract_version, proof_hash):
contract = TimestampManager.get_contract(contract_version)
return contract.functions.getBlockNumber(uint256_from_str(proof_hash.encode('utf-8'))).call()
import datetime
import hashlib
import time
from TsaApi.settings import ACCOUNT_ADDRESS, CURRENT_CONTRACT_VERSION
class Utils():
@classmethod
def sha256_encode(cls, string):
return hashlib.sha256(string.encode('utf-8')).hexdigest()
@classmethod
def datetime_from_timestamp(cls, timestamp):
return datetime.datetime.fromtimestamp(timestamp).strftime('%d/%m/%Y %H:%M:%S')
@classmethod
def get_proof_hash(cls, file_hash):
return Utils.sha256_encode(str(file_hash + Utils.sha256_encode(str(int(time.time()))) + Utils.sha256_encode(ACCOUNT_ADDRESS))) + CURRENT_CONTRACT_VERSION
import time
import datetime
import hashlib
import base64 import base64
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from rest_framework import status from rest_framework import status
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from web3 import Web3
from web3.exceptions import CannotHandleRequest from web3.exceptions import CannotHandleRequest
from bitcoin.core.serialize import uint256_from_str
from raven.contrib.django.raven_compat.models import client from raven.contrib.django.raven_compat.models import client
from TsaApi.settings import CURRENT_CONTRACT_VERSION, ACCOUNT_ADDRESS, CONTRACTS
from app.managers import TimestampManager from app.managers import TimestampManager
from app.utils import Utils
class Stamp(APIView): class Stamp(APIView):
""" """
...@@ -41,23 +36,18 @@ class Stamp(APIView): ...@@ -41,23 +36,18 @@ class Stamp(APIView):
file_hash = request.data.get('file_hash') file_hash = request.data.get('file_hash')
account_hash = hashlib.sha256(ACCOUNT_ADDRESS.encode('utf-8')).hexdigest() proof_hash = Utils.get_proof_hash(file_hash)
timestamp_hash = hashlib.sha256(str(int(time.time())).encode('utf-8')).hexdigest()
proof_hash = hashlib.sha256(str(file_hash + timestamp_hash + account_hash).encode('utf-8')).hexdigest() + CURRENT_CONTRACT_VERSION
web3 = TimestampManager.get_provider() tx_hash = TimestampManager.stamp(proof_hash, file_hash)
contract = web3.eth.contract(abi=CONTRACTS[CURRENT_CONTRACT_VERSION]['abi'], address=Web3.toChecksumAddress(CONTRACTS[CURRENT_CONTRACT_VERSION]['address']))
tx_hash = contract.functions.stamp(uint256_from_str(proof_hash.encode('utf-8')), uint256_from_str(file_hash.encode('utf-8'))).transact({'from': Web3.toChecksumAddress(ACCOUNT_ADDRESS)})
proof = proof_hash + '-' + tx_hash.hex() proof = proof_hash + '-' + tx_hash.hex()
base64_proof = base64.b64encode(proof.encode('utf-8')).decode('utf-8') return Response({'status': _('success'), _('proof'): base64.b64encode(proof.encode('utf-8')).decode('utf-8')}, status=status.HTTP_200_OK)
return Response({'status': _('success'), _('proof'): base64_proof}, status=status.HTTP_200_OK)
except ValidationError: except ValidationError as e:
return Response({'status': _('failure'), _('messages'): _('parameter_missing')}, status=status.HTTP_400_BAD_REQUEST) return Response({'status': _('failure'), _('messages'): _('parameter_missing') % e.message}, status=status.HTTP_400_BAD_REQUEST)
except CannotHandleRequest:
return Response({'status': _('failure'), _('messages'): _('could_not_connect')}, status=status.HTTP_503_SERVICE_UNAVAILABLE)
except Exception: except Exception:
client.captureException() client.captureException()
return Response({'status': _('failure'), _('messages'): _('operation_failed')}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({'status': _('failure'), _('messages'): _('operation_failed')}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
...@@ -91,41 +81,29 @@ class Verify(APIView): ...@@ -91,41 +81,29 @@ class Verify(APIView):
if not request.data.get('proof'): if not request.data.get('proof'):
raise ValidationError('proof') raise ValidationError('proof')
pending = False
file_hash = request.data.get('file_hash') file_hash = request.data.get('file_hash')
base64_proof = request.data.get('proof') base64_proof = request.data.get('proof')
proof = base64.b64decode(base64_proof).decode('utf-8') proof = base64.b64decode(base64_proof).decode('utf-8')
proof_hash, tx_hash = proof.split('-') proof_hash, tx_hash = proof.split('-')
contract_version = proof_hash[-2:] contract_version = proof_hash[-2:]
contract_info = CONTRACTS[contract_version]
web3 = TimestampManager.get_provider()
contract = web3.eth.contract(abi=contract_info['abi'], address=Web3.toChecksumAddress(contract_info['address'])) verified = TimestampManager.verify(contract_version, proof_hash, file_hash)
verified = contract.functions.verify(uint256_from_str(proof_hash.encode('utf-8')), uint256_from_str(file_hash.encode('utf-8'))).call()
if verified: if verified:
block_number = contract.functions.getBlockNumber(uint256_from_str(proof_hash.encode('utf-8'))).call() block_number = TimestampManager.get_block_number(contract_version, proof_hash)
block = web3.eth.getBlock(block_number) block = TimestampManager.get_block(block_number)
date = datetime.datetime.fromtimestamp(block.timestamp).strftime('%d/%m/%Y %H:%M:%S')
return Response({'status': _('success'),_('messages'): _('file_uploaded') % (file_hash, str(block.number), str(date))},status=status.HTTP_200_OK) return Response({'status': _('success'),_('messages'): _('file_uploaded') % (file_hash, str(block.number), str(Utils.datetime_from_timestamp(block.timestamp)))},status=status.HTTP_200_OK)
else: else:
try: try:
transaction = web3.eth.getTransaction(tx_hash) transaction = TimestampManager.get_transaction(tx_hash)
if transaction and not transaction.blockNumber: if transaction and not transaction.blockNumber:
pending = True return Response({'status': _('pending'), _('messages'): _('transaction_pending')}, status=status.HTTP_200_OK)
except ValueError: except ValueError:
pass pass
if pending: return Response({'status': _('failure'), _('messages'): _('file_not_found')},status=status.HTTP_404_NOT_FOUND)
return Response({'status': _('pending'), _('messages'): _('transaction_pending')},status=status.HTTP_200_OK)
else:
return Response({'status': _('failure'), _('messages'): _('file_not_found')},status=status.HTTP_404_NOT_FOUND)
except ValidationError as e: except ValidationError as e:
return Response({'status': _('failure'), _('messages'): _('parameter_missing') % e.message}, status=status.HTTP_400_BAD_REQUEST) return Response({'status': _('failure'), _('messages'): _('parameter_missing') % e.message}, status=status.HTTP_400_BAD_REQUEST)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment