コード例 #1
0
ファイル: tx_builder.py プロジェクト: Christewart/hashmal
class InputsEditor(BaseEditor):
    def __init__(self, main_window, tree, parent=None):
        super(InputsEditor, self).__init__(tree, parent)
        self.prev_tx = QLineEdit()
        self.prev_tx.setToolTip('Transaction ID of the tx with the output being spent')
        self.prev_tx.setWhatsThis('Use this field to specify the transaction that contains the output you\'re spending.')

        self.prev_vout = AmountEdit()
        self.prev_vout.setToolTip('Output index of the previous transaction')
        self.prev_vout.setWhatsThis('Use this field to specify the output you are spending of the previous transaction.')

        self.script = ScriptEditor(main_window)
        self.script.setToolTip('Script that will be put on the stack before the previous output\'s script.')
        self.script.setWhatsThis('Enter a script here. This script will be evaluated directly before the script of the output you are spending. Any values that are pushed onto the stack when this script finishes its execution are present when the output script is evaluated afterward.')

        self.sequence = AmountEdit()
        self.sequence.setText('4294967295')
        self.sequence.setWhatsThis('Use this field to specify the sequence value. It\'s likely that you should leave this as its default (maximum) value.')
        maxify_input_sequence = QPushButton('Max')
        maxify_input_sequence.clicked.connect(lambda: self.sequence.setText('0xffffffff'))
        maxify_input_sequence.setWhatsThis('This button will set the sequence to its default value.')

        for i in [self.prev_tx, self.prev_vout, self.script, self.sequence]:
            i.setFont(monospace_font)

        self.mapper.addMapping(self.prev_tx, 0)
        self.mapper.addMapping(self.prev_vout, 1, 'amount')
        self.mapper.addMapping(self.script, 2, 'humanText')
        self.mapper.addMapping(self.sequence, 3, 'amount')

        delete_button = QPushButton('Remove Input')
        delete_button.setToolTip('Remove this input from the transaction')
        delete_button.clicked.connect(self.do_delete)
        submit_button = QPushButton('Save')
        submit_button.setToolTip('Update input with the above data')
        submit_button.clicked.connect(self.do_submit)

        form = QFormLayout()
        form.setContentsMargins(0, 0, 0, 0)
        form.addRow('Previous Transaction: ', self.prev_tx)
        form.addRow('Previous Tx Output: ', self.prev_vout)
        form.addRow('Input script: ', self.script)
        seq_desc = QLabel('Sequence is mostly deprecated.\nIf an input has a sequence that\'s not the maximum value, the transaction\'s locktime will apply.')
        seq_desc.setWordWrap(True)
        form.addRow(seq_desc)
        form.addRow('Sequence: ', HBox(self.sequence, maxify_input_sequence))
        form.addRow(floated_buttons([delete_button, submit_button]))

        self.setLayout(form)
コード例 #2
0
ファイル: tx_builder.py プロジェクト: aesedepece/hashmal
class InputsEditor(BaseEditor):
    def __init__(self, main_window, tree, parent=None):
        super(InputsEditor, self).__init__(tree, parent)
        self.prev_tx = QLineEdit()
        self.prev_tx.setToolTip("Transaction ID of the tx with the output being spent")

        self.prev_vout = AmountEdit()
        self.prev_vout.setToolTip("Output index of the previous transaction")

        self.script = ScriptEditor(main_window)
        self.script.setToolTip("Script that will be put on the stack before the previous output's script.")

        self.sequence = AmountEdit()
        self.sequence.setText("4294967295")
        maxify_input_sequence = QPushButton("Max")
        maxify_input_sequence.clicked.connect(lambda: self.sequence.setText("0xffffffff"))

        for i in [self.prev_tx, self.prev_vout, self.script, self.sequence]:
            i.setFont(monospace_font)

        self.mapper.addMapping(self.prev_tx, 0)
        self.mapper.addMapping(self.prev_vout, 1, "amount")
        self.mapper.addMapping(self.script, 2, "humanText")
        self.mapper.addMapping(self.sequence, 3, "amount")

        delete_button = QPushButton("Remove Input")
        delete_button.setToolTip("Remove this input from the transaction")
        delete_button.clicked.connect(self.do_delete)
        submit_button = QPushButton("Save")
        submit_button.setToolTip("Update input with the above data")
        submit_button.clicked.connect(self.do_submit)

        form = QFormLayout()
        form.setContentsMargins(0, 0, 0, 0)
        form.addRow("Previous Transaction: ", self.prev_tx)
        form.addRow("Previous Tx Output: ", self.prev_vout)
        form.addRow("Input script: ", self.script)
        seq_desc = QLabel(
            "Sequence is mostly deprecated.\nIf an input has a sequence that's not the maximum value, the transaction's locktime will apply."
        )
        seq_desc.setWordWrap(True)
        form.addRow(seq_desc)
        form.addRow("Sequence: ", HBox(self.sequence, maxify_input_sequence))
        form.addRow(floated_buttons([delete_button, submit_button]))

        self.setLayout(form)
