diff --git a/.gitignore b/.gitignore
index 631e44495ad7478b58b994d2f8b5c1a278656c34..391626d7deaeade753f2b017a70e7da024835412 100644
--- a/.gitignore
+++ b/.gitignore
@@ -160,4 +160,8 @@ db.sqlite3
 .idea
 TsaApi/*.pyc
 *.pyc
-venv*
\ No newline at end of file
+venv*
+
+# pycache
+app/__pycache__/*
+TsaApi/__pycache__/*
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 50438ad815a0560502618fd6dc30adeb9ebaa018..7b49a021dc948be39e2146174b2b306ddaf1b84f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,13 +1,13 @@
-FROM python:3.5
-RUN apt-get update && apt-get install -y --no-install-recommends apt-utils
-RUN apt-get update && apt-get -y upgrade && apt-get install -y apt-transport-https software-properties-common libsasl2-dev python-dev libldap2-dev libssl-dev memcached
+FROM python:3.5.2
+RUN apt-get update && apt-get -y upgrade && apt-get install -y --no-install-recommends apt-utils && apt-get install -y apt-transport-https software-properties-common libsasl2-dev python-dev libldap2-dev libssl-dev memcached
 RUN apt-get install -y gettext
 RUN git clone https://github.com/ethereum/pyethereum/ /opt/pyethereum
-WORKDIR /opt/pyethereum
-RUN python setup.py install
-RUN mkdir -p /opt/project
 WORKDIR /opt/project
 ADD requirements.txt /opt/project
 RUN pip install -U pip
 RUN pip install -r requirements.txt
+WORKDIR /opt/pyethereum
+RUN python setup.py install
+RUN mkdir -p /opt/project
+WORKDIR /opt/project
 ADD . /opt/project
\ No newline at end of file
diff --git a/TsaApi/__init__.pyc b/TsaApi/__init__.pyc
deleted file mode 100644
index 709a90ef202746dd2664b041994144486056b90b..0000000000000000000000000000000000000000
Binary files a/TsaApi/__init__.pyc and /dev/null differ
diff --git a/TsaApi/__pycache__/__init__.cpython-35.pyc b/TsaApi/__pycache__/__init__.cpython-35.pyc
deleted file mode 100644
index 0867da956487e6a335bfb989fe0874b2d9f426d3..0000000000000000000000000000000000000000
Binary files a/TsaApi/__pycache__/__init__.cpython-35.pyc and /dev/null differ
diff --git a/TsaApi/__pycache__/local_settings.cpython-35.pyc b/TsaApi/__pycache__/local_settings.cpython-35.pyc
deleted file mode 100644
index 28354c72868e8eb0125421bd92f3bf444edce855..0000000000000000000000000000000000000000
Binary files a/TsaApi/__pycache__/local_settings.cpython-35.pyc and /dev/null differ
diff --git a/TsaApi/__pycache__/settings.cpython-35.pyc b/TsaApi/__pycache__/settings.cpython-35.pyc
deleted file mode 100644
index 668ba9be9382f726c5b2730593daa0d9612b45a3..0000000000000000000000000000000000000000
Binary files a/TsaApi/__pycache__/settings.cpython-35.pyc and /dev/null differ
diff --git a/TsaApi/__pycache__/urls.cpython-35.pyc b/TsaApi/__pycache__/urls.cpython-35.pyc
deleted file mode 100644
index 6ce68b54ef09b2ae4314920357e91db955db5c29..0000000000000000000000000000000000000000
Binary files a/TsaApi/__pycache__/urls.cpython-35.pyc and /dev/null differ
diff --git a/TsaApi/__pycache__/wsgi.cpython-35.pyc b/TsaApi/__pycache__/wsgi.cpython-35.pyc
deleted file mode 100644
index 2188d4539e91a971edc54ec9a54a32df922a194f..0000000000000000000000000000000000000000
Binary files a/TsaApi/__pycache__/wsgi.cpython-35.pyc and /dev/null differ
diff --git a/TsaApi/local_settings.pyc b/TsaApi/local_settings.pyc
deleted file mode 100644
index ea0a8c6f2daef69f37741515fb3ea8bd9383e1a4..0000000000000000000000000000000000000000
Binary files a/TsaApi/local_settings.pyc and /dev/null differ
diff --git a/TsaApi/settings.py b/TsaApi/settings.py
index b34187e28c258d435ab866e27007c0dda91bf5b5..1ad48e3fa4f20e614c78ac9f80a4808d854f79ca 100644
--- a/TsaApi/settings.py
+++ b/TsaApi/settings.py
@@ -237,7 +237,7 @@ LOGGING = {
         },
         'logger': {
             'handlers': ['error_file', 'info_file', 'sentry'],
-            'level': 'ERROR',
+            'level': 'INFO',
             'propagate': True,
         },
         'console-logger': {
diff --git a/TsaApi/settings.pyc b/TsaApi/settings.pyc
deleted file mode 100644
index a3a5461550eef7903024869749a1e45c2914eb17..0000000000000000000000000000000000000000
Binary files a/TsaApi/settings.pyc and /dev/null differ
diff --git a/app/__pycache__/__init__.cpython-35.pyc b/app/__pycache__/__init__.cpython-35.pyc
deleted file mode 100644
index 24d1a5b248593470699ea6ca599e2ad3ab41f35e..0000000000000000000000000000000000000000
Binary files a/app/__pycache__/__init__.cpython-35.pyc and /dev/null differ
diff --git a/app/__pycache__/managers.cpython-35.pyc b/app/__pycache__/managers.cpython-35.pyc
deleted file mode 100644
index 84414991941a0fd259b67fa171434bb6480e741d..0000000000000000000000000000000000000000
Binary files a/app/__pycache__/managers.cpython-35.pyc and /dev/null differ
diff --git a/app/__pycache__/tests.cpython-35.pyc b/app/__pycache__/tests.cpython-35.pyc
deleted file mode 100644
index 141c512ef8dc016ba00a152829e2128983e736d9..0000000000000000000000000000000000000000
Binary files a/app/__pycache__/tests.cpython-35.pyc and /dev/null differ
diff --git a/app/__pycache__/urls.cpython-35.pyc b/app/__pycache__/urls.cpython-35.pyc
deleted file mode 100644
index 602e748e6acf4f15fbeb391bb9b5166a1e478622..0000000000000000000000000000000000000000
Binary files a/app/__pycache__/urls.cpython-35.pyc and /dev/null differ
diff --git a/app/__pycache__/utils.cpython-35.pyc b/app/__pycache__/utils.cpython-35.pyc
deleted file mode 100644
index 767ebaa7167744a271dfa368637b20ddaf7d18de..0000000000000000000000000000000000000000
Binary files a/app/__pycache__/utils.cpython-35.pyc and /dev/null differ
diff --git a/app/__pycache__/views.cpython-35.pyc b/app/__pycache__/views.cpython-35.pyc
deleted file mode 100644
index 23d4e3818c6a522e24813642e31c0aa94e39d530..0000000000000000000000000000000000000000
Binary files a/app/__pycache__/views.cpython-35.pyc and /dev/null differ
diff --git a/app/managers.py b/app/managers.py
index ffe482e7b968701abcc6fdf708016e3058f2dbcc..11f17ef8b030c32ad842fbe00fe6f91dc74074bd 100644
--- a/app/managers.py
+++ b/app/managers.py
@@ -64,11 +64,11 @@ class TimestampManager(models.Manager):
     def stamp(proof_hash, file_hash):
 
         contract = TimestampManager.get_current_contract()
-        
-        web3 = TimestampManager.get_provider()
 
-        return contract.functions.stamp(proof_hash, file_hash).transact({'from': Web3.toChecksumAddress(ACCOUNT_ADDRESS), 'gas': GAS, 'gasPrice': web3.eth.gasPrice})
+        web3 = TimestampManager.get_provider()
 
+        return contract.functions.stamp(proof_hash, file_hash).transact(
+            {'from': Web3.toChecksumAddress(ACCOUNT_ADDRESS), 'gas': GAS, 'gasPrice': web3.eth.gasPrice})
 
     @staticmethod
     def verify(contract_version, proof_hash, file_hash):
@@ -105,7 +105,7 @@ class EthereumGateway:
         last_block_number = TimestampManager.get_last_block_number()
         tx_block_number = transaction.blockNumber
         required_block_difference = Utils.required_block_difference(TimestampManager.get_signers_count())
-        return (last_block_number - tx_block_number) < required_block_difference
+        return (last_block_number - tx_block_number) > required_block_difference
 
     def transaction(self, tx_hash):
         return TimestampManager.get_transaction(tx_hash)
@@ -125,7 +125,7 @@ class EthereumGateway:
         w3 = TimestampManager.get_provider()
         tx_2 = w3.eth.getTransaction(tx['hash'])
         if tx_2['blockNumber'] is not None:
-            raise TxAlreadySealedInBlock("Tx already seald in block {}".format(str(tx_2['blockNumber'])))
+            raise TxAlreadySealedInBlock("Tx already sealed in block {}".format(str(tx_2['blockNumber'])))
         return w3.eth.resend(tx, gas_price, gas)
 
 
@@ -135,4 +135,7 @@ class TimeStamp:
         return CONTRACTS[CURRENT_CONTRACT_VERSION]['abi']
 
     def verify(self, proof_hash, file_hash):
-        return TimestampManager.verify(CURRENT_CONTRACT_VERSION, proof_hash, file_hash)
\ No newline at end of file
+        return TimestampManager.verify(CURRENT_CONTRACT_VERSION, proof_hash, file_hash)
+
+    def get_block(self, proof_hash):
+        return TimestampManager.get_block_number(CURRENT_CONTRACT_VERSION, proof_hash)
diff --git a/app/migrations/__pycache__/__init__.cpython-35.pyc b/app/migrations/__pycache__/__init__.cpython-35.pyc
index 607aff09d96f8a1e3491a03b221cf63b89707c10..2387a6ec660cdb84289934a600da42e18277676c 100644
Binary files a/app/migrations/__pycache__/__init__.cpython-35.pyc and b/app/migrations/__pycache__/__init__.cpython-35.pyc differ
diff --git a/app/services.py b/app/services.py
index ef5c01ea48ca6e445e44d4984580bc671aa9f63f..ab51a9e37a7fee79c778f049321d9de6f2097e0b 100644
--- a/app/services.py
+++ b/app/services.py
@@ -9,6 +9,8 @@ import logging
 import json
 
 from sys import stdout
+from django.utils.translation import gettext as _, gettext
+
 if stdout.isatty():
     log_str = 'console-logger'
 else:
@@ -16,14 +18,6 @@ else:
 
 module_logger = logging.getLogger(log_str)
 
-class DefinitiveReceiptGenerator:
-    encoder = Base64EncodingService()
-
-    def generate_definitive_receipt(self, original_file_hash, ots_hash, tx_hash, block):
-        base64.b64encode(
-            Utils.get_permanent_ots(original_file_hash, ots_hash, tx_hash,
-                                    block.number).encode('utf-8')).decode('utf-8')
-
 
 class ReceiptInterpreter:
 
@@ -31,13 +25,24 @@ class ReceiptInterpreter:
         return ots.split('-')
 
 
+class DefinitiveReceiptGenerator:
+    encoder = Base64EncodingService()
+    interpreter = ReceiptInterpreter()
+    gateway = EthereumGateway()
+
+    def generate_definitive_receipt(self, original_file_hash, tx_hash, ots_hash):
+        tx = self.gateway.transaction(tx_hash)
+        return self.encoder.encode(Utils.get_permanent_ots(original_file_hash, ots_hash, tx_hash,
+                                                           tx['blockNumber']).encode('utf-8')).decode('utf-8')
+
+
 class TransactionInputVerification:
     gateway = EthereumGateway()
     interpreter = ReceiptInterpreter()
     ts = TimeStamp()
     tx_hash = ''
 
-    def verify(self, ots):
+    def verify(self, original_file_hash, ots):
         ots_version, file_hash, ots_hash, tx_hash, block_number = self.interpreter.interpret(ots)
         method_name, args = Utils.decode_contract_call(self.ts.abi(), TimestampManager.get_transaction(tx_hash).input)
         return args[0].decode('utf-8') == ots_hash and args[1].decode('utf-8') == file_hash
@@ -46,61 +51,93 @@ class TransactionInputVerification:
 class SmartContractVerification:
     timestamp = TimeStamp()
     interpreter = ReceiptInterpreter()
+    gateway = EthereumGateway()
 
-    def verify(self, ots):
-        ots_version, file_hash, ots_hash, tx_hash, block_number = self.interpreter.interpret(ots)
-        self.timestamp.verify(ots_hash, file_hash)
+    def verify(self, file_hash, ots_hash):
+        verified = self.timestamp.verify(ots_hash, file_hash)
+        block = None
+        if verified:
+            block_number = self.timestamp.get_block(ots_hash)
+            block = self.gateway.block(block_number)
+        return verified, block
+
+
+class EventVerification:
+    gateway = EthereumGateway()
 
 
 class VerifyService:
     receipt_generator = DefinitiveReceiptGenerator()
-    definitive_verificator = TransactionInputVerification()
+    definitive_verificator = SmartContractVerification()
+    temp_verificator = SmartContractVerification()
+    interpreter = ReceiptInterpreter()
     gateway = EthereumGateway()
     permanent_ots_prefix = ''
 
-    def verify(self, original_file_hash, ots):
-        if ots[:2] == self.permanent_ots_prefix:
-            if self.definitive_verificator.verify(ots):
-                block = TimestampManager.get_block(int(block_number))
-                return {
-                    'status': 'success',
-                    'messages': ('file_uploaded') % (str(original_file_hash), str(block.number),
-                                                     str(Utils.datetime_from_timestamp(block.timestamp)))}
+    def verify(self, original_file_hash, rd):
+        if rd[:2] == self.permanent_ots_prefix:
+            ots_version, file_hash, ots_hash, tx_hash, block_number = self.interpreter.interpret(rd)
+            verified, block = self.definitive_verificator.verify(original_file_hash, ots_hash)
+            if verified:
+                return {'status': 'success',
+                        'block': block,
+                        'permanent_rd': self.receipt_generator.generate_definitive_receipt(original_file_hash,
+                                                                                           tx_hash,
+                                                                                           ots_hash)}
             else:
-                return {'status': 'failure', 'messages': 'file_not_found'}
+                return {'status': 'failure'}
 
         else:
-
-            ots_version, ots_hash, tx_hash = ots.split('-')
-            transaction = TimestampManager.get_transaction(tx_hash)
-            contract_version = ots_hash[-2:]
-
-            if TimestampManager.verify(contract_version, ots_hash, original_file_hash):
-
-                if (
-                        TimestampManager.get_last_block_number() - transaction.blockNumber) < Utils.required_block_difference(
-                    TimestampManager.get_signers_count()):
-                    return {'status': 'pending', 'messages': 'transaction_pending'}
+            ots_version, ots_hash, tx_hash = self.interpreter.interpret(rd)
+            verified, block = self.temp_verificator.verify(original_file_hash, ots_hash)
+            tx = self.gateway.transaction(tx_hash)
+            if verified:
+                if not self.gateway.transaction_is_canonical(tx):
+                    return {'status': 'pending'}
                 else:
-
-                    block = TimestampManager.get_block(
-                        TimestampManager.get_block_number(contract_version, ots_hash))
-
                     return {'status': 'success',
-                            'permanent_rd': base64.b64encode(
-                                Utils.get_permanent_ots(original_file_hash, ots_hash, tx_hash,
-                                                        block.number).encode('utf-8')).decode('utf-8'),
-                            'messages': 'file_uploaded' % (
-                                original_file_hash, str(block.number), str(
-                                    Utils.datetime_from_timestamp(block.timestamp)))}
+                            'block': block,
+                            'permanent_rd': self.receipt_generator.generate_definitive_receipt(original_file_hash,
+                                                                                               tx_hash,
+                                                                                               ots_hash)}
             else:
                 try:
-                    if transaction and not transaction.blockNumber:
-                        return {'status': 'pending', 'messages': 'transaction_pending'}
+                    if tx and not tx.blockNumber:
+                        return {'status': 'pending'}
                 except ValueError:
                     pass
 
-                return {'status': 'failure', 'messages': 'file_not_found'}
+                return {'status': 'failure'}
+
+
+class StatusNotValidException(Exception):
+    pass
+
+
+class VerifyServiceTranslation:
+    verify_service = VerifyService()
+
+    def verify(self, original_file_hash, rd):
+        result = self.verify_service.verify(original_file_hash, rd)
+        dict_res = {gettext('status'): result['status']}
+        res_status = 200
+        if result['status'] == 'success':
+            dict_res[gettext('permanent_rd')] = result['permanent_rd']
+            dict_res[gettext('attestation_time')] = str(Utils.datetime_from_timestamp(result['block'].timestamp))
+            dict_res[gettext('messages')] = gettext('file_uploaded') % (
+                original_file_hash,
+                str(result['block'].number),
+                str(Utils.datetime_from_timestamp(result['block'].timestamp))
+            )
+        elif result['status'] == 'failure':
+            dict_res[gettext('messages')] = gettext('file_not_found')
+            res_status = 404
+        elif result['status'] == 'pending':
+            dict_res[gettext('messages')] = gettext('transaction_pending')
+        else:
+            raise StatusNotValidException('Status invalid in verify service result : {}'.format(result['status']))
+
+        return dict_res, res_status
 
 
 class MemcachedStorage:
diff --git a/app/tests.py b/app/tests.py
index 0e7b9b345fe260c3f65baad790d4e8979132d8f9..08b37f0e66a755ebfbe319bbb9a1dc33aa0727f5 100644
--- a/app/tests.py
+++ b/app/tests.py
@@ -7,37 +7,47 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
 
 You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/
 """
+import base64
+import json
+import time
+import unittest
+
+from django.utils.translation import gettext as _
 from django.test import TestCase
 from django.test import Client
 from eth_account.datastructures import AttributeDict
 from pymemcache.client import base
 from rest_framework import status
-from TsaApi.settings import TEST_MEMCACHED_HOST, TEST_MEMCACHED_PORT, TEST_PENDING_TXS_MEMCACHED_KEY
-
-from app.services import PendingTransactionsService, CheckCriteria, MemcachedStorage, TransactionUnstucker
+from TsaApi.settings import TEST_MEMCACHED_HOST, TEST_MEMCACHED_PORT, TEST_PENDING_TXS_MEMCACHED_KEY, \
+    PERMANENT_OTS_PREFIX
 
+from app.services import PendingTransactionsService, CheckCriteria, MemcachedStorage, TransactionUnstucker, \
+    VerifyService
 
-class TimestampTest(TestCase):
-
-    def test_verify(self):
-        c = Client()
-        response = c.post('/api/tsa/verify/', {
-            "file_hash": "1957db7fe23e4be1740ddeb941ddda7ae0a6b782e536a9e00b5aa82db1e84547",
-            "proof": "NjA2MWQ1ODNkMTM0YTlmZGZlYWYxMWE2MjY1ZDY1OTkwMGM0ZGZjNjM2MDk3MDY4N2VkNDk3NTNhZmE5MGM3YzAxLTB4NWRiYjg4NjNlNDlhN2NmYTY0N2FmYzVkOTFkMWRiMDUxY2YzODZiYWY4NzJkM2ZiYTIzN2JkY2IwOWUwNWMzYQ=="
-        })
 
-        self.assertEqual(response.status_code, status.HTTP_200_OK, 'Verify Error')
+class TimestampTest(unittest.TestCase):
 
-    def test_stamp(self):
+    def test_full_cycle(self):
         c = Client()
         response = c.post('/api/tsa/stamp/', {
             "file_hash": "1957db7fe23e4be1740ddeb941ddda7ae0a6b782e536a9e00b5aa82db1e84547"
         })
 
         self.assertEqual(response.status_code, status.HTTP_200_OK, 'Stamp Error')
+        dict_response = json.loads(response.content.decode())
+        time.sleep(30)
 
+        verify_response = c.post('/api/tsa/verify/', {
+            "file_hash": "1957db7fe23e4be1740ddeb941ddda7ae0a6b782e536a9e00b5aa82db1e84547",
+            "rd": dict_response['temporary_rd']
+        })
 
-class EthereumMocks():
+        self.assertEqual(verify_response.status_code, status.HTTP_200_OK, 'Verify Error')
+        dict_verify = json.loads(verify_response.content.decode())
+        self.assertEqual(dict_verify[_('status')], _('success'))
+
+
+class EthereumMocks:
     class HalfResender:
         balance = 2.1 * 21000 * 1000  # me da para 2 txs mockeadas
 
@@ -211,7 +221,7 @@ class EthereumMocks():
             ]
 
 
-class PendingTransactionTest(TestCase, EthereumMocks):
+class PendingTransactionTest(unittest.TestCase, EthereumMocks):
 
     def setUp(self):
         self.service = PendingTransactionsService()
@@ -264,7 +274,7 @@ class PendingTransactionTest(TestCase, EthereumMocks):
         self.assertEqual(failed, [txs[-1]])
 
 
-class MemcachedStorageTest(TestCase):
+class MemcachedStorageTest(unittest.TestCase):
 
     def setUp(self):
         self.storage = MemcachedStorage()
@@ -306,7 +316,7 @@ class MemcachedStorageTest(TestCase):
         self.assertEqual(some_stuff, retrieved)
 
 
-class TransactionUnstuckerTest(TestCase, EthereumMocks):
+class TransactionUnstuckerTest(unittest.TestCase, EthereumMocks):
 
     def setUp(self):
         self.unstucker = TransactionUnstucker()
@@ -360,3 +370,90 @@ class TransactionUnstuckerTest(TestCase, EthereumMocks):
         res, failed = self.unstucker.unstuck_pending_transactions(1000)
         self.assertEqual(failed, [])
         self.assertEqual(res, [])  # como no tenía cache entonces no se hizo nada
+
+
+class VerificationMocks:
+    class NotSealedTransactionMock:
+        def transaction(self, tx_hash):
+            return AttributeDict(
+                {'hash': tx_hash, 'blockNumber': None})
+
+    class SealedTransactionMock:
+        def transaction(self, tx_hash):
+            return AttributeDict(
+                {'hash': tx_hash, 'blockNumber': 1000})
+
+    class TXisCanonicalMock:
+        def transaction_is_canonical(self, tx):
+            return True
+
+    class TXisNotCanonicalMock:
+        def transaction_is_canonical(self, tx):
+            return False
+
+    class FalseVerificationMock:
+        def verify(self, file_hash, ots_hash):
+            return False, None
+
+    class TrueVerificationMock:
+        def verify(self, file_hash, ots_hash):
+            return True, AttributeDict({'number': 1000})
+
+    class TxCanonicalSealedTx(SealedTransactionMock, TXisCanonicalMock):
+        pass
+
+    class TxNoCanonicalSealedTx(SealedTransactionMock, TXisNotCanonicalMock):
+        pass
+
+    class ReceiptGeneratorMock:
+        def generate_definitive_receipt(self, original_file_hash, tx_hash, ots_hash):
+            return "{}{}{}".format(original_file_hash, tx_hash, ots_hash)
+
+
+class VerifyServiceTest(unittest.TestCase, VerificationMocks):
+
+    def setUp(self):
+        self.service = VerifyService()
+        self.service.permanent_ots_prefix = PERMANENT_OTS_PREFIX
+        self.ots = "d6b88be854cb88cf1e161d8bbd912987cff236eb43a3a15fff86370054dd4d3f01"
+        self.file_hash = 'some_hash'
+        self.contract_version = '01'
+        self.temp_rd = "0x-d6b88be854cb88cf1e161d8bbd912987cff236eb43a3a15fff86370054dd4d3f01-0xf495705b5d7d68afdcefe72d9bbacec59b1a968c964ab0b6b13cec6491e5ddec"
+        self.def_rd = "1x-7b58a42ee27c3699fc169ce43cb4ba598003cba5699f4cd518b91d4177f61f10-0577d1390a5733534c7b6cc45a7ba15d0b5bf37faec9c54f749826af75aa86bb01-0x1a3a5335b44bdb7f62201102e91658586fd1d7845c621503eeff7781c3020b09-2234445"
+        pass
+
+    def test_verify_temporary_rd_not_sealed(self):
+        self.service.gateway = self.NotSealedTransactionMock()
+        self.service.temp_verificator = self.FalseVerificationMock()
+        res = self.service.verify(self.file_hash, self.temp_rd)
+        self.assertEqual(res['status'], 'pending')
+
+    def test_verify_temporary_rd_sealed_not_canonical(self):
+        self.service.gateway = self.TxNoCanonicalSealedTx()
+        self.service.temp_verificator = self.TrueVerificationMock()
+        res = self.service.verify(self.file_hash, self.temp_rd)
+        self.assertEqual(res['status'], 'pending')
+
+    def test_verify_temporary_rd_sealed_canonical(self):
+        self.service.temp_verificator = self.TrueVerificationMock()
+        self.service.gateway = self.TxCanonicalSealedTx()
+        self.service.receipt_generator.gateway = self.SealedTransactionMock()
+        res = self.service.verify(self.file_hash, self.temp_rd)
+
+        self.assertEqual(res['status'], 'success')
+        rd = res['permanent_rd']
+        ots_version, file_hash, ots_hash, tx_hash, block_number = base64.b64decode(rd).decode().split('-')
+        self.assertEqual(ots_version, PERMANENT_OTS_PREFIX)
+        self.assertEqual(file_hash, self.file_hash)
+        self.assertEqual(ots_hash, self.ots)
+        self.assertEqual(res['block'].number, int(block_number))
+
+    def test_definitive_rd_correct(self):
+        self.service.definitive_verificator = self.TrueVerificationMock()
+        self.service.receipt_generator = self.ReceiptGeneratorMock()
+        res = self.service.verify(self.file_hash, self.def_rd)
+        self.assertEqual(res['status'], 'success')
+
+    def test_definitive_rd_incorrect(self):
+        res = self.service.verify(self.file_hash, self.def_rd)
+        self.assertEqual(res['status'], 'failure')
diff --git a/app/utils.py b/app/utils.py
index bb5eab97de531106ec790465048595ef703439f5..d3fa00b4a3437e6d46acada06ef032f7893f04aa 100644
--- a/app/utils.py
+++ b/app/utils.py
@@ -13,8 +13,6 @@ import hashlib
 import time
 import math
 from TsaApi.settings import ACCOUNT_ADDRESS, CURRENT_CONTRACT_VERSION, PERMANENT_OTS_PREFIX, TEMPORARY_OTS_PREFIX
-from ethereum.abi import (decode_abi, normalize_name as normalize_abi_method_name, method_id as get_abi_method_id)
-from ethereum.utils import encode_int, zpad, decode_hex
 
 
 class Utils:
diff --git a/app/views.py b/app/views.py
index 22e03de2b1b1c35943b9199643b2d69ef24e8d58..2642b5be2446c92b319d7590066f9629c5c372ca 100644
--- a/app/views.py
+++ b/app/views.py
@@ -8,19 +8,25 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
 You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/
 """
 import base64
+import logging
+
+import coreapi
+import coreschema
 from django.core.exceptions import ValidationError
 from django.utils.translation import gettext as _
+from raven.contrib.django.raven_compat.models import client
 from rest_framework import status
-from rest_framework.views import APIView
 from rest_framework.response import Response
-from web3.exceptions import CannotHandleRequest
-from raven.contrib.django.raven_compat.models import client
 from rest_framework.schemas import ManualSchema
-import coreschema, coreapi
+from rest_framework.views import APIView
+from web3.exceptions import CannotHandleRequest
 
+from TsaApi.local_settings import PERMANENT_OTS_PREFIX
 from app.managers import TimestampManager
+from app.services import VerifyServiceTranslation
 from app.utils import Utils
-from TsaApi.local_settings import TEMPORARY_OTS_PREFIX, PERMANENT_OTS_PREFIX, CONTRACTS
+
+logger = logging.getLogger('logger')
 
 
 class Stamp(APIView):
@@ -61,8 +67,9 @@ class Stamp(APIView):
 
             ots_hash = Utils.get_ots_hash(file_hash)
 
+            logger.info("Haciendo stamp para hash: {} ots: {} ".format(file_hash, ots_hash))
             tx_hash = TimestampManager.stamp(ots_hash, file_hash)
-
+            logger.info("Stamp para hash: {} ots: {} terminado, tx_hash : {}".format(file_hash, ots_hash, tx_hash.hex()))
             # Al OTS se le agrega la transacción para poder verificar luego si está pendiente de subida
             ots = Utils.get_temporary_ots(ots_hash, tx_hash.hex())
 
@@ -117,6 +124,8 @@ class Verify(APIView):
         )
     ])
 
+    verify_service = VerifyServiceTranslation()
+
     def post(self, request):
 
         try:
@@ -127,75 +136,26 @@ class Verify(APIView):
                 raise ValidationError('rd')
 
             original_file_hash = request.data.get('file_hash')
-            base64_ots = request.data.get('rd')
-
-            ots = base64.b64decode(base64_ots).decode('utf-8')
-
-            if ots[:2] == PERMANENT_OTS_PREFIX:
-
-                ots_version, file_hash, ots_hash, tx_hash, block_number = ots.split('-')
-
-                method_name, args = Utils.decode_contract_call(CONTRACTS['01']['abi'],
-                                                               TimestampManager.get_transaction(tx_hash).input)
+            base64_rd = request.data.get('rd')
 
-                if args[0].decode('utf-8') == ots_hash and args[1].decode('utf-8') == file_hash:
-
-                    block = TimestampManager.get_block(int(block_number))
-
-                    return Response({_('status'): _('success'),
-                                     _('permanent_rd'): base64.b64encode(Utils.get_permanent_ots(original_file_hash, ots_hash, tx_hash, block.number).encode('utf-8')).decode('utf-8'),
-                                     _('attestation_time'): str(Utils.datetime_from_timestamp(block.timestamp)),
-                                     _('messages'): _('file_uploaded') % (
-                                         file_hash, str(block.number),
-                                         str(Utils.datetime_from_timestamp(block.timestamp)))},
-                                    status=status.HTTP_200_OK)
-                else:
-                    return Response({_('status'): _('failure'), _('messages'): _('file_not_found')},
-                                    status=status.HTTP_404_NOT_FOUND)
-
-            else:
-
-                ots_version, ots_hash, tx_hash = ots.split('-')
-
-                transaction = TimestampManager.get_transaction(tx_hash)
-
-                contract_version = ots_hash[-2:]
-
-                if TimestampManager.verify(contract_version, ots_hash, original_file_hash):
-
-                    if (
-                            TimestampManager.get_last_block_number() - transaction.blockNumber) < Utils.required_block_difference(
-                            TimestampManager.get_signers_count()):
-                        return Response({_('status'): _('pending'), _('messages'): _('transaction_pending')},
-                                        status=status.HTTP_200_OK)
-                    else:
-
-                        block = TimestampManager.get_block(
-                            TimestampManager.get_block_number(contract_version, ots_hash))
-
-                        return Response({_('status'): _('success'),
-                                         _('permanent_rd'): base64.b64encode(Utils.get_permanent_ots(original_file_hash, ots_hash, tx_hash, block.number).encode('utf-8')).decode('utf-8'),
-                                         _('attestation_time'): str(Utils.datetime_from_timestamp(block.timestamp)),
-                                         _('messages'): _('file_uploaded') % (original_file_hash, str(block.number), str(
-                                             Utils.datetime_from_timestamp(block.timestamp)))}, status=status.HTTP_200_OK)
-                else:
-                    try:
-                        if transaction and not transaction.blockNumber:
-                            return Response({_('status'): _('pending'), _('messages'): _('transaction_pending')},
-                                            status=status.HTTP_200_OK)
-                    except ValueError:
-                        pass
-
-                    return Response({_('status'): _('failure'), _('messages'): _('file_not_found')},
-                                    status=status.HTTP_404_NOT_FOUND)
+            rd = base64.b64decode(base64_rd).decode('utf-8')
 
+            # importante la asignación del prefijo de ots permanente
+            self.verify_service.verify_service.permanent_ots_prefix = PERMANENT_OTS_PREFIX
+            logger.info("Iniciando verificacion para hash {} rd {} baserd {}".format(original_file_hash, rd, base64_rd))
+            result, res_status = self.verify_service.verify(original_file_hash, rd)
+            logger.info(
+                "Verificacion terminada para hash {} rd {}, resultado {}".format(original_file_hash, rd, str(result)))
+            return Response(result, status=res_status)
         except ValidationError as e:
             return Response({_('status'): _('failure'), _('messages'): _('parameter_missing') % e.message},
                             status=status.HTTP_400_BAD_REQUEST)
-        except CannotHandleRequest:
+        except CannotHandleRequest as e:
+            logger.critical('Servicio a nivel Geth no disponible!! error: {}'.format(str(e)))
             return Response({_('status'): _('failure'), _('messages'): _('could_not_connect')},
                             status=status.HTTP_503_SERVICE_UNAVAILABLE)
         except Exception as e:
             client.captureException()
+            logger.error('Error interno en la verificacion : {}'.format(str(e)))
             return Response({_('status'): _('failure'), _('messages'): _('operation_failed')},
-                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)
\ No newline at end of file
+                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)
diff --git a/pyethereum b/pyethereum
deleted file mode 160000
index d962694be03686a8e5c1d7459ae272b70a5c9f77..0000000000000000000000000000000000000000
--- a/pyethereum
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit d962694be03686a8e5c1d7459ae272b70a5c9f77
diff --git a/requirements.txt b/requirements.txt
index aaa7cba7627db42049d00ca5648b355df214497b..e7e919e6c5f1ea1ae27a23d4c7d124c58f98abfe 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,14 +1,13 @@
-asn1crypto==0.24.0
+ipython==7.2.0
+ipython-genutils==0.2.0
+pymemcache==2.1.1
+elastic-apm==3.0.0
 attrdict==2.0.0
-backcall==0.1.0
 certifi==2018.4.16
-cffi==1.12.0
 chardet==3.0.4
-coincurve==11.0.0
 coreapi==2.3.3
 coreschema==0.0.4
 cytoolz==0.9.0.1
-decorator==4.3.2
 Django==2.1
 django-cors-headers==2.4.0
 django-rest-swagger==2.2.0
@@ -20,50 +19,26 @@ eth-hash==0.1.4
 eth-keyfile==0.5.1
 eth-keys==0.2.0b3
 eth-rlp==0.1.2
-eth-typing==2.0.0
 eth-utils==1.0.3
-ethereum==2.3.2
-future==0.17.1
 hexbytes==0.1.0
 idna==2.7
-ipython==7.2.0
-ipython-genutils==0.2.0
 itypes==1.1.0
-jedi==0.13.2
 Jinja2==2.10
 lru-dict==1.1.6
 MarkupSafe==1.0
 openapi-codec==1.3.2
 parsimonious==0.8.0
-parso==0.3.4
-pbkdf2==1.3
-pexpect==4.6.0
-pickleshare==0.7.5
-prompt-toolkit==2.0.8
-ptyprocess==0.6.0
-py-ecc==1.4.7
-pycparser==2.19
 pycryptodome==3.6.4
-pyethash==0.1.27
-Pygments==2.3.1
 PyJWT==1.6.4
-pymemcache==2.1.1
-pysha3==1.0.2
 python-bitcoinlib==0.10.1
 pytz==2018.5
-PyYAML==4.2b4
 raven==6.9.0
-repoze.lru==0.7
 requests==2.19.1
 rlp==1.0.1
-scrypt==0.8.13
 simplejson==3.16.0
 six==1.11.0
 toolz==0.9.0
-traitlets==4.3.2
 uritemplate==3.0.0
 urllib3==1.23
-wcwidth==0.1.7
 web3==4.5.0
-websockets==5.0.1
-elastic-apm==3.0.0
\ No newline at end of file
+websockets==5.0.1
\ No newline at end of file