def do_claim(self): """Replace unsigned outputs.""" if not self.tx: self.error('Invalid or nonexistent transaction.') return dest = str(self.destination_edit.text()) hash160 = dest # Try to decode address try: raw = CBase58Data(dest).to_bytes() hash160 = '0x' + b2x(raw) except Exception: # Try to parse hash160 if len(dest.replace('0x', '')) == 40: hash160 = dest if not is_hex(hash160) and len(hash160.replace('0x', '')) == 40: self.error('Could not parse destination: %s' % hash160) return if not get_unsigned_outputs(self.tx): self.error('There are no unsigned outputs.') return new_tx = replace_outputs(self.tx, hash160) self.result_edit.setPlainText(b2x(new_tx.serialize())) self.info('Successfully altered outputs: %s' % unsigned_outputs)
def template_to_script(template, variables): text = template.text _vars = {} for k, v in variables.items(): var_type = template.variables[k] if var_type == "address": try: h160 = CBase58Data(v).to_bytes() except Exception: # Check if value is a hash160. if is_hex(v) and (len(v) == 42 if v.startswith("0x") else len(v) == 40): h160 = v[2:].decode("hex") if v.startswith("0x") else v.decode("hex") else: return "Error: Could not decode <{}> address.".format(k) _vars[k] = "".join(["0x", h160.encode("hex")]) elif var_type == "text": _vars[k] = "".join(["0x", v.encode("hex")]) else: _vars[k] = v # Replace the <variable> occurrences with their values. for k, v in _vars.items(): old = "".join(["<", k, ">"]) text = text.replace(old, v) return text
def format_variable_value(value, var_type): """Returns a 2-tuple of (is_valid, formatted_value).""" if var_type == 'address': try: h160 = CBase58Data(value).to_bytes() except Exception: # Check if value is a hash160. if is_hex(value) and len( format_hex_string(value, with_prefix=False)) == 40: h160 = format_hex_string(value, with_prefix=False).decode('hex') else: return False, 'Error: Could not decode address.' return True, '0x' + h160.encode('hex') elif var_type == 'pubkey': if not is_hex(value): return False, 'Error: Pubkey must be hex.' key_hex = format_hex_string(value, with_prefix=False) pub = CPubKey(key_hex.decode('hex')) if not pub.is_fullyvalid: return False, 'Error: Pubkey is invalid.' return True, '0x' + key_hex elif var_type == 'text': try: return True, '0x' + value.encode('hex') except Exception as e: return False, 'Error: ' + str(e) elif var_type == 'signature': if not is_hex(value): return False, 'Error: Signature must be hex.' # We remain algorithm-agnostic by not checking the length. return True, format_hex_string(value, with_prefix=True) elif var_type == 'script': if not is_hex(value): try: scr = Script.from_human(value) return True, format_hex_string(scr.get_hex(), with_prefix=True) except Exception: return False, 'Error: Cannot parse human-readable script.' try: scr = Script( format_hex_string(value, with_prefix=False).decode('hex')) return True, format_hex_string(value, with_prefix=True) except Exception: return False, 'Error: Cannot parse script.' return True, value
def format_variable_value(value, var_type): """Returns a 2-tuple of (is_valid, formatted_value).""" if var_type == 'address': try: h160 = CBase58Data(value).to_bytes() except Exception: # Check if value is a hash160. if is_hex(value) and len(format_hex_string(value, with_prefix=False)) == 40: h160 = format_hex_string(value, with_prefix=False).decode('hex') else: return False, 'Error: Could not decode address.' return True, '0x' + h160.encode('hex') elif var_type == 'pubkey': if not is_hex(value): return False, 'Error: Pubkey must be hex.' key_hex = format_hex_string(value, with_prefix=False) pub = CPubKey(key_hex.decode('hex')) if not pub.is_fullyvalid: return False, 'Error: Pubkey is invalid.' return True, '0x' + key_hex elif var_type == 'text': try: return True, '0x' + value.encode('hex') except Exception as e: return False, 'Error: ' + str(e) elif var_type == 'signature': if not is_hex(value): return False, 'Error: Signature must be hex.' # We remain algorithm-agnostic by not checking the length. return True, format_hex_string(value, with_prefix=True) elif var_type == 'script': if not is_hex(value): try: scr = Script.from_human(value) return True, format_hex_string(scr.get_hex(), with_prefix=True) except Exception: return False, 'Error: Cannot parse human-readable script.' try: scr = Script(format_hex_string(value, with_prefix=False).decode('hex')) return True, format_hex_string(value, with_prefix=True) except Exception: return False, 'Error: Cannot parse script.' return True, value
def test_is_hex(self): hex_tests = ( ('0x0', True), ('0x00', True), ('0', True), ('00', True), ('f', True), ('x', False), ('0x', False), ) for value, expected in hex_tests: self.assertEqual(expected, utils.is_hex(value))
def get_private_key(self): """Attempt to parse the private key that was input.""" txt = str(self.privkey_edit.text()) privkey = None if is_hex(txt): txt = format_hex_string(txt, with_prefix=False) try: privkey = CBitcoinSecret.from_secret_bytes(x(txt)) except Exception: pass return privkey
def encode_data(self): payload = str(self.payload_edit.toPlainText()) if not payload: self.error('No data was input.') if is_hex(payload): payload = format_hex_string(payload, with_prefix=False).decode('hex') try: msg = base58.encode(payload) self.encoded_edit.setPlainText(msg) except Exception as e: self.error(str(e))
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
VariableType = namedtuple('VariableType', ('name', 'classify')) """Variable type. Attributes: name (str): Human-readable name. classify (function): Function returning whether a value has this variable type. """ _var_types = [ VariableType('None', lambda x: False), VariableType('Hex', is_hex), VariableType('Text', lambda x: x.startswith('"') and x.endswith('"')), VariableType( '64 Hex Digits', lambda x: is_hex(x) and (len(x) == 66 if x.startswith('0x') else len(x) == 64)), ] variable_types = OrderedDict() for var_type in _var_types: variable_types.update({var_type.name: var_type}) def classify_data(value): """Determine what to categorize a value as. Returns a list of variable_types keys. """ var_types = [] for var_type in variable_types.values():
def make_plugin(): return Plugin(Variables) VariableType = namedtuple('VariableType', ('name', 'classify')) """Variable type. Attributes: name (str): Human-readable name. classify (function): Function returning whether a value has this variable type. """ _var_types = [ VariableType('None', lambda x: False), VariableType('Hex', is_hex), VariableType('Text', lambda x: x.startswith('"') and x.endswith('"')), VariableType('64 Hex Digits', lambda x: is_hex(x) and (len(x) == 66 if x.startswith('0x') else len(x) == 64)), ] variable_types = OrderedDict() for var_type in _var_types: variable_types.update({var_type.name: var_type}) def classify_data(value): """Determine what to categorize a value as. Returns a list of variable_types keys. """ var_types = [] for var_type in variable_types.values(): if var_type.classify(value): var_types.append(var_type.name)