コード例 #3
0
ファイル: tx_builder.py プロジェクト: aesedepece/hashmal
class InputsEditor(BaseEditor):
    def __init__(self, main_window, tree, parent=None):
        super(InputsEditor, self).__init__(tree, parent)
        self.prev_tx = QLineEdit()
        self.prev_tx.setToolTip('Transaction ID of the tx with the output being spent')

        self.prev_vout = AmountEdit()
        self.prev_vout.setToolTip('Output index of the previous transaction')

        self.script = ScriptEditor(main_window)
        self.script.setToolTip('Script that will be put on the stack before the previous output\'s script.')

        self.sequence = AmountEdit()
        self.sequence.setText('4294967295')
        maxify_input_sequence = QPushButton('Max')
        maxify_input_sequence.clicked.connect(lambda: self.sequence.setText('0xffffffff'))

        for i in [self.prev_tx, self.prev_vout, self.script, self.sequence]:
            i.setFont(monospace_font)

        self.mapper.addMapping(self.prev_tx, 0)
        self.mapper.addMapping(self.prev_vout, 1, 'amount')
        self.mapper.addMapping(self.script, 2, 'humanText')
        self.mapper.addMapping(self.sequence, 3, 'amount')

        delete_button = QPushButton('Remove Input')
        delete_button.setToolTip('Remove this input from the transaction')
        delete_button.clicked.connect(self.do_delete)
        submit_button = QPushButton('Save')
        submit_button.setToolTip('Update input with the above data')
        submit_button.clicked.connect(self.do_submit)

        form = QFormLayout()
        form.setContentsMargins(0, 0, 0, 0)
        form.addRow('Previous Transaction: ', self.prev_tx)
        form.addRow('Previous Tx Output: ', self.prev_vout)
        form.addRow('Input script: ', self.script)
        seq_desc = QLabel('Sequence is mostly deprecated.\nIf an input has a sequence that\'s not the maximum value, the transaction\'s locktime will apply.')
        seq_desc.setWordWrap(True)
        form.addRow(seq_desc)
        form.addRow('Sequence: ', HBox(self.sequence, maxify_input_sequence))
        form.addRow(floated_buttons([delete_button, submit_button]))

        self.setLayout(form)
