def serialize_input(self, i, for_sig=None): txin = self.inputs[i] s = [] s.append(txin['prevout_hash'].decode('hex')[::-1].encode( 'hex')) # prev hash s.append(int_to_hex(txin['prevout_n'], 4)) # prev index p2sh = txin.get('redeemScript') is not None num_sig = txin['num_sig'] address = txin['address'] x_signatures = txin['signatures'] signatures = filter(lambda x: x is not None, x_signatures) is_complete = len(signatures) == num_sig if for_sig in [-1, None]: # if we have enough signatures, we use the actual pubkeys # use extended pubkeys (with bip32 derivation) sig_list = [] if for_sig == -1: # we assume that signature will be 0x48 bytes long pubkeys = txin['pubkeys'] sig_list = ["00" * 0x48] * num_sig elif is_complete: pubkeys = txin['pubkeys'] for signature in signatures: sig_list.append(signature + '01') else: pubkeys = txin['x_pubkeys'] for signature in x_signatures: sig_list.append(( signature + '01') if signature is not None else NO_SIGNATURE) sig_list = ''.join(map(lambda x: push_script(x), sig_list)) if not p2sh: script = sig_list x_pubkey = pubkeys[0] if x_pubkey is None: addrtype, h160 = bc_address_to_hash_160(txin['address']) x_pubkey = 'fd' + (chr(addrtype) + h160).encode('hex') script += push_script(x_pubkey) else: script = '00' # op_0 script += sig_list redeem_script = multisig_script(pubkeys, num_sig) script += push_script(redeem_script) elif for_sig == i: script = txin['redeemScript'] if p2sh else self.pay_script( 'address', address) else: script = '' s.append(var_int(len(script) / 2)) # script length s.append(script) s.append("ffffffff") # sequence return ''.join(s)
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 serialize_output(self, output, for_sig=None): s = [] type, addr, amount = output s.append(int_to_hex(amount, 8)) # amount script = self.pay_script(type, addr) s.append(var_int(len(script) / 2)) # script length s.append(script) # script return ''.join(s)
def serialize_output(self, output, for_sig=None): s = [] type, addr, amount = output s.append(int_to_hex( amount, 8)) # amount script = self.pay_script(type, addr) s.append(var_int( len(script)/2 )) # script length s.append(script) # script return ''.join(s)
def serialize_input(self, i, for_sig=None): txin = self.inputs[i] s = [] s.append( txin['prevout_hash'].decode('hex')[::-1].encode('hex') ) # prev hash s.append( int_to_hex(txin['prevout_n'],4) ) # prev index p2sh = txin.get('redeemScript') is not None num_sig = txin['num_sig'] address = txin['address'] x_signatures = txin['signatures'] signatures = filter(lambda x: x is not None, x_signatures) is_complete = len(signatures) == num_sig if for_sig in [-1, None]: # if we have enough signatures, we use the actual pubkeys # use extended pubkeys (with bip32 derivation) sig_list = [] if for_sig == -1: # we assume that signature will be 0x48 bytes long pubkeys = txin['pubkeys'] sig_list = [ "00"* 0x48 ] * num_sig elif is_complete: pubkeys = txin['pubkeys'] for signature in signatures: sig_list.append(signature + '01') else: pubkeys = txin['x_pubkeys'] for signature in x_signatures: sig_list.append((signature + '01') if signature is not None else NO_SIGNATURE) sig_list = ''.join( map( lambda x: push_script(x), sig_list)) if not p2sh: script = sig_list x_pubkey = pubkeys[0] if x_pubkey is None: addrtype, h160 = bc_address_to_hash_160(txin['address']) x_pubkey = 'fd' + (chr(addrtype) + h160).encode('hex') script += push_script(x_pubkey) else: script = '00' # op_0 script += sig_list redeem_script = multisig_script(pubkeys,num_sig) script += push_script(redeem_script) elif for_sig==i: script = txin['redeemScript'] if p2sh else self.pay_script('address', address) else: script = '' s.append(var_int( len(script)/2 )) # script length s.append(script) s.append("ffffffff") # sequence return ''.join(s)
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 msg_magic(message): varint = var_int(len(message)) encoded_varint = "".join( [chr(int(varint[i:i + 2], 16)) for i in xrange(0, len(varint), 2)]) return "\x18Bitcoin Signed Message:\n" + encoded_varint + message