def get_address_from_output_script(bytes): try: decoded = [ x for x in script_GetOp(bytes) ] except: return None # list of tuples: # ([opcodes], format, address_index) matches = [] # The Genesis Block, self-payments, and pay-by-IP-address payments look like: # 65 BYTES:... CHECKSIG matches.append(([opcodes.OP_PUSHDATA4, opcodes.OP_CHECKSIG], 'pubkey', 0)) # coins sent to black hole # DUP HASH160 20 BYTES:... EQUALVERIFY CHECKSIG matches.append(([opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_0, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG], None, None)) # Pay-by-Bitcoin-address TxOuts look like: # DUP HASH160 20 BYTES:... EQUALVERIFY CHECKSIG matches.append(([opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG], 'hash160p2pkh', 2)) # strange tx matches.append(([opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG, opcodes.OP_NOP], 'hash160p2pkh', 2)) # p2sh matches.append(([ opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUAL ], 'hash160p2sh', 1)) run_chainhook('address_from_output_script_fields', opcodes, matches) return try_output_matches(decoded, matches)
def get_address_from_output_script(bytes, active_chain=None): if active_chain is None: active_chain = chainparams.get_active_chain() decoded = [x for x in script_GetOp(bytes)] # list of (opcodes_list, addr_type, addr_data_index, [actions_to_take]) # actions_to_take contains things such as 'encode' if the data should be hex-encoded. matches = [ # The Genesis Block, self-payments, and pay-by-IP-address payments ([opcodes.OP_PUSHDATA4, opcodes.OP_CHECKSIG], 'pubkey', 0, ['encode']), # Pay-to-Public-Key-Hash ([ opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG ], 'address', 2, [None]), # Pay-to-Script-Hash ([opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUAL], 'address', 1, ['p2sh']), # OP_RETURN (null output) ([opcodes.OP_RETURN, opcodes.OP_PUSHDATA4], 'op_return', 1, [None]) ] run_chainhook('transaction_get_address_from_output_script', opcodes, matches) return _get_address_from_output_script(decoded, matches, active_chain)
def parse_Transaction(vds, is_coinbase): d = {} start = vds.read_cursor fields = [('version', vds.read_int32, True), # version ('vin', vds.read_compact_size, False), # vin ('inputs', 'parse_inputs', True), # inputs ('vout', vds.read_compact_size, False), # vout ('outputs', 'parse_outputs', True), # outputs ('lockTime', vds.read_uint32, True) ] # locktime run_chainhook('transaction_parse_fields', vds, is_coinbase, fields) deserialize_tx_fields(vds, d, is_coinbase, fields) return d
def parse_Transaction(vds, is_coinbase): d = {} start = vds.read_cursor fields = [ ('version', vds.read_int32, True), # version ('vin', vds.read_compact_size, False), # vin ('inputs', 'parse_inputs', True), # inputs ('vout', vds.read_compact_size, False), # vout ('outputs', 'parse_outputs', True), # outputs ('lockTime', vds.read_uint32, True) ] # locktime run_chainhook('transaction_parse_fields', vds, is_coinbase, fields) deserialize_tx_fields(vds, d, is_coinbase, fields) return d
def serialize(self, for_sig=None): """Serialize transaction as a hex-encoded string. Args: for_sig: If this serialization is for signing. Has the following possible values: - -1 : do not sign, estimate length - >=0 : serialized tx for signing input i - None : add all known signatures """ inputs = self.inputs outputs = self.outputs # field, field data(data_overridden_by_chainhook) fields = [('version', []), ('vin', []), ('inputs', []), ('vout', []), ('outputs', []), ('locktime', []), ('hashtype', []) ] run_chainhook('transaction_serialize', self, for_sig, fields) for i, (field, field_data) in enumerate(fields): if not field_data: if field == 'version': field_data.append(int_to_hex(1,4)) elif field == 'vin': field_data.append(var_int(len(inputs))) elif field == 'inputs': for i in range(len(inputs)): field_data.append(self.serialize_input(i, for_sig)) elif field == 'vout': field_data.append(var_int(len(outputs))) elif field == 'outputs': for output in outputs: field_data.append(self.serialize_output(output, for_sig)) elif field == 'locktime': field_data.append(int_to_hex(0,4)) elif field == 'hashtype': if for_sig is not None and for_sig != -1: field_data.append(int_to_hex(1,4)) s = [] for field, field_data in fields: s.append(''.join(field_data)) return ''.join(s)
def deserialize(raw, active_chain=None): vds = BCDataStream() vds.write(raw.decode('hex')) fields = [('version', vds.read_int32, True), # version ('vin', vds.read_compact_size, False), # vin ('inputs', 'parse_inputs', True), # inputs ('vout', vds.read_compact_size, False), # vout ('outputs', 'parse_outputs', True), # outputs ('lockTime', vds.read_uint32, True) ] # locktime run_chainhook('transaction_deserialize_tx_fields', vds, fields) d = {} start = vds.read_cursor deserialize_tx_fields(vds, d, fields, active_chain) return d
def parse_Transaction(vds, is_coinbase): d = {} start = vds.read_cursor fields = [ ("version", vds.read_int32, True), # version ("nTime", vds.read_int32, True), # nTime ("vin", vds.read_compact_size, False), # vin ("inputs", "parse_inputs", True), # inputs ("vout", vds.read_compact_size, False), # vout ("outputs", "parse_outputs", True), # outputs ("lockTime", vds.read_uint32, True), ] # locktime run_chainhook("transaction_parse_fields", vds, is_coinbase, fields) deserialize_tx_fields(vds, d, is_coinbase, fields) return d
def deserialize(raw, active_chain=None): vds = BCDataStream() vds.write(raw.decode('hex')) fields = [ ('version', vds.read_int32, True), # version ('vin', vds.read_compact_size, False), # vin ('inputs', 'parse_inputs', True), # inputs ('vout', vds.read_compact_size, False), # vout ('outputs', 'parse_outputs', True), # outputs ('lockTime', vds.read_uint32, True) ] # locktime run_chainhook('transaction_deserialize_tx_fields', vds, fields) d = {} start = vds.read_cursor deserialize_tx_fields(vds, d, fields, active_chain) return d
def get_address_from_output_script(bytes): try: decoded = [x for x in script_GetOp(bytes)] except: return None # list of tuples: # ([opcodes], format, address_index) matches = [] # The Genesis Block, self-payments, and pay-by-IP-address payments look like: # 65 BYTES:... CHECKSIG matches.append(([opcodes.OP_PUSHDATA4, opcodes.OP_CHECKSIG], 'pubkey', 0)) # coins sent to black hole # DUP HASH160 20 BYTES:... EQUALVERIFY CHECKSIG matches.append(([ opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_0, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG ], None, None)) # Pay-by-Bitcoin-address TxOuts look like: # DUP HASH160 20 BYTES:... EQUALVERIFY CHECKSIG matches.append(([ opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG ], 'hash160p2pkh', 2)) # strange tx matches.append(([ opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG, opcodes.OP_NOP ], 'hash160p2pkh', 2)) # p2sh matches.append( ([opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUAL], 'hash160p2sh', 1)) run_chainhook('address_from_output_script_fields', opcodes, matches) return try_output_matches(decoded, matches)
def serialize(self, for_sig=None): """Serialize transaction as a hex-encoded string. Args: for_sig: If this serialization is for signing. Has the following possible values: - -1 : do not sign, estimate length - >=0 : serialized tx for signing input i - None : add all known signatures """ inputs = self.inputs outputs = self.outputs # field, field data(data_overridden_by_chainhook) fields = [('version', []), ('vin', []), ('inputs', []), ('vout', []), ('outputs', []), ('locktime', []), ('hashtype', [])] run_chainhook('transaction_serialize', self, for_sig, fields) for i, (field, field_data) in enumerate(fields): if not field_data: if field == 'version': field_data.append(int_to_hex(1, 4)) elif field == 'vin': field_data.append(var_int(len(inputs))) elif field == 'inputs': for i in range(len(inputs)): field_data.append(self.serialize_input(i, for_sig)) elif field == 'vout': field_data.append(var_int(len(outputs))) elif field == 'outputs': for output in outputs: field_data.append( self.serialize_output(output, for_sig)) elif field == 'locktime': field_data.append(int_to_hex(0, 4)) elif field == 'hashtype': if for_sig is not None and for_sig != -1: field_data.append(int_to_hex(1, 4)) s = [] for field, field_data in fields: s.append(''.join(field_data)) return ''.join(s)
def get_address_from_output_script(bytes, active_chain=None): if active_chain is None: active_chain = chainparams.get_active_chain() decoded = [ x for x in script_GetOp(bytes) ] # list of (opcodes_list, addr_type, addr_data_index, [actions_to_take]) # actions_to_take contains things such as 'encode' if the data should be hex-encoded. matches = [ # The Genesis Block, self-payments, and pay-by-IP-address payments ([ opcodes.OP_PUSHDATA4, opcodes.OP_CHECKSIG ], 'pubkey', 0, ['encode']), # Pay-to-Public-Key-Hash ([ opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG ], 'address', 2, [None]), # Pay-to-Script-Hash ([ opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUAL ], 'address', 1, ['p2sh']), # OP_RETURN (null output) ([ opcodes.OP_RETURN, opcodes.OP_PUSHDATA4 ], 'op_return', 1, [None]) ] run_chainhook('transaction_get_address_from_output_script', opcodes, matches) return _get_address_from_output_script(decoded, matches, active_chain)