f747d5a3ed4beb4a616d028ea0a14372bb85cebe
[electrum-nvc.git] / scripts / get_balance
1 #!/usr/bin/env python
2
3 import sys
4 from electrum import Interface
5 from electrum import bitcoin, Transaction
6
7 def get_transaction(interface, tx_hash, tx_height):
8     raw_tx = interface.synchronous_get([ ('blockchain.transaction.get',[tx_hash, tx_height]) ])[0]
9     tx = Transaction(raw_tx)
10     return tx
11
12 def get_history(interface, addr):
13     transactions = interface.synchronous_get([ ('blockchain.address.get_history',[addr]) ])[0]
14     transactions.sort(key=lambda x:x["height"])
15     return [(i["tx_hash"],i["height"]) for i in transactions]
16
17 def get_addr_balance(interface, address):
18     prevout_values = {}
19     h = get_history(interface, address)
20     if h == ['*']: return 0, 0
21     c = u = 0
22     received_coins = []   # list of coins received at address
23     transactions = {}
24
25     # fetch transactions
26     for tx_hash, tx_height in h:
27         transactions[(tx_hash, tx_height)] = get_transaction(interface, tx_hash, tx_height)
28
29     for tx_hash, tx_height in h:
30         tx = transactions[(tx_hash, tx_height)]
31         if not tx: continue
32         update_tx_outputs(tx, prevout_values)
33         for i, (addr, value) in enumerate(tx.outputs):
34             if addr == address:
35                 key = tx_hash + ':%d'%i
36                 received_coins.append(key)
37
38     for tx_hash, tx_height in h:
39         tx = transactions[(tx_hash, tx_height)]
40         if not tx: continue
41         v = 0
42
43         for item in tx.inputs:
44             addr = item.get('address')
45             if addr == address:
46                 key = item['prevout_hash']  + ':%d'%item['prevout_n']
47                 value = prevout_values.get(key)
48                 if key in received_coins:
49                     v -= value
50         for i, (addr, value) in enumerate(tx.outputs):
51             key = tx_hash + ':%d'%i
52             if addr == address:
53                 v += value
54         if tx_height:
55             c += v
56         else:
57             u += v
58     return c, u
59
60 def update_tx_outputs(tx, prevout_values):
61     for i, (addr, value) in enumerate(tx.outputs):
62         key = tx.hash() + ':%d' % i
63         prevout_values[key] = value
64
65 def main(address):
66     interface = Interface()
67     interface.start()
68     c, u = get_addr_balance(interface, address)
69
70     print("Final balance: confirmed: %d (%.8f BTC), unconfirmed: %d (%.8f BTC)" %
71           (c, c / 100000000., u, u / 100000000.))
72
73 if __name__ == "__main__":
74     try:
75         address = sys.argv[1]
76     except:
77         print "usage: get_balance <bitcoin_address>"
78         sys.exit(1)
79     main(address)