Browse Source

Qt GUI: let users type tx output in script language

283
ThomasV 9 years ago
parent
commit
a07a3f748e
  1. 3
      gui/kivy/main_window.py
  2. 14
      gui/qt/main_window.py
  3. 37
      gui/qt/paytoedit.py
  4. 2
      lib/commands.py
  5. 3
      lib/wallet.py
  6. 3
      plugins/trustedcoin/trustedcoin.py

3
gui/kivy/main_window.py

@ -8,6 +8,7 @@ from decimal import Decimal
import threading import threading
import electrum import electrum
from electrum.bitcoin import TYPE_ADDRESS
from electrum import WalletStorage, Wallet from electrum import WalletStorage, Wallet
from electrum_gui.kivy.i18n import _ from electrum_gui.kivy.i18n import _
from electrum.contacts import Contacts from electrum.contacts import Contacts
@ -563,7 +564,7 @@ class ElectrumWindow(App):
def get_max_amount(self): def get_max_amount(self):
inputs = self.wallet.get_spendable_coins(None) inputs = self.wallet.get_spendable_coins(None)
addr = str(self.send_screen.screen.address) or self.wallet.dummy_address() addr = str(self.send_screen.screen.address) or self.wallet.dummy_address()
amount, fee = self.wallet.get_max_amount(self.electrum_config, inputs, addr, None) amount, fee = self.wallet.get_max_amount(self.electrum_config, inputs, (TYPE_ADDRESS, addr), None)
return format_satoshis_plain(amount, self.decimal_point()) return format_satoshis_plain(amount, self.decimal_point())
def format_amount(self, x, is_diff=False, whitespaces=False): def format_amount(self, x, is_diff=False, whitespaces=False):

14
gui/qt/main_window.py

@ -1022,8 +1022,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
inputs = self.get_coins() inputs = self.get_coins()
sendable = sum(map(lambda x:x['value'], inputs)) sendable = sum(map(lambda x:x['value'], inputs))
fee = self.fee_e.get_amount() if self.fee_e.isModified() else None fee = self.fee_e.get_amount() if self.fee_e.isModified() else None
addr = self.get_payto_or_dummy() r = self.get_payto_or_dummy()
amount, fee = self.wallet.get_max_amount(self.config, inputs, addr, fee) amount, fee = self.wallet.get_max_amount(self.config, inputs, r, fee)
if not self.fee_e.isModified(): if not self.fee_e.isModified():
self.fee_e.setAmount(fee) self.fee_e.setAmount(fee)
self.amount_e.setAmount(amount) self.amount_e.setAmount(amount)
@ -1032,12 +1032,14 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.amount_e.textEdited.emit("") self.amount_e.textEdited.emit("")
self.is_max = True self.is_max = True
def update_fee(self): def update_fee(self):
self.require_fee_update = True self.require_fee_update = True
def get_payto_or_dummy(self): def get_payto_or_dummy(self):
return self.payto_e.payto_address if self.payto_e.payto_address else self.wallet.dummy_address() r = self.payto_e.get_recipient()
if r:
return r
return (TYPE_ADDRESS, self.wallet.dummy_address())
def do_update_fee(self): def do_update_fee(self):
'''Recalculate the fee. If the fee was manually input, retain it, but '''Recalculate the fee. If the fee was manually input, retain it, but
@ -1054,8 +1056,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
fee = self.fee_e.get_amount() if freeze_fee else None fee = self.fee_e.get_amount() if freeze_fee else None
outputs = self.payto_e.get_outputs() outputs = self.payto_e.get_outputs()
if not outputs: if not outputs:
addr = self.get_payto_or_dummy() _type, addr = self.get_payto_or_dummy()
outputs = [(TYPE_ADDRESS, addr, amount)] outputs = [(_type, addr, amount)]
try: try:
tx = self.wallet.make_unsigned_transaction(self.get_coins(), outputs, self.config, fee) tx = self.wallet.make_unsigned_transaction(self.get_coins(), outputs, self.config, fee)
self.not_enough_funds = False self.not_enough_funds = False

37
gui/qt/paytoedit.py

