Create the initial account balances.
    All accounts will be locked, and will have been created at the genesis date
    for Blockstack (i.e. FIRST_BLOCK_MAINNET)

    The genesis block has multiple "stages" that encode the transfer of tokens from
    Blockstack Token LLC to the various investors, GPs, etc.  For the initial genesis
    block for the accredited token sale, there should be four such stages.

    @initial_account_balances is the final genesis block stage that encodes the
    token allocations and unlock periods for each initial account holder (i.e. the
    initial investors)

    @genesis_block_history is a sequence of signed hashes over each stage.
    
    @initial_count_balances is a list of dicts:
    [
        {
            'address': ...,
            'type': ...,
            'value': ...,
            'vesting': {
                block_height: value
            },
            'vesting_total': ...,
            'lock_send': ... (optional; block height)
            'receive_whitelisted': ... (optional; bool)
            'metadata': ... (optional)
        },
        {...}
    ]
    @genesis_block_history this structure:
    [
        {
            "hash": ...,
            "signature": ...
        },
    ]
    We'll store the genesis block history's canonical hash as the first transaction.

def namedb_create_token_genesis(con, initial_account_balances, genesis_block_history):
    """
    Create the initial account balances.
    All accounts will be locked, and will have been created at the genesis date
    for Blockstack (i.e. FIRST_BLOCK_MAINNET)

    The genesis block has multiple "stages" that encode the transfer of tokens from
    Blockstack Token LLC to the various investors, GPs, etc.  For the initial genesis
    block for the accredited token sale, there should be four such stages.

    @initial_account_balances is the final genesis block stage that encodes the
    token allocations and unlock periods for each initial account holder (i.e. the
    initial investors)

    @genesis_block_history is a sequence of signed hashes over each stage.
    
    @initial_count_balances is a list of dicts:
    [
        {
            'address': ...,
            'type': ...,
            'value': ...,
            'vesting': {
                block_height: value
            },
            'vesting_total': ...,
            'lock_send': ... (optional; block height)
            'receive_whitelisted': ... (optional; bool)
            'metadata': ... (optional)
        },
        {...}
    ]
    @genesis_block_history this structure:
    [
        {
            "hash": ...,
            "signature": ...
        },
    ]
    We'll store the genesis block history's canonical hash as the first transaction.
    """
    namedb_query_execute(con, "BEGIN", ())
    for account_info in initial_account_balances:
        # check required fields 
        for f in ['address', 'type', 'value']:
            assert f in account_info, 'BUG: missing {} in {}'.format(f, account_info)

        metadata = None
        address = None

        try:
            address = account_info['address']
            if is_c32_address(address):
                address = address_as_b58(address)

            address = virtualchain.address_reencode(address)
        except ValueError:
            assert account_info.get('receive_whitelisted') == False, 'Unspendable address "{}" must be explicitly marked as not receive-whitelisted'.format(account_info['address'])

            log.warning('Using unspendable address "{}"'.format(account_info['address']))
            address = account_info['address']

        if 'metadata' in account_info and account_info['metadata'] is not None:
            metadata = account_info['metadata']
            log.debug('Grant {} to {} (originally: {}, metadata: {})'.format(account_info['value'], address, account_info['address'], metadata))

        else:
            log.debug('Grant {} to {}'.format(account_info['value'], address))
            metadata = '' 

        lock_send = account_info.get('lock_send', 0)
        assert lock_send >= 0, 'Invalid lock_send: {}'.format(lock_send)

        receive_whitelisted = account_info.get('receive_whitelisted', True)     # whitelist by default for now

        # set up initial account balances
        sql = 'INSERT INTO accounts VALUES (?,?,?,?,?,?,?,?,?,?);'

        fake_txid = namedb_genesis_txid(address, metadata)

        args = (address, account_info['type'], '{}'.format(account_info['value']), '0', lock_send, receive_whitelisted, metadata, FIRST_BLOCK_MAINNET, fake_txid, 0)
        namedb_query_execute(con, sql, args)

        # set up vesting period
        if 'vesting' in account_info:
            assert 'vesting_total' in account_info, 'BUG: vesting is present but vesting_total is not'

            vesting_sum = sum([account_info['vesting'][h] for h in account_info['vesting']]) 
            assert vesting_sum == account_info['vesting_total'], 'BUG: vesting mismatch on {}: {} != {} ({})'.format(address, vesting_sum, account_info['vesting_total'], account_info['vesting'])

            for block_height in account_info['vesting']:
                sql = 'INSERT INTO account_vesting VALUES (?,?,?,?);'
                args = (address, account_info['type'], '{}'.format(account_info['vesting'][block_height]), int(block_height))
                namedb_query_execute(con, sql, args)

    # insert genesis history 
    genesis_hash = namedb_genesis_block_history_hash(genesis_block_history)
    sql = 'INSERT INTO accounts VALUES (?,?,?,?,?,?,?,?,?,?);'
    args = (BLOCKSTACK_BURN_ADDRESS, 'GENESIS', '0', '0', True, False, genesis_hash, FIRST_BLOCK_MAINNET, genesis_hash, 0)
    namedb_query_execute(con, sql, args)

    namedb_query_execute(con, "END", ())