コード例 #4
0
ファイル: stack.py プロジェクト: zerocoolteam/hashmal
class StackEval(BaseDock):

    tool_name = 'Stack Evaluator'
    description = '\n'.join([
            'Stack Evaluator steps through scripts, showing you what\'s happening as it happens.',
            '<b>Please read this warning from the source of python-bitcoinlib, which Stack Evaluator uses to evaluate scripts:</b>',
            '"Be warned that there are highly likely to be consensus bugs in this code; it is unlikely to match Satoshi Bitcoin exactly. Think carefully before using this module."'
    ])
    is_large = True
    category = Category.Script

    def __init__(self, handler):
        super(StackEval, self).__init__(handler)
        self.widget().setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)

    @augmenter
    def item_actions(self, *args):
        return ItemAction(self.tool_name, 'Transaction', 'Set as spending transaction', self.set_spending_item)

    def init_data(self):
        self.tx = None
        self.inIdx = 0
        self.execution = ScriptExecution()

    def reset(self):
        self.tx_script.clear()
        self.clear_execution()

    def clear_execution(self):
        self.execution_widget.clear()
        for i in [self.script_passed, self.script_verified]:
            i.setChecked(False)
            i.setProperty('hasSuccess', False)
            self.style().polish(i)

    def create_layout(self):
        vbox = QVBoxLayout()

        tabs = QTabWidget()
        tabs.addTab(self.create_main_tab(), 'Stack')
        tabs.addTab(self.create_tx_tab(), 'Transaction')
        tabs.addTab(self.create_block_tab(), 'Block')
        self.setFocusProxy(tabs)
        vbox.addWidget(tabs)

        return vbox

    def create_main_tab(self):
        self.execution_widget = ScriptExecutionWidget(self.execution)
        # For variable substitution
        self.execution_widget.model.plugin_handler = self.handler

        self.execution_delegate = ScriptExecutionDelegate()
        self.execution_widget.view.setItemDelegate(self.execution_delegate)

        # Raw script input.
        self.tx_script = QPlainTextEdit()
        self.tx_script.setWhatsThis('Enter a raw script here to evaluate it.')
        self.tx_script.setFont(monospace_font)
        self.tx_script.setTabChangesFocus(True)

        self.clear_button = QPushButton('Clear')
        self.clear_button.setToolTip('Clear the current script.')
        self.clear_button.clicked.connect(self.reset)
        self.do_button = QPushButton('&Evaluate')
        self.do_button.setToolTip('Evaluate the entire script.')
        self.do_button.clicked.connect(self.do_evaluate)
        btn_hbox = floated_buttons([self.clear_button, self.do_button], left=True)

        vbox = QVBoxLayout()
        vbox.addWidget(QLabel('Script:'))
        vbox.addWidget(self.tx_script)
        vbox.addLayout(btn_hbox)
        vbox.addWidget(self.execution_widget, stretch=1)

        self.next_button = QPushButton('Next')
        self.next_button.setToolTip('Step forward in script execution.')
        self.next_button.clicked.connect(self.execution_widget.select_next)
        self.prev_button = QPushButton('Previous')
        self.prev_button.setToolTip('Step backward in script execution.')
        self.prev_button.clicked.connect(self.execution_widget.select_prev)

        controls_hbox = floated_buttons([self.prev_button, self.next_button], left=True)
        vbox.addLayout(controls_hbox)

        self.script_passed = ReadOnlyCheckBox('Passed')
        self.script_passed.setToolTip('Whether the script passed')
        self.script_passed.setWhatsThis('This box is checked if the script finished with a nonzero top stack value.')
        self.script_verified = ReadOnlyCheckBox('Verified')
        self.script_verified.setToolTip('Whether the script was verified with an input script')
        self.script_verified.setWhatsThis('This box is checked if the script was verified with a transaction\'s input script.')
        pass_hbox = HBox(QLabel('Script: '), self.script_passed, self.script_verified)
        pass_hbox.addStretch(1)
        vbox.addLayout(pass_hbox)

        w = QWidget()
        w.setLayout(vbox)
        return w

    def create_tx_tab(self):
        form = QFormLayout()

        # Spending transaction
        self.tx_edit = QPlainTextEdit()
        self.tx_edit.setWhatsThis('Enter a serialized transaction here. If you have a raw transaction stored in the Variables tool, you can enter the variable name preceded by a "$", and the variable value will be substituted automatically.')
        self.tx_edit.setFont(monospace_font)
        self.tx_edit.textChanged.connect(self.set_tx)
        self.handler.substitute_variables(self.tx_edit)
        self.tx_edit.setTabChangesFocus(True)
        # Input with scriptSig to include
        self.input_idx = QSpinBox()
        self.input_idx.setEnabled(False)
        self.input_idx.valueChanged.connect(self.set_input_index)
        self.input_idx.setToolTip('Input in the containing transaction with the relevant scriptSig.')
        self.input_idx.setWhatsThis('Use this to specify the input you want to simulate.')
        in_idx_box = QHBoxLayout()
        in_idx_box.addWidget(QLabel('Input containing scriptSig:'))
        in_idx_box.addWidget(self.input_idx)
        in_idx_box.addStretch(1)


        desc = QLabel(' '.join(['You can specify the transaction that contains the script you\'re testing.',
                        'This allows you to evaluate whether an input spends successfully.']))
        desc.setWordWrap(True)
        form.addRow(desc)
        form.addRow('Raw Transaction:', self.tx_edit)
        form.addRow('Spending Input:', self.input_idx)

        w = QWidget()
        w.setLayout(form)
        return w

    def create_block_tab(self):
        form = QFormLayout()

        desc = QLabel(''.join(['For most purposes, this tab can be ignored.\n\n'
                        'You can simulate the block that contains the script you\'re testing. ',
                        'This allows you to use certain opcodes like CHECKLOCKTIMEVERIFY, which require ',
                        'data about the block a transaction is in.']))
        desc.setWordWrap(True)
        form.addRow(desc)

        self.block_height_edit = AmountEdit()
        self.block_height_edit.setToolTip('Height of the block your script is in')
        self.block_height_edit.setWhatsThis('Use this to simulate the height of the block that your script is in.')

        self.block_time_edit = AmountEdit()
        self.block_time_edit.setToolTip('Timestamp of the block your script is in')
        self.block_time_edit.setWhatsThis('Use this to simulate the timestamp of the block that your script is in.')

        form.addRow('Block height:', self.block_height_edit)
        form.addRow('Block time:', self.block_time_edit)

        w = QWidget()
        w.setLayout(form)
        return w

    def set_spending_item(self, item):
        """Called from other tools to set the spending transaction."""
        self.needsFocus.emit()
        self.tx_edit.setPlainText(item.raw())

    def set_tx(self):
        """Set the spending transaction and (en|dis)able the input index box."""
        txt = str(self.tx_edit.toPlainText())
        # Variable substition
        if txt.startswith('$'):
                return
        try:
            assert txt
            self.tx = Transaction.deserialize(txt.decode('hex'))
            self.tx_edit.setToolTip(''.join(['Tx ID: ', bitcoin.core.b2lx(self.tx.GetHash())]))
            self.input_idx.setRange(0, len(self.tx.vin) - 1)
            self.input_idx.setEnabled(True)
        except Exception:
            self.tx = None
            self.tx_edit.setToolTip('')
            self.input_idx.setEnabled(False)

    def set_input_index(self, idx):
        self.inIdx = idx

    def evaluate_script(self, s):
        """Called by Plugin Handler to evaluate the current script."""
        self.needsFocus.emit()
        self.tx_script.setPlainText(s)
        self.do_button.animateClick()

    def do_evaluate(self):
        self.clear_execution()
        try:
            scr = Script(str(self.tx_script.toPlainText()).decode('hex'))
        except Exception as e:
            self.error('Error decoding script: %s' % str(e))
            return
        exec_data = None
        if not self.block_height_edit.property('hasError').toBool() and not self.block_time_edit.property('hasError').toBool():
            exec_data = ExecutionData(self.block_height_edit.get_amount(), self.block_time_edit.get_amount())
        self.execution_widget.evaluate(scr, self.tx, self.inIdx, execution_data=exec_data)
        passed = True if self.execution_widget.execution.script_passed else False
        verified = self.execution_widget.execution.script_verified
        self.script_passed.setChecked(passed)
        self.script_verified.setChecked(verified)
        for widget in [self.script_passed, self.script_verified]:
            widget.setProperty('hasSuccess', widget.isChecked())
            self.style().polish(widget)
