Пример #1
0
 def test_push_script(self):
     # https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#push-operators
     self.assertEqual(push_script(''), bh2u(bytes([Ops.OP_0])))
     self.assertEqual(push_script('07'), bh2u(bytes([Ops.OP_7])))
     self.assertEqual(push_script('10'), bh2u(bytes([Ops.OP_16])))
     self.assertEqual(push_script('81'), bh2u(bytes([Ops.OP_1NEGATE])))
     self.assertEqual(push_script('11'), '0111')
     self.assertEqual(push_script(75 * '42'), '4b' + 75 * '42')
     self.assertEqual(push_script(76 * '42'), bh2u(bytes([Ops.OP_PUSHDATA1]) + bfh('4c' + 76 * '42')))
     self.assertEqual(push_script(100 * '42'), bh2u(bytes([Ops.OP_PUSHDATA1]) + bfh('64' + 100 * '42')))
     self.assertEqual(push_script(255 * '42'), bh2u(bytes([Ops.OP_PUSHDATA1]) + bfh('ff' + 255 * '42')))
     self.assertEqual(push_script(256 * '42'), bh2u(bytes([Ops.OP_PUSHDATA2]) + bfh('0001' + 256 * '42')))
     self.assertEqual(push_script(520 * '42'), bh2u(bytes([Ops.OP_PUSHDATA2]) + bfh('0802' + 520 * '42')))
Пример #2
0
 def show_qr(self):
     text = bfh(str(self.tx))
     text = base_encode(text, base=43)
     try:
         self.main_window.show_qrcode(text, 'Transaction', parent=self)
     except Exception as e:
         self.show_message(str(e))
Пример #3
0
    def do_send(self, wallet, tx):
        def on_success(result):
            item.window.show_message('\n'.join((
                _("Your transaction was sent to the cosigning pool."),
                _("Open your cosigner wallet to retrieve it."),
            )))

        def on_failure(exc_info):
            logger.exception("", exc_info=exc_info)
            item.window.show_error('\n'.join((
                _("Failed to send transaction to cosigning pool"),
                str(exc_info[1]),
            )))

        def send_message():
            server.put(item.hash, message)

        for item in self.items:
            if self.is_theirs(wallet, item, tx):
                raw_tx_bytes = bfh(str(tx))
                public_key = ecc.ECPubkey(item.K)
                message = public_key.encrypt_message(raw_tx_bytes).decode(
                    'ascii')
                WaitingDialog(item.window,
                              _('Sending transaction to cosigning pool...'),
                              send_message, on_success, on_failure)
Пример #4
0
 def f(x_pubkey):
     if is_xpubkey(x_pubkey):
         xpub, s = parse_xpubkey(x_pubkey)
     else:
         xpub = xpub_from_pubkey(
             'standard', bfh(x_pubkey))
         s = []
     return self._make_node_path(xpub, s)
Пример #5
0
 def f(x_pubkey):
     if x_pubkey.is_bip32_key():
         xpub, path = x_pubkey.bip32_extended_key_and_path()
     else:
         xpub = BIP32PublicKey(bfh(x_pubkey), NULL_DERIVATION, Net.COIN)
         xpub = xpub.to_extended_key_string()
         path = []
     node = self.ckd_public.deserialize(xpub)
     return self.types.HDNodePathType(node=node, address_n=path)
Пример #6
0
 def f(x_pubkey):
     if is_xpubkey(x_pubkey):
         xpub, s = parse_xpubkey(x_pubkey)
     else:
         xpub = BIP32PublicKey(bfh(x_pubkey), NULL_DERIVATION, Net.COIN)
         xpub = xpub.to_extended_key_string()
         s = []
     node = self.ckd_public.deserialize(xpub)
     return self.types.HDNodePathType(node=node, address_n=s)
Пример #7
0
 def f(x_pubkey):
     if is_xpubkey(x_pubkey):
         xpub, s = parse_xpubkey(x_pubkey)
     else:
         xpub = xpub_from_pubkey(
             'standard', bfh(x_pubkey))
         s = []
     node = self.ckd_public.deserialize(xpub)
     return self.types.HDNodePathType(node=node,
                                      address_n=s)
