hashes.py (2865B)
1 2 import hashlib 3 import binascii 4 import math 5 6 ## stuff copied from electrum's source 7 8 def to_bytes(something, encoding='utf8'): 9 """ 10 cast string to bytes() like object, but for python2 support 11 it's bytearray copy 12 """ 13 if isinstance(something, bytes): 14 return something 15 if isinstance(something, str): 16 return something.encode(encoding) 17 elif isinstance(something, bytearray): 18 return bytes(something) 19 else: 20 raise TypeError("Not a string or bytes like object") 21 22 def sha256(x): 23 x = to_bytes(x, 'utf8') 24 return bytes(hashlib.sha256(x).digest()) 25 26 def bh2u(x): 27 return binascii.hexlify(x).decode('ascii') 28 29 def script_to_scripthash(script): 30 """Electrum uses a format hash(scriptPubKey) as the index keys""" 31 h = sha256(bytes.fromhex(script))[0:32] 32 return bh2u(bytes(reversed(h))) 33 34 #the 'result' field in the blockchain.scripthash.subscribe method 35 # reply uses this as a summary of the address 36 def get_status_electrum(h): 37 if not h: 38 return None 39 if len(h) == 0: 40 return None 41 status = '' 42 for tx_hash, height in h: 43 status += tx_hash + ':%d:' % height 44 return bh2u(hashlib.sha256(status.encode('ascii')).digest()) 45 46 bfh = bytes.fromhex 47 hash_encode = lambda x: bh2u(x[::-1]) 48 hash_decode = lambda x: bfh(x)[::-1] 49 50 def Hash(x): 51 x = to_bytes(x, 'utf8') 52 out = bytes(sha256(sha256(x))) 53 return out 54 55 def hash_merkle_root(merkle_s, target_hash, pos): 56 h = hash_decode(target_hash) 57 for i in range(len(merkle_s)): 58 item = merkle_s[i] 59 h = Hash(hash_decode(item) + h) if ((pos >> i) & 1) else Hash( 60 h + hash_decode(item)) 61 return hash_encode(h) 62 63 def hash_160(public_key): 64 try: 65 md = hashlib.new('ripemd160') 66 md.update(sha256(public_key)) 67 return md.digest() 68 except BaseException: 69 from . import ripemd 70 md = ripemd.new(sha256(public_key)) 71 return md.digest() 72 73 ## end of electrum copypaste 74 75 def script_to_address(scriptPubKey, rpc): 76 return rpc.call("decodescript", [scriptPubKey])["addresses"][0] 77 78 def address_to_script(addr, rpc): 79 return rpc.call("validateaddress", [addr])["scriptPubKey"] 80 81 def address_to_scripthash(addr, rpc): 82 return script_to_scripthash(address_to_script(addr, rpc)) 83 84 # doesnt really fit here but i dont want to clutter up server.py 85 86 unit_list = list(zip(['B', 'kB', 'MB', 'GB', 'TB', 'PB'], [0, 0, 1, 2, 2, 2])) 87 88 def bytes_fmt(num): 89 """Human friendly file size""" 90 if num > 1: 91 exponent = min(int(math.log(num, 1000)), len(unit_list) - 1) 92 quotient = float(num) / 1000**exponent 93 unit, num_decimals = unit_list[exponent] 94 format_string = '{:.%sf} {}' % (num_decimals) 95 return format_string.format(quotient, unit) 96 if num == 0: 97 return '0 bytes' 98 if num == 1: 99 return '1 byte' 100