diff --git a/CMakeLists.txt b/CMakeLists.txt
index ecaf5efeb98c0a8350b6ef22458a607f63885b8d..bc89b6933001a05f67334cf4e1b16e3784a9b55d 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,9 +4,27 @@ project (dap_chain_global_db)
 file(GLOB DAP_CHAIN_GLOBAL_DB_SRC *.c)
 file(GLOB DAP_CHAIN_GLOBAL_DB_HDR *.h)
 
+if(WIN32)
+  include_directories(../libdap/src/win32/)
+  include_directories(../3rdparty/libmemcached/)
+  include_directories(../3rdparty/libmemcached/win32/)
+  include_directories(../3rdparty/wepoll/include/)
+  include_directories(../3rdparty/uthash/src/)
+  include_directories(../3rdparty/libjson-c/)
+  include_directories(../3rdparty/libmagic/src/)
+  include_directories(../3rdparty/curl/include/)
+  include_directories(../3rdparty/libsqlite3/)
+endif()
+
 add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_GLOBAL_DB_SRC} ${DAP_CHAIN_GLOBAL_DB_HDR})
 
-target_link_libraries(dap_chain_global_db dap_core dap_crypto dap_chain dap_chain_crypto ldb talloc tevent sqlite3 ${CMAKE_CURRENT_SOURCE_DIR}/libcuttdb.a)
+if(WIN32)
+  target_link_libraries(dap_chain_global_db dap_core dap_crypto dap_chain dap_chain_crypto)
+endif()
+if(UNIX)
+  target_link_libraries(dap_chain_global_db dap_core dap_crypto dap_chain dap_chain_crypto ldb talloc tevent sqlite3 ${CMAKE_CURRENT_SOURCE_DIR}/libcuttdb.a)
+endif()
+
 target_include_directories(dap_chain_global_db INTERFACE .)
 
 set(${PROJECT_NAME}_DEFINITIONS CACHE INTERNAL "${PROJECT_NAME}: Definitions" FORCE)
