ThomasV
11 years ago
9 changed files with 257 additions and 149 deletions
@ -0,0 +1,220 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
# |
||||
|
# Electrum - lightweight Bitcoin client |
||||
|
# Copyright (C) 2012 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 <http://www.gnu.org/licenses/>. |
||||
|
|
||||
|
import sys, time, datetime, re, threading |
||||
|
from electrum.i18n import _, set_language |
||||
|
from electrum.util import print_error, print_msg |
||||
|
import os.path, json, ast, traceback |
||||
|
import shutil |
||||
|
import StringIO |
||||
|
|
||||
|
|
||||
|
try: |
||||
|
import PyQt4 |
||||
|
except: |
||||
|
sys.exit("Error: Could not import PyQt4 on Linux systems, you may try 'sudo apt-get install python-qt4'") |
||||
|
|
||||
|
from PyQt4.QtGui import * |
||||
|
from PyQt4.QtCore import * |
||||
|
import PyQt4.QtCore as QtCore |
||||
|
|
||||
|
from electrum import transaction |
||||
|
|
||||
|
|
||||
|
class TxDialog(QDialog): |
||||
|
|
||||
|
def __init__(self, tx, parent): |
||||
|
self.tx = tx |
||||
|
tx_dict = tx.as_dict() |
||||
|
self.parent = parent |
||||
|
self.wallet = parent.wallet |
||||
|
|
||||
|
QDialog.__init__(self) |
||||
|
self.setMinimumWidth(600) |
||||
|
self.setWindowTitle(_('Transaction')) |
||||
|
self.setModal(1) |
||||
|
|
||||
|
vbox = QVBoxLayout() |
||||
|
self.setLayout(vbox) |
||||
|
|
||||
|
vbox.addWidget(QLabel("Transaction ID:")) |
||||
|
self.tx_hash_e = QLineEdit() |
||||
|
self.tx_hash_e.setReadOnly(True) |
||||
|
vbox.addWidget(self.tx_hash_e) |
||||
|
self.status_label = QLabel() |
||||
|
vbox.addWidget(self.status_label) |
||||
|
|
||||
|
self.date_label = QLabel() |
||||
|
vbox.addWidget(self.date_label) |
||||
|
self.amount_label = QLabel() |
||||
|
vbox.addWidget(self.amount_label) |
||||
|
self.fee_label = QLabel() |
||||
|
vbox.addWidget(self.fee_label) |
||||
|
|
||||
|
self.io = self.io_widget(tx) |
||||
|
vbox.addWidget( self.io ) |
||||
|
|
||||
|
buttons = QHBoxLayout() |
||||
|
vbox.addLayout( buttons ) |
||||
|
|
||||
|
buttons.addStretch(1) |
||||
|
|
||||
|
self.sign_button = b = QPushButton(_("Sign")) |
||||
|
b.clicked.connect(self.sign) |
||||
|
buttons.addWidget(b) |
||||
|
|
||||
|
self.broadcast_button = b = QPushButton(_("Broadcast")) |
||||
|
b.clicked.connect(self.broadcast) |
||||
|
b.hide() |
||||
|
buttons.addWidget(b) |
||||
|
|
||||
|
self.save_button = b = QPushButton(_("Save")) |
||||
|
b.clicked.connect(self.save) |
||||
|
buttons.addWidget(b) |
||||
|
|
||||
|
cancelButton = QPushButton(_("Close")) |
||||
|
cancelButton.clicked.connect(lambda: self.done(0)) |
||||
|
buttons.addWidget(cancelButton) |
||||
|
|
||||
|
self.update() |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
def sign(self): |
||||
|
tx_dict = self.tx.as_dict() |
||||
|
input_info = json.loads(tx_dict["input_info"]) |
||||
|
self.parent.sign_raw_transaction(self.tx, input_info, self) |
||||
|
self.update() |
||||
|
|
||||
|
|
||||
|
def save(self): |
||||
|
fileName = self.parent.getSaveFileName(_("Select where to save your signed transaction"), 'signed_%s.txn' % (self.tx.hash()[0:8]), "*.txn") |
||||
|
if fileName: |
||||
|
with open(fileName, "w+") as f: |
||||
|
f.write(json.dumps(self.tx.as_dict(),indent=4) + '\n') |
||||
|
self.show_message(_("Transaction saved successfully")) |
||||
|
|
||||
|
|
||||
|
def update(self): |
||||
|
tx_hash = self.tx.hash() |
||||
|
|
||||
|
is_relevant, is_mine, v, fee = self.wallet.get_tx_value(self.tx) |
||||
|
|
||||
|
if self.tx.is_complete: |
||||
|
status = "Status: Signed" |
||||
|
self.sign_button.hide() |
||||
|
|
||||
|
if tx_hash in self.wallet.transactions.keys(): |
||||
|
conf, timestamp = self.wallet.verifier.get_confirmations(tx_hash) |
||||
|
if timestamp: |
||||
|
time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] |
||||
|
else: |
||||
|
time_str = 'pending' |
||||
|
status = "Status: %d confirmations"%conf |
||||
|
self.broadcast_button.hide() |
||||
|
else: |
||||
|
time_str = None |
||||
|
conf = 0 |
||||
|
self.broadcast_button.show() |
||||
|
else: |
||||
|
status = "Status: Unsigned" |
||||
|
time_str = None |
||||
|
self.sign_button.show() |
||||
|
self.broadcast_button.hide() |
||||
|
|
||||
|
self.tx_hash_e.setText(tx_hash) |
||||
|
self.status_label.setText(status) |
||||
|
|
||||
|
if time_str is not None: |
||||
|
self.date_label.setText("Date: %s"%time_str) |
||||
|
self.date_label.show() |
||||
|
else: |
||||
|
self.date_label.hide() |
||||
|
|
||||
|
if is_relevant: |
||||
|
if is_mine: |
||||
|
if fee is not None: |
||||
|
self.amount_label.setText("Amount sent: %s"% self.parent.format_amount(v-fee)) |
||||
|
self.fee_label.setText("Transaction fee: %s"% self.parent.format_amount(fee)) |
||||
|
else: |
||||
|
self.amount_label.setText("Amount sent: %s"% self.parent.format_amount(v)) |
||||
|
self.fee_label.setText("Transaction fee: unknown") |
||||
|
else: |
||||
|
self.amount_label.setText("Amount received: %s"% self.parent.format_amount(v)) |
||||
|
else: |
||||
|
self.amount_label.setText("Transaction unrelated to your wallet") |
||||
|
|
||||
|
|
||||
|
|
||||
|
def io_widget(self, tx): |
||||
|
tabs = QTabWidget(self) |
||||
|
|
||||
|
tab1 = QWidget() |
||||
|
grid_ui = QGridLayout(tab1) |
||||
|
grid_ui.setColumnStretch(0,1) |
||||
|
tabs.addTab(tab1, _('Outputs') ) |
||||
|
|
||||
|
tree_widget = QTreeWidget(self) |
||||
|
tree_widget.setColumnCount(2) |
||||
|
tree_widget.setHeaderLabels( [_('Address'), _('Amount')] ) |
||||
|
tree_widget.setColumnWidth(0, 300) |
||||
|
tree_widget.setColumnWidth(1, 50) |
||||
|
|
||||
|
for address, value in tx.outputs: |
||||
|
item = QTreeWidgetItem( [address, "%s" % ( self.parent.format_amount(value))] ) |
||||
|
tree_widget.addTopLevelItem(item) |
||||
|
|
||||
|
tree_widget.setMaximumHeight(100) |
||||
|
|
||||
|
grid_ui.addWidget(tree_widget) |
||||
|
|
||||
|
tab2 = QWidget() |
||||
|
grid_ui = QGridLayout(tab2) |
||||
|
grid_ui.setColumnStretch(0,1) |
||||
|
tabs.addTab(tab2, _('Inputs') ) |
||||
|
|
||||
|
tree_widget = QTreeWidget(self) |
||||
|
tree_widget.setColumnCount(2) |
||||
|
tree_widget.setHeaderLabels( [ _('Address'), _('Previous output')] ) |
||||
|
|
||||
|
for input_line in tx.inputs: |
||||
|
item = QTreeWidgetItem( [ str(input_line["address"]), str(input_line.get("prevout_hash"))] ) |
||||
|
tree_widget.addTopLevelItem(item) |
||||
|
|
||||
|
tree_widget.setMaximumHeight(100) |
||||
|
|
||||
|
grid_ui.addWidget(tree_widget) |
||||
|
return tabs |
||||
|
|
||||
|
|
||||
|
def broadcast(self): |
||||
|
result, result_message = self.wallet.sendtx( self.tx ) |
||||
|
if result: |
||||
|
self.show_message("Transaction successfully sent: %s" % (result_message)) |
||||
|
if dialog: |
||||
|
dialog.done(0) |
||||
|
else: |
||||
|
self.show_message("There was a problem sending your transaction:\n %s" % (result_message)) |
||||
|
|
||||
|
def show_message(self, msg): |
||||
|
QMessageBox.information(self, _('Message'), msg, _('OK')) |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
Loading…
Reference in new issue