Spaces:
Build error
Build error
| import sys | |
| import json | |
| import logging | |
| from PyQt5.QtWidgets import ( | |
| QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, | |
| QLabel, QLineEdit, QPushButton, QTextEdit, QTabWidget, | |
| QTreeWidget, QTreeWidgetItem, QMessageBox | |
| ) | |
| from PyQt5.QtGui import QFont, QIcon | |
| from PyQt5.QtCore import Qt, QThread, pyqtSignal | |
| # Import the P2SH Transaction Debugger | |
| from p2sh_transaction_debugger import P2SHTransactionDebugger | |
| class TransactionDebuggerThread(QThread): | |
| """ | |
| Background thread for processing transaction debugging | |
| to prevent UI freezing | |
| """ | |
| debug_complete = pyqtSignal(dict) | |
| error_occurred = pyqtSignal(str) | |
| def __init__(self, debugger, tx_hash, network): | |
| super().__init__() | |
| self.debugger = debugger | |
| self.tx_hash = tx_hash | |
| self.network = network | |
| def run(self): | |
| try: | |
| # Temporarily switch network if needed | |
| original_network = self.debugger.network | |
| self.debugger.network = self.network | |
| # Debug the transaction | |
| tx_details = self.debugger.debug_p2sh_transaction(self.tx_hash) | |
| # Restore original network | |
| self.debugger.network = original_network | |
| if tx_details: | |
| self.debug_complete.emit(tx_details) | |
| else: | |
| self.error_occurred.emit("Failed to retrieve transaction details") | |
| except Exception as e: | |
| self.error_occurred.emit(str(e)) | |
| class P2SHDebuggerApp(QMainWindow): | |
| def __init__(self): | |
| super().__init__() | |
| self.setWindowTitle("P2SH Transaction Debugger") | |
| self.setGeometry(100, 100, 800, 600) | |
| # Initialize debugger | |
| self.debugger = P2SHTransactionDebugger() | |
| # Setup main UI | |
| self.init_ui() | |
| def init_ui(self): | |
| """ | |
| Create the main user interface | |
| """ | |
| # Central widget and main layout | |
| central_widget = QWidget() | |
| main_layout = QVBoxLayout() | |
| central_widget.setLayout(main_layout) | |
| self.setCentralWidget(central_widget) | |
| # Transaction input section | |
| input_layout = QHBoxLayout() | |
| # Network selection | |
| self.network_input = QLineEdit() | |
| self.network_input.setPlaceholderText("Network (mainnet/testnet)") | |
| self.network_input.setText("mainnet") | |
| input_layout.addWidget(self.network_input) | |
| # Transaction hash input | |
| self.tx_hash_input = QLineEdit() | |
| self.tx_hash_input.setPlaceholderText("Enter Bitcoin Transaction Hash") | |
| input_layout.addWidget(self.tx_hash_input) | |
| # Transaction serialData input | |
| self.tx_data_input = QLineEdit() | |
| self.tx_data_input.setPlaceholderText("Enter Serialized Bitcoin Transaction Data") | |
| input_layout.addWidget(self.tx_data_input) | |
| # Debug button | |
| debug_button = QPushButton("Debug Transaction") | |
| debug_button.clicked.connect(self.start_transaction_debug) | |
| input_layout.addWidget(debug_button) | |
| main_layout.addLayout(input_layout) | |
| # Tabs for different views | |
| self.tabs = QTabWidget() | |
| main_layout.addWidget(self.tabs) | |
| # Create tabs | |
| self.details_tab = QTextEdit() | |
| self.details_tab.setReadOnly(True) | |
| self.tree_tab = QTreeWidget() | |
| self.tree_tab.setHeaderLabel("Transaction Structure") | |
| self.tabs.addTab(self.details_tab, "Detailed View") | |
| self.tabs.addTab(self.tree_tab, "Structured View") | |
| def start_transaction_debug(self): | |
| """ | |
| Initiate transaction debugging process | |
| """ | |
| # Validate inputs | |
| tx_hash = self.tx_hash_input.text().strip() | |
| network = self.network_input.text().strip().lower() | |
| if not tx_hash: | |
| QMessageBox.warning(self, "Input Error", "Please enter a transaction hash") | |
| return | |
| if network not in ['mainnet', 'testnet']: | |
| QMessageBox.warning(self, "Network Error", "Invalid network. Use 'mainnet' or 'testnet'") | |
| return | |
| # Clear previous results | |
| self.details_tab.clear() | |
| self.tree_tab.clear() | |
| # Start debugging thread | |
| self.debug_thread = TransactionDebuggerThread( | |
| self.debugger, | |
| tx_hash, | |
| network | |
| ) | |
| self.debug_thread.debug_complete.connect(self.display_debug_results) | |
| self.debug_thread.error_occurred.connect(self.handle_debug_error) | |
| self.debug_thread.start() | |
| def display_debug_results(self, results): | |
| """ | |
| Display debugging results in both tabs | |
| """ | |
| # Detailed Text View | |
| self.details_tab.setPlainText( | |
| json.dumps(results, indent=2) | |
| ) | |
| # Structured Tree View | |
| self._populate_tree_view(results) | |
| def _populate_tree_view(self, results): | |
| """ | |
| Populate the tree view with transaction details | |
| """ | |
| self.tree_tab.clear() | |
| # Transaction hash root item | |
| root = QTreeWidgetItem(self.tree_tab, | |
| [f"Transaction: {results.get('transaction_hash', 'N/A')}"]) | |
| # Inputs section | |
| inputs_item = QTreeWidgetItem(root, ["Inputs"]) | |
| for idx, input_data in enumerate(results.get('inputs', [])): | |
| input_item = QTreeWidgetItem(inputs_item, [f"Input {idx+1}"]) | |
| for key, value in input_data.items(): | |
| QTreeWidgetItem(input_item, [f"{key}: {str(value)}"]) | |
| # Outputs section | |
| outputs_item = QTreeWidgetItem(root, ["Outputs"]) | |
| for idx, output_data in enumerate(results.get('outputs', [])): | |
| output_item = QTreeWidgetItem(outputs_item, [f"Output {idx+1}"]) | |
| for key, value in output_data.items(): | |
| QTreeWidgetItem(output_item, [f"{key}: {str(value)}"]) | |
| self.tree_tab.expandAll() | |
| def handle_debug_error(self, error_message): | |
| """ | |
| Handle errors during debugging process | |
| """ | |
| QMessageBox.critical( | |
| self, | |
| "Debugging Error", | |
| f"An error occurred: {error_message}" | |
| ) | |
| def main(): | |
| """ | |
| Main application entry point | |
| """ | |
| # Configure logging | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format='%(asctime)s - %(levelname)s - %(message)s' | |
| ) | |
| # Create application | |
| app = QApplication(sys.argv) | |
| # Set application style | |
| app.setStyle('Fusion') # Modern, cross-platform style | |
| # Create and show main window | |
| debugger_app = P2SHDebuggerApp() | |
| debugger_app.show() | |
| # Execute the application | |
| sys.exit(app.exec_()) | |
| if __name__ == "__main__": | |
| main() | |
| # Required dependencies: | |
| # pip install PyQt5 requests base58 |