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):
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]