btc.py (1777B)
1 import os 2 import logging 3 import hashlib 4 import time 5 6 from bip32 import BIP32 7 import base58 8 9 from srvaddrgen import DbKey 10 11 logg = logging.getLogger('btc') 12 13 14 envkey = 'SRVADDRGEN_BTC_XPUB' 15 16 def btc_reserve(responder, msg, dbenv): 17 logg.debug('processing btc') 18 xpub = os.environ.get(envkey, None) 19 idx = -1 20 addr = None 21 k = DbKey.BTC_XPUB.value 22 xpub_bin = xpub.encode('utf-8') 23 if xpub != None: 24 tx = dbenv.begin(write=True) 25 v = tx.get(k) 26 if v == None: 27 logg.info('BTC XPUB not set') 28 v = b'\x00' * 8 29 v += xpub_bin 30 tx.put(k, v, dupdata=False) 31 tx.commit() 32 33 tx = dbenv.begin(write=True) 34 v = tx.get(k) 35 idx = int.from_bytes(v[:8]) 36 if v[8:] != xpub_bin: 37 responder.croak(500, 'Master key has changed on server. Contact server administrator.', reason='Illegal key change') 38 raise responder 39 40 xpub = v[8:].decode('utf-8') 41 o = BIP32.from_xpub(xpub) 42 pubk_bytes = o.get_pubkey_from_path('m/0/' + str(idx)) 43 hsh = b'\x00' + hashlib.new('ripemd160', hashlib.new('sha256', pubk_bytes).digest()).digest() 44 pfx = hashlib.new('sha256', hashlib.new('sha256', hsh).digest()).digest()[:4] 45 addr = base58.b58encode(hsh + pfx) 46 47 k = DbKey.ADDR.value + addr 48 v = int.to_bytes(idx, 8) 49 v += int(time.time()).to_bytes(8) 50 v += msg.serialize() 51 r = tx.put(k, v, dupdata=False) 52 if not r: 53 tx.abort() 54 return responder.croak(500, 'Database write error') 55 56 idx = idx + 1 57 k = DbKey.BTC_XPUB.value 58 v = idx.to_bytes(8) 59 v += xpub_bin 60 r = tx.put(k, v) 61 if not r: 62 tx.abort() 63 return responder.croak(500, 'Database write error') 64 65 tx.commit() 66 67 responder.complete(content=addr)