diff --git a/_ucoinpy_test/api/bma/test_blockchain.py b/_ucoinpy_test/api/bma/test_blockchain.py
index 08055076ff9287efb521e41a333f37cab853b53e..73955d7344a0f9295a576f821ef7de77666f80a9 100644
--- a/_ucoinpy_test/api/bma/test_blockchain.py
+++ b/_ucoinpy_test/api/bma/test_blockchain.py
@@ -27,14 +27,14 @@ class Test_BMA_Blockchain(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Parameters.schema)
 
     def test_parameters_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/', handler)
             params = Parameters(None)
-            params.reverse_url = lambda path: url
+            params.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await params.get()
 
@@ -95,28 +95,28 @@ class Test_BMA_Blockchain(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Current.schema)
 
     def test_block_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/100', handler)
             block = Block(None, 100)
-            block.reverse_url = lambda path: url
+            block.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await block.get()
 
         self.loop.run_until_complete(go())
 
     def test_current_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/', handler)
             current = Current(None)
-            current.reverse_url = lambda path: url
+            current.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await current.get()
 
@@ -169,14 +169,14 @@ class Test_BMA_Blockchain(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Hardship.schema)
 
     def test_hardship_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/fingerprint', handler)
             hardship = Hardship(None, "fingerprint")
-            hardship.reverse_url = lambda path: url
+            hardship.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await hardship.get()
 
@@ -207,14 +207,14 @@ class Test_BMA_Blockchain(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Membership.schema)
 
     def test_membership_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/pubkey', handler)
             membership = Membership(None, "pubkey")
-            membership.reverse_url = lambda path: url
+            membership.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await membership.get()
 
@@ -229,14 +229,14 @@ class Test_BMA_Blockchain(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Newcomers.schema)
 
     def test_newcomers_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/', handler)
             newcomers = Newcomers(None)
-            newcomers.reverse_url = lambda path: url
+            newcomers.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await newcomers.get()
 
@@ -251,14 +251,14 @@ class Test_BMA_Blockchain(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Certifications.schema)
 
     def test_certifications_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/', handler)
             certs = Certifications(None)
-            certs.reverse_url = lambda path: url
+            certs.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await certs.get()
 
@@ -273,14 +273,14 @@ class Test_BMA_Blockchain(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Joiners.schema)
 
     def test_joiners_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/', handler)
             joiners = Joiners(None)
-            joiners.reverse_url = lambda path: url
+            joiners.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await joiners.get()
 
@@ -295,14 +295,14 @@ class Test_BMA_Blockchain(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Actives.schema)
 
     def test_actives_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/', handler)
             actives = Actives(None)
-            actives.reverse_url = lambda path: url
+            actives.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await actives.get()
 
@@ -317,14 +317,14 @@ class Test_BMA_Blockchain(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Leavers.schema)
 
     def test_leavers_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/', handler)
             leavers = Leavers(None)
-            leavers.reverse_url = lambda path: url
+            leavers.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await leavers.get()
 
@@ -339,14 +339,14 @@ class Test_BMA_Blockchain(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, UD.schema)
 
     def test_ud_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/', handler)
             ud = UD(None)
-            ud.reverse_url = lambda path: url
+            ud.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await ud.get()
 
@@ -361,14 +361,14 @@ class Test_BMA_Blockchain(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, TX.schema)
 
     def test_tx_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/', handler)
             tx = TX(None)
-            tx.reverse_url = lambda path: url
+            tx.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await tx.get()
 
diff --git a/_ucoinpy_test/api/bma/test_tx.py b/_ucoinpy_test/api/bma/test_tx.py
index 902e9607b1b2628d771306e4605acefb9ed6522e..20d87ed2f565bfc9154298cd37a5f6c0a9054c38 100644
--- a/_ucoinpy_test/api/bma/test_tx.py
+++ b/_ucoinpy_test/api/bma/test_tx.py
@@ -121,28 +121,28 @@ class Test_BMA_TX(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Blocks.schema)
 
     def test_bma_tx_history_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/pubkey', handler)
             history = History(None, 'pubkey')
-            history.reverse_url = lambda path: url
+            history.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await history.get()
 
         self.loop.run_until_complete(go())
 
     def test_bma_tx_history_blocks_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/pubkey/0/100', handler)
             blocks = Blocks(None, 'pubkey', 0, 100)