Пример #8
0
    def tx_inputs(self, tx, xpub_path, for_sig=False):
        inputs = []
        for txin in tx.inputs():
            txinputtype = TxInputType()
            if txin['type'] == 'coinbase':
                prev_hash = b"\x00" * 32
                prev_index = 0xffffffff  # signed int -1
            else:
                if for_sig:
                    x_pubkeys = txin['x_pubkeys']
                    xpubs = [parse_xpubkey(x) for x in x_pubkeys]
                    multisig = self._make_multisig(txin.get('num_sig'), xpubs,
                                                   txin.get('signatures'))
                    script_type = self.get_trezor_input_script_type(
                        multisig is not None)
                    txinputtype = TxInputType(script_type=script_type,
                                              multisig=multisig)
                    # find which key is mine
                    for xpub, deriv in xpubs:
                        if xpub in xpub_path:
                            xpub_n = bip32_decompose_chain_string(
                                xpub_path[xpub])
                            txinputtype.address_n = xpub_n + deriv
                            break

                prev_hash = bfh(txin['prevout_hash'])
                prev_index = txin['prevout_n']

            if 'value' in txin:
                txinputtype.amount = txin['value']
            txinputtype.prev_hash = prev_hash
            txinputtype.prev_index = prev_index

            if 'scriptSig' in txin:
                script_sig = bfh(txin['scriptSig'])
                txinputtype.script_sig = script_sig

            txinputtype.sequence = txin.get('sequence', 0xffffffff - 1)

            inputs.append(txinputtype)

        return inputs
Пример #9
0
 def electrumsv_tx_to_txtype(self, tx):
     t = self.types.TransactionType()
     d = deserialize(tx.raw)
     t.version = d['version']
     t.lock_time = d['lockTime']
     inputs = self.tx_inputs(tx)
     t.inputs.extend(inputs)
     for vout in d['outputs']:
         o = t.bin_outputs.add()
         o.amount = vout['value']
         o.script_pubkey = bfh(vout['scriptPubKey'])
     return t
Пример #10
0
def validate_op_return_output_and_get_data(output):
    if output.type != TYPE_SCRIPT:
        raise Exception("Unexpected output type: {}".format(output.type))
    script = bfh(output.address)
    if not (script[0] == Ops.OP_RETURN and script[1] == len(script) - 2
            and script[1] <= 75):
        raise Exception(
            _("Only OP_RETURN scripts, with one constant push, are supported.")
        )
    if output.value != 0:
        raise Exception(_("Amount for OP_RETURN output must be zero."))
    return script[2:]
Пример #11
0
    def test_sign_transaction(self):
        eckey1 = PrivateKey(bfh('7e1255fddb52db1729fc3ceb21a46f95b8d9fe94cc83425e936a6c5223bb679d'))
        sig1 = eckey1.sign(bfh('5a548b12369a53faaa7e51b5081829474ebdd9c924b3a8230b69aa0be254cd94'), None)
        self.assertEqual(bfh('3045022100902a288b98392254cd23c0e9a49ac6d7920f171b8249a48e484b998f1874a2010220723d844826828f092cf400cb210c4fa0b8cd1b9d1a7f21590e78e022ff6476b9'), sig1)

        eckey2 = PrivateKey(bfh('c7ce8c1462c311eec24dff9e2532ac6241e50ae57e7d1833af21942136972f23'))
        sig2 = eckey2.sign(bfh('642a2e66332f507c92bda910158dfe46fc10afbf72218764899d3af99a043fac'), None)
        self.assertEqual(bfh('30440220618513f4cfc87dde798ce5febae7634c23e7b9254a1eabf486be820f6a7c2c4702204fef459393a2b931f949e63ced06888f35e286e446dc46feb24b5b5f81c6ed52'), sig2)
Пример #12
0
    def _do_test_bip32(self, seed, sequence):
        xprv, xpub = bip32_root(bfh(seed), 'standard')
        self.assertEqual("m/", sequence[0:2])
        path = 'm'
        sequence = sequence[2:]
        for n in sequence.split('/'):
            child_path = path + '/' + n
            if n[-1] != "'":
                xpub2 = bip32_public_derivation(xpub, path, child_path)
            xprv, xpub = bip32_private_derivation(xprv, path, child_path)
            if n[-1] != "'":
                self.assertEqual(xpub, xpub2)
            path = child_path

        return xpub, xprv
Пример #13
0
    def _make_multisig(self, m, xpubs, signatures=None):
        if len(xpubs) == 1:
            return None

        pubkeys = [self._make_node_path(xpub, deriv) for xpub, deriv in xpubs]
        if signatures is None:
            signatures = [b''] * len(pubkeys)
        elif len(signatures) != len(pubkeys):
            raise RuntimeError('Mismatched number of signatures')
        else:
            signatures = [bfh(x)[:-1] if x else b'' for x in signatures]

        return MultisigRedeemScriptType(pubkeys=pubkeys,
                                        signatures=signatures,
                                        m=m)
