import time import struct from .constants import * from .opcodes import * from .hash import * from .encode import * import math import io # Bitcoin keys # def create_private_key(hex=False): """ :return: 32 bytes private key """ a = random.SystemRandom().randint(0,MAX_INT_PRIVATE_KEY) i = int((time.time()%0.01)*100000) h = a.to_bytes(32,byteorder="big") while True: h = hashlib.sha256(h).digest() if i>1: i -= 1 else: if int.from_bytes(h,byteorder="big") 1 and l <= 82: if script[1] == l - 2: return {"nType": 3, "type": "NULL_DATA", "reqSigs": 0, "data": script[2:]} if script[0] >= 81 and script[0] <= 96: if script[-1] == 174: if script[-2] >= 81 and script[-2] <= 96: if script[-2] >= script[0]: c, s = 0, 1 while l - 2 - s > 0: if script[s] < 0x4c: s += script[s] c += 1 else: c = 0 break s += 1 if c == script[-2] - 80: return {"nType": 4, "type": "MULTISIG", "reqSigs": script[0] - 80, "script": script} s, m, n, last, req_sigs = 0, 0, 0, 0, 0 while l - s > 0: if script[s] >= 81 and script[s] <= 96: if not n: n = script[s] - 80 else: if m == 0: n, m = script[s] - 80, 0 elif n > m: n, m = script[s] - 80, 0 elif m == script[s] - 80: last = 0 if last else 2 elif script[s] < 0x4c: s += script[s] m += 1 if m > 16: n, m = 0, 0 elif script[s] == OPCODE["OP_PUSHDATA1"]: s += 1 + script[s + 1] elif script[s] == OPCODE["OP_PUSHDATA2"]: s += 2 + struct.unpack(' 0: if script[s] < 0x4c and script[s]: if asm: result.append(hexlify(script[s+1:s+1 +script[s]]).decode()) else: result.append('[%s]' % script[s]) s += script[s] + 1 continue elif script[s] == OPCODE["OP_PUSHDATA1"]: s += 1 + script[s + 1] elif script[s] == OPCODE["OP_PUSHDATA2"]: s += 2 + struct.unpack(' 73): return False # A signature is of type 0x30 (compound). if sig[0] != 0x30: return False # Make sure the length covers the entire signature. if sig[1] != (length - 3): return False # Extract the length of the R element. lenR = sig[3] # Make sure the length of the S element is still inside the signature. if (5 + lenR) >= length: return False # Extract the length of the S element. lenS = sig[5 + lenR] # Verify that the length of the signature matches the sum of the length # of the elements. if (lenR + lenS + 7) != length: return False # Check whether the R element is an integer. if sig[2] != 0x02: return False # Zero-length integers are not allowed for R. if lenR == 0: return False # Negative numbers are not allowed for R. if sig[4] & 0x80: return False # Null bytes at the start of R are not allowed, unless R would # otherwise be interpreted as a negative number. if (lenR > 1) and (sig[4] == 0x00) and (not sig[5] & 0x80): return False # Check whether the S element is an integer. if sig[lenR + 4] != 0x02: return False # Zero-length integers are not allowed for S. if lenS == 0: return False # Negative numbers are not allowed for S. if sig[lenR + 6] & 0x80: return False # Null bytes at the start of S are not allowed, unless S would otherwise be # interpreted as a negative number. if (lenS > 1) and (sig[lenR + 6] == 0x00) and (not sig[lenR + 7] & 0x80): return False return True # # Transaction encoding # def rh2s(tthash): return hexlify(tthash[::-1]).decode() def s2rh(hash_string): return unhexlify(hash_string)[::-1] def s2rh_step4(hash_string): h = unhexlify(hash_string) return reverse_hash(h) def reverse_hash(h): return struct.pack('>IIIIIIII', *struct.unpack('>IIIIIIII', h)[::-1])[::-1] # # # def merkleroot(tx_hash_list): tx_hash_list = list(tx_hash_list) if len(tx_hash_list) == 1: return tx_hash_list[0] while True: new_hash_list = list() while tx_hash_list: h1 = tx_hash_list.pop(0) try: h2 = tx_hash_list.pop(0) except: h2 = h1 new_hash_list.append(double_sha256(h1 + h2)) if len(new_hash_list) > 1: tx_hash_list = new_hash_list else: return new_hash_list[0] def merkle_branches(tx_hash_list): tx_hash_list = list(tx_hash_list) branches = [] if len(tx_hash_list) == 1: return [] tx_hash_list.pop(0) while True: branches.append(tx_hash_list.pop(0)) new_hash_list = list() while tx_hash_list: h1 = tx_hash_list.pop(0) try: h2 = tx_hash_list.pop(0) except: h2 = h1 new_hash_list.append(double_sha256(h1 + h2)) if len(new_hash_list) > 1: tx_hash_list = new_hash_list else: if new_hash_list: branches.append(new_hash_list.pop(0)) return branches def merkleroot_from_branches(merkle_branches, coinbase_hash_bin): merkle_root = coinbase_hash_bin for h in merkle_branches: if type(h) == str: h = unhexlify(h) merkle_root = double_sha256(merkle_root + h) return merkle_root def bits_to_target(bits): if type(bits) == str: bits = unhexlify(bits) if type(bits) == bytes: return int.from_bytes(bits[1:], 'big') * (2 ** (8 * (bits[0] - 3))) else: shift = bits >> 24 target = (bits & 0xffffff) * (1 << (8 * (shift - 3))) return target def target_to_difficulty(target): return 0x00000000FFFF0000000000000000000000000000000000000000000000000000 / target def bits_to_difficulty(bits): return target_to_difficulty(bits_to_target(bits)) def difficulty_to_target(difficulty): return int(0x00000000FFFF0000000000000000000000000000000000000000000000000000 / difficulty) # # # def bytes_needed(n): if n == 0: return 1 return math.ceil(n.bit_length()/8) def int_to_bytes(i, byteorder='big'): return i.to_bytes(bytes_needed(i), byteorder=byteorder, signed=False) def bytes_to_int(i, byteorder='big'): return int.from_bytes(i, byteorder=byteorder, signed=False) # variable integer def int_to_var_int(i): if i < 0xfd: return struct.pack(' 0: s.append((v >> ((i - 1) * 8)) & 0xff) i -= 1 return s def bin2bn(s): l = 0 for ch in s: l = (l << 8) | ch return l def bn2mpi(v): have_ext = False if v.bit_length() > 0: have_ext = (v.bit_length() & 0x07) == 0 neg = False if v < 0: neg = True v = -v s = struct.pack(b">I", bn_bytes(v, have_ext)) ext = bytearray() if have_ext: ext.append(0) v_bin = bn2bin(v) if neg: if have_ext: ext[0] |= 0x80 else: v_bin[0] |= 0x80 return s + ext + v_bin def mpi2bn(s): if len(s) < 4: return None s_size = bytes(s[:4]) v_len = struct.unpack(b">I", s_size)[0] if len(s) != (v_len + 4): return None if v_len == 0: return 0 v_str = bytearray(s[4:]) neg = False i = v_str[0] if i & 0x80: neg = True i &= ~0x80 v_str[0] = i v = bin2bn(v_str) if neg: return -v return v # bitcoin-specific little endian format, with implicit size def mpi2vch(s): r = s[4:] # strip size # if r: r = r[::-1] # reverse string, converting BE->LE # else: r=b'\x00' return r def bn2vch(v): return bytes(mpi2vch(bn2mpi(v))) def vch2mpi(s): r = struct.pack(b">I", len(s)) # size r += s[::-1] # reverse string, converting LE->BE return r def vch2bn(s): return mpi2bn(vch2mpi(s)) def i2b(i): return bn2vch(i) def b2i(b): return vch2bn(b) def get_stream(stream): if type(stream) != io.BytesIO: if type(stream) == str: stream = unhexlify(stream) if type(stream) == bytes: stream = io.BytesIO(stream) else: raise TypeError return stream