daemon
[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, Network
6
7
8
9 def get_transaction(network, tx_hash, tx_height):
10     raw_tx = network.synchronous_get([(
11         'blockchain.transaction.get', [tx_hash, tx_height])])[0]
12     tx = Transaction(raw_tx)
13     return tx
14
15
16 def get_history(network, addr):
17     transactions = network.synchronous_get([(
18         'blockchain.address.get_history', [addr])])[0]
19     transactions.sort(key=lambda x: x["height"])
20     return [(i["tx_hash"], i["height"]) for i in transactions]
21
22
23 def get_addr_balance(network, address):
24     prevout_values = {}
25     h = get_history(network, address)
26     if h == ['*']:
27         return 0, 0
28     c = u = 0
29     received_coins = []   # list of coins received at address
30     transactions = {}
31
32     # fetch transactions
33     for tx_hash, tx_height in h:
34         transactions[(tx_hash, tx_height)] = get_transaction(
35             network, tx_hash, tx_height)
36
37     for tx_hash, tx_height in h:
38         tx = transactions[(tx_hash, tx_height)]
39         if not tx:
40             continue
41         update_tx_outputs(tx, prevout_values)
42         for i, (addr, value) in enumerate(tx.outputs):
43             if addr == address:
44                 key = tx_hash + ':%d' % i
45                 received_coins.append(key)
46
47     for tx_hash, tx_height in h:
48         tx = transactions[(tx_hash, tx_height)]
49         if not tx:
50             continue
51         v = 0
52
53         for item in tx.inputs:
54             addr = item.get('address')
55             if addr == address:
56                 key = item['prevout_hash'] + ':%d' % item['prevout_n']
57                 value = prevout_values.get(key)
58                 if key in received_coins:
59                     v -= value
60         for i, (addr, value) in enumerate(tx.outputs):
61             key = tx_hash + ':%d' % i
62             if addr == address:
63                 v += value
64         if tx_height:
65             c += v
66         else:
67             u += v
68     return c, u
69
70
71 def update_tx_outputs(tx, prevout_values):
72     for i, (addr, value) in enumerate(tx.outputs):
73         key = tx.hash() + ':%d' % i
74         prevout_values[key] = value
75
76
77 def main(address):
78     network = Network()
79     network.start(wait=True)
80     c, u = get_addr_balance(network, address)
81
82     print("Balance - confirmed: %d (%.8f BTC), unconfirmed: %d (%.8f BTC)" %
83           (c, c / 100000000., u, u / 100000000.))
84
85 if __name__ == "__main__":
86     try:
87         address = sys.argv[1]
88     except Exception:
89         print "usage: get_balance <bitcoin_address>"
90         sys.exit(1)
91     main(address)