def merkle_root(tx_hash_list, return_hex=True, receive_hex=True): """ Calculate merkle root from transaction hash list :param tx_hash_list: list of transaction hashes in bytes or HEX encoded string. :param return_hex: (optional) If set to True return result in HEX format, by default is True. :param receive_hex: (optional) If set to False no internal check or decode from hex to bytes, by default is True. :return: merkle root in bytes or HEX encoded string corresponding hex flag. """ if receive_hex: tx_hash_list = deque([h if isinstance(h, bytes) else s2rh(h) for h in tx_hash_list]) else: tx_hash_list = deque(tx_hash_list) if len(tx_hash_list) == 1: return rh2s(tx_hash_list[0]) if return_hex else tx_hash_list[0] while True: new_hash_list = deque() append = new_hash_list.append while tx_hash_list: h1 = tx_hash_list.popleft() try: h2 = tx_hash_list.popleft() except: h2 = h1 append(double_sha256(b"".join((h1, h2)))) if len(new_hash_list) > 1: tx_hash_list = new_hash_list else: return new_hash_list[0] if not return_hex else rh2s(new_hash_list[0])
def merkle_proof(merkle_tree, index, return_hex=True, receive_hex=False): if receive_hex == True: _merkle_tree = dict() for i in merkle_tree: _merkle_tree[i] = dict() for k in range(len(merkle_tree[i])): h = merkle_tree[i][k] _merkle_tree[i][k] = s2rh(h) if isinstance(h, str) else h merkle_tree = _merkle_tree mp = deque() mp_append = mp.append c = len(merkle_tree) - 1 while c: if index % 2: mp_append(merkle_tree[c][index - 1]) else: if len(merkle_tree[c]) > index + 1: mp_append(merkle_tree[c][index + 1]) else: mp_append(merkle_tree[c][index]) c -= 1 index = index//2 if return_hex: return [rh2s(h) for h in mp] else: return mp
def merkle_tree(tx_hash_list, return_hex=False, receive_hex=False): if receive_hex: tx_hash_deque = deque() tx_hash_deque_append = tx_hash_deque.append for h in tx_hash_list: tx_hash_deque_append(h if isinstance(h, bytes) else s2rh(h)) else: tx_hash_deque = deque(tx_hash_list) c = merkle_tree_depth(len(tx_hash_deque)) m = {c: deque(tx_hash_deque)} while len(tx_hash_deque) > 1: new_deque = deque() new_deque_append = new_deque.append while tx_hash_deque: h1 = tx_hash_deque.popleft() try: h2 = tx_hash_deque.popleft() except: h2 = h1 hs = double_sha256(b"".join((h1, h2))) new_deque_append(hs) tx_hash_deque = new_deque c -= 1 m[c] = deque(tx_hash_deque) if return_hex: for i in m: for k in range(len(m[i])): m[i][k] = rh2s(m[i][k]) return m
def decode_block_tx(block): s = get_stream(block) b = dict() b["amount"] = 0 b["size"] = int(len(block)/2) b["strippedSize"] = 80 b["version"] = unpack("<L", s.read(4))[0] b["versionHex"] = pack(">L", b["version"]).hex() b["previousBlockHash"] = rh2s(s.read(32)) b["merkleRoot"] = rh2s(s.read(32)) b["time"] = unpack("<L", s.read(4))[0] b["bits"] = s.read(4) b["target"] = bits_to_target(unpack("<L", b["bits"])[0]) b["targetDifficulty"] = target_to_difficulty(b["target"]) b["target"] = b["target"].to_bytes(32, byteorder="little") b["nonce"] = unpack("<L", s.read(4))[0] s.seek(-80, 1) b["header"] = s.read(80) b["bits"] = rh2s(b["bits"]) b["target"] = rh2s(b["target"]) b["hash"] = double_sha256(b["header"], hex=0) b["hash"] = rh2s(b["hash"]) b["rawTx"] = dict() b["tx"] = list() for i in range(var_int_to_int(read_var_int(s))): b["rawTx"][i] = Transaction(s, format="raw", keep_raw_tx=True) b["tx"].append(rh2s(b["rawTx"][i]["txId"])) b["amount"] += b["rawTx"][i]["amount"] b["strippedSize"] += b["rawTx"][i]["bSize"] b["strippedSize"] += var_int_len(len(b["tx"])) b["weight"] = b["strippedSize"] * 3 + b["size"] return b
async def load_utxo_from_daemon(self): # # load missed utxo from bitcoind daemon # if not self.missed_failed: return missed = chunks_by_count(self.missed_failed, 50) for m in missed: result = await self.rpc.batch( [["getrawtransaction", rh2s(i[:32]), 1] for i in m]) hash_list = set() for r in result: if r["result"]["blockhash"] not in self.restore_blocks_cache: hash_list.add(r["result"]["blockhash"]) result2 = await self.rpc.batch([["getblock", r] for r in hash_list]) for r in result2: self.restore_blocks_cache[r["result"]["hash"]] = r["result"] for key, r in zip(m, result): out_index = bytes_to_int(key[32:]) tx = r["result"] amount = int(tx["vout"][out_index]["value"] * 100000000) script = parse_script( tx["vout"][out_index]["scriptPubKey"]["hex"]) try: address = b"".join( (bytes([script["nType"]]), script["addressHash"])) except: address = b"".join( (bytes([script["nType"]]), script["script"])) block = self.restore_blocks_cache[tx["blockhash"]] tx_index = block["tx"].index(tx["txid"]) block_height = block["height"] pointer = (block_height << 39) + (tx_index << 20) + ( 1 << 19) + out_index self.loaded[key] = (pointer, amount, address) self.missed_failed = list() while len(self.restore_blocks_cache) > 1000: self.restore_blocks_cache.pop()
def merkle_root_from_proof(merkle_proof, tx_id, index, return_hex=True, receive_hex=True): if isinstance(merkle_proof, str): merkle_proof = bytes_from_hex(merkle_proof) if isinstance(merkle_proof, bytes): merkle_proof = [merkle_proof[y - 32:y] for y in range(32, len(merkle_proof) + 32, 32)] if receive_hex: _merkle_proof = deque() _merkle_proof_append = _merkle_proof.append for h in merkle_proof: _merkle_proof_append(s2rh(h) if isinstance(h, str) else h) merkle_proof = _merkle_proof tx_id = s2rh(tx_id) if isinstance(tx_id, str) else tx_id root = tx_id for h in merkle_proof: root = double_sha256(b"".join((h, root) if index % 2 else (root, h))) index = index // 2 if return_hex: return rh2s(root) return root
def decode(self, testnet=None): self["format"] = "decoded" if testnet is not None: self["testnet"] = testnet if isinstance(self["hash"], bytes): self["hash"] = rh2s(self["hash"]) if isinstance(self["target"], bytes): self["target"] = rh2s(self["target"]) if isinstance(self["previousBlockHash"], bytes): self["previousBlockHash"] = rh2s(self["previousBlockHash"]) if "nextBlockHash" in self: if isinstance(self["nextBlockHash"], bytes): self["nextBlockHash"] = rh2s(self["nextBlockHash"]) if isinstance(self["merkleRoot"], bytes): self["merkleRoot"] = rh2s(self["merkleRoot"]) if isinstance(self["header"], bytes): self["header"] = self["header"].hex() if isinstance(self["bits"], bytes): self["bits"] = rh2s(self["bits"]) for i in self["tx"]: self["tx"][i].decode(testnet=testnet)