def decode_gcs(h): stream = get_stream(h) L = var_int_to_int(read_var_int(stream)) P = var_int_to_int(read_var_int(stream)) s = deque() s_append = s.append last = 0 gcs_filter = bitarray(endian='big') gcs_filter.frombytes(stream.read()) f = 0 for i in range(L): q = 0 r = 0 while gcs_filter[f]: q += 1 f += 1 f += 1 c = P - 1 while c >= 0: r = r << 1 if gcs_filter[f]: r += 1 f += 1 c -= 1 delta = (q << P) + r last += delta s_append(last) return s
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
def __init__(self, raw_block=None, format="decoded", version=536870912, testnet=False): if format not in ("decoded", "raw"): raise ValueError("tx_format error, raw or decoded allowed") self["format"] = format self["testnet"] = testnet self["header"] = None self["hash"] = None self["version"] = version self["versionHex"] = pack(">L", version).hex() self["previousBlockHash"] = None self["merkleRoot"] = None self["tx"] = dict() self["time"] = None self["bits"] = None self["nonce"] = None self["weight"] = 0 self["size"] = 80 self["strippedSize"] = 80 self["amount"] = 0 self["height"] = None self["difficulty"] = None self["targetDifficulty"] = None self["target"] = None if raw_block is None: return self["size"] = len(raw_block) if isinstance(raw_block, bytes) else int( len(raw_block) / 2) s = self.get_stream(raw_block) self["format"] = "raw" self["version"] = unpack("<L", s.read(4))[0] self["versionHex"] = pack(">L", self["version"]).hex() self["previousBlockHash"] = s.read(32) self["merkleRoot"] = s.read(32) self["time"] = unpack("<L", s.read(4))[0] self["bits"] = s.read(4) self["target"] = bits_to_target(unpack("<L", self["bits"])[0]) self["targetDifficulty"] = target_to_difficulty(self["target"]) self["target"] = self["target"].to_bytes(32, byteorder="little") self["nonce"] = unpack("<L", s.read(4))[0] s.seek(-80, 1) self["header"] = s.read(80) self["hash"] = double_sha256(self["header"]) block_target = int.from_bytes(self["hash"], byteorder="little") self["difficulty"] = target_to_difficulty(block_target) tx_count = var_int_to_int(read_var_int(s)) self["tx"] = {i: Transaction(s, format="raw") for i in range(tx_count)} for t in self["tx"].values(): self["amount"] += t["amount"] self["strippedSize"] += t["bSize"] self["strippedSize"] += var_int_len(tx_count) self["weight"] = self["strippedSize"] * 3 + self["size"] if format == "decoded": self.decode(testnet=testnet)
def decode_huffman(h): if h: stream = get_stream(h) c = var_int_to_int(read_var_int(stream)) freq = dict() for i in range(c): key = var_int_to_int(read_var_int(stream)) freq[key] = i + 1 codes = huffman_code(huffman_tree(freq)) l = var_int_to_int(read_var_int(stream)) delta_bit_length = var_int_to_int(read_var_int(stream)) d = bitarray() d.frombytes(stream.read(l)) while d.length() > (l * 8 - delta_bit_length): d.pop() return d.decode(codes) return []
def __init__(self, raw_tx=None, format="decoded", version=1, lock_time=0, testnet=False, auto_commit=True): if format not in ("decoded", "raw"): raise ValueError("format error, raw or decoded allowed") self.auto_commit = auto_commit self["format"] = format self["testnet"] = testnet self["segwit"] = False self["txId"] = None self["hash"] = None self["version"] = version self["size"] = 0 self["vSize"] = 0 self["bSize"] = 0 self["lockTime"] = lock_time self["vIn"] = dict() self["vOut"] = dict() self["rawTx"] = None self["blockHash"] = None self["confirmations"] = None self["time"] = None self["blockTime"] = None self["blockIndex"] = None self["coinbase"] = False self["fee"] = None self["data"] = None self["amount"] = None if raw_tx is None: return self["amount"] = 0 sw = sw_len = 0 stream = self.get_stream(raw_tx) start = stream.tell() read = stream.read tell = stream.tell seek = stream.seek # start deserialization self["version"] = unpack('<L', read(4))[0] n = read_var_int(stream) if n == b'\x00': # segwit format sw = 1 self["flag"] = read(1) n = read_var_int(stream) # inputs ic = var_int_to_int(n) for k in range(ic): self["vIn"][k] = dict() self["vIn"][k]["txId"] = read(32) self["vIn"][k]["vOut"] = unpack('<L', read(4))[0] self["vIn"][k]["scriptSig"] = read(var_int_to_int(read_var_int(stream))) self["vIn"][k]["sequence"] = unpack('<L', read(4))[0] # outputs for k in range(var_int_to_int(read_var_int(stream))): self["vOut"][k] = dict() self["vOut"][k]["value"] = unpack('<Q', read(8))[0] self["amount"] += self["vOut"][k]["value"] self["vOut"][k]["scriptPubKey"] = read(var_int_to_int(read_var_int(stream))) s = parse_script(self["vOut"][k]["scriptPubKey"]) self["vOut"][k]["nType"] = s["nType"] self["vOut"][k]["type"] = s["type"] if self["data"] is None: if s["nType"] == 3: self["data"] = s["data"] if s["nType"] not in (3, 4, 7, 8): self["vOut"][k]["addressHash"] = s["addressHash"] self["vOut"][k]["reqSigs"] = s["reqSigs"] # witness if sw: sw = tell() - start for k in range(ic): self["vIn"][k]["txInWitness"] = [read(var_int_to_int(read_var_int(stream))) \ for c in range(var_int_to_int(read_var_int(stream)))] sw_len = (stream.tell() - start) - sw + 2 self["lockTime"] = unpack('<L', read(4))[0] end = tell() seek(start) b = read(end - start) self["rawTx"] = b self["size"] = end - start self["bSize"] = end - start - sw_len self["weight"] = self["bSize"] * 3 + self["size"] self["vSize"] = ceil(self["weight"] / 4) if ic == 1 and \ self["vIn"][0]["txId"] == b'\x00' * 32 and \ self["vIn"][0]["vOut"] == 0xffffffff: self["coinbase"] = True else: self["coinbase"] = False if sw: self["segwit"] = True self["hash"] = double_sha256(b) self["txId"] = double_sha256(b"%s%s%s" % (b[:4], b[6:sw],b[-4:])) else: self["segwit"] = False self["txId"] = double_sha256(b) self["hash"] = self["txId"] if self["format"] == "decoded": self.decode()
def decode_dhcs(h): # Delta-Hoffman coded set stream = get_stream(h) # read code_table_1 c = var_int_to_int(read_var_int(stream)) code_table_1 = dict() for i in range(c): key = var_int_to_int(read_var_int(stream)) l = var_int_to_int(read_var_int(stream)) code = bitarray([bool(k) for k in stream.read(l)]) code_table_1[key] = code # read code_table_2 c = var_int_to_int(read_var_int(stream)) code_table_2 = dict() for i in range(c): key = var_int_to_int(read_var_int(stream)) l = var_int_to_int(read_var_int(stream)) code = bitarray([bool(k) for k in stream.read(l)]) code_table_2[key] = code # read compressed deltas deltas_bits_len_1 = var_int_to_int(read_var_int(stream)) deltas_bits_len_2 = var_int_to_int(read_var_int(stream)) deltas_byte_len = deltas_bits_len_2 // 8 + int(bool(deltas_bits_len_2 % 8)) r = stream.read(deltas_byte_len) deltas = bitarray() deltas.frombytes(r) while deltas.length() > deltas_bits_len_2: deltas.pop() # Huffman decode round 1 r = deltas.decode(code_table_2) deltas_string = bytearray() for i in range(int(len(r) / 2)): deltas_string += bytes([(r[i * 2] << 4) + r[i * 2 + 1]]) # Huffman decode round 2 r = bitarray() r.frombytes(bytes(deltas_string)) while r.length() > deltas_bits_len_1: r.pop() deltas_bits = r.decode(code_table_1) d_filter_bit_len = var_int_to_int(read_var_int(stream)) d_filter_byte_len = d_filter_bit_len // 8 + int(bool(d_filter_bit_len % 8)) r = stream.read(d_filter_byte_len) d_filter = bitarray() d_filter.frombytes(r) while d_filter.length() > d_filter_bit_len: d_filter.pop() f = 0 f_max = d_filter.length() decoded_set = set() last = 0 for bits in deltas_bits: d = 0 while bits > 0 and f < f_max: bits -= 1 d = d << 1 if d_filter[f]: d += 1 f += 1 last += d decoded_set.add(last) return decoded_set