File size: 6,804 Bytes
42fc15a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
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