tImplement blockchain.scripthash.get_balance method - electrum-personal-server - Maximally lightweight electrum server for a single user HTML git clone https://git.parazyd.org/electrum-personal-server DIR Log DIR Files DIR Refs DIR README --- DIR commit dcbbf60f42b0477e38b868bcefe37948f33e7a37 DIR parent 9119d0d0d13b21cb355280b003e408ffbb68cbee HTML Author: chris-belcher <chris-belcher@users.noreply.github.com> Date: Wed, 14 Nov 2018 14:37:22 +0000 Implement blockchain.scripthash.get_balance method Issue #68 is a report that this method is sometimes used by Electrum wallet version 3.2.3. As with similar methods in Electrum Personal Server it only works with addresses for which the server has been configured to know about. Diffstat: M electrumpersonalserver/server/comm… | 11 ++++++++++- M electrumpersonalserver/server/tran… | 29 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) --- DIR diff --git a/electrumpersonalserver/server/common.py b/electrumpersonalserver/server/common.py t@@ -170,6 +170,14 @@ def handle_query(sock, line, rpc, txmonitor): logger.warning("Address history not known to server, " + "hash(address) = " + scrhash) send_response(sock, query, history) + elif method == "blockchain.scripthash.get_balance": + scrhash = query["params"][0] + balance = txmonitor.get_address_balance(scrhash) + if balance == None: + logger.warning("Address history not known to server, " + + "hash(address) = " + scrhash) + balance = {"confirmed": 0, "unconfirmed": 0} + send_response(sock, query, balance) elif method == "server.ping": send_response(sock, query, None) elif method == "blockchain.headers.subscribe": t@@ -314,7 +322,8 @@ def handle_query(sock, line, rpc, txmonitor): result = txid else: core_proof = rpc.call("gettxoutproof", [[txid], blockhash]) - electrum_proof = merkleproof.convert_core_to_electrum_merkle_proof( + electrum_proof =\ + merkleproof.convert_core_to_electrum_merkle_proof( core_proof) result = {"tx_hash": txid, "merkle": electrum_proof["merkle"]} send_response(sock, query, result) DIR diff --git a/electrumpersonalserver/server/transactionmonitor.py b/electrumpersonalserver/server/transactionmonitor.py t@@ -76,6 +76,35 @@ class TransactionMonitor(object): else: return None + def get_address_balance(self, scrhash): + history = self.get_electrum_history(scrhash) + if history == None: + return None + utxos = {} + for tx_info in history: + tx = self.rpc.call("gettransaction", [tx_info["tx_hash"]]) + txd = self.rpc.call("decoderawtransaction", [tx["hex"]]) + for index, output in enumerate(txd["vout"]): + if script_to_scripthash(output["scriptPubKey"]["hex"] + ) != scrhash: + continue + utxos[txd["txid"] + ":" + str(index)] = (output["value"], + tx["confirmations"]) + for inputt in txd["vin"]: + outpoint = inputt["txid"] + ":" + str(inputt["vout"]) + if outpoint in utxos: + del utxos[outpoint] + confirmed_balance = 0 + unconfirmed_balance = 0 + for utxo in utxos.values(): + value = int(Decimal(utxo[0]) * Decimal(1e8)) + if utxo[1] > 0: + confirmed_balance += value + else: + unconfirmed_balance += value + return {"confirmed": confirmed_balance, "unconfirmed": + unconfirmed_balance} + def subscribe_address(self, scrhash): if scrhash in self.address_history: self.address_history[scrhash]["subscribed"] = True