示例#1
0
    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)
示例#2
0
    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)
示例#3
0
 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)
示例#4
0
 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)
示例#5
0
    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)
示例#6
0
    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)
示例#7
0
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