-            blocks.reverse_url = lambda path: url
+            blocks.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await blocks.get()
 
@@ -172,14 +172,14 @@ class Test_BMA_TX(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Sources.schema)
 
     def test_bma_tx_sources_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/pubkey', handler)
             sources = Sources(None, 'pubkey')
-            sources.reverse_url = lambda path: url
+            sources.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await sources.get()
 
diff --git a/_ucoinpy_test/api/bma/test_wot.py b/_ucoinpy_test/api/bma/test_wot.py
index 6205bd6cdc178112b9ae343eb8009fcd724b3851..4b89091d00e4a5cb8dbcb3e4748ef5ca579d9cda 100644
--- a/_ucoinpy_test/api/bma/test_wot.py
+++ b/_ucoinpy_test/api/bma/test_wot.py
@@ -70,14 +70,14 @@ class Test_BMA_Wot(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, Lookup.schema)
 
     def test_bma_wot_lookup_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/pubkey', handler)
             lookup = Lookup(None, "pubkey")
-            lookup.reverse_url = lambda path: url
+            lookup.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await lookup.get()
 
@@ -94,14 +94,14 @@ class Test_BMA_Wot(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(Members.schema, json_sample)
 
     def test_bma_wot_members_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/', handler)
             members = Members(None)
-            members.reverse_url = lambda path: url
+            members.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await members.get()
 
@@ -144,21 +144,21 @@ class Test_BMA_Wot(WebFunctionalSetupMixin, unittest.TestCase):
         jsonschema.validate(json_sample, CertifiedBy.schema)
 
     def test_bma_wot_certifiers_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/pubkey', handler)
             certsof = CertifiersOf(None, 'pubkey')
-            certsof.reverse_url = lambda path: url
+            certsof.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await certsof.get()
 
         self.loop.run_until_complete(go())
 
     def test_bma_wot_certifiers_inner_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=bytes(json.dumps({
     "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
@@ -180,24 +180,24 @@ class Test_BMA_Wot(WebFunctionalSetupMixin, unittest.TestCase):
     ]
 }), "utf-8"), content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/pubkey', handler)
             certsof = CertifiersOf(None, 'pubkey')
-            certsof.reverse_url = lambda path: url
+            certsof.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await certsof.get()
 
         self.loop.run_until_complete(go())
 
     def test_bma_wot_certified_bad(self):
-        async        def handler(request):
+        async def handler(request):
             await request.read()
             return web.Response(body=b'{}', content_type='application/json')
 
-        async        def go():
+        async def go():
             _, srv, url = await self.create_server('GET', '/pubkey', handler)
             certby = CertifiedBy(None, 'pubkey')
-            certby.reverse_url = lambda path: url
+            certby.reverse_url = lambda scheme, path: url
             with self.assertRaises(jsonschema.exceptions.ValidationError):
                 await certby.get()
 
diff --git a/_ucoinpy_test/api/test_bma.py b/_ucoinpy_test/api/test_bma.py
index 60e2b705e1a91c3ed4568b747cade410dc2901aa..803393b1f3a12717fb775b8238a74d7e97917be3 100644
--- a/_ucoinpy_test/api/test_bma.py
+++ b/_ucoinpy_test/api/test_bma.py
@@ -8,14 +8,14 @@ class Test_BMA_API(unittest.TestCase):
     def test_reverse_url_complete(self):
         endpoint = BMAEndpoint("test.com", "124.2.2.1", "2001:0db8:0000:85a3:0000:0000:ac1f:8001 ", 9092)
         api = API(endpoint.conn_handler(), "any")
-        self.assertEqual(api.reverse_url("/test/url"), "http://test.com:9092/any/test/url")
+        self.assertEqual(api.reverse_url("http", "/test/url"), "http://test.com:9092/any/test/url")
 
     def test_reverse_url_only_ipv4(self):
         endpoint = BMAEndpoint(None, "124.2.2.1", None, 9092)
         api = API(endpoint.conn_handler(), "any")
