commit dcbbf60f42b0477e38b868bcefe37948f33e7a37
parent 9119d0d0d13b21cb355280b003e408ffbb68cbee
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:
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/electrumpersonalserver/server/common.py b/electrumpersonalserver/server/common.py
@@ -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":
@@ -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)
diff --git a/electrumpersonalserver/server/transactionmonitor.py b/electrumpersonalserver/server/transactionmonitor.py
@@ -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