'Return a dict with the following:
* chain_candidates[]
* chain
* in_longest
* chain_satoshis
* chain_satoshi_seconds
* chain_work
* fees
* generated
* hash
* hashMerkleRoot
* hashPrev
* height
* nBits
* next_block_hashes
* nNonce
* nTime
* satoshis_destroyed
* satoshi_seconds
* transactions[]
* fees
* hash
* in[]
* address_version
* binaddr
* value
* out[]
* address_version
* binaddr
* value
* size
* value_out
* version
Additionally, for multisig inputs and outputs:
* subbinaddr[]
* required_signatures
Additionally, for proof-of-stake chains:
* is_proof_of_stake
* proof_of_stake_generated'

def export_block(store, chain=None, block_hash=None, block_number=None):

    if ((block_number is None) and (block_hash is None)):
        raise ValueError('export_block    requires    either    block_hash    or    block_number')
    where = []
    bind = []
    if (chain is not None):
        where.append('chain_id    =    ?')
        bind.append(chain.id)
    if (block_hash is not None):
        where.append('block_hash    =    ?')
        bind.append(store.hashin_hex(block_hash))
    if (block_number is not None):
        where.append('block_height    =    ?    AND    in_longest    =    1')
        bind.append(block_number)
    sql = (('\n                                                SELECT\n                                                                chain_id,\n                                                                in_longest,\n                                                                block_id,\n                                                                block_hash,\n                                                                block_version,\n                                                                block_hashMerkleRoot,\n                                                                block_nTime,\n                                                                block_nBits,\n                                                                block_nNonce,\n                                                                block_height,\n                                                                prev_block_hash,\n                                                                block_chain_work,\n                                                                block_value_in,\n                                                                block_value_out,\n                                                                block_total_satoshis,\n                                                                block_total_seconds,\n                                                                block_satoshi_seconds,\n                                                                block_total_ss,\n                                                                block_ss_destroyed,\n                                                                block_num_tx\n                                                        FROM    chain_summary\n                                                    WHERE    ' + '    AND    '.join(where)) + '\n                                                    ORDER    BY\n                                                                in_longest    DESC,\n                                                                chain_id    DESC')
    rows = store.selectall(sql, bind)
    if (len(rows) == 0):
        return None
    row = rows[0][2:]
    def parse_cc(row):
        (chain_id, in_longest) = row[:2]
        return {'chain': store.get_chain_by_id(chain_id), 'in_longest': in_longest}
    cc = map(parse_cc, rows)
    found_chain = chain
    if (found_chain is None):
        if (len(cc) > 0):
            found_chain = cc[0]['chain']
        else:
            found_chain = store.get_default_chain()
    (block_id, block_hash, block_version, hashMerkleRoot, nTime, nBits, nNonce, height, prev_block_hash, block_chain_work, value_in, value_out, satoshis, seconds, ss, total_ss, destroyed, num_tx) = (row[0], store.hashout_hex(row[1]), row[2], store.hashout_hex(row[3]), row[4], int(row[5]), row[6], row[7], store.hashout_hex(row[8]), store.binout_int(row[9]), int(row[10]), int(row[11]), (None if (row[12] is None) else int(row[12])), (None if (row[13] is None) else int(row[13])), (None if (row[14] is None) else int(row[14])), (None if (row[15] is None) else int(row[15])), (None if (row[16] is None) else int(row[16])), int(row[17]))
    next_hashes = [store.hashout_hex(hash) for (hash, il) in store.selectall('\n                                                SELECT    DISTINCT    n.block_hash,    cc.in_longest\n                                                        FROM    block_next    bn\n                                                        JOIN    block    n    ON    (bn.next_block_id    =    n.block_id)\n                                                        JOIN    chain_candidate    cc    ON    (n.block_id    =    cc.block_id)\n                                                    WHERE    bn.block_id    =    ?\n                                                    ORDER    BY    cc.in_longest    DESC', (block_id,))]
    tx_ids = []
    txs = {}
    block_out = 0
    block_in = 0
    for row in store.selectall('\n                                                SELECT    tx_id,    tx_hash,    tx_size,    txout_value,    txout_scriptPubKey\n                                                        FROM    txout_detail\n                                                    WHERE    block_id    =    ?\n                                                    ORDER    BY    tx_pos,    txout_pos\n                                ', (block_id,)):
        (tx_id, tx_hash, tx_size, txout_value, scriptPubKey) = (row[0], row[1], row[2], int(row[3]), store.binout(row[4]))
        tx = txs.get(tx_id)
        if (tx is None):
            tx_ids.append(tx_id)
            txs[tx_id] = {'hash': store.hashout_hex(tx_hash), 'total_out': 0, 'total_in': 0, 'out': [], 'in': [], 'size': int(tx_size)}
            tx = txs[tx_id]
        tx['total_out'] += txout_value
        block_out += txout_value
        txout = {'value': txout_value}
        store._export_scriptPubKey(txout, found_chain, scriptPubKey)
        tx['out'].append(txout)
    for row in store.selectall('\n                                                SELECT    tx_id,    txin_value,    txin_scriptPubKey\n                                                        FROM    txin_detail\n                                                    WHERE    block_id    =    ?\n                                                    ORDER    BY    tx_pos,    txin_pos\n                                ', (block_id,)):
        (tx_id, txin_value, scriptPubKey) = (row[0], (0 if (row[1] is None) else int(row[1])), store.binout(row[2]))
        tx = txs.get(tx_id)
        if (tx is None):
            tx_ids.append(tx_id)
            (tx_hash, tx_size) = store.selectrow('\n                                                                                SELECT    tx_hash,    tx_size    FROM    tx    WHERE    tx_id    =    ?', (tx_id,))
            txs[tx_id] = {'hash': store.hashout_hex(tx_hash), 'total_out': 0, 'total_in': 0, 'out': [], 'in': [], 'size': int(tx_size)}
            tx = txs[tx_id]
        tx['total_in'] += txin_value
        block_in += txin_value
        txin = {'value': txin_value}
        store._export_scriptPubKey(txin, found_chain, scriptPubKey)
        tx['in'].append(txin)
    generated = (block_out - block_in)
    coinbase_tx = txs[tx_ids[0]]
    coinbase_tx['fees'] = 0
    block_fees = (coinbase_tx['total_out'] - generated)
    b = {'chain_candidates': cc, 'chain_satoshis': satoshis, 'chain_satoshi_seconds': total_ss, 'chain_work': block_chain_work, 'fees': block_fees, 'generated': generated, 'hash': block_hash, 'hashMerkleRoot': hashMerkleRoot, 'hashPrev': prev_block_hash, 'height': height, 'nBits': nBits, 'next_block_hashes': next_hashes, 'nNonce': nNonce, 'nTime': nTime, 'satoshis_destroyed': destroyed, 'satoshi_seconds': ss, 'transactions': [txs[tx_id] for tx_id in tx_ids], 'value_out': block_out, 'version': block_version}
    is_stake_chain = ((chain is not None) and chain.has_feature('nvc_proof_of_stake'))
    if is_stake_chain:
        b['is_proof_of_stake'] = ((len(tx_ids) > 1) and (coinbase_tx['total_out'] == 0))
    for tx_id in tx_ids[1:]:
        tx = txs[tx_id]
        tx['fees'] = (tx['total_in'] - tx['total_out'])
    if (is_stake_chain and b['is_proof_of_stake']):
        b['proof_of_stake_generated'] = (- txs[tx_ids[1]]['fees'])
        txs[tx_ids[1]]['fees'] = 0
        b['fees'] += b['proof_of_stake_generated']
    return b
