electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 0c37009cdb3cb276096cf14b5dca18b9338f7eaa
parent c0858f314f16162f39b3034af85d8be59be84e39
Author: ThomasV <thomasv@gitorious>
Date:   Thu,  2 Jul 2015 08:53:17 +0200

fix is_address (forgot p2sh)

Diffstat:
Mlib/bitcoin.py | 2+-
Mlib/wallet.py | 10+++++++++-
Mplugins/trezor.py | 56+++++++++++++++++++++++++++++++++++++-------------------
3 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/lib/bitcoin.py b/lib/bitcoin.py @@ -358,7 +358,7 @@ def is_address(addr): addrtype, h = bc_address_to_hash_160(addr) except Exception: return False - if addrtype != 0: + if addrtype not in [0, 5]: return False return addr == hash_160_to_bc_address(h, addrtype) diff --git a/lib/wallet.py b/lib/wallet.py @@ -196,7 +196,7 @@ class Abstract_Wallet(object): for tx_hash, raw in tx_list.items(): tx = Transaction(raw) self.transactions[tx_hash] = tx - if self.txi.get(tx_hash) is None and self.txo.get(tx_hash) is None: + if self.txi.get(tx_hash) is None and self.txo.get(tx_hash) is None and (tx_hash not in self.pruned_txo.values()): print_error("removing unreferenced tx", tx_hash) self.transactions.pop(tx_hash) @@ -748,6 +748,14 @@ class Abstract_Wallet(object): if (tx_hash, height) not in hist: self.remove_transaction(tx_hash, height) + # fix: maybe remove only at the end, tx that have only unspent outputs + # bug: if tx is used by many addresses, not clear what we should do.. + # we should remove tx iff it is completely unreferenced + + # note about balance bug: on fist sync, it downloaded a lot of new tx, and I had a wrong balance. + # after one reconnection it was fixed. (probably after changing server, going from pruned to long) + # this could be related to the 'download missing tx' behaviour, that kicks in on startup + self.history[addr] = hist self.storage.put('addr_history', self.history, True) diff --git a/plugins/trezor.py b/plugins/trezor.py @@ -221,25 +221,26 @@ class Plugin(BasePlugin): else: return False - def sign_transaction(self, tx): - if tx.is_complete(): - return + def sign_transaction(self, tx, prev_tx, xpub_path): + self.prev_tx = prev_tx + self.xpub_path = xpub_path client = self.get_client() - inputs = self.tx_inputs(tx) + inputs = self.tx_inputs(tx, True) outputs = self.tx_outputs(tx) - try: - signed_tx = client.sign_tx('Bitcoin', inputs, outputs)[1] - except Exception, e: - give_error(e) - finally: - self.handler.stop() + #try: + signed_tx = client.sign_tx('Bitcoin', inputs, outputs)[1] + #except Exception, e: + # give_error(e) + #finally: + self.handler.stop() + #values = [i['value'] for i in tx.inputs] raw = signed_tx.encode('hex') tx.update(raw) #for i, txinput in enumerate(tx.inputs): # txinput['value'] = values[i] - def tx_inputs(self, tx): + def tx_inputs(self, tx, for_sig=False): inputs = [] for txinput in tx.inputs: txinputtype = types.TxInputType() @@ -247,12 +248,12 @@ class Plugin(BasePlugin): prev_hash = "\0"*32 prev_index = 0xffffffff # signed int -1 else: - address = txinput['address'] - try: - address_path = self.wallet.address_id(address) - address_n = self.get_client().expand_path(address_path) - txinputtype.address_n.extend(address_n) - except: pass + + if for_sig: + x_pubkey = txinput['x_pubkeys'][0] + xpub, s = BIP32_Account.parse_xpubkey(x_pubkey) + xpub_n = self.get_client().expand_path(self.xpub_path[xpub]) + txinputtype.address_n.extend(xpub_n + s) prev_hash = unhexlify(txinput['prevout_hash']) prev_index = txinput['prevout_n'] @@ -310,7 +311,7 @@ class Plugin(BasePlugin): return t def get_tx(self, tx_hash): - tx = self.wallet.transactions[tx_hash] + tx = self.prev_tx[tx_hash] tx.deserialize() return self.electrum_tx_to_txtype(tx) @@ -429,9 +430,26 @@ class TrezorWallet(BIP32_HD_Wallet): return str(b64_msg_sig) def sign_transaction(self, tx, password): + if tx.is_complete(): + return if not self.check_proper_device(): give_error('Wrong device or password') - self.plugin.sign_transaction(tx) + # previous transactions used as inputs + prev_tx = {} + # path of the xpubs that are involved + xpub_path = {} + for txin in tx.inputs: + tx_hash = txin['prevout_hash'] + prev_tx[tx_hash] = self.transactions[tx_hash] + address = txin['address'] + address_path = self.address_id(address) + account_id, (change, address_index) = self.get_address_index(address) + + for x_pubkey in txin['x_pubkeys']: + xpub, s = BIP32_Account.parse_xpubkey(x_pubkey) + xpub_path[xpub] = "44'/0'/%s'"%account_id + + self.plugin.sign_transaction(tx, prev_tx, xpub_path) def check_proper_device(self): self.get_client().ping('t')