#!/usr/bin/env python # # Electrum - lightweight Bitcoin client # Copyright (C) 2011 thomasv@gitorious # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from util import * from bitcoin import * from decimal import Decimal import bitcoin protected_commands = ['payto', 'password', 'mktx', 'get_seed', 'importprivkey','signmessage', 'signrawtransaction','dumpprivkey' ] class Commands: def __init__(self, wallet, interface): self.wallet = wallet self.interface = interface def _run(self, method, args, password_getter): if method in protected_commands: pw = apply(password_getter,()) args += (pw,) f = eval('self.'+method) apply(f,args) def get_history(self, addr): h = self.wallet.get_history(addr) if h is None: h = self.wallet.interface.synchronous_get([ ('blockchain.address.get_history',[addr]) ])[0] print_json(h) def listunspent(self): print_json(self.wallet.get_unspent_coins()) def createrawtransaction(self, inputs, outputs): # convert to own format for i in inputs: i['tx_hash'] = i['txid'] i['index'] = i['vout'] outputs = map(lambda x: (x[0],int(1e8*x[1])), outputs.items()) tx = Transaction.from_io(inputs, outputs) print_msg( tx ) def signrawtransaction(self, raw_tx, input_info, private_keys, password): tx = Transaction(raw_tx) unspent_coins = self.wallet.get_unspent_coins() # convert private_keys to dict pk = {} for sec in private_keys: address = bitcoin.address_from_private_key(sec) pk[address] = sec private_keys = pk for txin in tx.inputs: # convert to own format txin['tx_hash'] = txin['prevout_hash'] txin['index'] = txin['prevout_n'] for item in input_info: if item.get('txid') == txin['tx_hash'] and item.get('vout') == txin['index']: txin['raw_output_script'] = item['scriptPubKey'] txin['redeemScript'] = item.get('redeemScript') txin['electrumKeyID'] = item.get('electrumKeyID') break else: for item in unspent_coins: if txin['tx_hash'] == item['tx_hash'] and txin['index'] == item['index']: txin['raw_output_script'] = item['raw_output_script'] break else: # if neither, we might want to get it from the server.. raise # find the address: import deserialize if txin.get('electrumKeyID'): n, for_change = txin.get('electrumKeyID') sec = wallet.sequence.get_private_key(n, for_change, seed) address = bitcoin.address_from_private_key(sec) txin['address'] = address private_keys[address] = sec elif txin.get("redeemScript"): txin['address'] = bitcoin.hash_160_to_bc_address(bitcoin.hash_160(txin.get("redeemScript").decode('hex')), 5) elif txin.get("raw_output_script"): addr = deserialize.get_address_from_output_script(txin.get("raw_output_script").decode('hex')) sec = wallet.get_private_key(addr, password) if sec: private_keys[addr] = sec txin['address'] = addr tx.sign( private_keys ) print_json({ "hex":str(tx),"complete":tx.is_complete}) def decoderawtransaction(self, raw): tx = Transaction(raw) print_json( tx.deserialize() ) def sendrawtransaction(self, raw): tx = Transaction(raw) r, h = wallet.sendtx( tx ) print_msg(h) def createmultisig(self, num, pubkeys): assert isinstance(pubkeys, list) print_json( Transaction.multisig_script(pubkeys, num) ) def freeze(self,addr): print_msg(self.wallet.freeze(addr)) def unfreeze(self,addr): print_msg(self.wallet.unfreeze(addr)) def prioritize(self, addr): print_msg(self.wallet.prioritize(addr)) def unprioritize(self, addr): print_msg(self.wallet.unprioritize(addr)) def dumpprivkey(self, addr, password): sec = self.wallet.get_private_key(addr, password) print_msg( sec ) def validateaddress(self,addr): is_valid = self.wallet.is_valid(addr) out = { 'isvalid':is_valid } if is_valid: is_mine = self.wallet.is_mine(addr) out['address'] = addr out['ismine'] = is_mine if is_mine: out['pubkey'] = self.wallet.get_public_key(addr) print_json(out) def balance(self, addresses = []): if addresses == []: c, u = self.wallet.get_balance() if u: print_msg(Decimal( c ) / 100000000 , Decimal( u ) / 100000000) else: print_msg(Decimal( c ) / 100000000) else: for addr in addresses: c, u = wallet.get_addr_balance(addr) if u: print_msg("%s %s, %s" % (addr, str(Decimal(c)/100000000), str(Decimal(u)/100000000))) else: print_msg("%s %s" % (addr, str(Decimal(c)/100000000))) def get_seed(self, password): import mnemonic seed = self.wallet.decode_seed(password) print_msg(seed + ' "' + ' '.join(mnemonic.mn_encode(seed)) + '"') def importprivkey(self, sec): try: addr = wallet.import_key(sec,password) wallet.save() print_msg("Keypair imported: ", addr) except BaseException as e: print_msg("Error: Keypair import failed: " + str(e)) def sign_message(self, address, message, password): print_msg(self.wallet.sign_message(address, message, password)) def verify_message(self, address, signature, message): try: EC_KEY.verify_message(address, signature, message) print_msg(True) except BaseException as e: print_error("Verification error: {0}".format(e)) print_msg(False) def mktx(self, to_address, amount, fee, change_addr, from_addr, password = None): for k, v in self.wallet.labels.items(): if v == to_address: to_address = k print_msg("alias", to_address) break if change_addr and v == change_addr: change_addr = k amount = int(10000000*amount) if fee: fee = int(10000000*fee) tx = self.wallet.mktx( [(to_address, amount)], password, fee , change_addr, from_addr) out = {"hex":str(tx), "complete":tx.is_complete} if not tx.is_complete: out['input_info'] = repr(tx.input_info).replace(' ','') print_json(out) def payto(self, to_address, amount, fee, change_addr, from_addr, password = None): amount = int(10000000*amount) if fee: fee = int(10000000*fee) tx = self.wallet.mktx( [(to_address, amount)], password, fee, change_addr, from_addr ) r, h = wallet.sendtx( tx ) print_msg(h) def history(self): import datetime balance = 0 for item in self.wallet.get_tx_history(): tx_hash, conf, is_mine, value, fee, balance, timestamp = item try: time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] except: time_str = "----" label, is_default_label = self.wallet.get_label(tx_hash) if not label: label = tx_hash else: label = label + ' '*(64 - len(label) ) print_msg("%17s"%time_str, " " + label + " " + format_satoshis(value)+ " "+ format_satoshis(balance)) print_msg("# balance: ", format_satoshis(balance)) def setlabel(self, tx, label): self.wallet.labels[tx] = label self.wallet.save() def contacts(self): c = {} for addr in self.wallet.addressbook: c[addr] = self.wallet.labels.get(addr) print_json(c)