diff --git a/dap_chain_global_db.c b/dap_chain_global_db.c
index 071fe2cd1914a52a0cccc7cb224a46504688871c..83710a19e5d5a8ee18e3f43798303c737acf2f4e 100644
--- a/dap_chain_global_db.c
+++ b/dap_chain_global_db.c
@@ -81,6 +81,22 @@ void dap_chain_global_db_deinit(void)
  *
  */
 
+void* dap_chain_global_db_obj_get(const char *a_key, const char *a_group)
+{
+    int count = 0;
+    if(!a_key)
+        return NULL;
+    size_t query_len = snprintf(NULL, 0, "(&(cn=%s)(objectClass=%s))", a_key, a_group);
+    char *query = DAP_NEW_Z_SIZE(char, query_len + 1); //char query[32 + strlen(a_key)];
+    snprintf(query, query_len + 1, "(&(cn=%s)(objectClass=%s))", a_key, a_group); // objectClass != ou
+    pthread_mutex_lock(&ldb_mutex);
+    pdap_store_obj_t store_data = dap_db_read_data(query, &count, a_group);
+    pthread_mutex_unlock(&ldb_mutex);
+    assert(count <= 1);
+    DAP_DELETE(query);
+    return store_data;
+}
+
 char * dap_chain_global_db_gr_get(const char *a_key, const char *a_group)
 {
     char *str = NULL;
@@ -208,12 +224,26 @@ dap_global_db_obj_t** dap_chain_global_db_load(size_t *a_data_size_out)
 /**
  * Write to the database from an array of data_size bytes
  *
- * @param data array wish base dump
- * @param data size of array
  * @return
  */
+bool dap_chain_global_db_obj_save(void* a_store_data, size_t a_objs_count)
+{
+    dap_store_obj_t* l_store_data = (dap_store_obj_t*)a_store_data;
+    if(l_store_data && a_objs_count>0)
+    {
+        const char *l_group = l_store_data[0].group;
+        pthread_mutex_lock(&ldb_mutex);
+        int res = dap_db_add(l_store_data, a_objs_count);
+        if(!res && !is_local_group(l_group))
+            dap_db_history_add('a', l_store_data, a_objs_count);
+        pthread_mutex_unlock(&ldb_mutex);
+        if(!res)
+            return true;
+    }
+    return false;
+}
+
 bool dap_chain_global_db_gr_save(dap_global_db_obj_t* a_objs, size_t a_objs_count, const char *a_group)
-//bool dap_chain_global_db_gr_save(uint8_t* a_data, size_t a_data_size, const char *a_group)
 {
     //int count = 0;
     //dap_store_obj_pkt_t *pkt = DAP_NEW_Z_SIZE(dap_store_obj_pkt_t, sizeof(dap_store_obj_pkt_t));
@@ -236,7 +266,7 @@ bool dap_chain_global_db_gr_save(dap_global_db_obj_t* a_objs, size_t a_objs_coun
         if(!res && !is_local_group(a_group))
             dap_db_history_add('a', store_data, a_objs_count);
         pthread_mutex_unlock(&ldb_mutex);
-        DAP_DELETE(store_data);//dab_db_free_pdap_store_obj_t(store_data, a_objs_count);
+        DAP_DELETE(store_data); //dab_db_free_pdap_store_obj_t(store_data, a_objs_count);
         if(!res)
             return true;
     }
diff --git a/dap_chain_global_db.h b/dap_chain_global_db.h
index 554ba942c8d196d4c3823c3f46df18fbc5725e2b..ef3ab4e787b53ca25cf574f79957bc5e1d8cc88d 100644
--- a/dap_chain_global_db.h
+++ b/dap_chain_global_db.h
@@ -39,6 +39,7 @@ void dap_chain_global_db_deinit();
 /**
  * Get entry from base
  */
+void* dap_chain_global_db_obj_get(const char *a_key, const char *a_group);
 char * dap_chain_global_db_gr_get(const char *a_key, const char *a_group);
 char* dap_chain_global_db_get(const char *a_key);
 
@@ -66,10 +67,9 @@ dap_global_db_obj_t** dap_chain_global_db_load(size_t *a_data_size_out);
 /**
  * Write to the database from an array of data_size bytes
  *
- * @param data array wish base dump
- * @param data size of array
  * @return
  */
+bool dap_chain_global_db_obj_save(void* a_store_data, size_t a_objs_count);
 bool dap_chain_global_db_gr_save(dap_global_db_obj_t* a_objs, size_t a_objs_count, const char *a_group);
 bool dap_chain_global_db_save(dap_global_db_obj_t* a_objs, size_t a_objs_count);
 
@@ -81,6 +81,11 @@ bool dap_chain_global_db_save(dap_global_db_obj_t* a_objs, size_t a_objs_count);
 char* dap_chain_global_db_hash(const uint8_t *data, size_t data_size);
 char* dap_chain_global_db_hash_fast(const uint8_t *data, size_t data_size);
 
+// Get data according the history log
+uint8_t* dap_db_log_pack(dap_global_db_obj_t *a_obj, int *a_data_size_out);
+// Parse data from dap_db_log_pack()
+void* dap_db_log_unpack(uint8_t *a_data, int a_data_size, int *a_store_obj_count);
+
 // Get last timestamp in log
 char *dap_db_log_get_last_timestamp(void);
 // Get log diff as list
diff --git a/dap_chain_global_db_hist.c b/dap_chain_global_db_hist.c
index 52766ebc3ae2c57bbfb7d20c1927ddbd53c50e3c..9ef5a9847fb85dd74b6c56b27858c1241642104c 100644
--- a/dap_chain_global_db_hist.c
+++ b/dap_chain_global_db_hist.c
@@ -38,6 +38,61 @@ static char* dap_db_history_timestamp()
     return dap_strdup_printf("%lld", (uint64_t) l_cur_time);
 }
 
+/**
+ * Get data according the history log
+ *
+ * return dap_store_obj_pkt_t*
+ */
+uint8_t* dap_db_log_pack(dap_global_db_obj_t *a_obj, int *a_data_size_out)
+{
+    if(!a_obj)
+        return NULL;
+    dap_global_db_hist_t l_rec;
+    if(dap_db_history_unpack_hist(a_obj->value, &l_rec) == -1)
+        return NULL;
+    // parse global_db records in a history record
+    char **l_keys = dap_strsplit(l_rec.keys, HIST_KEY_SEPARATOR, -1);
+    int l_count = dap_str_countv(l_keys);
+    // read records from global_db
+    int i = 0;
+    dap_store_obj_t *l_store_obj = DAP_NEW_Z_SIZE(dap_store_obj_t, l_count * sizeof(dap_store_obj_t));
+    while(l_keys[i]) {
+
+        dap_store_obj_t *l_obj = (dap_store_obj_t*) dap_chain_global_db_obj_get(l_keys[i], l_rec.group);
+        memcpy(l_store_obj + i, l_obj, sizeof(dap_store_obj_t));
+        DAP_DELETE(l_obj);
+        i++;
+    };
+    // serialize data
+    dap_store_obj_pkt_t *l_data_out = dap_store_packet_multiple(l_store_obj, l_count);
+
+    dab_db_free_pdap_store_obj_t(l_store_obj, l_count);
+    dap_strfreev(l_keys);
+
+    if(l_data_out && a_data_size_out) {
+        *a_data_size_out = sizeof(dap_store_obj_pkt_t) + l_data_out->data_size;
+    }
+    return (uint8_t*) l_data_out;
+
+}
+
+/**
+ * Parse data from dap_db_log_pack()
+ *
+ * return dap_store_obj_t*
+ */
+void* dap_db_log_unpack(uint8_t *a_data, int a_data_size, int *a_store_obj_count)
+{
+    dap_store_obj_pkt_t *l_pkt = (dap_store_obj_pkt_t*) a_data;
+    if(!l_pkt || l_pkt->data_size != (a_data_size - sizeof(dap_store_obj_pkt_t)))
+        return NULL;
+    int l_store_obj_count = 0;
+    dap_store_obj_t *l_obj = dap_store_unpacket(l_pkt, &l_store_obj_count);
+    if(a_store_obj_count)
+        *a_store_obj_count = l_store_obj_count;
+    return l_obj;
+}
+
 /**
  * Add data to the history log
  */
@@ -48,6 +103,7 @@ bool dap_db_history_add(char a_type, pdap_store_obj_t a_store_obj, int a_dap_sto
     dap_global_db_hist_t l_rec;
     l_rec.keys_count = a_dap_store_count;
     l_rec.type = a_type;
+    // TODO Make for keys_count>1
     if(l_rec.keys_count >= 1)
         l_rec.group = a_store_obj->group;
     if(l_rec.keys_count == 1)
@@ -94,7 +150,7 @@ bool dap_db_history_truncate(void)
  */
 char *dap_db_log_get_last_timestamp(void)
 {
-    char *last_key;
+    char *last_key = NULL;
     size_t l_data_size_out = 0;
     dap_global_db_obj_t **l_objs = dap_chain_global_db_gr_load(GROUP_HISTORY, &l_data_size_out);
     if(l_data_size_out > 0)
@@ -140,7 +196,7 @@ dap_list_t* dap_db_log_get_list(time_t first_timestamp)
  */
 void dap_db_log_del_list(dap_list_t *a_list)
 {
-    dap_list_free_full(a_list, dap_chain_global_db_obj_delete);
+    dap_list_free_full(a_list, (DapDestroyNotify) dap_chain_global_db_obj_delete);
 }
 
 /**