コード例 #5
0
ファイル: tx_builder.py プロジェクト: zerocoolteam/hashmal
class InputsEditor(BaseEditor):
    def __init__(self, main_window, tree, parent=None):
        super(InputsEditor, self).__init__(tree, parent)
        self.prev_tx = QLineEdit()
        self.prev_tx.setToolTip(
            'Transaction ID of the tx with the output being spent')
        self.prev_tx.setWhatsThis(
            'Use this field to specify the transaction that contains the output you\'re spending.'
        )

        self.prev_vout = AmountEdit()
        self.prev_vout.setToolTip('Output index of the previous transaction')
        self.prev_vout.setWhatsThis(
            'Use this field to specify the output you are spending of the previous transaction.'
        )

        self.script = ScriptEditor(main_window)
        self.script.setToolTip(
            'Script that will be put on the stack before the previous output\'s script.'
        )
        self.script.setWhatsThis(
            'Enter a script here. This script will be evaluated directly before the script of the output you are spending. Any values that are pushed onto the stack when this script finishes its execution are present when the output script is evaluated afterward.'
        )

        self.sequence = AmountEdit()
        self.sequence.setText('4294967295')
        self.sequence.setWhatsThis(
            'Use this field to specify the sequence value. It\'s likely that you should leave this as its default (maximum) value.'
        )
        maxify_input_sequence = QPushButton('Max')
        maxify_input_sequence.clicked.connect(
            lambda: self.sequence.setText('0xffffffff'))
        maxify_input_sequence.setWhatsThis(
            'This button will set the sequence to its default value.')

        for i in [self.prev_tx, self.prev_vout, self.script, self.sequence]:
            i.setFont(monospace_font)

        self.mapper.addMapping(self.prev_tx, 0)
        self.mapper.addMapping(self.prev_vout, 1, 'amount')
        self.mapper.addMapping(self.script, 2, 'humanText')
        self.mapper.addMapping(self.sequence, 3, 'amount')

        delete_button = QPushButton('Remove Input')
        delete_button.setToolTip('Remove this input from the transaction')
        delete_button.clicked.connect(self.do_delete)
        submit_button = QPushButton('Save')
        submit_button.setToolTip('Update input with the above data')
        submit_button.clicked.connect(self.do_submit)

        form = QFormLayout()
        form.setContentsMargins(0, 0, 0, 0)
        form.addRow('Previous Transaction: ', self.prev_tx)
        form.addRow('Previous Tx Output: ', self.prev_vout)
        form.addRow('Input script: ', self.script)
        seq_desc = QLabel(
            'Sequence is mostly deprecated.\nIf an input has a sequence that\'s not the maximum value, the transaction\'s locktime will apply.'
        )
        seq_desc.setWordWrap(True)
        form.addRow(seq_desc)
        form.addRow('Sequence: ', HBox(self.sequence, maxify_input_sequence))
        form.addRow(floated_buttons([delete_button, submit_button]))

        self.setLayout(form)
