new script: get_balance <bitcoin_address>
authorMaxime Biais <maxime.biais@gmail.com>
Tue, 6 Aug 2013 14:03:03 +0000 (16:03 +0200)
committerMaxime Biais <maxime.biais@gmail.com>
Tue, 6 Aug 2013 14:03:03 +0000 (16:03 +0200)
scripts/get_balance [new file with mode: 0755]

diff --git a/scripts/get_balance b/scripts/get_balance
new file mode 100755 (executable)
index 0000000..f747d5a
--- /dev/null
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+import sys
+from electrum import Interface
+from electrum import bitcoin, Transaction
+
+def get_transaction(interface, tx_hash, tx_height):
+    raw_tx = interface.synchronous_get([ ('blockchain.transaction.get',[tx_hash, tx_height]) ])[0]
+    tx = Transaction(raw_tx)
+    return tx
+
+def get_history(interface, addr):
+    transactions = interface.synchronous_get([ ('blockchain.address.get_history',[addr]) ])[0]
+    transactions.sort(key=lambda x:x["height"])
+    return [(i["tx_hash"],i["height"]) for i in transactions]
+
+def get_addr_balance(interface, address):
+    prevout_values = {}
+    h = get_history(interface, address)
+    if h == ['*']: return 0, 0
+    c = u = 0
+    received_coins = []   # list of coins received at address
+    transactions = {}
+
+    # fetch transactions
+    for tx_hash, tx_height in h:
+        transactions[(tx_hash, tx_height)] = get_transaction(interface, tx_hash, tx_height)
+
+    for tx_hash, tx_height in h:
+        tx = transactions[(tx_hash, tx_height)]
+        if not tx: continue
+        update_tx_outputs(tx, prevout_values)
+        for i, (addr, value) in enumerate(tx.outputs):
+            if addr == address:
+                key = tx_hash + ':%d'%i
+                received_coins.append(key)
+
+    for tx_hash, tx_height in h:
+        tx = transactions[(tx_hash, tx_height)]
+        if not tx: continue
+        v = 0
+
+        for item in tx.inputs:
+            addr = item.get('address')
+            if addr == address:
+                key = item['prevout_hash']  + ':%d'%item['prevout_n']
+                value = prevout_values.get(key)
+                if key in received_coins:
+                    v -= value
+        for i, (addr, value) in enumerate(tx.outputs):
+            key = tx_hash + ':%d'%i
+            if addr == address:
+                v += value
+        if tx_height:
+            c += v
+        else:
+            u += v
+    return c, u
+
+def update_tx_outputs(tx, prevout_values):
+    for i, (addr, value) in enumerate(tx.outputs):
+        key = tx.hash() + ':%d' % i
+        prevout_values[key] = value
+
+def main(address):
+    interface = Interface()
+    interface.start()
+    c, u = get_addr_balance(interface, address)
+
+    print("Final balance: confirmed: %d (%.8f BTC), unconfirmed: %d (%.8f BTC)" %
+          (c, c / 100000000., u, u / 100000000.))
+
+if __name__ == "__main__":
+    try:
+        address = sys.argv[1]
+    except:
+        print "usage: get_balance <bitcoin_address>"
+        sys.exit(1)
+    main(address)