Пример #14
0
 def do_send(self, tx):
     for window, xpub, K, _hash in self.cosigner_list:
         if not self.cosigner_can_sign(tx, xpub):
             continue
         message = bitcoin.encrypt_message(bfh(tx.raw),
                                           bh2u(K)).decode('ascii')
         try:
             server.put(_hash, message)
         except Exception as e:
             logging.exception("")
             window.show_message(
                 _("Failed to send transaction to cosigning pool."))
             return
         window.show_message(
             _("Your transaction was sent to the cosigning pool.") + '\n' +
             _("Open your cosigner wallet to retrieve it."))
Пример #15
0
    def on_receive(self, keyhash, message):
        logger.debug("signal arrived for '%s'", keyhash)
        window = None
        for key, _hash, window in self.keys:
            if _hash == keyhash:
                break
        else:
            logger.error("keyhash not found")
            return

        wallet = window.wallet
        if isinstance(wallet.keystore, keystore.Hardware_KeyStore):
            window.show_warning(
                _('An encrypted transaction was retrieved from cosigning pool.'
                  ) + '\n' +
                _('However, hardware wallets do not support message decryption, '
                  'which makes them not compatible with the current design of cosigner pool.'
                  ))
            return
        if wallet.has_password():
            password = window.password_dialog(
                _('An encrypted transaction was retrieved from cosigning pool.'
                  ) + '\n' + _('Please enter your password to decrypt it.'))
            if not password:
                return
        else:
            password = None
            if not window.question(
                    _("An encrypted transaction was retrieved from cosigning pool."
                      ) + '\n' + _("Do you want to open it now?")):
                return

        xprv = wallet.keystore.get_master_private_key(password)
        if not xprv:
            return
        try:
            k = bh2u(bitcoin.deserialize_xprv(xprv)[-1])
            EC = bitcoin.EC_KEY(bfh(k))
            message = bh2u(EC.decrypt_message(message))
        except Exception as e:
            logging.exception("")
            window.show_message(str(e))
            return

        self.listener.clear(keyhash)
        tx = transaction.Transaction(message)
        window.show_transaction(tx, prompt_if_unsaved=True)
Пример #16
0
    def do_send(self, wallet, tx):
        def on_done(window, future):
            try:
                future.result()
            except Exception as exc:
                window.on_exception(exc)
            else:
                window.show_message('\n'.join((
                    _("Your transaction was sent to the cosigning pool."),
                    _("Open your cosigner wallet to retrieve it."),
                )))

        def send_message():
            server.put(item.hash, message)

        for item in self.items:
            if self.is_theirs(wallet, item, tx):
                raw_tx_bytes = bfh(str(tx))
                public_key = PublicKey.from_bytes(item.K)
                message = public_key.encrypt_message_to_base64(raw_tx_bytes)
                WaitingDialog(item.window,
                              _('Sending transaction to cosigning pool...'),
                              send_message,
                              on_done=partial(on_done, item.window))
