URI: 
       tcode refactoring; remove redundancies and sanitize transactions read from file or text - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit dfb1bd120315091d9dbefae227fb6295c1e3901c
   DIR parent 5aa18c4bb5ea406e784d023272522bee4f09cf6d
  HTML Author: thomasv <thomasv@gitorious>
       Date:   Thu, 28 Feb 2013 11:16:07 +0100
       
       code refactoring; remove redundancies and sanitize transactions read from file or text
       
       Diffstat:
         M lib/gui_qt.py                       |     187 +++++++++++++++++--------------
       
       1 file changed, 100 insertions(+), 87 deletions(-)
       ---
   DIR diff --git a/lib/gui_qt.py b/lib/gui_qt.py
       t@@ -1751,23 +1751,21 @@ class ElectrumWindow(QMainWindow):
        
                return seed, gap
        
       -    def generate_transaction_information_widget(self,layout, decoded_tx):
       +    def generate_transaction_information_widget(self, tx):
                tabs = QTabWidget(self)
       -        layout.addWidget(tabs)
        
                tab1 = QWidget()
                grid_ui = QGridLayout(tab1)
                grid_ui.setColumnStretch(0,1)
                tabs.addTab(tab1, _('Outputs') )
        
       -        
                tree_widget = MyTreeWidget(self)
                tree_widget.setColumnCount(2)
                tree_widget.setHeaderLabels( [_('Address'), _('Amount')] )
                tree_widget.setColumnWidth(0, 300)
                tree_widget.setColumnWidth(1, 50)
        
       -        for output in decoded_tx["outputs"]:
       +        for output in tx.d["outputs"]:
                    item = QTreeWidgetItem( ["%s" %(output["address"]), "%s" % ( format_satoshis(output["value"]))] )
                    tree_widget.addTopLevelItem(item)
        
       t@@ -1775,141 +1773,155 @@ class ElectrumWindow(QMainWindow):
        
                grid_ui.addWidget(tree_widget)
        
       -
                tab2 = QWidget()
                grid_ui = QGridLayout(tab2)
                grid_ui.setColumnStretch(0,1)
                tabs.addTab(tab2, _('Inputs') )
       -
                
                tree_widget = MyTreeWidget(self)
                tree_widget.setColumnCount(2)
                tree_widget.setHeaderLabels( [_('Sequence'), _('Address'), _('Previous output')] )
        
       -        for input_line in decoded_tx["inputs"]:
       +        for input_line in tx.d["inputs"]:
                    item = QTreeWidgetItem( [str(input_line["sequence"]), str(input_line["address"]), str(input_line["prevout_hash"])] )
                    tree_widget.addTopLevelItem(item)
        
                tree_widget.setMaximumHeight(100)
        
                grid_ui.addWidget(tree_widget)
       +        return tabs
        
        
       -    def sign_raw_transaction(self):
       -      input_info = json.loads(self.raw_tx["input_info"])
       -      tx = Transaction(self.raw_tx["hex"])
       +    def tx_dict_from_text(self, txt):
       +        try:
       +            tx_dict = json.loads(str(txt))
       +            assert "hex" in tx_dict.keys()
       +            assert "complete" in tx_dict.keys()
       +            if not tx_dict["complete"]:
       +                assert "input_info" in tx_dict.keys()
       +        except:
       +            QMessageBox.critical(None, "Unable to parse transaction", _("Electrum was unable to parse your transaction:"))
       +            return None
       +        return tx_dict
        
       -      if self.wallet.use_encryption:
       -          password = self.password_dialog()
       -          if not password:
       -              return
       -      else:
       -          password = None
        
       -      try:
       -          self.wallet.signrawtransaction(tx, input_info, [], password)
       +    def read_tx_from_file(self):
       +        fileName = QFileDialog.getOpenFileName(QWidget(), _("Select your transaction file"), os.path.expanduser('~'))
       +        if not fileName:
       +            return
       +        try:
       +            with open(fileName, "r") as f:
       +                file_content = f.read()
       +        except (ValueError, IOError, os.error), reason:
       +            QMessageBox.critical(None,"Unable to read file or no transaction found", _("Electrum was unable to open your transaction file") + "\n" + str(reason))
        
       -          fileName = QFileDialog.getSaveFileName(QWidget(), _("Select where to save your signed transaction"), os.path.expanduser('~/signed_tx_%s' % (tx.hash()[0:8])))
       -          if fileName:
       -              with open(fileName, "w+") as f:
       -                  f.write(json.dumps(tx.as_dict(),indent=4) + '\n')
       -              self.show_message(_("Transaction saved succesfully"))
       -      except BaseException, e:
       -        self.show_message(str(e))
       -        return
       +        return self.tx_dict_from_text(file_content)
        
       -    def create_sign_transaction_window(self, tx):
       -        decoded_tx = Transaction(tx["hex"])
       -        decoded_tx = decoded_tx.deserialize()
       -        self.raw_tx = tx
       +
       +    def sign_raw_transaction(self, tx, input_info):
       +        if self.wallet.use_encryption:
       +            password = self.password_dialog()
       +            if not password:
       +                return
       +        else:
       +            password = None
       +
       +        try:
       +            self.wallet.signrawtransaction(tx, input_info, [], password)
       +            
       +            fileName = QFileDialog.getSaveFileName(QWidget(), _("Select where to save your signed transaction"), os.path.expanduser('~/signed_tx_%s' % (tx.hash()[0:8])))
       +            if fileName:
       +                with open(fileName, "w+") as f:
       +                    f.write(json.dumps(tx.as_dict(),indent=4) + '\n')
       +                self.show_message(_("Transaction saved succesfully"))
       +        except BaseException, e:
       +            self.show_message(str(e))
       +
       +
       +    def create_sign_transaction_window(self, tx_dict):
       +        tx = Transaction(tx_dict["hex"])
        
                dialog = QDialog(self)
                dialog.setMinimumWidth(500)
                dialog.setWindowTitle(_('Sign unsigned transaction'))
                dialog.setModal(1)
        
       -        vbox = QGridLayout()
       +        vbox = QVBoxLayout()
                dialog.setLayout(vbox)
       -        tx_information_widget = self.generate_transaction_information_widget(vbox, decoded_tx)
       +        vbox.addWidget( self.generate_transaction_information_widget(tx) )
        
       -        if tx["complete"] == True:
       +        if tx_dict["complete"] == True:
                    vbox.addWidget(QLabel(_("This transaction is already signed.")))
                else:
       -            vbox.addWidget(EnterButton(_("Sign this transaction"), self.sign_raw_transaction))
       +            vbox.addWidget(QLabel(_("Create a signed transaction.")))
       +            vbox.addLayout(ok_cancel_buttons(dialog))
       +            input_info = json.loads(tx_dict["input_info"])
        
       -        if not dialog.exec_(): return
       +        if dialog.exec_():
       +            self.sign_raw_transaction(tx, input_info)
        
       -    def do_sign_from_text(self):
       -        tx, ok = QInputDialog.getText(QTextEdit(), _('Sign raw transaction'), _('Transaction data in JSON') + ':')
        
       -        try:
       -          tx = json.loads(unicode(tx))
       -        except (ValueError, IOError, os.error), reason:
       -          QMessageBox.critical(None,"Unable to read transaction", _("Electrum was unable to read your transaction:") + "\n" + str(reason))
        
       -        self.create_sign_transaction_window(tx)
       +    def do_sign_from_text(self):
       +        txt, ok = QInputDialog.getText(QTextEdit(), _('Sign raw transaction'), _('Transaction data in JSON') + ':')
       +        if not ok:
       +            return
       +        tx_dict = self.tx_dict_from_text(unicode(txt))
       +        if tx_dict:
       +            self.create_sign_transaction_window(tx_dict)
        
       -    def do_sign_from_file(self):
       -        try:
       -            fileName = QFileDialog.getOpenFileName(QWidget(), _("Select your transaction file"), os.path.expanduser('~'))
       -            if fileName:
       -                with open(fileName, "r") as transaction_file:
       -                    tx = json.loads(transaction_file.read())
       -                    self.create_sign_transaction_window(tx)
        
       -        except (ValueError, IOError, os.error), reason:
       -            QMessageBox.critical(None,"Unable to read file or no transaction found", _("Electrum was unable to read your transaction file") + "\n" + str(reason))
       +    def do_sign_from_file(self):
       +        tx_dict = self.read_tx_from_file()
       +        if tx_dict:
       +            self.create_sign_transaction_window(tx_dict)
            
       -    def send_raw_transaction(self):
       -        tx = Transaction(self.raw_tx["hex"])
       -        result, result_message = self.wallet.sendtx( tx )
       +
       +    def send_raw_transaction(self, raw_tx):
       +        print "sending", raw_tx
       +        #result, result_message = self.wallet.sendtx( raw_tx )
                if result:
                    self.show_message("Transaction succesfully sent: %s" % (result_message))
                else:
                    self.show_message("There was a problem sending your transaction:\n %s" % (result_message))
        
       -    def create_send_transaction_window(self, tx):
       -        decoded_tx = Transaction(tx["hex"])
       -        decoded_tx = decoded_tx.deserialize()
       -        self.raw_tx = tx
       +
       +    def create_send_transaction_window(self, tx_dict):
       +        tx = Transaction(tx_dict["hex"])
        
                dialog = QDialog(self)
                dialog.setMinimumWidth(500)
                dialog.setWindowTitle(_('Send raw transaction'))
                dialog.setModal(1)
        
       -        vbox = QGridLayout()
       +        vbox = QVBoxLayout()
                dialog.setLayout(vbox)
       -        tx_information_widget = self.generate_transaction_information_widget(vbox, decoded_tx)
       +        vbox.addWidget( self.generate_transaction_information_widget(tx))
        
       -        if tx["complete"] == False:
       +        if tx_dict["complete"] == False:
                    vbox.addWidget(QLabel(_("This transaction is not signed yet.")))
                else:
       -            vbox.addWidget(EnterButton(_("Send this transaction"), self.send_raw_transaction))
       +            vbox.addWidget(QLabel(_("Broadcast this transaction")))
       +            vbox.addLayout(ok_cancel_buttons(dialog))
        
       -        if not dialog.exec_(): return
       +        if dialog.exec_():
       +            self.send_raw_transaction(tx_dict["hex"])
        
       -    def do_send_from_file(self):
       -        try:
       -            fileName = QFileDialog.getOpenFileName(QWidget(), _("Select your transaction file"), os.path.expanduser('~'))
       -            if fileName:
       -                with open(fileName, "r") as transaction_file:
       -                    file_content = transaction_file.read()
       -                    tx = json.loads(str(file_content))
       -                    self.create_send_transaction_window(tx)
        
       -        except (ValueError, IOError, os.error), reason:
       -            QMessageBox.critical(None,"Unable to read file or no transaction found", _("Electrum was unable to read your transaction file") + "\n" + str(reason))
       +    def do_send_from_file(self):
       +        tx_dict = self.read_tx_from_file()
       +        if tx_dict: 
       +            self.create_send_transaction_window(tx_dict)
       +        
        
            def do_send_from_text(self):
       -        tx, ok = QInputDialog.getText(QTextEdit(), _('Send raw transaction'), _('Transaction data in JSON') + ':')
       -
       -        try:
       -          tx = json.loads(unicode(tx))
       -        except (ValueError, IOError, os.error), reason:
       -          QMessageBox.critical(None,"Unable to read transaction", _("Electrum was unable to read your transaction:") + "\n" + str(reason))
       +        txt, ok = QInputDialog.getText(QTextEdit(), _('Send raw transaction'), _('Transaction data in JSON') + ':')
       +        if not ok:
       +            return
       +        tx_dict = self.tx_dict_from_text(unicode(txt))
       +        if tx_dict:
       +            self.create_send_transaction_window(tx_dict)
        
       -        self.create_send_transaction_window(tx)
        
            def do_export_privkeys(self):
                self.show_message("%s\n%s\n%s" % (_("WARNING: ALL your private keys are secret."),  _("Exposing a single private key can compromise your entire wallet!"), _("In particular, DO NOT use 'redeem private key' services proposed by third parties.")))
       t@@ -2155,15 +2167,16 @@ class ElectrumWindow(QMainWindow):
                #grid_raw.addWidget(EnterButton(_("From text"), self.do_sign_from_text),3,2)
                #grid_raw.addWidget(HelpButton(_("This will show you some useful information about an unsigned transaction")),3,3)
        
       -        grid_raw.addWidget(QLabel(_("Send raw transaction")), 2, 0)
       +        if self.wallet.seed:
       +            grid_raw.addWidget(QLabel(_("Sign transaction")), 1, 0)
       +            grid_raw.addWidget(EnterButton(_("From file"), self.do_sign_from_file),1,1)
       +            grid_raw.addWidget(EnterButton(_("From text"), self.do_sign_from_text),1,2)
       +            grid_raw.addWidget(HelpButton(_("Sign an unsigned transaction generated by a watching-only wallet")),1,3)
       +
       +        grid_raw.addWidget(QLabel(_("Send signed transaction")), 2, 0)
                grid_raw.addWidget(EnterButton(_("From file"), self.do_send_from_file),2,1)
                grid_raw.addWidget(EnterButton(_("From text"), self.do_send_from_text),2,2)
       -        grid_raw.addWidget(HelpButton(_("This will send a transaction.")),2,3)
       -
       -        grid_raw.addWidget(QLabel(_("Sign transaction")), 1, 0)
       -        grid_raw.addWidget(EnterButton(_("From file"), self.do_sign_from_file),1,1)
       -        grid_raw.addWidget(EnterButton(_("From text"), self.do_sign_from_text),1,2)
       -        grid_raw.addWidget(HelpButton(_("This will sign an previously unsigned transaction")),1,3)
       +        grid_raw.addWidget(HelpButton(_("This will broadcast a transaction to the network.")),2,3)
        
                vbox.addLayout(ok_cancel_buttons(d))
                d.setLayout(vbox)