コード例 #6
0
    def create_inputs_tab(self):
        form = QFormLayout()
        self.inputs_tree = InputsTree()

        input_prev_tx = QLineEdit()
        input_prev_tx.setToolTip('Transaction ID of the tx with the output being spent')

        input_prev_vout = AmountEdit()
        input_prev_vout.setToolTip('Output index of the previous transaction')

        input_script = QTextEdit()
        input_script.setToolTip('Script that will be put on the stack before the previous output\'s script.')

        input_sequence = AmountEdit()
        input_sequence.setText('4294967295')
        maxify_input_sequence = QPushButton('Max')
        maxify_input_sequence.clicked.connect(lambda: input_sequence.setText('0xffffffff'))

        rm_input_edit = QSpinBox()
        rm_input_edit.setRange(0, 0)
        rm_input_button = QPushButton('Remove input')

        def add_input():
            try:
                outpoint = COutPoint(lx(str(input_prev_tx.text())), input_prev_vout.get_amount())
                in_script = Script.from_human(str(input_script.toPlainText()))
                new_input = CTxIn(outpoint, in_script.get_hex().decode('hex'), input_sequence.get_amount())
            except Exception as e:
                self.status_message(str(e), True)
                return
            else:
                self.inputs_tree.add_input(new_input)
                rm_input_edit.setRange(0, len(self.inputs_tree.get_inputs()) - 1)

        def rm_input():
            in_num = rm_input_edit.value()
            self.inputs_tree.model.takeRow(in_num)
            rm_input_edit.setRange(0, len(self.inputs_tree.get_inputs()) - 1)

        add_input_button = QPushButton('Add input')
        add_input_button.setToolTip('Add the above input')
        add_input_button.clicked.connect(add_input)

        rm_input_button.clicked.connect(rm_input)

        for i in [input_prev_tx, input_prev_vout, input_script, input_sequence]:
            i.setFont(monospace_font)

        form.addRow(self.inputs_tree)
        form.addRow(Separator())

        form.addRow('Previous Transaction:', input_prev_tx)
        form.addRow('Previous Tx Output:', input_prev_vout)
        form.addRow('Input script:', input_script)
        seq_desc = QLabel('Sequence is mostly deprecated.\nIf an input has a sequence that\'s not the maximum value, the transaction\'s locktime will apply.')
        seq_desc.setWordWrap(True)
        form.addRow(seq_desc)
        form.addRow('Sequence:', HBox(input_sequence, maxify_input_sequence))

        form.addRow(Separator())
        form.addRow(floated_buttons([add_input_button]))
        form.addRow('Remove input:', HBox(rm_input_edit, rm_input_button))

        w = QWidget()
        w.setLayout(form)
        return w