pub(crate) fn convert_vm_events_to_log_queries(events: &[VmEvent]) -> Vec<LogQuery> {
    events
        .iter()
        .flat_map(|event| {
            // Construct first query. This query holds an information about
            // - number of event topics (on log query level `event.address` is treated as a topic, thus + 1 is added)
            // - length of event value
            // - `event.address` (or first topic in terms of log query terminology).
            let first_key_word =
                (event.indexed_topics.len() as u64 + 1) + ((event.value.len() as u64) << 32);
            let key = U256([first_key_word, 0, 0, 0]);

            // `timestamp`, `aux_byte`, `read_value`, `rw_flag`, `rollback` are set as per convention.
            let first_log = LogQuery {
                timestamp: Timestamp(0),
                tx_number_in_block: event.location.1 as u16,
                aux_byte: 0,
                shard_id: 0,
                address: EVENT_WRITER_ADDRESS,
                key,
                read_value: U256::zero(),
                written_value: address_to_u256(&event.address),
                rw_flag: false,
                rollback: false,
                is_service: true,
            };

            // The next logs hold information about remaining topics and `event.value`.
            // Each log can hold at most two values each of 32 bytes.
            // The following piece of code prepares these 32-byte values.
            let values = event.indexed_topics.iter().map(|h| h256_to_u256(*h)).chain(
                event.value.chunks(32).map(|value_chunk| {
                    let mut padded = value_chunk.to_vec();
                    padded.resize(32, 0);
                    U256::from_big_endian(&padded)
                }),
            );

            // And now we process these values in chunks by two.
            let value_chunks = values.chunks(2);
            let other_logs = value_chunks.into_iter().map(|mut chunk| {
                // The first value goes to `log_query.key`.
                let key = chunk.next().unwrap();

                // If the second one is present then it goes to `log_query.written_value`.
                let written_value = chunk.next().unwrap_or_default();

                LogQuery {
                    timestamp: Timestamp(0),
                    tx_number_in_block: event.location.1 as u16,
                    aux_byte: 0,
                    shard_id: 0,
                    address: EVENT_WRITER_ADDRESS,
                    key,
                    read_value: U256::zero(),
                    written_value,
                    rw_flag: false,
                    rollback: false,
                    is_service: false,
                }
            });

            std::iter::once(first_log)
                .chain(other_logs)
                .collect::<Vec<_>>()
        })
        .collect()
}
Each `VmEvent` can be translated to several log queries.
This methods converts each event from input to log queries and returns all produced log queries.
core/node/commitment_generator/src/utils.rs