class BalancePlugin: def __init__(self, chain, chainpath): self.chain = chain self.chainpath = chainpath self.last_block = 0 if not os.path.isdir("txdata"): os.mkdir("txdata") try: f = open("txdata/" + self.chain + "-balances.pickle", "rb") self.balances = pickle.load(f) except: self.balances = {} self.blockchain = Blockchain(os.path.expanduser(self.chainpath), chain_const[self.chain]["pch"]) def load_settings(self): try: f = open("settings.json", "r") except: self.last_block = 0 return settings = json.loads(f.read()) if "last_block" in settings: if self.chain in settings["last_block"]: self.last_block = settings["last_block"][self.chain] return self.last_block = 0 def dump_settings(self): try: f = open("settings.json", "r") settings = json.loads(f.read()) if not "last_block" in settings: settings["last_block"] = {self.chain: self.last_block} else: settings["last_block"][self.chain] = self.last_block f.close() except: settings = {"last_block": {self.chain: self.last_block}} f = open("settings.json", "w") f.write(json.dumps(settings, indent=4)) f.close() def dump(self): f = open("txdata/" + self.chain + "-balances.pickle", "wb") pickle.dump(self.balances, f) def dump_txindex(self): prefixes = gen_prefix(PREFIX_SIZE) for p in prefixes: p_keys = [ txid for txid in self.txindex.keys() if txid.startswith(p) ] try: f = open("txdata/" + self.chain + "-" + p + "-txindex.pickle", "rb") txindex_p = pickle.load(f) f.close() except: txindex_p = {} for k in p_keys: txindex_p[k] = self.txindex[k] f = open("txdata/" + self.chain + "-" + p + "-txindex.pickle", "wb") pickle.dump(txindex_p, f) f.close() def scan_all(self, start=None, end=None): self.load_settings() self.txindex = {} if start is None: start = self.last_block + 1 block_generator = self.blockchain.get_ordered_blocks( os.path.expanduser(self.chainpath + "/index"), start=start, end=end) stop = start print(stop) unresolved = [] txcount = 0 print(start, stop, end) for block in block_generator: self.last_block = block.height stop = stop + 1 if not (end is None) and (stop > end): break #print block if stop % 1000 == 0: print(stop) for transaction in block.transactions: self.txindex[transaction.hash] = {} output_i = 0 for output in transaction.outputs: self.txindex[transaction.hash][output_i] = [ output.value, [], "u", block.height ] txcount += 1 for address in output.addresses: addr = address.get_address( version_bytes=chain_const[self.chain]["vb"]) self.txindex[transaction.hash][output_i][1].append( addr) if not addr in self.balances: self.balances[addr] = output.value else: self.balances[addr] += output.value output_i += 1 for inp in transaction.inputs: if inp.transaction_hash.replace("0", "") == "": continue try: tx = self.txindex[inp.transaction_hash][ inp.transaction_index] for address in tx[1]: if not address in self.balances: self.balances[address] = -tx[0] else: self.balances[address] -= tx[0] self.txindex[inp.transaction_hash][ inp.transaction_index][2] = "s" except: unresolved.append( [inp.transaction_hash, inp.transaction_index]) if txcount > 100000: self.dump_txindex() self.txindex = {} txcount = 0 self.dump_txindex() prefixes = gen_prefix(PREFIX_SIZE) for p in prefixes: p_unresolved = [txd for txd in unresolved if txd[0].startswith(p)] f = open("txdata/" + self.chain + "-" + p + "-txindex.pickle", "rb") self.txindex = pickle.load(f) f.close() for txd in p_unresolved: try: tx = self.txindex[txd[0]][txd[1]] for address in tx[1]: if not address in self.balances: self.balances[address] = -tx[0] else: self.balances[address] -= tx[0] self.txindex[txd[0]][txd[1]][2] = "s" except: pass f = open("txdata/" + self.chain + "-" + p + "-txindex.pickle", "wb") pickle.dump(self.txindex, f) f.close() self.dump() self.dump_settings() self.blockchain.dump_indexes("txdata/" + self.chain + "-index-cache.txt") del self.txindex self.txindex = {} def get_balance(self, address): if address in self.balances: return self.balances[address] / 100000000.0 else: return "Unknown address" def get_utxos(self, address): prefixes = gen_prefix(PREFIX_SIZE) result = [] self.blockchain.load_indexes( os.path.expanduser(self.chainpath + "/index"), cache="txdata/" + self.chain + "-index-cache.txt") for p in prefixes: f = open("txdata/" + self.chain + "-" + p + "-txindex.pickle", "rb") txindex = pickle.load(f) f.close() for txhash in txindex.keys(): for vout in txindex[txhash].keys(): tx = txindex[txhash][vout] if address in tx[1]: if tx[2] == "u": block = self.blockchain.load_block(tx[3]) result.append({ "txhash": txhash, "vout": vout, "value": tx[0], "block_number": tx[3], "block_hash": block.hash }) return sorted(result, key=lambda x: x["block_number"])