def build_spending_tx(script_sig, credit_tx): tx = Transaction(version=1, locktime=0) txin = CMutableTxIn(CMutableOutPoint(credit_tx.GetHash(), 0), script_sig) tx.vin = [txin] txout = CMutableTxOut(0, Script()) tx.vout = [txout] return tx
def build_crediting_tx(script_pubkey): tx = Transaction(version=1, locktime=0) txin = CMutableTxIn() txin.scriptSig = Script.from_human('0x00 0x00') tx.vin = [txin] txout = CMutableTxOut(0, script_pubkey) tx.vout = [txout] return tx
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 replace_outputs(tx, hash160): """Replace unsigned outputs in tx.""" if not is_hex(hash160) and len(hash160.replace('0x', '')) == 40: raise ValueError('hash160 must be 40 hex digits.') out_script = Script.from_human('OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG' % hash160) unsigned_outputs = get_unsigned_outputs(tx) if not unsigned_outputs: return tx new_tx = Transaction.from_tx(tx) for o in unsigned_outputs: new_tx.vout[o].scriptPubKey = out_script return new_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 build_transaction(self): self.tx_widget.clear() self.sighash_widget.clear() self.tx = tx = Transaction() tx.nVersion = self.version_edit.get_amount() tx.vin = self.inputs_tree.get_inputs() tx.vout = self.outputs_tree.get_outputs() tx.nLockTime = self.locktime_edit.get_amount() for name, w in self.tx_field_widgets: if not name in [field[0] for field in tx.fields]: continue value = str(w.text()) default = getattr(tx, name) if isinstance(default, int): value = w.get_amount() setattr(tx, name, value) self.raw_tx.setText(bitcoin.core.b2x(tx.serialize())) self.tx_widget.set_tx(tx) self.sighash_widget.set_tx(tx)
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()