Browse Source

fix fee computation in sweep

283
ThomasV 8 years ago
parent
commit
1e55f4fda0
  1. 3
      gui/qt/main_window.py
  2. 11
      lib/commands.py
  3. 31
      lib/transaction.py
  4. 35
      lib/wallet.py

3
gui/qt/main_window.py

@ -2198,8 +2198,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
if not d.exec_(): if not d.exec_():
return return
fee = self.wallet.fee_per_kb(self.config) tx = self.wallet.sweep(get_pk(), self.network, self.config, get_address(), None)
tx = Transaction.sweep(get_pk(), self.network, get_address(), fee)
if not tx: if not tx:
self.show_message(_('No inputs found. (Note that inputs need to be confirmed)')) self.show_message(_('No inputs found. (Note that inputs need to be confirmed)'))
return return

11
lib/commands.py

@ -368,7 +368,7 @@ class Commands:
raise BaseException('cannot verify alias', x) raise BaseException('cannot verify alias', x)
return out['address'] return out['address']
@command('n') @command('nw')
def sweep(self, privkey, destination, tx_fee=None, nocheck=False): def sweep(self, privkey, destination, tx_fee=None, nocheck=False):
"""Sweep private keys. Returns a transaction that spends UTXOs from """Sweep private keys. Returns a transaction that spends UTXOs from
privkey to a destination address. The transaction is not privkey to a destination address. The transaction is not
@ -376,10 +376,8 @@ class Commands:
privkeys = privkey if type(privkey) is list else [privkey] privkeys = privkey if type(privkey) is list else [privkey]
self.nocheck = nocheck self.nocheck = nocheck
dest = self._resolver(destination) dest = self._resolver(destination)
if tx_fee is None: tx = self.wallet.sweep(privkeys, self.network, self.config, dest, tx_fee)
tx_fee = 0.0001 return tx.as_dict()
fee = int(Decimal(tx_fee)*COIN)
return Transaction.sweep(privkeys, self.network, dest, fee)
@command('wp') @command('wp')
def signmessage(self, address, message): def signmessage(self, address, message):
@ -398,7 +396,6 @@ class Commands:
self.nocheck = nocheck self.nocheck = nocheck
change_addr = self._resolver(change_addr) change_addr = self._resolver(change_addr)
domain = None if domain is None else map(self._resolver, domain) domain = None if domain is None else map(self._resolver, domain)
fee = None if fee is None else int(COIN*Decimal(fee))
final_outputs = [] final_outputs = []
for address, amount in outputs: for address, amount in outputs:
address = self._resolver(address) address = self._resolver(address)
@ -686,7 +683,7 @@ arg_types = {
'jsontx': json_loads, 'jsontx': json_loads,
'inputs': json_loads, 'inputs': json_loads,
'outputs': json_loads, 'outputs': json_loads,
'tx_fee': lambda x: str(Decimal(x)) if x is not None else None, 'tx_fee': lambda x: int(COIN*Decimal(x)) if x is not None else None,
'amount': lambda x: str(Decimal(x)) if x!='!' else '!', 'amount': lambda x: str(Decimal(x)) if x!='!' else '!',
} }

31
lib/transaction.py

@ -524,37 +524,6 @@ class Transaction:
self.locktime = locktime self.locktime = locktime
return self return self
@classmethod
def sweep(klass, privkeys, network, to_address, fee):
inputs = []
keypairs = {}
for privkey in privkeys:
pubkey = public_key_from_private_key(privkey)
address = address_from_private_key(privkey)
u = network.synchronous_get(('blockchain.address.listunspent', [address]))
pay_script = klass.pay_script(TYPE_ADDRESS, address)
for item in u:
item['scriptPubKey'] = pay_script
item['redeemPubkey'] = pubkey
item['address'] = address
item['prevout_hash'] = item['tx_hash']
item['prevout_n'] = item['tx_pos']
item['pubkeys'] = [pubkey]
item['x_pubkeys'] = [pubkey]
item['signatures'] = [None]
item['num_sig'] = 1
inputs += u
keypairs[pubkey] = privkey
if not inputs:
return
total = sum(i.get('value') for i in inputs) - fee
outputs = [(TYPE_ADDRESS, to_address, total)]
self = klass.from_io(inputs, outputs)
self.sign(keypairs)
return self
@classmethod @classmethod
def multisig_script(klass, public_keys, m): def multisig_script(klass, public_keys, m):
n = len(public_keys) n = len(public_keys)

35
lib/wallet.py

@ -854,6 +854,41 @@ class Abstract_Wallet(PrintError):
self.sign_transaction(tx, password) self.sign_transaction(tx, password)
return tx return tx
def sweep(self, privkeys, network, config, recipient, fee):
inputs = []
keypairs = {}
for privkey in privkeys:
pubkey = public_key_from_private_key(privkey)
address = address_from_private_key(privkey)
u = network.synchronous_get(('blockchain.address.listunspent', [address]))
pay_script = Transaction.pay_script(TYPE_ADDRESS, address)
for item in u:
item['scriptPubKey'] = pay_script
item['redeemPubkey'] = pubkey
item['address'] = address
item['prevout_hash'] = item['tx_hash']
item['prevout_n'] = item['tx_pos']
item['pubkeys'] = [pubkey]
item['x_pubkeys'] = [pubkey]
item['signatures'] = [None]
item['num_sig'] = 1
inputs += u
keypairs[pubkey] = privkey
if not inputs:
return
total = sum(i.get('value') for i in inputs)
if fee is None:
outputs = [(TYPE_ADDRESS, recipient, total)]
tx = Transaction.from_io(inputs, outputs)
fee = self.estimate_fee(config, tx.estimated_size())
outputs = [(TYPE_ADDRESS, recipient, total - fee)]
tx = Transaction.from_io(inputs, outputs)
tx.sign(keypairs)
return tx
def is_frozen(self, addr): def is_frozen(self, addr):
return addr in self.frozen_addresses return addr in self.frozen_addresses

Loading…
Cancel
Save