def test_valid_flow_control(self): valid_tests = ( ('1 1', 'IF IF 1 ELSE 0 ENDIF ENDIF'), ('1 0', 'IF IF 1 ELSE 0 ENDIF ENDIF'), ('1 1', 'IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF'), ('0 0', 'IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF'), ('1 0', 'NOTIF IF 1 ELSE 0 ENDIF ENDIF'), ('1 1', 'NOTIF IF 1 ELSE 0 ENDIF ENDIF'), ('1 0', 'NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF'), ('0 1', 'NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF'), ) valid_scripts = [] for script_sig, script_pubkey in valid_tests: script_sig, _ = transform_human(script_sig) script_pubkey, _ = transform_human(script_pubkey) script_sig = Script.from_human(script_sig) script_pubkey = Script.from_human(script_pubkey) valid_scripts.append((script_sig, script_pubkey)) execution = ScriptExecution() for script_sig, script_pubkey in valid_scripts: tx = build_spending_tx(script_sig, build_crediting_tx(script_pubkey)) _ = execution.evaluate(script_pubkey, txTo=tx, inIdx=0) self.assertTrue(execution.script_passed) self.assertTrue(execution.script_verified)
def test_invalid_flow_control(self): invalid_tests = ( ('0 1', 'IF IF 1 ELSE 0 ENDIF ENDIF'), ('0 0', 'IF IF 1 ELSE 0 ENDIF ENDIF'), ('1 0', 'IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF'), ('0 1', 'IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF'), ('0 0', 'NOTIF IF 1 ELSE 0 ENDIF ENDIF'), ('0 1', 'NOTIF IF 1 ELSE 0 ENDIF ENDIF'), ('1 1', 'NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF'), ('0 0', 'NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF'), ) invalid_scripts = [] for script_sig, script_pubkey in invalid_tests: script_sig, _ = transform_human(script_sig) script_pubkey, _ = transform_human(script_pubkey) script_sig = Script.from_human(script_sig) script_pubkey = Script.from_human(script_pubkey) invalid_scripts.append((script_sig, script_pubkey)) execution = ScriptExecution() for script_sig, script_pubkey in invalid_scripts: tx = build_spending_tx(script_sig, build_crediting_tx(script_pubkey)) _ = execution.evaluate(script_pubkey, txTo=tx, inIdx=0) self.assertFalse(execution.script_passed) self.assertFalse(execution.script_verified)
def __init__(self, parent=None): super(ScriptEdit, self).__init__(parent) self.current_format = 'Human' self.script = Script() self.textChanged.connect(self.on_text_changed) self.setFont(monospace_font) # For tooltips self.context = []
def add_input(self, i): in_script = Script(i.scriptSig) item = map(lambda x: QStandardItem(x), [str(i.prevout), in_script.get_human(), str(i.nSequence)]) # Raw scriptSig is stored as RawRole. item[1].setData(QtCore.QVariant(in_script.get_hex()), RawRole) self.model.appendRow(item)
def add_input(self, i): in_script = Script(i.scriptSig) item = map(lambda x: QStandardItem(x), [ str(i.prevout), in_script.get_human(), str(i.nSequence) ]) # Raw scriptSig is stored as RawRole. item[1].setData(QtCore.QVariant(in_script.get_hex()), RawRole) self.model.appendRow(item)
def add_output(self, o): out_script = Script(o.scriptPubKey) value = Amount(o.nValue) item = map(lambda x: QStandardItem(x), [value.get_str(), out_script.get_human()]) # Value in satoshis is stored as RawRole. item[0].setData(QtCore.QVariant(value.satoshis), RawRole) # Raw scriptPubKey is stored as RawRole. item[1].setData(QtCore.QVariant(out_script.get_hex()), RawRole) self.model.appendRow(item)
def set_data(self, text, fmt): script = None if fmt == 'Hex' and len(text) % 2 == 0: try: script = Script(text.decode('hex')) except Exception: pass elif fmt == 'Human': txt, self.context = transform_human(text) script = Script.from_human(txt) self.script = script
def get_outputs(self): vout = [] for i in range(self.model.rowCount()): value, ok = self.model.item(i, 0).data(RawRole).toInt() if not ok: raise Exception('Could not get satoshis for output %d' % i) return out_script = Script(str(self.model.item(i, 1).data(RawRole).toString()).decode('hex')) i_output = CTxOut(value, out_script.get_hex().decode('hex')) vout.append(i_output) return vout
def add_output(self, o): out_script = Script(o.scriptPubKey) value = Amount(o.nValue) item = map(lambda x: QStandardItem(x), [ value.get_str(), out_script.get_human() ]) # Value in satoshis is stored as RawRole. item[0].setData(QtCore.QVariant(value.satoshis), RawRole) # Raw scriptPubKey is stored as RawRole. item[1].setData(QtCore.QVariant(out_script.get_hex()), RawRole) self.model.appendRow(item)
def get_outputs(self): vout = [] for i in range(self.model.rowCount()): value, ok = self.model.item(i, 0).data(RawRole).toInt() if not ok: raise Exception('Could not get satoshis for output %d' % i) return out_script = Script( str(self.model.item(i, 1).data(RawRole).toString()).decode('hex')) i_output = CTxOut(value, out_script.get_hex().decode('hex')) vout.append(i_output) return vout
def test_script_from_human_to_human_and_hex(self): i = ScriptItem('0102010393', '0x02 0x03 OP_ADD') s = Script.from_human(i.human) self.assertEqual(s.get_hex(), i.hex) self.assertEqual(s.get_human(), i.human) i = ScriptItem('0051', 'OP_0 OP_1') s = Script.from_human(i.human) self.assertEqual(s.get_hex(), i.hex) self.assertEqual(s.get_human(), i.human) i = ScriptItem('510474657374', 'OP_1 "test"') s = Script.from_human(i.human) self.assertEqual(s.get_hex(), i.hex) self.assertEqual(s.get_human(), i.human)
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 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 setup_data(self, execution, parent): self.beginResetModel() for count, step in enumerate(execution.steps): step_item = TopLevelScriptItem((count, step.last_op, step.stack, step.log), parent) # Loop through stack items. scr = Script(step.stack).get_human().split() sub_level_item_data = [] for i, data in enumerate(step.stack): human = scr[i] # Variable name if self.plugin_handler: key = self.plugin_handler.get_plugin('Variables').ui.key_for_value(human, strict=False) if key: human = '$' + key stack_data = data try: stack_data = stack_data.encode('hex') except Exception: stack_data = str(stack_data) sub_level_item_data.append([i, '', stack_data, human]) # Reverse items for a more visually-accurate stack. sub_level_item_data.reverse() for sub in sub_level_item_data: data_item = SubLevelScriptItem(sub, step_item) step_item.appendChild(data_item) parent.appendChild(step_item) self.endResetModel()
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 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 test_script_from_hex_to_human(self): i = ScriptItem('6a0105', 'OP_RETURN 0x05') s = Script(i.hex.decode('hex')) self.assertEqual(s.get_human(), i.human) i = ScriptItem('6a01010131', 'OP_RETURN 0x01 "1"') s = Script(i.hex.decode('hex')) self.assertEqual(s.get_human(), i.human) i = ScriptItem( '76a914000000000000000000000000000000000000000088ac', 'OP_DUP OP_HASH160 0x0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG' ) s = Script(i.hex.decode('hex')) self.assertEqual(s.get_human(), i.human)
def setData(self, index, value, role = Qt.EditRole): if not index.isValid() or not self.vout: return False tx_out = self.vout[index.row()] col = index.column() if col == 0: tx_out.nValue, _ = value.toULongLong() elif col == 1: tx_out.scriptPubKey = x(Script.from_human(str(value.toString())).get_hex()) self.dataChanged.emit(self.index(index.row(), col), self.index(index.row(), col)) return True
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 data(self, index, role=Qt.DisplayRole): if not index.isValid() or not self.tx: return QVariant(None) if role not in [Qt.DisplayRole, Qt.ToolTipRole, Qt.EditRole, RawRole]: return None tx_input = self.tx.vin[index.row()] col = index.column() data = None if col == 0: data = b2lx(tx_input.prevout.hash) elif col == 1: data = tx_input.prevout.n elif col == 2: if role == RawRole: data = Script(tx_input.scriptSig).get_hex() else: data = Script(tx_input.scriptSig).get_human() elif col == 3: data = tx_input.nSequence return QVariant(data)
def human(self, value): self.clear() s = [] self.script = Script.from_human(str(value)) iterator = self.script.human_iter() while 1: try: s.append(next(iterator)) except Exception: break s.reverse() self.addItems(s)
def data(self, index, role=Qt.DisplayRole): if not index.isValid() or not self.vout: return QVariant(None) if role not in [Qt.DisplayRole, Qt.ToolTipRole, Qt.EditRole, RawRole]: return None tx_out = self.vout[index.row()] col = index.column() data = None if col == 0: if role in [Qt.EditRole, RawRole]: data = tx_out.nValue elif role in [Qt.ToolTipRole]: data = ' '.join([str(tx_out.nValue), 'satoshis']) else: data = self.format_amount(tx_out.nValue) elif col == 1: if role == RawRole: data = Script(tx_out.scriptPubKey).get_hex() else: data = Script(tx_out.scriptPubKey).get_human() return QVariant(data)
def setData(self, index, value, role=Qt.EditRole): if not index.isValid() or not self.vout: return False tx_out = self.vout[index.row()] col = index.column() if col == 0: tx_out.nValue, _ = value.toULongLong() elif col == 1: tx_out.scriptPubKey = x( Script.from_human(str(value.toString())).get_hex()) self.dataChanged.emit(self.index(index.row(), col), self.index(index.row(), col)) return True
def setData(self, index, value, role = Qt.EditRole): if not index.isValid() or not self.vin: return False tx_input = self.vin[index.row()] col = index.column() if col == 0: tx_input.prevout.hash = lx(str(value.toString())) elif col == 1: tx_input.prevout.n, _ = value.toUInt() elif col == 2: tx_input.scriptSig = x(Script.from_human(str(value.toString())).get_hex()) elif col == 3: tx_input.nSequence, _ = value.toUInt() self.dataChanged.emit(self.index(index.row(), col), self.index(index.row(), col)) return True
def set_tx(self, tx): self.beginResetModel() self.inputs = [] for i in tx.vin: hash_type = 0 try: s = Script(i.scriptSig).get_human().split()[-2] # Loose sanity check to ensure the data is long enough. if len(s) >= 120: hash_type = int(s[-2:], 16) except Exception: pass self.inputs.append([False, hash_type]) self.endResetModel()
class StackWidget(QListWidget): """List view of a stack.""" def __init__(self, *args): super(StackWidget, self).__init__(*args) self.setAlternatingRowColors(True) self.script = Script() @pyqtProperty(str) def human(self): return self.script.get_human() @human.setter def human(self, value): self.clear() s = [] self.script = Script.from_human(str(value)) iterator = self.script.human_iter() while 1: try: s.append(next(iterator)) except Exception: break s.reverse() self.addItems(s)
def test_string_literal_transform_and_instantiate_script(self): str_tests = ( ('"a"', '"a"', '0161'), ('2 "2"', '0x02 "2"', '01020132'), ('"1 2"', '"1 2"', '03312032'), ('0 "1 2"', '0x00 "1 2"', '010003312032'), ('0 "1 2" 3', '0x00 "1 2" 0x03', '0100033120320103'), ('"2 3 4"', '"2 3 4"', '053220332034'), ('1 "2 3 4" 5', '0x01 "2 3 4" 0x05','01010532203320340105'), ) for text, expected, expected_hex in str_tests: txt, _ = transform_human(text) self.assertEqual(expected, txt) s = Script.from_human(txt) self.assertEqual(expected_hex, s.get_hex())
def test_string_literal_transform_and_instantiate_script(self): str_tests = ( ('"a"', '"a"', '0161'), ('2 "2"', '0x02 "2"', '01020132'), ('"1 2"', '"1 2"', '03312032'), ('0 "1 2"', '0x00 "1 2"', '010003312032'), ('0 "1 2" 3', '0x00 "1 2" 0x03', '0100033120320103'), ('"2 3 4"', '"2 3 4"', '053220332034'), ('1 "2 3 4" 5', '0x01 "2 3 4" 0x05', '01010532203320340105'), ) for text, expected, expected_hex in str_tests: txt, _ = transform_human(text) self.assertEqual(expected, txt) s = Script.from_human(txt) self.assertEqual(expected_hex, s.get_hex())
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_script_from_hex(self): s = Script('6a0105'.decode('hex')) self.assertEqual(s.get_human(), 'OP_RETURN 0x05') s = Script( '76a914000000000000000000000000000000000000000088ac'.decode('hex')) self.assertEqual( s.get_human(), 'OP_DUP OP_HASH160 0x0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG' )
def __init__(self, data, parent=None): super(TopLevelScriptItem, self).__init__(data, parent) self.stack_data = Script(self.item_data[2]).get_human() # Convert log data representations to human-readable ones. log_data = self.item_data[3].split() for i, word in enumerate(log_data): # Try to put the data in human-readable form. try: hex_word = format_hex_string(word, with_prefix=False) if all(ord(c) < 128 and ord(c) > 31 for c in hex_word.decode('hex')): log_data[i] = ''.join(['"', hex_word.decode('hex'), '"']) except Exception: pass self.log_data = ' '.join(log_data) self.op_name = opcodes.opcode_names.get(self.item_data[1], 'PUSHDATA')
def setData(self, index, value, role=Qt.EditRole): if not index.isValid() or not self.vin: return False tx_input = self.vin[index.row()] col = index.column() if col == 0: tx_input.prevout.hash = lx(str(value.toString())) elif col == 1: tx_input.prevout.n, _ = value.toUInt() elif col == 2: tx_input.scriptSig = x( Script.from_human(str(value.toString())).get_hex()) elif col == 3: tx_input.nSequence, _ = value.toUInt() self.dataChanged.emit(self.index(index.row(), col), self.index(index.row(), col)) return True
def test_transform_human(self): variables = { 'numberOne': '0x01', 'stringOne': '"1"', } human_tests = [ ('0x02 "test" 0x03', '010204746573740103'), ('$numberOne 0x01', '01010101'), ('0x10 $stringOne 0x11', '011001310111'), # nonexistent variable ('$one 0x05', '04246f6e650105') ] for text, expected_hex in human_tests: txt, _ = transform_human(text, variables) s = Script.from_human(txt) self.assertEqual(s.get_hex(), expected_hex)
def add_output(): try: val_str = str(output_value.text()) value = 0 if '.' in val_str: value = int(float(val_str) * pow(10, 8)) else: value = int(val_str) out_script = Script.from_human(str(output_script.toPlainText())) new_output = CTxOut(value, out_script.get_hex().decode('hex')) except Exception as e: self.status_message(str(e), True) return else: self.outputs_tree.add_output(new_output) rm_output_edit.setRange(0, len(self.outputs_tree.get_outputs()) - 1)
def test_script_from_hex_to_human(self): i = ScriptItem('6a0105', 'OP_RETURN 0x05') s = Script(i.hex.decode('hex')) self.assertEqual(s.get_human(), i.human) i = ScriptItem('6a01010131', 'OP_RETURN 0x01 "1"') s = Script(i.hex.decode('hex')) self.assertEqual(s.get_human(), i.human) i = ScriptItem('76a914000000000000000000000000000000000000000088ac', 'OP_DUP OP_HASH160 0x0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG') s = Script(i.hex.decode('hex')) self.assertEqual(s.get_human(), i.human)
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 sign_transaction(self): """Sign the transaction.""" script, txTo, inIdx, hash_type = self.model.get_fields() if inIdx >= len(txTo.vin): self.set_result_message('Nonexistent input specified for signing.', error=True) return if not script: self.set_result_message('Invalid output script.', error=True) return privkey = self.get_private_key() if not privkey: self.set_result_message('Could not parse private key.', error=True) return sig_hash = chainparams.signature_hash(script, txTo, inIdx, hash_type) sig = privkey.sign(sig_hash) hash_type_hex = format_hex_string(hex(hash_type), with_prefix=False).decode('hex') sig = sig + hash_type_hex txTo.vin[inIdx].scriptSig = Script([sig, privkey.pub]) if self.verify_script.isChecked(): # Try verify try: VerifyScript(txTo.vin[inIdx].scriptSig, script, txTo, inIdx, (SCRIPT_VERIFY_P2SH, )) except Exception as e: self.set_result_message('Error when verifying: %s' % str(e), error=True) return self.dock.deserialize_raw(b2x(txTo.serialize())) # Deserializing a tx clears the model, so re-populate. self.model.set_fields(script=script.get_human(), inIdx=inIdx, hashType=hash_type) self.set_result_message( 'Successfully set scriptSig for input %d (SigHash type: %s).' % (inIdx, sig_hash_name(hash_type)))
def test_compatibility_with_cscript(self): cs = CScript(['01'.decode('hex'), OP_DUP, OP_HASH160]) s = Script(cs) self.assertEqual(s.get_human(), '0x01 OP_DUP OP_HASH160')
def test_script_from_human(self): s = Script.from_human('0x02 0x03 OP_ADD') self.assertEqual(s.get_hex(), '0102010393') s = Script.from_human('OP_1') self.assertEqual(s.get_hex(), '51')
class ScriptEdit(QTextEdit): """Script editor. Keeps an internal Script instance that it updates with its text, and uses to convert formats. """ def __init__(self, parent=None): super(ScriptEdit, self).__init__(parent) self.current_format = 'Human' self.script = Script() self.textChanged.connect(self.on_text_changed) self.setFont(monospace_font) # For tooltips self.context = [] def on_text_changed(self): txt = str(self.toPlainText()) self.set_data(txt, self.current_format) def copy_hex(self): txt = self.get_data('Hex') QApplication.clipboard().setText(txt) def contextMenuEvent(self, e): menu = self.createStandardContextMenu() menu.addAction('Copy Hex', self.copy_hex) menu.exec_(e.globalPos()) def set_format(self, fmt): self.current_format = fmt self.setPlainText(self.get_data()) def set_data(self, text, fmt): script = None if fmt == 'Hex' and len(text) % 2 == 0: try: script = Script(text.decode('hex')) except Exception: pass elif fmt == 'Human': txt, self.context = transform_human(text) script = Script.from_human(txt) self.script = script def get_data(self, fmt=None): if fmt is None: fmt = self.current_format if not self.script: return '' if fmt == 'Hex': return self.script.get_hex() elif fmt == 'Human': return self.script.get_human() def event(self, e): if e.type() == QEvent.ToolTip: cursor = self.cursorForPosition(e.pos()) context = self.get_tooltip(cursor.position()) if not context: QToolTip.hideText() else: QToolTip.showText(e.globalPos(), context) return True return super(ScriptEdit, self).event(e) def get_tooltip(self, index): """Returns the contextual tip for the word at index.""" if index < 0 or len(self.toPlainText()) < index: return '' for start, end, value, match_type in self.context: if index >= start and index < end: return '{} ({})'.format(value, match_type)
def test_script_from_hex(self): s = Script('6a0105'.decode('hex')) self.assertEqual(s.get_human(), 'OP_RETURN 0x05') s = Script('76a914000000000000000000000000000000000000000088ac'.decode('hex')) self.assertEqual(s.get_human(), 'OP_DUP OP_HASH160 0x0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG')
def copy_script_hex(self): """Copy the scriptPubKey to clipboard as hex.""" item = self.model.itemFromIndex(self.view.selectedIndexes()[1]) script = Script.from_human(str(item.text())) QApplication.clipboard().setText(script.get_hex())
def setUp(self): super(StackTest, self).setUp() self.script_simple_addition = Script.from_human("0x02 0x03 OP_ADD") self.script_push_dup = Script.from_human("0x80 OP_DUP")
def __init__(self, *args): super(StackWidget, self).__init__(*args) self.setAlternatingRowColors(True) self.script = Script()