-        self.assertEqual(api.reverse_url("/test/url"), "http://124.2.2.1:9092/any/test/url")
+        self.assertEqual(api.reverse_url("http", "/test/url"), "http://124.2.2.1:9092/any/test/url")
 
     def test_reverse_url_only_ipv6(self):
         endpoint = BMAEndpoint(None, None, "2001:0db8:0000:85a3:0000:0000:ac1f:8001", 9092)
         api = API(endpoint.conn_handler(), "any")
-        self.assertEqual(api.reverse_url("/test/url"), "http://2001:0db8:0000:85a3:0000:0000:ac1f:8001:9092/any/test/url")
+        self.assertEqual(api.reverse_url("http", "/test/url"), "http://2001:0db8:0000:85a3:0000:0000:ac1f:8001:9092/any/test/url")
diff --git a/_ucoinpy_test/documents/test_certification.py b/_ucoinpy_test/documents/test_certification.py
index 5380daf9f49b2182a2334fc855c621ad6e87c568..4a10e384de371d7e92449cd43ada99a63d9d694e 100644
--- a/_ucoinpy_test/documents/test_certification.py
+++ b/_ucoinpy_test/documents/test_certification.py
@@ -47,13 +47,13 @@ class Test_SelfCertification(unittest.TestCase):
         cert = Certification.from_inline(version, currency, blockhash, cert_inlines[0])
         self.assertEqual(cert.pubkey_from, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU")
         self.assertEqual(cert.pubkey_to, "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk")
-        self.assertEqual(cert.blocknumber, 0)
-        self.assertEqual(cert.blockhash, blockhash)
+        self.assertEqual(cert.blockid.number, 0)
+        self.assertEqual(cert.blockid.sha_hash, blockhash)
         self.assertEqual(cert.signatures[0], "TgmDuMxZdyutroj9jiLJA8tQp/389JIzDKuxW5+h7GIfjDu1ZbwI7HNm5rlUDhR2KreaV/QJjEaItT4Cf75rCQ==")
 
         cert = Certification.from_inline(version, currency, blockhash, cert_inlines[1])
         self.assertEqual(cert.pubkey_from, "9fx25FmeBDJcikZLWxK5HuzKNbY6MaWYXoK1ajteE42Y")
         self.assertEqual(cert.pubkey_to, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU")
-        self.assertEqual(cert.blocknumber, 0)
-        self.assertEqual(cert.blockhash, blockhash)
+        self.assertEqual(cert.blockid.number, 0)
+        self.assertEqual(cert.blockid.sha_hash, blockhash)
         self.assertEqual(cert.signatures[0], "qn/XNJjaGIwfnR+wGrDME6YviCQbG+ywsQWnETlAsL6q7o3k1UhpR5ZTVY9dvejLKuC+1mUEXVTmH+8Ib55DBA==")
diff --git a/_ucoinpy_test/documents/test_membership.py b/_ucoinpy_test/documents/test_membership.py
index d314311591d328712e6e734f436cb8738337b199..d05cf89b8731cc2a34ac8b120a71bd570dc69c42 100644
--- a/_ucoinpy_test/documents/test_membership.py
+++ b/_ucoinpy_test/documents/test_membership.py
@@ -26,8 +26,8 @@ class Test_Membership(unittest.TestCase):
     def test_frominline(self):
         membership = Membership.from_inline(1, "zeta_brousouf", 'IN', membership_inline)
         self.assertEqual(membership.issuer, "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk")
-        self.assertEqual(membership.block_number, 0)
-        self.assertEqual(membership.block_hash, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709")
+        self.assertEqual(membership.blockid.number, 0)
+        self.assertEqual(membership.blockid.sha_hash, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709")
         self.assertEqual(membership.cert_ts, 1416335620)
         self.assertEqual(membership.uid, "cgeek")
         self.assertEqual(membership.signatures[0], "dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu84rraDg==")
@@ -36,8 +36,8 @@ class Test_Membership(unittest.TestCase):
     def test_fromraw(self):
         membership = Membership.from_signed_raw(membership_raw)
         self.assertEqual(membership.issuer, "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk")
-        self.assertEqual(membership.block_number, 0)
-        self.assertEqual(membership.block_hash, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709")
+        self.assertEqual(membership.blockid.number, 0)
+        self.assertEqual(membership.blockid.sha_hash, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709")
         self.assertEqual(membership.cert_ts, 1416335620)
         self.assertEqual(membership.uid, "cgeek")
         self.assertEqual(membership.signatures[0], "dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu84rraDg==")
@@ -48,8 +48,8 @@ class Test_Membership(unittest.TestCase):
         rendered_membership = membership.signed_raw()
         from_rendered_membership = Membership.from_signed_raw(rendered_membership)
         self.assertEqual(from_rendered_membership.issuer, "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk")
-        self.assertEqual(from_rendered_membership.block_number, 0)
-        self.assertEqual(from_rendered_membership.block_hash, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709")
+        self.assertEqual(from_rendered_membership.blockid.number, 0)
+        self.assertEqual(from_rendered_membership.blockid.sha_hash, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709")
         self.assertEqual(from_rendered_membership.cert_ts, 1416335620)
         self.assertEqual(from_rendered_membership.uid, "cgeek")
         self.assertEqual(from_rendered_membership.signatures[0], "dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu84rraDg==")
diff --git a/_ucoinpy_test/documents/test_peer.py b/_ucoinpy_test/documents/test_peer.py
index ed8213b116fc13a7c71429d0d04b5f2527a231de..66a4153eda4119d91d8dbee4368d31d6f798e646 100644
--- a/_ucoinpy_test/documents/test_peer.py
+++ b/_ucoinpy_test/documents/test_peer.py
@@ -25,7 +25,7 @@ class TestPeer(unittest.TestCase):
         peer = Peer.from_signed_raw(rawpeer)
         self.assertEqual(peer.currency, "beta_brousouf")
         self.assertEqual(peer.pubkey, "HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY")
-        self.assertEqual(peer.blockid, "8-1922C324ABC4AF7EF7656734A31F5197888DDD52")
+        self.assertEqual(str(peer.blockid), "8-1922C324ABC4AF7EF7656734A31F5197888DDD52")
         self.assertEqual(len(peer.endpoints), 3)
         self.assertTrue(type(peer.endpoints[0]) is BMAEndpoint)
         self.assertTrue(type(peer.endpoints[1]) is BMAEndpoint)
@@ -50,7 +50,7 @@ class TestPeer(unittest.TestCase):
 
         self.assertEqual(from_rendered_peer.currency, "beta_brousouf")
         self.assertEqual(from_rendered_peer.pubkey, "HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY")
-        self.assertEqual(from_rendered_peer.blockid, "8-1922C324ABC4AF7EF7656734A31F5197888DDD52")
+        self.assertEqual(str(from_rendered_peer.blockid), "8-1922C324ABC4AF7EF7656734A31F5197888DDD52")
         self.assertEqual(len(from_rendered_peer.endpoints), 3)
         self.assertTrue(type(from_rendered_peer.endpoints[0]) is BMAEndpoint)
         self.assertTrue(type(from_rendered_peer.endpoints[1]) is BMAEndpoint)
diff --git a/ucoinpy/__init__.py b/ucoinpy/__init__.py
index eddb94f857d77f83f3fb5511da4c0446a6fcdf83..3c2a706fe390c730914557fb89b01742284fe568 100644
--- a/ucoinpy/__init__.py
+++ b/ucoinpy/__init__.py
@@ -21,7 +21,7 @@ PROTOCOL_VERSION="1"
 MANAGED_API=["BASIC_MERKLED_API"]
 
 __author__      = 'Caner Candan & inso'
-__version__     = '0.13.2'
+__version__     = '0.14.0'
 __nonsense__    = 'uCoin'
 
 from . import api, documents, key
\ No newline at end of file
diff --git a/ucoinpy/api/bma/__init__.py b/ucoinpy/api/bma/__init__.py
index 4acc81044a69c65e2042803fdb585bb5300613e9..d524b2f03a5198fc48f87e9232cfb902fb7280a6 100644
--- a/ucoinpy/api/bma/__init__.py
+++ b/ucoinpy/api/bma/__init__.py
@@ -21,7 +21,7 @@ __all__ = ['api']
 
 PROTOCOL_VERSION = "1"
 
-import aiohttp, asyncio, logging, jsonschema
+import aiohttp, json, logging, jsonschema
 
 logger = logging.getLogger("ucoin")
 
@@ -59,7 +59,7 @@ class API(object):
         self.connection_handler = connection_handler
         self.headers = {}
 
-    def reverse_url(self, path):
+    def reverse_url(self, scheme, path):
         """
         Reverses the url using self.url and path given in parameter.
 
@@ -69,7 +69,10 @@ class API(object):
 
         server, port = self.connection_handler.server, self.connection_handler.port
 
-        url = 'http://%s:%d/%s' % (server, port, self.module)
+        url = '{scheme}://{server}:{port}/{module}'.format(scheme=scheme,
+                                                           server=server,
+                                                           port=port,
+                                                           module=self.module)
         return url + path
 
     def get(self, **kwargs):
@@ -96,7 +99,21 @@ class API(object):
         """interface purpose for POST request"""
         pass
 
-    async def parse(self, response):
+    def parse_text(self, text):
+        """
+        Validate and parse the BMA answer from websocket
+
+        :param str text: the bma answer
+        :return: the json data
+        """
+        try:
+            data = json.loads(text)
+            jsonschema.validate(data, self.schema)
+            return data
+        except TypeError:
+            raise jsonschema.ValidationError("Could not parse json")
+
+    async def parse_response(self, response):
         """
         Validate and parse the BMA answer
 
@@ -117,9 +134,9 @@ class API(object):
         Arguments:
         - `path`: the request path
         """
-        logging.debug("Request : {0}".format(self.reverse_url(path)))
+        logging.debug("Request : {0}".format(self.reverse_url("http", path)))
         with aiohttp.Timeout(15):
-            response = await aiohttp.get(self.reverse_url(path), params=kwargs,headers=self.headers)
+            response = await aiohttp.get(self.reverse_url("http", path), params=kwargs,headers=self.headers)
             if response.status != 200:
                 raise ValueError('status code != 200 => %d (%s)' % (response.status, (await response.text())))
 
@@ -137,7 +154,18 @@ class API(object):
 
         logging.debug("POST : {0}".format(kwargs))
         with aiohttp.Timeout(15):
-            response = await aiohttp.post(self.reverse_url(path), data=kwargs, headers=self.headers)
+            response = await aiohttp.post(self.reverse_url("http", path), data=kwargs, headers=self.headers)
             return response
 
-from . import network, blockchain, tx, wot, node, ud
+    def connect_ws(self, path):
+        """
+        Connect to a websocket in order to use API parameters
+
+        :param str path: the url path
+        :return:
+        """
+        url = self.reverse_url("ws", path)
+        return aiohttp.ws_connect(url)
+
+
+from . import network, blockchain, tx, wot, node, ud, ws
diff --git a/ucoinpy/api/bma/blockchain/__init__.py b/ucoinpy/api/bma/blockchain/__init__.py
index 95bfc187f262a8322d38eaf1671d63c2b3b16785..62920a1a18f5cd5745c0df43756bb25f35169e08 100644
--- a/ucoinpy/api/bma/blockchain/__init__.py
+++ b/ucoinpy/api/bma/blockchain/__init__.py
@@ -84,7 +84,7 @@ class Parameters(Blockchain):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/parameters', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class Membership(Blockchain):
@@ -143,7 +143,7 @@ class Membership(Blockchain):
     async def __get__(self, **kwargs):
         assert self.search is not None
         r = await self.requests_get('/memberships/%s' % self.search, **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class Block(Blockchain):
@@ -281,7 +281,7 @@ class Block(Blockchain):
     async def __get__(self, **kwargs):
         assert self.number is not None
         r = await self.requests_get('/block/%d' % self.number, **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
     async def __post__(self, **kwargs):
         assert 'block' in kwargs
@@ -298,7 +298,7 @@ class Current(Blockchain):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/current', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class Hardship(Blockchain):
@@ -331,7 +331,7 @@ class Hardship(Blockchain):
     async def __get__(self, **kwargs):
         assert self.fingerprint is not None
         r = await self.requests_get('/hardship/%s' % self.fingerprint.upper(), **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class Newcomers(Blockchain):
@@ -358,7 +358,7 @@ class Newcomers(Blockchain):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/with/newcomers', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class Certifications(Blockchain):
@@ -368,7 +368,7 @@ class Certifications(Blockchain):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/with/certs', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class Joiners(Blockchain):
@@ -378,7 +378,7 @@ class Joiners(Blockchain):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/with/joiners', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class Actives(Blockchain):
@@ -388,7 +388,7 @@ class Actives(Blockchain):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/with/actives', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class Leavers(Blockchain):
@@ -398,7 +398,7 @@ class Leavers(Blockchain):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/with/leavers', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class Excluded(Blockchain):
@@ -408,7 +408,7 @@ class Excluded(Blockchain):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/with/excluded', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class UD(Blockchain):
@@ -418,7 +418,7 @@ class UD(Blockchain):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/with/ud', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class TX(Blockchain):
@@ -428,4 +428,4 @@ class TX(Blockchain):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/with/tx', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
diff --git a/ucoinpy/api/bma/network/__init__.py b/ucoinpy/api/bma/network/__init__.py
index 53ee46270fb44cf8227954a526bc87bc1971170d..8729c1051f903b5cbb6153b63ef85dd53842fc37 100644
--- a/ucoinpy/api/bma/network/__init__.py
+++ b/ucoinpy/api/bma/network/__init__.py
@@ -55,6 +55,6 @@ class Peering(Network):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/peering', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 from . import peering
diff --git a/ucoinpy/api/bma/network/peering/__init__.py b/ucoinpy/api/bma/network/peering/__init__.py
index 31ae7f208112007cf66318bd67de8a8155693331..4eeaea0b7584380b12125a6a97b96f73f68b3e4b 100644
--- a/ucoinpy/api/bma/network/peering/__init__.py
+++ b/ucoinpy/api/bma/network/peering/__init__.py
@@ -85,7 +85,7 @@ class Peers(Base):
         """creates a generator with one peering entry per iteration."""
 
         r = await self.requests_get('/peers', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
     async def __post__(self, **kwargs):
         assert 'entry' in kwargs
diff --git a/ucoinpy/api/bma/node/__init__.py b/ucoinpy/api/bma/node/__init__.py
index 2c66a383d527f3d656e50926e4c68302891a17ba..3de4f651a42e34d93390e2d6eafa52489bbd911c 100644
--- a/ucoinpy/api/bma/node/__init__.py
+++ b/ucoinpy/api/bma/node/__init__.py
@@ -55,5 +55,5 @@ class Summary(Node):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/summary', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
diff --git a/ucoinpy/api/bma/tx/__init__.py b/ucoinpy/api/bma/tx/__init__.py
index 80562fbf17f64a8cee474d79153a79fdbc2bbede..14d04d2e3039a6b8c7fe9f38f441092583bc2d3e 100644
--- a/ucoinpy/api/bma/tx/__init__.py
+++ b/ucoinpy/api/bma/tx/__init__.py
@@ -160,7 +160,7 @@ class History(Tx):
     async def __get__(self, **kwargs):
         assert self.pubkey is not None
         r = await self.requests_get('/history/%s' % self.pubkey, **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class Process(Tx):
@@ -219,7 +219,7 @@ class Sources(Tx):
     async def __get__(self, **kwargs):
         assert self.pubkey is not None
         r = await self.requests_get('/sources/%s' % self.pubkey, **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 from . import history
diff --git a/ucoinpy/api/bma/tx/history/__init__.py b/ucoinpy/api/bma/tx/history/__init__.py
index 857fdd29b4db7eba0e3f61c84aa57adc22da857a..db4b52bee8ecc60e989fce2ca5c2ac0603f647d0 100644
--- a/ucoinpy/api/bma/tx/history/__init__.py
+++ b/ucoinpy/api/bma/tx/history/__init__.py
@@ -32,4 +32,4 @@ class Blocks(History):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/history/%s/blocks/%s/%s' % (self.pubkey, self.from_, self.to_), **kwargs)
-        return (await self.parse(r))
\ No newline at end of file
+        return (await self.parse_response(r))
\ No newline at end of file
diff --git a/ucoinpy/api/bma/wot/__init__.py b/ucoinpy/api/bma/wot/__init__.py
index dba3883333ee2350db5536149b324f9f7ecc3f16..df4a79618952fa5537fb42eb88a0254786afe05e 100644
--- a/ucoinpy/api/bma/wot/__init__.py
+++ b/ucoinpy/api/bma/wot/__init__.py
@@ -148,7 +148,7 @@ class Lookup(WOT):
         assert self.search is not None
 
         r = await self.requests_get('/lookup/%s' % self.search, **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class CertifiersOf(WOT):
@@ -231,7 +231,7 @@ class CertifiersOf(WOT):
         assert self.search is not None
 
         r = await self.requests_get('/certifiers-of/%s' % self.search, **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class CertifiedBy(WOT):
@@ -248,7 +248,7 @@ class CertifiedBy(WOT):
         assert self.search is not None
 
         r = await self.requests_get('/certified-by/%s' % self.search, **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
 
 
 class Members(WOT):
@@ -277,4 +277,4 @@ class Members(WOT):
 
     async def __get__(self, **kwargs):
         r = await self.requests_get('/members', **kwargs)
-        return (await self.parse(r))
+        return (await self.parse_response(r))
diff --git a/ucoinpy/api/bma/ws/__init__.py b/ucoinpy/api/bma/ws/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..8aaeab65442a65e2d3f3084ec2b0c90fe981fde1
--- /dev/null
+++ b/ucoinpy/api/bma/ws/__init__.py
@@ -0,0 +1,49 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import API, logging
+from ..blockchain import Block as _Block
+from ..network.peering import Peers as _Peers
+
+logger = logging.getLogger("ucoin/ws")
+
+
+class Websocket(API):
+    def __init__(self, connection_handler, module='ws'):
+        super(Websocket, self).__init__(connection_handler, module)
+
+
+class Block(Websocket):
+    """Connect to block websocket."""
+    schema = _Block.schema
+
+    def connect(self):
+
+        r = self.connect_ws('/block')
+        return r
+
+
+class Peer(Websocket):
+    """Connect to block websocket."""
+    schema = _Peers.schema
+
+    def connect(self):
+
+        r = self.connect_ws('/peer')
+        return r
+
diff --git a/ucoinpy/documents/block.py b/ucoinpy/documents/block.py
index 9e3b0b8d3fef8eee8c86a31654dc36d15ce16535..a7c4e35a1c434f1b878f1b0ff9ef8b91587b3a6d 100644
--- a/ucoinpy/documents/block.py
+++ b/ucoinpy/documents/block.py
@@ -1,11 +1,9 @@
-from .. import PROTOCOL_VERSION
 from .document import Document
 from .certification import SelfCertification, Certification
 from .membership import Membership
 from .transaction import Transaction
 
 import re
-import logging
 
 
 class BlockId:
diff --git a/ucoinpy/documents/certification.py b/ucoinpy/documents/certification.py
index eae93750605d60ba45f8b3035d8208bd5fd6cab2..96a4a81f9bbf8fcd1f4e13881048be45dfa811de 100644
--- a/ucoinpy/documents/certification.py
+++ b/ucoinpy/documents/certification.py
@@ -51,15 +51,14 @@ class Certification(Document):
     re_timestamp = re.compile("META:TS:([0-9]+)-([0-9a-fA-F]{5,40})\n")
 
     def __init__(self, version, currency, pubkey_from, pubkey_to,
-                 blocknumber, blockhash, signature):
+                 blockid, signature):
         """
         Constructor
         """
         super().__init__(version, currency, [signature])
         self.pubkey_from = pubkey_from
         self.pubkey_to = pubkey_to
-        self.blockhash = blockhash
-        self.blocknumber = blocknumber
+        self.blockid = blockid
 
     @classmethod
     def from_inline(cls, version, currency, blockhash, inline):
@@ -70,12 +69,13 @@ class Certification(Document):
         if blocknumber == 0:
             blockhash = "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"
         signature = cert_data.group(4)
+        from .block import BlockId
         return cls(version, currency, pubkey_from, pubkey_to,
-                   blocknumber, blockhash, signature)
+                   BlockId(blocknumber, blockhash), signature)
 
     def raw(self, selfcert):
-        return """{0}META:TS:{1}-{2}
-""".format(selfcert.signed_raw(), self.blocknumber, self.blockhash)
+        return """{0}META:TS:{1}
+""".format(selfcert.signed_raw(), self.blockid)
 
     def sign(self, selfcert, keys):
         """
@@ -96,7 +96,7 @@ class Certification(Document):
 
     def inline(self):
         return "{0}:{1}:{2}:{3}".format(self.pubkey_from, self.pubkey_to,
-                                        self.blocknumber, self.signatures[0])
+                                        self.blockid.number, self.signatures[0])
 
 
 class Revocation(Document):
diff --git a/ucoinpy/documents/membership.py b/ucoinpy/documents/membership.py
index c41547df70befa35b6c37e0d03b676a087a3146e..ca9b89978c7ca07aeedc19af1ad6794bed626e42 100644
--- a/ucoinpy/documents/membership.py
+++ b/ucoinpy/documents/membership.py
@@ -3,7 +3,6 @@ Created on 2 déc. 2014
 
 @author: inso
 """
-from .. import PROTOCOL_VERSION
 from .document import Document
 
 import re
@@ -34,17 +33,14 @@ class Membership(Document):
     re_userid = re.compile("UserID: ([^\n]+)\n")
     re_certts = re.compile("CertTS: ([0-9]+)\n")
 
-
-
-    def __init__(self, version, currency, issuer, block_number, block_hash,
+    def __init__(self, version, currency, issuer, blockid,
                  membership_type, uid, cert_ts, signature):
         """
         Constructor
         """
         super().__init__(version, currency, [signature])
         self.issuer = issuer
-        self.block_number = block_number
-        self.block_hash = block_hash
+        self.blockid = blockid
         self.membership_type = membership_type
         self.uid = uid
         self.cert_ts = cert_ts
@@ -58,8 +54,8 @@ class Membership(Document):
         block_hash = data.group(4)
         cert_ts = int(data.group(5))
         uid = data.group(6)
-        return cls(version, currency, issuer, block_number,
-                   block_hash, membership_type, uid, cert_ts, signature)
+        from .block import BlockId
+        return cls(version, currency, issuer, BlockId(block_number, block_hash), membership_type, uid, cert_ts, signature)
 
     @classmethod
     def from_signed_raw(cls, raw, signature=None):
@@ -95,7 +91,8 @@ class Membership(Document):
         signature = Membership.re_signature.match(lines[n]).group(1)
         n = n + 1
 
-        return cls(version, currency, issuer, blocknumber, blockhash,
+        from .block import BlockId
+        return cls(version, currency, issuer, BlockId(blocknumber, blockhash),
                    membership_type, uid, cert_ts, signature)
 
     def raw(self):
@@ -103,14 +100,14 @@ class Membership(Document):
 Type: Membership
 Currency: {1}
 Issuer: {2}
-Block: {3}-{4}
-Membership: {5}
-UserID: {6}
-CertTS: {7}
+Block: {3}
+Membership: {4}
+UserID: {5}
+CertTS: {6}
 """.format(self.version,
                       self.currency,
                       self.issuer,
-                      self.block_number, self.block_hash,
+                      self.blockid,
                       self.membership_type,
                       self.uid,
                       self.cert_ts)
@@ -118,7 +115,7 @@ CertTS: {7}
     def inline(self):
         return "{0}:{1}:{2}:{3}:{4}:{5}".format(self.issuer,
                                         self.signatures[0],
-                                        self.block_number,
-                                        self.block_hash,
+                                        self.blockid.number,
+                                        self.blockid.sha_hash,
                                         self.cert_ts,
                                         self.uid)
diff --git a/ucoinpy/documents/peer.py b/ucoinpy/documents/peer.py
index 5716a78511a0e807a0a6939eb0810e9a8ba5c0e2..838c55b3e476673650f3c45950eaea88dea5e05b 100644
--- a/ucoinpy/documents/peer.py
+++ b/ucoinpy/documents/peer.py
@@ -2,6 +2,7 @@ import re
 
 from ..api.bma import ConnectionHandler
 from .document import Document
+from . import BlockId
 from .. import PROTOCOL_VERSION, MANAGED_API
 
 
@@ -52,7 +53,7 @@ class Peer(Document):
         pubkey = Peer.re_pubkey.match(lines[n]).group(1)
         n = n + 1
 
-        blockid = Peer.re_block.match(lines[n]).group(1)
+        blockid = BlockId.from_str(Peer.re_block.match(lines[n]).group(1))
         n = n + 1
 
         Peer.re_endpoints.match(lines[n])
@@ -83,7 +84,7 @@ Endpoints:
         return doc
 
 
-class Endpoint():
+class Endpoint:
     """
     Describing endpoints
     """