@ -80,15 +80,28 @@ class PayToEdit(ScanQRTextEdit):
def parse_address_and_amount(self, line): def parse_address_and_amount(self, line):
x, y = line.split(',') x, y = line.split(',')
n = re.match('^SCRIPT\s+([0-9a-fA-F]+)$', x.strip()) out_type, out = self.parse_output(x)
if n: amount = self.parse_amount(y)
script = str(n.group(1)).decode('hex') return out_type, out, amount
amount = self.parse_amount(y)
return bitcoin.TYPE_SCRIPT, script, amount def parse_output(self, x):
else: try:
address = self.parse_address(x) address = self.parse_address(x)
amount = self.parse_amount(y) return bitcoin.TYPE_ADDRESS, address
return bitcoin.TYPE_ADDRESS, address, amount except:
script = self.parse_script(x)
return bitcoin.TYPE_SCRIPT, script
def parse_script(self, x):
from electrum.transaction import opcodes, push_script
script = ''
for word in x.split():
if word[0:3] == 'OP_':
assert word in opcodes.lookup
script += chr(opcodes.lookup[word])
else:
script += push_script(word).decode('hex')
return script
def parse_amount(self, x): def parse_amount(self, x):
p = pow(10, self.amount_edit.decimal_point()) p = pow(10, self.amount_edit.decimal_point())
@ -116,7 +129,7 @@ class PayToEdit(ScanQRTextEdit):
self.scan_f(data) self.scan_f(data)
return return
try: try:
self.payto_address = self.parse_address(data) self.payto_address = self.parse_output(data)
except: except:
pass pass
if self.payto_address: if self.payto_address:
@ -150,13 +163,17 @@ class PayToEdit(ScanQRTextEdit):
def get_errors(self): def get_errors(self):
return self.errors return self.errors
def get_recipient(self):
return self.payto_address
def get_outputs(self): def get_outputs(self):
if self.payto_address: if self.payto_address:
try: try:
amount = self.amount_edit.get_amount() amount = self.amount_edit.get_amount()
except: except:
amount = None amount = None
self.outputs = [(bitcoin.TYPE_ADDRESS, self.payto_address, amount)] _type, addr = self.payto_address
self.outputs = [(_type, addr, amount)]
return self.outputs[:] return self.outputs[:]

2
lib/commands.py

@ -418,7 +418,7 @@ class Commands:
if amount == '!': if amount == '!':
assert len(outputs) == 1 assert len(outputs) == 1
inputs = self.wallet.get_spendable_coins(domain) inputs = self.wallet.get_spendable_coins(domain)
amount, fee = self.wallet.get_max_amount(self.config, inputs, address, fee) amount, fee = self.wallet.get_max_amount(self.config, inputs, (TYPE_ADDRESS, address), fee)
else: else:
amount = int(COIN*Decimal(amount)) amount = int(COIN*Decimal(amount))
final_outputs.append((TYPE_ADDRESS, address, amount)) final_outputs.append((TYPE_ADDRESS, address, amount))

3
lib/wallet.py

@ -681,7 +681,8 @@ class Abstract_Wallet(PrintError):
if fee is None: if fee is None:
for i in inputs: for i in inputs:
self.add_input_info(i) self.add_input_info(i)
outputs = [(TYPE_ADDRESS, recipient, sendable)] _type, addr = recipient
outputs = [(_type, addr, sendable)]
dummy_tx = Transaction.from_io(inputs, outputs) dummy_tx = Transaction.from_io(inputs, outputs)
fee = self.estimate_fee(config, dummy_tx.estimated_size()) fee = self.estimate_fee(config, dummy_tx.estimated_size())
amount = max(0, sendable - fee) amount = max(0, sendable - fee)

3
plugins/trustedcoin/trustedcoin.py

@ -220,7 +220,8 @@ class Wallet_2fa(Multisig_Wallet):
if xf and sendable >= xf: if xf and sendable >= xf:
billing_address = self.billing_info['billing_address'] billing_address = self.billing_info['billing_address']
sendable -= xf sendable -= xf
outputs = [(TYPE_ADDRESS, recipient, sendable), _type, addr = recipient
outputs = [(_type, addr, sendable),
(TYPE_ADDRESS, billing_address, xf)] (TYPE_ADDRESS, billing_address, xf)]
else: else:
outputs = [(TYPE_ADDRESS, recipient, sendable)] outputs = [(TYPE_ADDRESS, recipient, sendable)]

Loading…
Cancel
Save