Пример #17
0
    def sign_transaction(self, tx, password):
        if tx.is_complete():
            return
        client = self.get_client()
        inputs = []
        inputsPaths = []
        pubKeys = []
        chipInputs = []
        redeemScripts = []
        signatures = []
        preparedTrustedInputs = []
        changePath = ""
        changeAmount = None
        output = None
        outputAmount = None
        p2shTransaction = False
        pin = ""
        self.get_client() # prompt for the PIN before displaying the dialog if necessary

        # Fetch inputs of the transaction to sign
        derivations = self.get_tx_derivations(tx)
        for txin in tx.inputs():
            if txin['type'] == 'coinbase':
                self.give_error("Coinbase not supported")     # should never happen

            if txin['type'] in ['p2sh']:
                p2shTransaction = True

            pubkeys, x_pubkeys = tx.get_sorted_pubkeys(txin)
            for i, x_pubkey in enumerate(x_pubkeys):
                if x_pubkey in derivations:
                    signingPos = i
                    s = derivations.get(x_pubkey)
                    hwAddress = "{:s}/{:d}/{:d}".format(self.get_derivation()[2:], s[0], s[1])
                    break
            else:
                self.give_error("No matching x_key for sign_transaction") # should never happen

            redeemScript = Transaction.get_preimage_script(txin)
            inputs.append([txin['prev_tx'].raw, txin['prevout_n'], redeemScript,
                           txin['prevout_hash'], signingPos,
                           txin.get('sequence', 0xffffffff - 1)])
            inputsPaths.append(hwAddress)
            pubKeys.append(pubkeys)

        # Sanity check
        if p2shTransaction:
            for txin in tx.inputs():
                if txin['type'] != 'p2sh':   # should never happen
                    self.give_error(
                        "P2SH / regular input mixed in same transaction not supported")

        txOutput = var_int(len(tx.outputs()))
        for txout in tx.outputs():
            output_type, addr, amount = txout
            txOutput += int_to_hex(amount, 8)
            script = tx.pay_script(addr)
            txOutput += var_int(len(script)//2)
            txOutput += script
        txOutput = bfh(txOutput)

        # Recognize outputs - only one output and one change is authorized
        if not p2shTransaction:
            for _type, address, amount in tx.outputs():
                assert _type == TYPE_ADDRESS
                info = tx.output_info.get(address)
                if (info is not None) and (len(tx.outputs()) != 1):
                    index, xpubs, m = info
                    changePath = self.get_derivation()[2:] + "/{:d}/{:d}".format(*index)
                    changeAmount = amount
                else:
                    output = address
                    outputAmount = amount

        self.handler.show_message(_("Confirm Transaction on your Ledger device..."))
        try:
            # Get trusted inputs from the original transactions
            for utxo in inputs:
                sequence = int_to_hex(utxo[5], 4)
                txtmp = bitcoinTransaction(bfh(utxo[0]))
                tmp = bfh(utxo[3])[::-1]
                tmp += bfh(int_to_hex(utxo[1], 4))
                tmp += txtmp.outputs[utxo[1]].amount
                chipInputs.append({'value' : tmp, 'witness' : True, 'sequence' : sequence})
                redeemScripts.append(bfh(utxo[2]))

            # Sign all inputs
            inputIndex = 0
            rawTx = tx.serialize()
            self.get_client().enableAlternate2fa(False)
            self.get_client().startUntrustedTransaction(True, inputIndex,
                                                        chipInputs, redeemScripts[inputIndex])
            outputData = self.get_client().finalizeInputFull(txOutput)
            outputData['outputData'] = txOutput
            transactionOutput = outputData['outputData']
            if outputData['confirmationNeeded']:
                outputData['address'] = output
                self.handler.finished()
                pin = self.handler.get_auth( outputData ) # the authenticate dialog and returns pin
                if not pin:
                    raise UserWarning()
                if pin != 'paired':
                    self.handler.show_message(_("Confirmed. Signing Transaction..."))
            while inputIndex < len(inputs):
                singleInput = [ chipInputs[inputIndex] ]
                self.get_client().startUntrustedTransaction(
                    False, 0, singleInput, redeemScripts[inputIndex])
                inputSignature = self.get_client().untrustedHashSign(inputsPaths[inputIndex],
                                                                     pin, lockTime=tx.locktime,
                                                                     sighashType=tx.nHashType())
                inputSignature[0] = 0x30 # force for 1.4.9+
                signatures.append(inputSignature)
                inputIndex = inputIndex + 1
        except UserWarning:
            self.handler.show_error(_('Cancelled by user'))
            return
        except BTChipException as e:
            if e.sw == 0x6985:  # cancelled by user
                return
            else:
                logging.exception("")
                self.give_error(e, True)
        except BaseException as e:
            logging.exception("")
            self.give_error(e, True)
        finally:
            self.handler.finished()

        for i, txin in enumerate(tx.inputs()):
            signingPos = inputs[i][4]
            txin['signatures'][signingPos] = bh2u(signatures[i])
        tx.raw = tx.serialize()
Пример #18
0
    def sign_transaction(self, tx, password):
        if tx.is_complete():
            return
        client = self.get_client()
        inputs = []
        inputsPaths = []
        chipInputs = []
        redeemScripts = []
        signatures = []
        preparedTrustedInputs = []
        changePath = ""
        changeAmount = None
        output = None
        outputAmount = None
        pin = ""
        self.get_client() # prompt for the PIN before displaying the dialog if necessary

        # Sanity check
        is_p2sh = any(txin.type() == 'p2sh' for txin in tx.inputs)
        if is_p2sh and not all(txin.type() == 'p2sh' for txin in tx.inputs):
            self.give_error("P2SH / regular input mixed in same transaction not supported")

        # Fetch inputs of the transaction to sign
        derivations = self.get_tx_derivations(tx)
        for txin in tx.inputs:
            for i, x_pubkey in enumerate(txin.x_pubkeys):
                if x_pubkey.to_hex() in derivations:
                    signingPos = i
                    s = derivations.get(x_pubkey.to_hex())
                    hwAddress = "{:s}/{:d}/{:d}".format(self.get_derivation()[2:], s[0], s[1])
                    break
            else:
                self.give_error("No matching x_key for sign_transaction") # should never happen

            redeemScript = Transaction.get_preimage_script(txin)
            inputs.append([txin.value, txin.prev_idx, redeemScript,
                           txin.prev_hash, signingPos, txin.sequence])
            inputsPaths.append(hwAddress)

        # Concatenate all the tx outputs as binary
        txOutput = pack_list(tx.outputs, TxOutput.to_bytes)

        # Recognize outputs - only one output and one change is authorized
        if not is_p2sh:
            for tx_output, info in zip(tx.outputs, tx.output_info):
                if (info is not None) and len(tx.outputs) != 1:
                    index, xpubs, m = info
                    changePath = self.get_derivation()[2:] + "/{:d}/{:d}".format(*index)
                    changeAmount = tx_output.value
                else:
                    output = classify_tx_output(tx_output)
                    outputAmount = tx_output.value

        self.handler.show_message(_("Confirm Transaction on your Ledger device..."))
        try:
            for utxo in inputs:
                sequence = int_to_hex(utxo[5], 4)
                chipInputs.append({'value' : utxo[0], 'witness' : True, 'sequence' : sequence})
                redeemScripts.append(bfh(utxo[2]))

            # Sign all inputs
            inputIndex = 0
            rawTx = tx.serialize()
            self.get_client().enableAlternate2fa(False)
            self.get_client().startUntrustedTransaction(True, inputIndex,
                                                        chipInputs, redeemScripts[inputIndex])
            outputData = self.get_client().finalizeInputFull(txOutput)
            outputData['outputData'] = txOutput
            transactionOutput = outputData['outputData']
            if outputData['confirmationNeeded']:
                outputData['address'] = output.to_string(coin=Net.COIN)
                self.handler.finished()
                pin = self.handler.get_auth( outputData ) # the authenticate dialog and returns pin
                if not pin:
                    raise UserWarning()
                self.handler.show_message(_("Confirmed. Signing Transaction..."))
            while inputIndex < len(inputs):
                singleInput = [ chipInputs[inputIndex] ]
                self.get_client().startUntrustedTransaction(
                    False, 0, singleInput, redeemScripts[inputIndex])
                inputSignature = self.get_client().untrustedHashSign(inputsPaths[inputIndex],
                                                                     pin, lockTime=tx.locktime,
                                                                     sighashType=tx.nHashType())
                inputSignature[0] = 0x30 # force for 1.4.9+
                signatures.append(inputSignature)
                inputIndex = inputIndex + 1
        except UserWarning:
            self.handler.show_error(_('Cancelled by user'))
            return
        except BTChipException as e:
            if e.sw == 0x6985:  # cancelled by user
                return
            else:
                logger.exception("")
                self.give_error(e, True)
        except Exception as e:
            logger.exception("")
            self.give_error(e, True)
        finally:
            self.handler.finished()

        for txin, input, signature in zip(tx.inputs, inputs, signatures):
            txin.signatures[input[4]] = signature
        tx.raw = tx.serialize()
Пример #19
0
    def tx_inputs(self, tx, for_sig=False):
        inputs = []
        for txin in tx.inputs():
            txinputtype = self.types.TxInputType()
            if txin['type'] == 'coinbase':
                prev_hash = bytes(32)
                prev_index = 0xffffffff  # signed int -1
            else:
                if for_sig:
                    x_pubkeys = txin['x_pubkeys']
                    if len(x_pubkeys) == 1:
                        x_pubkey = x_pubkeys[0]
                        xpub, s = parse_xpubkey(x_pubkey)
                        xpub_n = bip32_decompose_chain_string(
                            self.xpub_path[xpub])
                        txinputtype.address_n.extend(xpub_n + s)
                        txinputtype.script_type = self.types.SPENDADDRESS
                    else:

                        def f(x_pubkey):
                            if is_xpubkey(x_pubkey):
                                xpub, s = parse_xpubkey(x_pubkey)
                            else:
                                xpub = BIP32PublicKey(bfh(x_pubkey),
                                                      NULL_DERIVATION,
                                                      Net.COIN)
                                xpub = xpub.to_extended_key_string()
                                s = []
                            node = self.ckd_public.deserialize(xpub)
                            return self.types.HDNodePathType(node=node,
                                                             address_n=s)

                        pubkeys = [f(x) for x in x_pubkeys]
                        multisig = self.types.MultisigRedeemScriptType(
                            pubkeys=pubkeys,
                            signatures=[
                                bfh(x)[:-1] if x else b''
                                for x in txin.get('signatures')
                            ],
                            m=txin.get('num_sig'),
                        )
                        script_type = self.types.SPENDMULTISIG
                        txinputtype = self.types.TxInputType(
                            script_type=script_type, multisig=multisig)
                        # find which key is mine
                        for x_pubkey in x_pubkeys:
                            if is_xpubkey(x_pubkey):
                                xpub, s = parse_xpubkey(x_pubkey)
                                if xpub in self.xpub_path:
                                    xpub_n = bip32_decompose_chain_string(
                                        self.xpub_path[xpub])
                                    txinputtype.address_n.extend(xpub_n + s)
                                    break

                prev_hash = bytes.fromhex(txin['prevout_hash'])
                prev_index = txin['prevout_n']

            if 'value' in txin:
                txinputtype.amount = txin['value']
            txinputtype.prev_hash = prev_hash
            txinputtype.prev_index = prev_index

            if 'scriptSig' in txin:
                script_sig = bfh(txin['scriptSig'])
                txinputtype.script_sig = script_sig

            txinputtype.sequence = txin.get('sequence', 0xffffffff - 1)

            inputs.append(txinputtype)

        return inputs
Пример #20
0
    def tx_inputs(self, tx, for_sig=False):
        inputs = []
        for txin in tx.inputs():
            txinputtype = self.types.TxInputType()
            if txin['type'] == 'coinbase':
                prev_hash = "\0" * 32
                prev_index = 0xffffffff  # signed int -1
            else:
                if for_sig:
                    x_pubkeys = txin['x_pubkeys']
                    if len(x_pubkeys) == 1:
                        x_pubkey = x_pubkeys[0]
                        xpub, s = parse_xpubkey(x_pubkey)
                        xpub_n = self.client_class.expand_path(
                            self.xpub_path[xpub])
                        txinputtype.address_n.extend(xpub_n + s)
                        txinputtype.script_type = self.types.SPENDADDRESS
                    else:

                        def f(x_pubkey):
                            if is_xpubkey(x_pubkey):
                                xpub, s = parse_xpubkey(x_pubkey)
                            else:
                                xpub = xpub_from_pubkey(
                                    'standard', bfh(x_pubkey))
                                s = []
                            node = self.ckd_public.deserialize(xpub)
                            return self.types.HDNodePathType(node=node,
                                                             address_n=s)

                        pubkeys = [f(x) for x in x_pubkeys]
                        multisig = self.types.MultisigRedeemScriptType(
                            pubkeys=pubkeys,
                            signatures=[
                                bfh(x)[:-1] if x else b''
                                for x in txin.get('signatures')
                            ],
                            m=txin.get('num_sig'),
                        )
                        script_type = self.types.SPENDMULTISIG
                        txinputtype = self.types.TxInputType(
                            script_type=script_type, multisig=multisig)
                        # find which key is mine
                        for x_pubkey in x_pubkeys:
                            if is_xpubkey(x_pubkey):
                                xpub, s = parse_xpubkey(x_pubkey)
                                if xpub in self.xpub_path:
                                    xpub_n = self.client_class.expand_path(
                                        self.xpub_path[xpub])
                                    txinputtype.address_n.extend(xpub_n + s)
                                    break

                prev_hash = unhexlify(txin['prevout_hash'])
                prev_index = txin['prevout_n']

            if 'value' in txin:
                txinputtype.amount = txin['value']
            txinputtype.prev_hash = prev_hash
            txinputtype.prev_index = prev_index

            if 'scriptSig' in txin:
                script_sig = bfh(txin['scriptSig'])
                txinputtype.script_sig = script_sig

            txinputtype.sequence = txin.get('sequence', 0xffffffff - 1)

            inputs.append(txinputtype)

        return inputs