update validate script with 0.5 protocol
[electrum-nvc.git] / scripts / validate_tx
index 6671fe9..8904c5b 100755 (executable)
@@ -2,28 +2,20 @@
 
 import sys, hashlib
 from electrum import Interface
-from electrum.bitcoin import Hash, rev_hex, int_to_hex
+from electrum.bitcoin import Hash, rev_hex, int_to_hex, hash_encode, hash_decode
 
 """validate a transaction (SPV)"""
 
-
 i = Interface({'server':'ecdsa.org:50002:s'})
 i.start()
 
 
-def merkle_root(merkle):
-
-    merkle = map (lambda tx_hash: tx_hash.decode('hex')[::-1], merkle)
-    while len(merkle) != 1:
-        if len(merkle)%2: merkle.append( merkle[-1] )
-        n = []
-        while merkle:
-            n.append( Hash( merkle[0] + merkle[1] ) )
-            merkle = merkle[2:]
-
-        merkle = n
-            
-    return merkle[0][::-1].encode('hex')
+def hash_merkle_root(merkle_s, target_hash, pos):
+    h = hash_decode(target_hash)
+    for i in range(len(merkle_s)):
+        item = merkle_s[i]
+        h = Hash( hash_decode(item) + h ) if ((pos >> i) & 1) else Hash( h + hash_decode(item) )
+    return hash_encode(h)
 
 
 def hash_header(res):
@@ -39,25 +31,25 @@ def hash_header(res):
 def verify_tx(tx_hash):
     
     res = i.synchronous_get([ ('blockchain.transaction.get_merkle',[tx_hash]) ])[0]
-    assert tx_hash in res.get('merkle')
-    assert res.get('merkle_root') == merkle_root(res['merkle'])
-    block_height = res.get('block_height')
-    print block_height
+    raw_tx = i.synchronous_get([ ('blockchain.transaction.get',[tx_hash, res['block_height']]) ])[0]
+    assert hash_encode(Hash(raw_tx.decode('hex'))) == tx_hash
 
+    merkle_root = hash_merkle_root(res['merkle'], tx_hash, res['pos'])
+    tx_height = res.get('block_height')
     headers_requests = []
-    for height in range(block_height-10,block_height+10):
+    for height in range(tx_height-10,tx_height+10):
         headers_requests.append( ('blockchain.block.get_header',[height]) )
-    res = i.synchronous_get(headers_requests)
-
+    headers = i.synchronous_get(headers_requests)
     _hash = None
-    for header in res:
+    for header in headers:
         if _hash: assert _hash == header.get('prev_block_hash')
         _hash = hash_header(header)
-        print _hash
-        if height==block_height:
-            assert header.get('merkle_root') == res.get('merkle_root')
-        
-
+        height = header.get('block_height')
+        if height==tx_height:
+            assert header.get('merkle_root') == merkle_root
+            print height, _hash, '*'
+        else:
+            print height, _hash
 
 try:
     tx = sys.argv[1]