def do_verify_input(self, tx, in_idx): if tx.is_coinbase(): self.result_edit.setText('Error: Cannot verify coinbase transactions.') self.error('Attempted to verify coinbase transaction.') return False raw_prev_tx = None tx_in = tx.vin[in_idx] txid = b2lx(tx_in.prevout.hash) prev_out_n = tx_in.prevout.n try: raw_prev_tx = self.handler.download_blockchain_data('raw_transaction', txid) except Exception as e: self.error(str(e)) return False try: prev_tx = Transaction.deserialize(raw_prev_tx.decode('hex')) result = bitcoin.core.scripteval.VerifyScript(tx_in.scriptSig, prev_tx.vout[prev_out_n].scriptPubKey, tx, in_idx) self.result_edit.setText('Successfully verified input {}'.format(in_idx)) self.inputs_table_model.set_verified(in_idx, True) except Exception as e: self.result_edit.setText(str(e)) self.inputs_table_model.set_verified(in_idx, False) self.error(str(e)) return False return True
def check_raw_tx(self): txt = str(self.raw_tx_edit.toPlainText()) # Variable substitution if txt.startswith('$'): return tx = None valid = True try: tx = Transaction.deserialize(txt.decode('hex')) except Exception: valid = False self.tx = tx self.inputs_box.setEnabled(valid) self.verify_button.setEnabled(valid) self.verify_all_button.setEnabled(valid) self.tx_widget.setEnabled(valid) self.clear() if valid: self.raw_tx_invalid.hide() self.inputs_box.setRange(0, len(tx.vin) - 1) self.deserialize() elif txt: self.raw_tx_invalid.show() else: self.raw_tx_invalid.hide()
def check_raw_tx(self): txt = str(self.raw_tx_edit.toPlainText()) try: tx = Transaction.deserialize(x(txt)) except Exception: tx = None self.tx = tx self.model.set_tx(tx)
def test_p2sh_script_verification(self): # P2SH tx from Bitcoin Core tests. rawtx = '01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100c66c9cdf4c43609586d15424c54707156e316d88b0a1534c9e6b0d4f311406310221009c0fe51dbc9c4ab7cc25d3fdbeccf6679fe6827f08edf2b4a9f16ee3eb0e438a0123210338e8034509af564c62644c07691942e0c056752008a173c89f60ab2a88ac2ebfacffffffff010000000000000000015100000000' tx = Transaction.deserialize(rawtx.decode('hex')) tx_script = Script.from_human('OP_HASH160 0x8febbed40483661de6958d957412f82deed8e2f7 OP_EQUAL') execution = ScriptExecution() _ = execution.evaluate(tx_script, txTo=tx, inIdx=0) self.assertTrue(execution.script_passed) self.assertTrue(execution.script_verified) invalid_tx_script = Script.from_human('OP_HASH160 0x0febbed40483661de6958d957412f82deed8e2f7 OP_EQUAL') _ = execution.evaluate(invalid_tx_script, txTo=tx, inIdx=0) self.assertFalse(execution.script_passed) self.assertTrue(execution.script_verified)
def setData(self, index, value, role=Qt.EditRole): if not index.isValid(): return False c = index.column() if c == 0: try: self.utxo_script = Script.from_human(str(value.toString())) except Exception: return False self.dataChanged.emit(self.index(index.row(), c), self.index(index.row(), c)) elif c == 1: try: self.tx = Transaction.deserialize(x(str(value.toString()))) except Exception: return False self.dataChanged.emit(self.index(index.row(), c), self.index(index.row(), c)) elif c == 2: tmpIdx, ok = value.toInt() if not ok: return False self.inIdx = tmpIdx self.dataChanged.emit(self.index(index.row(), c), self.index(index.row(), c)) elif c == 3: if role == Qt.EditRole: val = str(value.toString()) sighash_type = sighash_types.get(val) if not sighash_type: return False self.sighash_type = sighash_type elif role == RawRole: tmpType, ok = value.toInt() if not ok: return False self.sighash_type = tmpType self.dataChanged.emit( self.index(index.row(), c), self.index(index.row(), self.SigHashExplanation)) elif c == 4: self.anyone_can_pay = value.toBool() self.dataChanged.emit( self.index(index.row(), c), self.index(index.row(), self.SigHashExplanation)) return True
def test_p2sh_script_verification(self): # P2SH tx from Bitcoin Core tests. rawtx = '01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100c66c9cdf4c43609586d15424c54707156e316d88b0a1534c9e6b0d4f311406310221009c0fe51dbc9c4ab7cc25d3fdbeccf6679fe6827f08edf2b4a9f16ee3eb0e438a0123210338e8034509af564c62644c07691942e0c056752008a173c89f60ab2a88ac2ebfacffffffff010000000000000000015100000000' tx = Transaction.deserialize(rawtx.decode('hex')) tx_script = Script.from_human( 'OP_HASH160 0x8febbed40483661de6958d957412f82deed8e2f7 OP_EQUAL') execution = ScriptExecution() _ = execution.evaluate(tx_script, txTo=tx, inIdx=0) self.assertTrue(execution.script_passed) self.assertTrue(execution.script_verified) invalid_tx_script = Script.from_human( 'OP_HASH160 0x0febbed40483661de6958d957412f82deed8e2f7 OP_EQUAL') _ = execution.evaluate(invalid_tx_script, txTo=tx, inIdx=0) self.assertFalse(execution.script_passed) self.assertFalse(execution.script_verified)
def test_transaction_deserialization_and_serialization(self): # Transaction from Decred unit test. raw_tx = x( "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff0200f2052a01000000abab434104d64bdfd09eb1c5fe295abdeb1dca4281be988e2da0b6c1c6a59dc226c28624e18175e851c96b973d81b01cc31f047834bc06d6d6edf620d184241a6aed8b63a6ac00e1f50500000000bcbc434104d64bdfd09eb1c5fe295abdeb1dca4281be988e2da0b6c1c6a59dc226c28624e18175e851c96b973d81b01cc31f047834bc06d6d6edf620d184241a6aed8b63a6ac00000000000000000112121212121212121515151534343434070431dc001b0162" ) tx = Transaction.deserialize(raw_tx) self.assertEqual(1, tx.nVersion) self.assertEqual(0, tx.nLockTime) self.assertEqual(0, tx.expiry) # Test input. self.assertEqual(1, len(tx.vin)) txin = tx.vin[0] self.assertEqual(1302123111085380114, txin.value) self.assertEqual(353703189, txin.block_height) self.assertEqual(875836468, txin.block_index) self.assertEqual(x("0431dc001b0162"), txin.scriptSig) self.assertEqual(4294967295, txin.nSequence) self.assertEqual(2, len(tx.vout)) # Test output 0. txout = tx.vout[0] self.assertEqual(5000000000, txout.nValue) self.assertEqual(43947, txout.version) self.assertEqual( x( "4104d64bdfd09eb1c5fe295abdeb1dca4281be988e2da0b6c1c6a59dc226c28624e18175e851c96b973d81b01cc31f047834bc06d6d6edf620d184241a6aed8b63a6ac" ), txout.scriptPubKey, ) # Test output 1. txout = tx.vout[1] self.assertEqual(100000000, txout.nValue) self.assertEqual(48316, txout.version) self.assertEqual( x( "4104d64bdfd09eb1c5fe295abdeb1dca4281be988e2da0b6c1c6a59dc226c28624e18175e851c96b973d81b01cc31f047834bc06d6d6edf620d184241a6aed8b63a6ac" ), txout.scriptPubKey, ) self.assertEqual(b2x(raw_tx), b2x(tx.serialize()))
def setData(self, index, value, role = Qt.EditRole): if not index.isValid(): return False c = index.column() if c == 0: try: self.utxo_script = Script.from_human(str(value.toString())) except Exception: return False self.dataChanged.emit(self.index(index.row(), c), self.index(index.row(), c)) elif c == 1: try: self.tx = Transaction.deserialize(x(str(value.toString()))) except Exception: return False self.dataChanged.emit(self.index(index.row(), c), self.index(index.row(), c)) elif c == 2: tmpIdx, ok = value.toInt() if not ok: return False self.inIdx = tmpIdx self.dataChanged.emit(self.index(index.row(), c), self.index(index.row(), c)) elif c == 3: if role == Qt.EditRole: val = str(value.toString()) sighash_type = sighash_types.get(val) if not sighash_type: return False self.sighash_type = sighash_type elif role == RawRole: tmpType, ok = value.toInt() if not ok: return False self.sighash_type = tmpType self.dataChanged.emit(self.index(index.row(), c), self.index(index.row(), self.SigHashExplanation)) elif c == 4: self.anyone_can_pay = value.toBool() self.dataChanged.emit(self.index(index.row(), c), self.index(index.row(), self.SigHashExplanation)) return True
def deserialize_raw(self, rawtx): """Update editor widgets with rawtx's data.""" self.needsFocus.emit() try: tx = Transaction.deserialize(x(rawtx)) except Exception: return else: self.version_edit.set_amount(tx.nVersion) self.inputs_tree.model.set_tx(tx) self.outputs_tree.model.set_tx(tx) self.locktime_edit.set_amount(tx.nLockTime) for name, w in self.tx_field_widgets: if name in ['nVersion', 'vin', 'vout', 'nLockTime']: continue try: value = getattr(tx, name) except AttributeError: continue if isinstance(w, AmountEdit): w.set_amount(value) else: w.setText(str(value)) self.build_transaction()