Calculate the sighash for a segwit transaction, according to bip143

def btc_tx_sighash_segwit(tx, i, prevout_amount, prevout_script, hashcode=SIGHASH_ALL):
    """
    Calculate the sighash for a segwit transaction, according to bip143
    """
    txobj = btc_tx_deserialize(tx)

    hash_prevouts = encoding.encode(0, 256, 32)
    hash_sequence = encoding.encode(0, 256, 32)
    hash_outputs = encoding.encode(0, 256, 32)

    if (hashcode & SIGHASH_ANYONECANPAY) == 0:
        prevouts = ''
        for inp in txobj['ins']:
            prevouts += hashing.reverse_hash(inp['outpoint']['hash'])
            prevouts += encoding.encode(inp['outpoint']['index'], 256, 4)[::-1].encode('hex')

        hash_prevouts = hashing.bin_double_sha256(prevouts.decode('hex'))

        # print 'prevouts: {}'.format(prevouts)

    if (hashcode & SIGHASH_ANYONECANPAY) == 0 and (hashcode & 0x1f) != SIGHASH_SINGLE and (hashcode & 0x1f) != SIGHASH_NONE:
        sequences = ''
        for inp in txobj['ins']:
            sequences += encoding.encode(inp['sequence'], 256, 4)[::-1].encode('hex')

        hash_sequence = hashing.bin_double_sha256(sequences.decode('hex'))

        # print 'sequences: {}'.format(sequences)

    if (hashcode & 0x1f) != SIGHASH_SINGLE and (hashcode & 0x1f) != SIGHASH_NONE:
        outputs = ''
        for out in txobj['outs']:
            outputs += encoding.encode(out['value'], 256, 8)[::-1].encode('hex')
            outputs += make_var_string(out['script'])

        hash_outputs = hashing.bin_double_sha256(outputs.decode('hex'))

        # print 'outputs: {}'.format(outputs)

    elif (hashcode & 0x1f) == SIGHASH_SINGLE and i < len(txobj['outs']):
        outputs = ''
        outputs += encoding.encode(txobj['outs'][i]['value'], 256, 8)[::-1].encode('hex')
        outputs += make_var_string(txobj['outs'][i]['script'])

        hash_outputs = hashing.bin_double_sha256(outputs.decode('hex'))

        # print 'outputs: {}'.format(outputs)

    # print 'hash_prevouts: {}'.format(hash_prevouts.encode('hex'))
    # print 'hash_sequence: {}'.format(hash_sequence.encode('hex'))
    # print 'hash_outputs: {}'.format(hash_outputs.encode('hex'))
    # print 'prevout_script: {}'.format(prevout_script)
    # print 'prevout_amount: {}'.format(prevout_amount)

    sighash_preimage = ''
    sighash_preimage += encoding.encode(txobj['version'], 256, 4)[::-1].encode('hex')
    sighash_preimage += hash_prevouts.encode('hex')
    sighash_preimage += hash_sequence.encode('hex')

    # this input's prevout, script, amount, and sequence
    sighash_preimage += hashing.reverse_hash(txobj['ins'][i]['outpoint']['hash'])
    sighash_preimage += encoding.encode(txobj['ins'][i]['outpoint']['index'], 256, 4)[::-1].encode('hex')
    sighash_preimage += make_var_string(prevout_script)
    sighash_preimage += encoding.encode(prevout_amount, 256, 8)[::-1].encode('hex')
    sighash_preimage += encoding.encode(txobj['ins'][i]['sequence'], 256, 4)[::-1].encode('hex')

    sighash_preimage += hash_outputs.encode('hex')
    sighash_preimage += encoding.encode(txobj['locktime'], 256, 4)[::-1].encode('hex')
    sighash_preimage += encoding.encode(hashcode, 256, 4)[::-1].encode('hex')

    sighash = hashing.bin_double_sha256(sighash_preimage.decode('hex')).encode('hex')

    # print 'sighash_preimage: {}'.format(sighash_preimage)
    # print 'sighash: {}'.format(sighash)

    return sighash