diff --git a/dap_chain_global_db.c b/dap_chain_global_db.c
index 412c07bc138936fe1ca6a5eeed9a15dde27f839a..f28b49dc147ae6b8d821a5ef5c52e5248cf002d0 100755
--- a/dap_chain_global_db.c
+++ b/dap_chain_global_db.c
@@ -77,7 +77,10 @@ char * extract_group_prefix(const char * a_group)
 {
     char * l_group_prefix = NULL, *l_delimeter;
     size_t l_group_prefix_size;
-    l_delimeter = index(a_group, '.');
+
+//    l_delimeter = index(a_group, '.');
+    l_delimeter = strchr(a_group, '.');
+
     if(l_delimeter == NULL) {
         l_group_prefix = dap_strdup(a_group);
         l_group_prefix_size = dap_strlen(l_group_prefix) + 1;
diff --git a/dap_chain_global_db.h b/dap_chain_global_db.h
index 23ff07d57334ff888b0f8e654ab70c921f81cb29..0bc7ae0e7705e777578e6e27cb454427ae561848 100755
--- a/dap_chain_global_db.h
+++ b/dap_chain_global_db.h
@@ -7,6 +7,7 @@
 #include "dap_common.h"
 #include "dap_config.h"
 #include "dap_list.h"
+#include "dap_chain_common.h"
 #include "dap_chain_global_db_driver.h"
 
 
@@ -100,6 +101,12 @@ 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, size_t *a_data_size_out);
+
+// Get data according the history log
+//char* dap_db_history_tx(dap_chain_hash_fast_t * a_tx_hash, const char *a_group_mempool);
+//char* dap_db_history_addr(dap_chain_addr_t * a_addr, const char *a_group_mempool);
+//char* dap_db_history_filter(dap_chain_addr_t * a_addr, const char *a_group_mempool);
+
 // Parse data from dap_db_log_pack()
 void* dap_db_log_unpack(const void *a_data, size_t a_data_size, size_t *a_store_obj_count);
 // Get timestamp from dap_db_log_pack()
diff --git a/dap_chain_global_db_driver_cdb.c b/dap_chain_global_db_driver_cdb.c
index 67742a34236b52392e5d7065214e52f2df3d0b87..85ac361b8e06f0f5999b116cf8eba0b74fa40d92 100644
--- a/dap_chain_global_db_driver_cdb.c
+++ b/dap_chain_global_db_driver_cdb.c
@@ -187,7 +187,13 @@ int dap_db_driver_cdb_init(const char *a_cdb_path, dap_db_driver_callbacks_t *a_
     if(s_cdb_path[strlen(s_cdb_path)] == '/') {
         s_cdb_path[strlen(s_cdb_path)] = '\0';
     }
+
+#ifdef _WIN32
+    mkdir(s_cdb_path);
+#else
     mkdir(s_cdb_path, 0755);
+#endif
+
     struct dirent *d;
     DIR *dir = opendir(s_cdb_path);
     if (!dir) {
@@ -229,7 +235,13 @@ int dap_cdb_add_group(const char *a_group) {
     strcat(l_cdb_path, s_cdb_path);
     strcat(l_cdb_path, "/");
     strcat(l_cdb_path, a_group);
+
+#ifdef _WIN32
+    mkdir(l_cdb_path);
+#else
     mkdir(l_cdb_path, 0755);
+#endif
+
     return 0;
 }
 
@@ -312,7 +324,7 @@ dap_store_obj_t *dap_db_driver_cdb_read_store_obj(const char *a_group, const cha
         if(a_count_out) {
             *a_count_out = l_count_out;
         }
-        for (ulong i = 0; i < l_count_out; ++i) {
+        for (uint64_t i = 0; i < l_count_out; ++i) {
             l_arg.o[i].group = dap_strdup(a_group);
         }
         l_obj = l_arg.o;
@@ -360,7 +372,7 @@ dap_store_obj_t* dap_db_driver_cdb_read_cond_store_obj(const char *a_group, uint
     if(a_count_out) {
         *a_count_out = l_count_out;
     }
-    for (ulong i = 0; i < l_count_out; ++i) {
+    for (uint64_t i = 0; i < l_count_out; ++i) {
         l_arg.o[i].group = dap_strdup(a_group);
     }
     return l_arg.o;
diff --git a/dap_chain_global_db_hist.c b/dap_chain_global_db_hist.c
index 6f642922dbe3420cb758686f7bf2c80a64507005..b1ca5b4a9dfa643d265bd1ad30a71c065bf08fca 100755
--- a/dap_chain_global_db_hist.c
+++ b/dap_chain_global_db_hist.c
@@ -5,9 +5,26 @@
 
 #include <dap_common.h>
 #include <dap_strfuncs.h>
+#include <dap_list.h>
+#include <dap_string.h>
+#include <dap_hash.h>
+#include "dap_chain_datum_tx_items.h"
+
 #include "dap_chain_global_db.h"
 #include "dap_chain_global_db_hist.h"
 
+#include "uthash.h"
+// for dap_db_history_filter()
+typedef struct dap_tx_data{
+        dap_chain_hash_fast_t tx_hash;
+        char tx_hash_str[70];
+        char token_ticker[10];
+        size_t obj_num;
+        size_t pos_num;
+        dap_chain_addr_t addr;
+        UT_hash_handle hh;
+} dap_tx_data_t;
+
 #define LOG_TAG "dap_chain_global_db_hist"
 
 static char* dap_db_history_pack_hist(dap_global_db_hist_t *a_rec)
@@ -111,6 +128,938 @@ uint8_t* dap_db_log_pack(dap_global_db_obj_t *a_obj, size_t *a_data_size_out)
 
 }
 
+
+// for dap_db_history_filter()
+static dap_store_obj_t* get_prev_tx(dap_global_db_obj_t *a_objs, dap_tx_data_t *a_tx_data)
+{
+    if(!a_objs || !a_tx_data)
+        return NULL;
+    dap_global_db_obj_t *l_obj_cur = a_objs + a_tx_data->obj_num;
+    dap_global_db_hist_t l_rec;
+    if(dap_db_history_unpack_hist((char*) l_obj_cur->value, &l_rec) == -1)
+        return NULL;
+    char **l_keys = dap_strsplit(l_rec.keys, GLOBAL_DB_HIST_KEY_SEPARATOR, -1);
+    size_t l_count = dap_str_countv(l_keys);
+    if(a_tx_data->pos_num >= l_count) {
+        dap_strfreev(l_keys);
+        return NULL;
+    }
+    dap_store_obj_t *l_obj =
+            (dap_store_obj_t*) l_keys ? dap_chain_global_db_obj_get(l_keys[a_tx_data->pos_num], l_rec.group) : NULL;
+    dap_strfreev(l_keys);
+    return l_obj;
+}
+
+/**
+ * Get data according the history log
+ *
+ * return history string
+ */
+#if 0
+char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, const char *a_group_mempool)
+{
+    dap_string_t *l_str_out = dap_string_new(NULL);
+    // load history
+    size_t l_data_size_out = 0;
+    dap_global_db_obj_t *l_objs = dap_chain_global_db_gr_load(GROUP_LOCAL_HISTORY, &l_data_size_out);
+    size_t i, j;
+    bool l_tx_hash_found = false;
+    dap_tx_data_t *l_tx_data_hash = NULL;
+    for(i = 0; i < l_data_size_out; i++) {
+        dap_global_db_obj_t *l_obj_cur = l_objs + i;
+
+        // parse global_db records in a history record
+        dap_global_db_hist_t l_rec;
+        if(dap_db_history_unpack_hist((char*) l_obj_cur->value, &l_rec) == -1)
+            continue;
+        // use only groups with datums
+        if(dap_strcmp(a_group_mempool, l_rec.group))
+            continue;
+
+        char **l_keys = dap_strsplit(l_rec.keys, GLOBAL_DB_HIST_KEY_SEPARATOR, -1);
+        size_t l_count = dap_str_countv(l_keys);
+        dap_store_obj_t *l_obj = NULL;
+        // all objs in one history records
+        for(j = 0; j < l_count; j++) {
+
+            if(l_rec.type != 'a')
+                continue;
+            l_obj = (dap_store_obj_t*) dap_chain_global_db_obj_get(l_keys[j], l_rec.group);
+            if(!l_obj)
+                continue;
+            // datum
+            dap_chain_datum_t *l_datum = (dap_chain_datum_t*) l_obj->value;
+            if(!l_datum && l_datum->header.type_id != DAP_CHAIN_DATUM_TX)
+                continue;
+
+            dap_tx_data_t *l_tx_data = NULL;
+
+            // transaction
+            dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data;
+
+            // find Token items - present in emit transaction
+            dap_list_t *l_list_tx_token = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN, NULL);
+
+            // find OUT items
+            dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL);
+            dap_list_t *l_list_tmp = l_list_out_items;
+            while(l_list_tmp) {
+                const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data;
+                // save OUT item l_tx_out
+                if(!l_tx_data)
+                {
+                    // save tx hash
+                    l_tx_data = DAP_NEW_Z(dap_tx_data_t);
+                    dap_chain_hash_fast_t l_tx_hash;
+                    dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
+                    memcpy(&l_tx_data->tx_hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t));
+                    memcpy(&l_tx_data->addr, &l_tx_out->addr, sizeof(dap_chain_addr_t));
+                    dap_chain_hash_fast_to_str(&l_tx_data->tx_hash, l_tx_data->tx_hash_str,
+                            sizeof(l_tx_data->tx_hash_str));
+                    l_tx_data->obj_num = i;
+                    l_tx_data->pos_num = j;
+                    // save token name
+                    if(l_list_tx_token) {
+                        dap_chain_tx_token_t *tk = l_list_tx_token->data;
+                        int d = sizeof(l_tx_data->token_ticker);
+                        memcpy(l_tx_data->token_ticker, tk->header.ticker, sizeof(l_tx_data->token_ticker));
+                    }
+                    // take token from prev out item
+                    else {
+
+                        // find IN items
+                        dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN, NULL);
+                        dap_list_t *l_list_tmp_in = l_list_in_items;
+                        // find token_ticker in prev OUT items
+                        while(l_list_tmp_in) {
+                            const dap_chain_tx_in_t *l_tx_in =
+                                    (const dap_chain_tx_in_t*) l_list_tmp_in->data;
+                            dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash;
+
+                            //find prev OUT item
+                            dap_tx_data_t *l_tx_data_prev = NULL;
+                            HASH_FIND(hh, l_tx_data_hash, &tx_prev_hash, sizeof(dap_chain_hash_fast_t),
+                                    l_tx_data_prev);
+                            if(l_tx_data_prev != NULL) {
+                                // fill token in l_tx_data from prev transaction
+                                if(l_tx_data) {
+                                    // get token from prev tx
+                                    memcpy(l_tx_data->token_ticker, l_tx_data_prev->token_ticker,
+                                            sizeof(l_tx_data->token_ticker));
+                                    break;
+                                }
+                                l_list_tmp_in = dap_list_next(l_list_tmp_in);
+                            }
+                        }
+                        if(l_list_in_items)
+                            dap_list_free(l_list_in_items);
+                    }
+                    HASH_ADD(hh, l_tx_data_hash, tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_data);
+                }
+                l_list_tmp = dap_list_next(l_list_tmp);
+            }
+            if(l_list_out_items)
+                dap_list_free(l_list_out_items);
+
+            // calc hash
+            dap_chain_hash_fast_t l_tx_hash;
+            dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
+            // search tx with a_tx_hash
+            if(!dap_hash_fast_compare(a_tx_hash, &l_tx_hash))
+                continue;
+            // found a_tx_hash now
+
+            // transaction time
+            char *l_time_str = NULL;
+            if(l_tx->header.ts_created > 0) {
+                time_t rawtime = (time_t) l_tx->header.ts_created;
+                struct tm * timeinfo;
+                timeinfo = localtime(&rawtime);
+                if(timeinfo) {
+                    dap_string_append_printf(l_str_out, " %s", asctime(timeinfo));
+                }
+            }
+
+            // find all OUT items in transaction
+            l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL);
+            l_list_tmp = l_list_out_items;
+            while(l_list_tmp) {
+                const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data;
+                dap_tx_data_t *l_tx_data_prev = NULL;
+
+                const char *l_token_str = NULL;
+                if(l_tx_data)
+                    l_token_str = l_tx_data->token_ticker;
+                char *l_dst_to_str =
+                        (l_tx_out) ? dap_chain_addr_to_str(&l_tx_out->addr) :
+                        NULL;
+                dap_string_append_printf(l_str_out, " OUT item %lld %s to %s\n",
+                        l_tx_out->header.value,
+                        dap_strlen(l_token_str) > 0 ? l_token_str : "?",
+                        l_dst_to_str ? l_dst_to_str : "?"
+                                       );
+                DAP_DELETE(l_dst_to_str);
+                l_list_tmp = dap_list_next(l_list_tmp);
+            }
+            // find all IN items in transaction
+            dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN, NULL);
+            l_list_tmp = l_list_in_items;
+            // find cur addr in prev OUT items
+            while(l_list_tmp) {
+                const dap_chain_tx_in_t *l_tx_in = (const dap_chain_tx_in_t*) l_list_tmp->data;
+                dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash;
+                char l_tx_hash_str[70];
+                if(!dap_hash_fast_is_blank(&tx_prev_hash))
+                    dap_chain_hash_fast_to_str(&tx_prev_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
+                else
+                    strcpy(l_tx_hash_str,"Null");
+                dap_string_append_printf(l_str_out, " IN item \n  prev tx_hash %s\n", l_tx_hash_str);
+
+                //find prev OUT item
+                dap_tx_data_t *l_tx_data_prev = NULL;
+                HASH_FIND(hh, l_tx_data_hash, &tx_prev_hash, sizeof(dap_chain_hash_fast_t), l_tx_data_prev);
+                if(l_tx_data_prev != NULL) {
+
+                    dap_store_obj_t *l_obj_prev = get_prev_tx(l_objs, l_tx_data_prev);
+                    dap_chain_datum_t *l_datum_prev =
+                            l_obj_prev ? (dap_chain_datum_t*) l_obj_prev->value : NULL;
+                    dap_chain_datum_tx_t *l_tx_prev =
+                            l_datum_prev ? (dap_chain_datum_tx_t*) l_datum_prev->data : NULL;
+
+                    // find OUT items in prev datum
+                    dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev,
+                            TX_ITEM_TYPE_OUT, NULL);
+                    // find OUT item for IN item;
+                    dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items,
+                            l_tx_in->header.tx_out_prev_idx);
+                    dap_chain_tx_out_t *l_tx_prev_out =
+                            l_list_out_prev_item ?
+                                                   (dap_chain_tx_out_t*) l_list_out_prev_item->data :
+                                                   NULL;
+                    // print value from prev out item
+                    dap_string_append_printf(l_str_out, "  prev OUT item value=%lld",
+                            l_tx_prev_out->header.value
+                            );
+                }
+                dap_string_append_printf(l_str_out, "\n");
+                l_list_tmp = dap_list_next(l_list_tmp);
+            }
+
+            if(l_list_tx_token)
+                dap_list_free(l_list_tx_token);
+            if(l_list_out_items)
+                dap_list_free(l_list_out_items);
+            if(l_list_in_items)
+                dap_list_free(l_list_in_items);
+            l_tx_hash_found = true;
+            break;
+        }
+        dap_list_t *l_records_out = NULL;
+
+        DAP_DELETE(l_obj);
+        dap_strfreev(l_keys);
+        // transaction was found -> exit
+        if(l_tx_hash_found)
+            break;
+    }
+    dap_chain_global_db_objs_delete(l_objs, l_data_size_out);
+    // if no history
+    if(!l_str_out->len)
+        dap_string_append(l_str_out, "empty");
+    char *l_ret_str = l_str_out ? dap_string_free(l_str_out, false) : NULL;
+    return l_ret_str;
+}
+#endif
+
+/**
+ * Get data according the history log
+ *
+ * return history string
+ */
+#if 0
+char* dap_db_history_addr(dap_chain_addr_t * a_addr, const char *a_group_mempool)
+{
+    dap_string_t *l_str_out = dap_string_new(NULL);
+    // load history
+    size_t l_data_size_out = 0;
+    dap_global_db_obj_t *l_objs = dap_chain_global_db_gr_load(GROUP_LOCAL_HISTORY, &l_data_size_out);
+    size_t i, j;
+    dap_tx_data_t *l_tx_data_hash = NULL;
+    for(i = 0; i < l_data_size_out; i++) {
+        dap_global_db_obj_t *l_obj_cur = l_objs + i;
+        // parse global_db records in a history record
+        dap_global_db_hist_t l_rec;
+        if(dap_db_history_unpack_hist((char*) l_obj_cur->value, &l_rec) == -1)
+            continue;
+        // use only groups with datums
+        if(dap_strcmp(a_group_mempool, l_rec.group))
+            continue;
+
+        char **l_keys = dap_strsplit(l_rec.keys, GLOBAL_DB_HIST_KEY_SEPARATOR, -1);
+        size_t l_count = dap_str_countv(l_keys);
+        dap_store_obj_t *l_obj = NULL;
+        // all objs in one history records
+        for(j = 0; j < l_count; j++) {
+            if(l_rec.type != 'a')
+                continue;
+            l_obj = (dap_store_obj_t*) dap_chain_global_db_obj_get(l_keys[j], l_rec.group);
+            if(!l_obj)
+                continue;
+            // datum
+            dap_chain_datum_t *l_datum = (dap_chain_datum_t*) l_obj->value;
+            if(!l_datum && l_datum->header.type_id != DAP_CHAIN_DATUM_TX)
+                continue;
+
+            // transaction
+            dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data;
+            dap_list_t *l_records_out = NULL;
+            // transaction time
+            char *l_time_str = NULL;
+            {
+                if(l_tx->header.ts_created > 0) {
+                    time_t rawtime = (time_t) l_tx->header.ts_created;
+                    struct tm * timeinfo;
+                    timeinfo = localtime(&rawtime);
+                    if(timeinfo)
+                        l_time_str = dap_strdup(asctime(timeinfo));
+                }
+                else
+                    l_time_str = dap_strdup(" ");
+            }
+
+            // transaction
+            dap_tx_data_t *l_tx_data = NULL;
+
+            // find Token items - present in emit transaction
+            dap_list_t *l_list_tx_token = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN, NULL);
+
+            // find OUT items
+            dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL);
+            dap_list_t *l_list_tmp = l_list_out_items;
+            while(l_list_tmp) {
+                const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data;
+                // save OUT item l_tx_out
+                {
+                    // save tx hash
+                    l_tx_data = DAP_NEW_Z(dap_tx_data_t);
+                    dap_chain_hash_fast_t l_tx_hash;
+                    dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
+                    memcpy(&l_tx_data->tx_hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t));
+                    memcpy(&l_tx_data->addr, &l_tx_out->addr, sizeof(dap_chain_addr_t));
+                    dap_chain_hash_fast_to_str(&l_tx_data->tx_hash, l_tx_data->tx_hash_str,
+                                                                sizeof(l_tx_data->tx_hash_str));
+                    l_tx_data->obj_num = i;
+                    l_tx_data->pos_num = j;
+                    // save token name
+                    if(l_tx_data && l_list_tx_token) {
+                        dap_chain_tx_token_t *tk = l_list_tx_token->data;
+                        int d = sizeof(l_tx_data->token_ticker);
+                        memcpy(l_tx_data->token_ticker, tk->header.ticker, sizeof(l_tx_data->token_ticker));
+                    }
+                    HASH_ADD(hh, l_tx_data_hash, tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_data);
+
+                    // save OUT items to list
+                    {
+                        l_records_out = dap_list_append(l_records_out, (void*) l_tx_out);
+                    }
+                }
+                l_list_tmp = dap_list_next(l_list_tmp);
+            }
+
+            // find IN items
+            l_count = 0;
+            dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN, NULL);
+            l_list_tmp = l_list_in_items;
+            // find cur addr in prev OUT items
+            bool l_is_use_all_cur_out = false;
+            {
+                while(l_list_tmp) {
+                    const dap_chain_tx_in_t *l_tx_in = (const dap_chain_tx_in_t*) l_list_tmp->data;
+                    dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash;
+
+                    //find prev OUT item
+                    dap_tx_data_t *l_tx_data_prev = NULL;
+                    HASH_FIND(hh, l_tx_data_hash, &tx_prev_hash, sizeof(dap_chain_hash_fast_t), l_tx_data_prev);
+                    if(l_tx_data_prev != NULL) {
+                        // fill token in l_tx_data from prev transaction
+                        if(l_tx_data) {
+                            // get token from prev tx
+                            memcpy(l_tx_data->token_ticker, l_tx_data_prev->token_ticker,
+                                    sizeof(l_tx_data->token_ticker));
+                            dap_store_obj_t *l_obj_prev = get_prev_tx(l_objs, l_tx_data_prev);
+                            dap_chain_datum_t *l_datum_prev =
+                                    l_obj_prev ? (dap_chain_datum_t*) l_obj_prev->value : NULL;
+                            dap_chain_datum_tx_t *l_tx_prev =
+                                    l_datum_prev ? (dap_chain_datum_tx_t*) l_datum_prev->data : NULL;
+
+                            // find OUT items in prev datum
+                            dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev,
+                                    TX_ITEM_TYPE_OUT, NULL);
+                            // find OUT item for IN item;
+                            dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items,
+                                    l_tx_in->header.tx_out_prev_idx);
+                            dap_chain_tx_out_t *l_tx_prev_out =
+                                    l_list_out_prev_item ?
+                                                           (dap_chain_tx_out_t*) l_list_out_prev_item->data :
+                                                           NULL;
+                            if(l_tx_prev_out && !memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t)))
+                                l_is_use_all_cur_out = true;
+
+                        }
+                    }
+
+                    // find prev OUT items for IN items
+                    l_list_tmp = l_list_in_items;
+                    while(l_list_tmp) {
+                        const dap_chain_tx_in_t *l_tx_in = (const dap_chain_tx_in_t*) l_list_tmp->data;
+                        dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash;
+                        // if first transaction - empty prev OUT item
+                        if(dap_hash_fast_is_blank(&tx_prev_hash)) {
+                            // add emit info to ret string
+                            if(!memcmp(&l_tx_data->addr, a_addr, sizeof(dap_chain_addr_t)))
+                                    {
+                                dap_list_t *l_records_tmp = l_records_out;
+                                while(l_records_tmp) {
+
+                                    const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_records_tmp->data;
+                                    dap_string_append_printf(l_str_out, "tx hash %s \n emit %lld %s\n",
+                                            l_tx_data->tx_hash_str,
+                                            l_tx_out->header.value,
+                                            l_tx_data->token_ticker);
+                                    l_records_tmp = dap_list_next(l_records_tmp);
+                                }
+                            }
+                            dap_list_free(l_records_out);
+                        }
+                        // in other transactions except first one
+                        else {
+                            //find prev OUT item
+                            dap_tx_data_t *l_tx_data_prev = NULL;
+                            HASH_FIND(hh, l_tx_data_hash, &tx_prev_hash, sizeof(dap_chain_hash_fast_t), l_tx_data_prev);
+                            if(l_tx_data_prev != NULL) {
+                                char *l_src_str = NULL;
+                                bool l_src_str_is_cur = false;
+                                if(l_tx_data) {
+                                    // get token from prev tx
+                                    memcpy(l_tx_data->token_ticker, l_tx_data_prev->token_ticker,
+                                            sizeof(l_tx_data->token_ticker));
+
+                                    dap_store_obj_t *l_obj_prev = get_prev_tx(l_objs, l_tx_data_prev);
+                                    dap_chain_datum_t *l_datum_prev =
+                                            l_obj_prev ? (dap_chain_datum_t*) l_obj_prev->value : NULL;
+                                    dap_chain_datum_tx_t *l_tx_prev =
+                                            l_datum_prev ? (dap_chain_datum_tx_t*) l_datum_prev->data : NULL;
+
+                                    // find OUT items in prev datum
+                                    dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev,
+                                            TX_ITEM_TYPE_OUT, NULL);
+                                    // find OUT item for IN item;
+                                    dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items,
+                                            l_tx_in->header.tx_out_prev_idx);
+                                    dap_chain_tx_out_t *l_tx_prev_out =
+                                            l_list_out_prev_item ?
+                                                                   (dap_chain_tx_out_t*) l_list_out_prev_item->data :
+                                                                   NULL;
+                                    // if use src addr
+                                    bool l_is_use_src_addr = false;
+                                    // find source addrs
+                                    dap_string_t *l_src_addr = dap_string_new(NULL);
+                                    {
+                                        // find IN items in prev datum - for get destination addr
+                                        dap_list_t *l_list_in_prev_items = dap_chain_datum_tx_items_get(l_tx_prev,
+                                                TX_ITEM_TYPE_IN, NULL);
+                                        dap_list_t *l_list_tmp = l_list_in_prev_items;
+                                        while(l_list_tmp) {
+                                            dap_chain_tx_in_t *l_tx_prev_in = l_list_tmp->data;
+                                            dap_chain_hash_fast_t l_tx_prev_prev_hash =
+                                                    l_tx_prev_in->header.tx_prev_hash;
+                                            //find prev OUT item
+                                            dap_tx_data_t *l_tx_data_prev_prev = NULL;
+                                            HASH_FIND(hh, l_tx_data_hash, &l_tx_prev_prev_hash,
+                                                    sizeof(dap_chain_hash_fast_t), l_tx_data_prev_prev);
+                                            if(l_tx_data_prev_prev) {
+                                                // if use src addr
+                                                if(!memcmp(&l_tx_data_prev_prev->addr, a_addr,
+                                                        sizeof(dap_chain_addr_t)))
+                                                    l_is_use_src_addr = true;
+                                                char *l_str = dap_chain_addr_to_str(&l_tx_data_prev_prev->addr);
+                                                if(l_src_addr->len > 0)
+                                                    dap_string_append_printf(l_src_addr, "\n   %s", l_str);
+                                                else
+                                                    dap_string_append_printf(l_src_addr, "%s", l_str); // first record
+                                                DAP_DELETE(l_str);
+                                            }
+                                            l_list_tmp = dap_list_next(l_list_tmp);
+                                        }
+                                    }
+
+                                    char *l_dst_to_str =
+                                            (l_tx_prev_out) ? dap_chain_addr_to_str(&l_tx_prev_out->addr) :
+                                            NULL;
+                                    // if use dst addr
+                                    bool l_is_use_dst_addr = false;
+                                    if(!memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t)))
+                                        l_is_use_dst_addr = true;
+
+                                    l_src_str_is_cur = l_is_use_src_addr;
+                                    if(l_src_addr->len <= 1) {
+                                        l_src_str =
+                                                (l_tx_data) ? dap_chain_addr_to_str(&l_tx_data->addr) :
+                                                NULL;
+                                        if(!memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t)))
+                                            l_src_str_is_cur = true;
+                                        dap_string_free(l_src_addr, true);
+                                    }
+                                    else
+                                        l_src_str = dap_string_free(l_src_addr, false);
+                                    if(l_is_use_src_addr && !l_is_use_dst_addr) {
+                                        dap_string_append_printf(l_str_out,
+                                                "tx hash %s \n %s in send  %lld %s from %s\n to %s\n",
+                                                l_tx_data->tx_hash_str,
+                                                l_time_str ? l_time_str : "",
+                                                l_tx_prev_out->header.value,
+                                                l_tx_data->token_ticker,
+                                                l_src_str ? l_src_str : "",
+                                                l_dst_to_str);
+                                    } else if(l_is_use_dst_addr && !l_is_use_src_addr) {
+                                        if(!l_src_str_is_cur)
+                                            dap_string_append_printf(l_str_out,
+                                                    "tx hash %s \n %s in recv %lld %s from %s\n",
+                                                    l_tx_data->tx_hash_str,
+                                                    l_time_str ? l_time_str : "",
+                                                    l_tx_prev_out->header.value,
+                                                    l_tx_data->token_ticker,
+                                                    l_src_str ? l_src_str : "");
+                                    }
+
+                                    DAP_DELETE(l_dst_to_str);
+                                    dap_list_free(l_list_out_prev_items);
+                                    DAP_DELETE(l_obj_prev);
+                                }
+
+                                // OUT items
+                                dap_list_t *l_records_tmp = l_records_out;
+                                while(l_records_tmp) {
+
+                                    const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_records_tmp->data;
+
+                                    if(l_is_use_all_cur_out
+                                            || !memcmp(&l_tx_out->addr, a_addr, sizeof(dap_chain_addr_t))) {
+
+                                        char *l_addr_str = (l_tx_out) ? dap_chain_addr_to_str(&l_tx_out->addr) : NULL;
+
+                                        if(!memcmp(&l_tx_out->addr, a_addr, sizeof(dap_chain_addr_t))) {
+                                            if(!l_src_str_is_cur)
+                                                dap_string_append_printf(l_str_out, "tx hash %s \n %s recv %lld %s from %s\n",
+                                                        l_tx_data->tx_hash_str,
+                                                        l_time_str ? l_time_str : "",
+                                                        l_tx_out->header.value,
+                                                        l_tx_data_prev->token_ticker,
+                                                        l_src_str ? l_src_str : "?");
+                                        }
+                                        else {
+                                            dap_string_append_printf(l_str_out, "tx hash %s \n %s send %lld %s to %sd\n",
+                                                    l_tx_data->tx_hash_str,
+                                                    l_time_str ? l_time_str : "",
+                                                    l_tx_out->header.value,
+                                                    l_tx_data_prev->token_ticker,
+                                                    l_addr_str ? l_addr_str : "");
+                                        }
+                                        DAP_DELETE(l_addr_str);
+                                    }
+                                    l_records_tmp = dap_list_next(l_records_tmp);
+                                }
+                                dap_list_free(l_records_out);
+                                DAP_DELETE(l_src_str);
+
+                            }
+                        }
+                        l_list_tmp = dap_list_next(l_list_tmp);
+                    }
+                    l_list_tmp = dap_list_next(l_list_tmp);
+                }
+            }
+
+
+
+            if(l_list_tx_token)
+                dap_list_free(l_list_tx_token);
+            if(l_list_out_items)
+                dap_list_free(l_list_out_items);
+            if(l_list_in_items)
+                dap_list_free(l_list_in_items);
+
+            DAP_DELETE(l_time_str);
+        }
+        DAP_DELETE(l_obj);
+        dap_strfreev(l_keys);
+
+    }
+    // delete hashes
+    dap_tx_data_t *l_iter_current, *l_item_tmp;
+    HASH_ITER(hh, l_tx_data_hash , l_iter_current, l_item_tmp)
+    {
+        // delete struct
+        DAP_DELETE(l_iter_current);
+        HASH_DEL(l_tx_data_hash, l_iter_current);
+    }
+    dap_chain_global_db_objs_delete(l_objs, l_data_size_out);
+    // if no history
+    if(!l_str_out->len)
+        dap_string_append(l_str_out, " empty");
+    char *l_ret_str = l_str_out ? dap_string_free(l_str_out, false) : NULL;
+    return l_ret_str;
+}
+#endif
+
+
+/**
+ * Get data according the history log
+ *
+ * return history string
+ */
+char* dap_db_history_filter(dap_chain_addr_t * a_addr, const char *a_group_mempool)
+{
+    dap_string_t *l_str_out = dap_string_new(NULL);
+    // load history
+    size_t l_data_size_out = 0;
+    dap_global_db_obj_t *l_objs = dap_chain_global_db_gr_load(GROUP_LOCAL_HISTORY, &l_data_size_out);
+    size_t i, j;
+    dap_tx_data_t *l_tx_data_hash = NULL;
+    for(i = 0; i < l_data_size_out; i++) {
+        dap_global_db_obj_t *l_obj_cur = l_objs + i;
+
+        // parse global_db records in a history record
+        dap_global_db_hist_t l_rec;
+        if(dap_db_history_unpack_hist((char*) l_obj_cur->value, &l_rec) == -1)
+            continue;
+        // use only groups with datums
+        if(dap_strcmp(a_group_mempool, l_rec.group))
+            continue;
+
+        char **l_keys = dap_strsplit(l_rec.keys, GLOBAL_DB_HIST_KEY_SEPARATOR, -1);
+        size_t l_count = dap_str_countv(l_keys);
+        dap_store_obj_t *l_obj = NULL;
+        // all objs in one history records
+        for(j = 0; j < l_count; j++) {
+            // add record
+            if(l_rec.type == 'a') {
+                l_obj = (dap_store_obj_t*) dap_chain_global_db_obj_get(l_keys[j], l_rec.group);
+                if(!l_obj)
+                    continue;
+                dap_chain_datum_t *l_datum = (dap_chain_datum_t*) l_obj->value;
+                if(!l_datum)
+                    continue;
+                switch (l_datum->header.type_id) {
+                /*                case DAP_CHAIN_DATUM_TOKEN_DECL: {
+                 dap_chain_datum_token_t *l_token = (dap_chain_datum_token_t*) l_datum->data;
+                 }
+                 break;
+                 case DAP_CHAIN_DATUM_TOKEN_EMISSION: {
+                 dap_chain_datum_token_emission_t *l_token_emission =
+                 (dap_chain_datum_token_emission_t*) l_datum->data;
+                 }
+                 break;*/
+                // find transaction
+                case DAP_CHAIN_DATUM_TX: {
+                    dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data;
+                    dap_list_t *l_records_out = NULL;
+
+                    // transaction time
+                    char *l_time_str = NULL;
+                    if(l_tx->header.ts_created > 0) {
+                        time_t rawtime = (time_t) l_tx->header.ts_created;
+                        struct tm * timeinfo;
+                        timeinfo = localtime(&rawtime);
+                        if(timeinfo)
+                            l_time_str = dap_strdup(asctime(timeinfo));
+                    }
+                    else
+                        l_time_str = dap_strdup(" ");
+
+                    int l_count = 0;
+                    dap_tx_data_t *l_tx_data = NULL;
+                    // find Token items - present in emit transaction
+                    l_count = 0;
+                    dap_list_t *l_list_tx_token = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN, &l_count);
+
+                    // find OUT items
+                    dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, &l_count);
+                    dap_list_t *l_list_tmp = l_list_out_items;
+                    while(l_list_tmp) {
+                        const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data;
+                        // save OUT item l_tx_out
+                        {
+                            // save tx hash
+                            l_tx_data = DAP_NEW_Z(dap_tx_data_t);
+                            dap_chain_hash_fast_t l_tx_hash;
+                            dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
+                            memcpy(&l_tx_data->tx_hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t));
+                            memcpy(&l_tx_data->addr, &l_tx_out->addr, sizeof(dap_chain_addr_t));
+                            l_tx_data->obj_num = i;
+                            l_tx_data->pos_num = j;
+                            // save token name
+                            if(l_tx_data && l_list_tx_token) {
+                                dap_chain_tx_token_t *tk = l_list_tx_token->data;
+                                int d = sizeof(l_tx_data->token_ticker);
+                                memcpy(l_tx_data->token_ticker, tk->header.ticker, sizeof(l_tx_data->token_ticker));
+                            }
+                            HASH_ADD(hh, l_tx_data_hash, tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_data);
+
+                            // save OUT items to list
+                            {
+                                l_records_out = dap_list_append(l_records_out, (void*) l_tx_out);
+                            }
+                        }
+                        l_list_tmp = dap_list_next(l_list_tmp);
+                    }
+
+                    // find IN items
+                    l_count = 0;
+                    dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN, &l_count);
+                    l_list_tmp = l_list_in_items;
+
+                    // find cur addr in prev OUT items
+                    bool l_is_use_all_cur_out = false;
+                    {
+                        while(l_list_tmp) {
+                            const dap_chain_tx_in_t *l_tx_in = (const dap_chain_tx_in_t*) l_list_tmp->data;
+                            dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash;
+
+                            //find prev OUT item
+                            dap_tx_data_t *l_tx_data_prev = NULL;
+                            HASH_FIND(hh, l_tx_data_hash, &tx_prev_hash, sizeof(dap_chain_hash_fast_t), l_tx_data_prev);
+                            if(l_tx_data_prev != NULL) {
+                                // fill token in l_tx_data from prev transaction
+                                if(l_tx_data) {
+                                    // get token from prev tx
+                                    memcpy(l_tx_data->token_ticker, l_tx_data_prev->token_ticker,
+                                            sizeof(l_tx_data->token_ticker));
+                                    dap_store_obj_t *l_obj_prev = get_prev_tx(l_objs, l_tx_data_prev);
+                                    dap_chain_datum_t *l_datum_prev =
+                                            l_obj_prev ? (dap_chain_datum_t*) l_obj_prev->value : NULL;
+                                    dap_chain_datum_tx_t *l_tx_prev =
+                                            l_datum_prev ? (dap_chain_datum_tx_t*) l_datum_prev->data : NULL;
+
+                                    // find OUT items in prev datum
+                                    dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev,
+                                            TX_ITEM_TYPE_OUT, &l_count);
+                                    // find OUT item for IN item;
+                                    dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items,
+                                            l_tx_in->header.tx_out_prev_idx);
+                                    dap_chain_tx_out_t *l_tx_prev_out =
+                                            l_list_out_prev_item ?
+                                                                   (dap_chain_tx_out_t*) l_list_out_prev_item->data :
+                                                                   NULL;
+                                    if(l_tx_prev_out && !memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t)))
+                                        l_is_use_all_cur_out = true;
+
+                                }
+                            }
+                            l_list_tmp = dap_list_next(l_list_tmp);
+                        }
+                    }
+
+                    // find prev OUT items for IN items
+                    l_list_tmp = l_list_in_items;
+                    while(l_list_tmp) {
+                        const dap_chain_tx_in_t *l_tx_in = (const dap_chain_tx_in_t*) l_list_tmp->data;
+                        dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash;
+                        // if first transaction - empty prev OUT item
+                        if(dap_hash_fast_is_blank(&tx_prev_hash)) {
+                            // add emit info to ret string
+                            if(!memcmp(&l_tx_data->addr, a_addr, sizeof(dap_chain_addr_t)))
+                                    {
+                                dap_list_t *l_records_tmp = l_records_out;
+                                while(l_records_tmp) {
+                                    const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_records_tmp->data;
+                                    dap_string_append_printf(l_str_out, "emit %lld %s\n",
+                                            l_tx_out->header.value,
+                                            l_tx_data->token_ticker);
+                                    l_records_tmp = dap_list_next(l_records_tmp);
+                                }
+                            }
+                            dap_list_free(l_records_out);
+                        }
+                        // in other transactions except first one
+                        else {
+                            //find prev OUT item
+                            dap_tx_data_t *l_tx_data_prev = NULL;
+                            HASH_FIND(hh, l_tx_data_hash, &tx_prev_hash, sizeof(dap_chain_hash_fast_t), l_tx_data_prev);
+                            if(l_tx_data_prev != NULL) {
+                                char *l_src_str = NULL;
+                                bool l_src_str_is_cur = false;
+                                if(l_tx_data) {
+                                    // get token from prev tx
+                                    memcpy(l_tx_data->token_ticker, l_tx_data_prev->token_ticker,
+                                            sizeof(l_tx_data->token_ticker));
+
+                                    dap_store_obj_t *l_obj_prev = get_prev_tx(l_objs, l_tx_data_prev);
+                                    dap_chain_datum_t *l_datum_prev =
+                                            l_obj_prev ? (dap_chain_datum_t*) l_obj_prev->value : NULL;
+                                    dap_chain_datum_tx_t *l_tx_prev =
+                                            l_datum_prev ? (dap_chain_datum_tx_t*) l_datum_prev->data : NULL;
+
+                                    // find OUT items in prev datum
+                                    dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev,
+                                            TX_ITEM_TYPE_OUT, &l_count);
+                                    // find OUT item for IN item;
+                                    dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items,
+                                            l_tx_in->header.tx_out_prev_idx);
+                                    dap_chain_tx_out_t *l_tx_prev_out =
+                                            l_list_out_prev_item ?
+                                                                   (dap_chain_tx_out_t*) l_list_out_prev_item->data :
+                                                                   NULL;
+                                    // if use src addr
+                                    bool l_is_use_src_addr = false;
+                                    // find source addrs
+                                    dap_string_t *l_src_addr = dap_string_new(NULL);
+                                    {
+                                        // find IN items in prev datum - for get destination addr
+                                        dap_list_t *l_list_in_prev_items = dap_chain_datum_tx_items_get(l_tx_prev,
+                                                TX_ITEM_TYPE_IN, &l_count);
+                                        dap_list_t *l_list_tmp = l_list_in_prev_items;
+                                        while(l_list_tmp) {
+                                            dap_chain_tx_in_t *l_tx_prev_in = l_list_tmp->data;
+                                            dap_chain_hash_fast_t l_tx_prev_prev_hash =
+                                                    l_tx_prev_in->header.tx_prev_hash;
+                                            //find prev OUT item
+                                            dap_tx_data_t *l_tx_data_prev_prev = NULL;
+                                            HASH_FIND(hh, l_tx_data_hash, &l_tx_prev_prev_hash,
+                                                    sizeof(dap_chain_hash_fast_t), l_tx_data_prev_prev);
+                                            if(l_tx_data_prev_prev) {
+                                                // if use src addr
+                                                if(!memcmp(&l_tx_data_prev_prev->addr, a_addr,
+                                                        sizeof(dap_chain_addr_t)))
+                                                    l_is_use_src_addr = true;
+                                                char *l_str = dap_chain_addr_to_str(&l_tx_data_prev_prev->addr);
+                                                if(l_src_addr->len > 0)
+                                                    dap_string_append_printf(l_src_addr, "\n   %s", l_str);
+                                                else
+                                                    dap_string_append_printf(l_src_addr, "%s", l_str); // first record
+                                                DAP_DELETE(l_str);
+                                            }
+                                            l_list_tmp = dap_list_next(l_list_tmp);
+                                        }
+                                    }
+
+                                    char *l_dst_to_str =
+                                            (l_tx_prev_out) ? dap_chain_addr_to_str(&l_tx_prev_out->addr) :
+                                            NULL;
+                                    // if use dst addr
+                                    bool l_is_use_dst_addr = false;
+                                    if(!memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t)))
+                                        l_is_use_dst_addr = true;
+
+                                    l_src_str_is_cur = l_is_use_src_addr;
+                                    if(l_src_addr->len <= 1) {
+                                        l_src_str =
+                                                (l_tx_data) ? dap_chain_addr_to_str(&l_tx_data->addr) :
+                                                NULL;
+                                        if(!memcmp(&l_tx_prev_out->addr, a_addr, sizeof(dap_chain_addr_t)))
+                                            l_src_str_is_cur = true;
+                                        dap_string_free(l_src_addr, true);
+                                    }
+                                    else
+                                        l_src_str = dap_string_free(l_src_addr, false);
+                                    if(l_is_use_src_addr && !l_is_use_dst_addr) {
+                                        dap_string_append_printf(l_str_out,
+                                                "%s in send  %lld %s from %s\n to %s\n",
+                                                l_time_str ? l_time_str : "",
+                                                l_tx_prev_out->header.value,
+                                                l_tx_data->token_ticker,
+                                                l_src_str ? l_src_str : "",
+                                                l_dst_to_str);
+                                    } else if(l_is_use_dst_addr && !l_is_use_src_addr) {
+                                        if(!l_src_str_is_cur)
+                                            dap_string_append_printf(l_str_out,
+                                                    "%s in recv %lld %s from %s\n",
+                                                    l_time_str ? l_time_str : "",
+                                                    l_tx_prev_out->header.value,
+                                                    l_tx_data->token_ticker,
+                                                    l_src_str ? l_src_str : "");
+                                    }
+
+                                    DAP_DELETE(l_dst_to_str);
+                                    dap_list_free(l_list_out_prev_items);
+                                    DAP_DELETE(l_obj_prev);
+                                }
+
+                                // OUT items
+                                dap_list_t *l_records_tmp = l_records_out;
+                                while(l_records_tmp) {
+
+                                    const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_records_tmp->data;
+
+                                    if(l_is_use_all_cur_out
+                                            || !memcmp(&l_tx_out->addr, a_addr, sizeof(dap_chain_addr_t))) {
+
+                                        char *l_addr_str = (l_tx_out) ? dap_chain_addr_to_str(&l_tx_out->addr) : NULL;
+
+                                        if(!memcmp(&l_tx_out->addr, a_addr, sizeof(dap_chain_addr_t))) {
+                                            if(!l_src_str_is_cur)
+                                                dap_string_append_printf(l_str_out, "%s recv %lld %s from %s\n",
+                                                        l_time_str ? l_time_str : "",
+                                                        l_tx_out->header.value,
+                                                        l_tx_data_prev->token_ticker,
+                                                        l_src_str ? l_src_str : "?");
+                                        }
+                                        else {
+                                            dap_string_append_printf(l_str_out, "%s send %lld %s to %sd\n",
+                                                    l_time_str ? l_time_str : "",
+                                                    l_tx_out->header.value,
+                                                    l_tx_data_prev->token_ticker,
+                                                    l_addr_str ? l_addr_str : "");
+                                        }
+                                        DAP_DELETE(l_addr_str);
+                                    }
+                                    l_records_tmp = dap_list_next(l_records_tmp);
+                                }
+                                dap_list_free(l_records_out);
+                                DAP_DELETE(l_src_str);
+
+                            }
+                        }
+                        l_list_tmp = dap_list_next(l_list_tmp);
+                    }
+                    if(l_list_tx_token)
+                        dap_list_free(l_list_tx_token);
+                    if(l_list_out_items)
+                        dap_list_free(l_list_out_items);
+                    if(l_list_in_items)
+                        dap_list_free(l_list_in_items);
+
+                    DAP_DELETE(l_time_str);
+                }
+                    break;
+                default:
+                    continue;
+                }
+            }
+            // delete record
+            else if(l_rec.type == 'd') {
+                //printf("del_gr%d_%d=%s\n", i, j, l_rec.group);
+            }
+        }
+        DAP_DELETE(l_obj);
+        dap_strfreev(l_keys);
+    }
+    // delete hashes
+    dap_tx_data_t *l_iter_current, *l_item_tmp;
+    HASH_ITER(hh, l_tx_data_hash , l_iter_current, l_item_tmp)
+    {
+        // delete struct
+        DAP_DELETE(l_iter_current);
+        HASH_DEL(l_tx_data_hash, l_iter_current);
+    }
+    dap_chain_global_db_objs_delete(l_objs, l_data_size_out);
+    // if no history
+    if(!l_str_out->len)
+        dap_string_append(l_str_out, "empty");
+    char *l_ret_str = l_str_out ? dap_string_free(l_str_out, false) : NULL;
+    return l_ret_str;
+}
+
 /**
  * Add data to the history log
  */