diff --git a/dap-sdk/core/libdap.pri b/dap-sdk/core/libdap.pri
index 945c55411cbcb03efe3eb294d31e2eb33872181a..257fa33003db52eea1f59558a8ea25d21c4be02c 100755
--- a/dap-sdk/core/libdap.pri
+++ b/dap-sdk/core/libdap.pri
@@ -76,7 +76,6 @@ HEADERS += $$PWD/include/dap_common.h \
 SOURCES += $$PWD/src/dap_common.c \
     $$PWD/src/dap_binary_tree.c \
     $$PWD/src/dap_config.c \
-    $$PWD/src/dap_math_ops.c \
     $$PWD/src/dap_file_utils.c \
     $$PWD/src/dap_circular_buffer.c \
     $$PWD/src/dap_list.c \
diff --git a/dap-sdk/crypto/include/dap_sign.h b/dap-sdk/crypto/include/dap_sign.h
index 23d13c366641c28d3f6f0bae351bdc3f2c1a92b2..98def4e69a3de1e7cf1711498b511dd7ce3a946b 100755
--- a/dap-sdk/crypto/include/dap_sign.h
+++ b/dap-sdk/crypto/include/dap_sign.h
@@ -141,7 +141,7 @@ dap_multi_sign_t *dap_multi_sign_create(dap_multi_sign_params_t *a_params, const
 int dap_multi_sign_verify(dap_multi_sign_t *a_sign, const void *a_data, const size_t a_data_size);
 void dap_multi_sign_delete(dap_multi_sign_t *a_sign);
 
-void dap_sign_get_information(dap_sign_t* a_sign, dap_string_t *a_str_out);
+void dap_sign_get_information(dap_sign_t *a_sign, dap_string_t *a_str_out, const char *a_hash_out_type);
 
 #ifdef __cplusplus
 }
diff --git a/dap-sdk/crypto/src/dap_sign.c b/dap-sdk/crypto/src/dap_sign.c
index 7c64420b0b4202cb9cbf8d8a7a5a3e0332b0667b..7ef32815968bae394a8413e7286a74a11f30b96d 100755
--- a/dap-sdk/crypto/src/dap_sign.c
+++ b/dap-sdk/crypto/src/dap_sign.c
@@ -28,6 +28,7 @@
 #include "dap_strfuncs.h"
 #include "dap_hash.h"
 #include "dap_sign.h"
+#include "dap_enc_base58.h"
 #include "dap_enc_bliss.h"
 #include "dap_enc_tesla.h"
 #include "dap_enc_picnic.h"
@@ -410,7 +411,7 @@ int dap_sign_verify(dap_sign_t * a_chain_sign, const void * a_data, const size_t
         case DAP_ENC_KEY_TYPE_SIG_TESLA:
         case DAP_ENC_KEY_TYPE_SIG_PICNIC:
         case DAP_ENC_KEY_TYPE_SIG_DILITHIUM:
-            if(l_key->dec_na(l_key, a_data, a_data_size, l_sign_data, l_sign_data_size) < 0)
+            if((ssize_t)l_key->dec_na(l_key, a_data, a_data_size, l_sign_data, l_sign_data_size) < 0)
                 l_ret = 0;
             else
                 l_ret = 1;
@@ -861,14 +862,22 @@ void dap_multi_sign_delete(dap_multi_sign_t *a_sign)
  * @param a_sign Signature can be NULL
  * @param a_str_out The output string pointer
  */
-void dap_sign_get_information(dap_sign_t* a_sign, dap_string_t *a_str_out){
+void dap_sign_get_information(dap_sign_t* a_sign, dap_string_t *a_str_out, const char *a_hash_out_type)
+{
     dap_string_append_printf(a_str_out, "Signature: \n");
     if (a_sign != NULL){
         dap_chain_hash_fast_t l_hash_pkey;
         dap_string_append_printf(a_str_out, "\tType: %s\n",
                                  dap_sign_type_to_str(a_sign->header.type));
         if(dap_sign_get_pkey_hash(a_sign, &l_hash_pkey)){
-            dap_string_append_printf(a_str_out, "\tPublic key hash: %s\n", dap_chain_hash_fast_to_str_new(&l_hash_pkey));
+            char *l_hash_str = NULL;
+            if (!dap_strcmp(a_hash_out_type, "hex"))
+                l_hash_str = dap_chain_hash_fast_to_str_new(&l_hash_pkey);
+            else
+                l_hash_str = dap_enc_base58_encode_hash_to_str(&l_hash_pkey);
+            dap_string_append_printf(a_str_out, "\tPublic key hash: %s\n", l_hash_str);
+            DAP_DELETE(l_hash_str);
+
         }
         dap_string_append_printf(a_str_out, "\tPublic key size: %u\n"
                                             "\tSignature size: %u\n",
diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index cebd13bf91905204568363f090ba0e9135c1365e..5f64beb19e574f60e437627b29b114959d9128b7 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -117,15 +117,21 @@ typedef struct dap_chain_ledger_tx_item {
         time_t ts_created;
         int n_outs;
         int n_outs_used;
-        char token_tiker[10];
+        char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
         // TODO dynamically allocates the memory in order not to limit the number of outputs in transaction
         dap_chain_hash_fast_t tx_hash_spent_fast[MAX_OUT_ITEMS]; // spent outs list
     } cache_data;
     UT_hash_handle hh;
 } dap_chain_ledger_tx_item_t;
 
+typedef struct dap_chain_ledger_tx_spent_item {
+    dap_chain_hash_fast_t tx_hash_fast;
+    char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
+    UT_hash_handle hh;
+} dap_chain_ledger_tx_spent_item_t;
+
 typedef struct dap_chain_ledger_tokenizer {
-    char token_ticker[10];
+    char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
     uint256_t sum;
     UT_hash_handle hh;
 } dap_chain_ledger_tokenizer_t;
@@ -173,6 +179,7 @@ typedef struct dap_ledger_private {
     dap_chain_ledger_token_emission_item_t * treshold_emissions;
 
     dap_chain_ledger_tx_item_t *ledger_items;
+    dap_chain_ledger_tx_spent_item_t *spent_items;
 
     dap_chain_ledger_token_item_t *tokens;
 
@@ -194,7 +201,7 @@ typedef struct dap_ledger_private {
     dap_chain_cell_id_t local_cell_id;
     /* Cache section */
     dap_ledger_cache_item_t last_tx;
-    dap_ledger_cache_item_t last_thres_tx;
+    dap_ledger_cache_item_t last_spent_tx;
     dap_ledger_cache_item_t last_emit;
     dap_ledger_cache_str_item_t last_ticker;
 } dap_ledger_private_t;
@@ -281,7 +288,7 @@ void dap_chain_ledger_handle_free(dap_ledger_t *a_ledger)
 void dap_chain_ledger_load_end(dap_ledger_t *a_ledger)
 {
     PVT(a_ledger)->last_tx.found = true;
-    PVT(a_ledger)->last_thres_tx.found = true;
+    PVT(a_ledger)->last_spent_tx.found = true;
     PVT(a_ledger)->last_emit.found = true;
     PVT(a_ledger)->last_ticker.found = true;
 }
@@ -1101,23 +1108,22 @@ void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger)
         l_ledger_pvt->last_tx.found = true;
     }
 
-    l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_THRES_STR);
+    l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR);
     l_objs_count = 0;
     l_objs = dap_chain_global_db_gr_load(l_gdb_group, &l_objs_count);
     for (size_t i = 0; i < l_objs_count; i++) {
-        dap_chain_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_chain_ledger_tx_item_t);
-        dap_chain_hash_fast_from_str(l_objs[i].key, &l_tx_item->tx_hash_fast);
-        l_tx_item->tx = DAP_NEW_SIZE(dap_chain_datum_tx_t, l_objs[i].value_len);
-        memcpy(l_tx_item->tx, l_objs[i].value, l_objs[i].value_len);
-        HASH_ADD(hh, l_ledger_pvt->treshold_txs, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_tx_item);
+        dap_chain_ledger_tx_spent_item_t *l_tx_spent_item = DAP_NEW_Z(dap_chain_ledger_tx_spent_item_t);
+        dap_chain_hash_fast_from_str(l_objs[i].key, &l_tx_spent_item->tx_hash_fast);
+        strncpy(l_tx_spent_item->token_ticker, (char *)l_objs[i].value, DAP_CHAIN_TICKER_SIZE_MAX);
+        HASH_ADD(hh, l_ledger_pvt->spent_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_tx_spent_item);
         if (i == l_objs_count - 1) {
-            l_ledger_pvt->last_thres_tx.hash = &l_tx_item->tx_hash_fast;
+            l_ledger_pvt->last_spent_tx.hash = &l_tx_spent_item->tx_hash_fast;
         }
     }
     dap_chain_global_db_objs_delete(l_objs, l_objs_count);
     DAP_DELETE(l_gdb_group);
-    if (l_objs_count == 0 || l_ledger_pvt->last_thres_tx.hash == NULL) {
-        l_ledger_pvt->last_thres_tx.found = true;
+    if (l_objs_count == 0 || l_ledger_pvt->last_spent_tx.hash == NULL) {
+        l_ledger_pvt->last_spent_tx.found = true;
     }
 
     l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_BALANCES_STR);
@@ -1440,11 +1446,18 @@ const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,
     if ( dap_hash_fast_is_blank(a_tx_hash) )
         return NULL;
 
-    dap_chain_ledger_tx_item_t *l_item= NULL;
+    dap_chain_ledger_tx_item_t *l_item;
     pthread_rwlock_rdlock(&l_ledger_priv->ledger_rwlock);
-    HASH_FIND(hh, l_ledger_priv->ledger_items, a_tx_hash, sizeof ( *a_tx_hash), l_item );
+    HASH_FIND(hh, l_ledger_priv->ledger_items, a_tx_hash, sizeof (*a_tx_hash), l_item);
+    if (l_item) {
+        pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
+        return l_item->cache_data.token_ticker;
+    }
+    dap_chain_ledger_tx_spent_item_t *l_spent_item;
+    HASH_FIND(hh, l_ledger_priv->spent_items, a_tx_hash, sizeof (*a_tx_hash), l_spent_item);
     pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
-    return l_item ? l_item->cache_data.token_tiker : NULL;
+    return l_spent_item ? l_spent_item->token_ticker : NULL;
+
 }
 
 /**
@@ -1470,7 +1483,7 @@ void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chai
             for(size_t i = 0; i < l_tickers_size; i++) {
                 if (l_tickers[i]==NULL)
                     break;
-                if(l_tickers[i] && strcmp(l_tickers[i], l_tx_item->cache_data.token_tiker) == 0) {
+                if(l_tickers[i] && strcmp(l_tickers[i], l_tx_item->cache_data.token_ticker) == 0) {
                     l_is_not_in_list = false;
                     break;
                 }
@@ -1480,7 +1493,7 @@ void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chai
                     l_tickers_size += (l_tickers_size / 2);
                     l_tickers = DAP_REALLOC(l_tickers, l_tickers_size);
                 }
-                l_tickers[l_tickers_pos] = dap_strdup(l_tx_item->cache_data.token_tiker);
+                l_tickers[l_tickers_pos] = dap_strdup(l_tx_item->cache_data.token_ticker);
                 l_tickers_pos++;
             }
             dap_chain_hash_fast_t* l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx_item->tx);
@@ -1909,7 +1922,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
             l_token = NULL;
         }
         if (!l_token || !*l_token) {
-            l_token = l_item_out->cache_data.token_tiker;
+            l_token = l_item_out->cache_data.token_ticker;
         }
         if (! l_token || !*l_token ) {
             log_it(L_WARNING, "No token ticker found in previous transaction");
@@ -2312,8 +2325,8 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
         dap_chain_ledger_tx_item_t *l_prev_item_out = bound_item->item_out;
         dap_chain_tx_item_type_t l_out_type = *(uint8_t *)l_prev_item_out;
         
-        if ( *l_prev_item_out->cache_data.token_tiker ) 
-            l_ticker_trl = dap_stpcpy(l_token_ticker, l_prev_item_out->cache_data.token_tiker);
+        if ( *l_prev_item_out->cache_data.token_ticker )
+            l_ticker_trl = dap_stpcpy(l_token_ticker, l_prev_item_out->cache_data.token_ticker);
         else if ( l_out_type == TX_ITEM_TYPE_OUT_EXT) // 256
             l_ticker_trl = dap_stpcpy(l_token_ticker, bound_item->out.tx_prev_out_ext_256->token);
 
@@ -2557,7 +2570,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
                     : NULL;
         }
         if (l_ticker_trl && !l_multichannel)
-            dap_stpcpy(l_item_tmp->cache_data.token_tiker, l_token_ticker);
+            dap_stpcpy(l_item_tmp->cache_data.token_ticker, l_token_ticker);
 
         size_t l_tx_size = dap_chain_datum_tx_get_size(a_tx);
         memcpy(l_item_tmp->tx, a_tx, l_tx_size);
@@ -2576,8 +2589,8 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
             DAP_DELETE(l_tx_cache);
         }
         DAP_DELETE(l_gdb_group);
-        if (!a_from_threshold)
-            s_treshold_txs_proc(a_ledger);
+        //if (!a_from_threshold)
+        //    s_treshold_txs_proc(a_ledger);        // TODO process thresholds only for non consensus chains
         ret = 1;
     }
 FIN:
@@ -2587,7 +2600,7 @@ FIN:
 
 int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx)
 {
-    if (PVT(a_ledger)->last_tx.found && PVT(a_ledger)->last_thres_tx.found) {
+    if (PVT(a_ledger)->last_tx.found && PVT(a_ledger)->last_spent_tx.found) {
         return dap_chain_ledger_tx_add(a_ledger, a_tx, false);
     } else {
         dap_chain_hash_fast_t l_tx_hash = {};
@@ -2596,9 +2609,9 @@ int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx)
                 !memcmp(PVT(a_ledger)->last_tx.hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t))) {
             PVT(a_ledger)->last_tx.found = true;
         }
-        if (!PVT(a_ledger)->last_thres_tx.found &&
-                !memcmp(PVT(a_ledger)->last_thres_tx.hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t))) {
-            PVT(a_ledger)->last_thres_tx.found = true;
+        if (!PVT(a_ledger)->last_spent_tx.found &&
+                !memcmp(PVT(a_ledger)->last_spent_tx.hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t))) {
+            PVT(a_ledger)->last_spent_tx.found = true;
         }
     }
     return 1;
@@ -2618,24 +2631,37 @@ int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_
     dap_chain_ledger_tx_item_t *l_item_tmp;
     pthread_rwlock_rdlock(&l_ledger_priv->ledger_rwlock);
     HASH_FIND(hh, l_ledger_priv->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_item_tmp);
-    pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
     if(l_item_tmp != NULL) {
-        pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock);
-        HASH_DEL(l_ledger_priv->ledger_items, l_item_tmp);
-        pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
-        // delete transaction
-        DAP_DELETE(l_item_tmp->tx);
-        // del struct for hash
-        DAP_DELETE(l_item_tmp);
         // Remove it from cache
         char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_STR);
         dap_chain_global_db_gr_del(dap_chain_hash_fast_to_str_new(a_tx_hash), l_gdb_group);
         DAP_DELETE(l_gdb_group);
         l_ret = 1;
+        dap_chain_ledger_tx_spent_item_t *l_item_used;
+        HASH_FIND(hh, l_ledger_priv->spent_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_item_used);
+        if (!l_item_used) {   // Add it to spent items
+            l_item_used = DAP_NEW_Z(dap_chain_ledger_tx_spent_item_t);
+            memcpy(&l_item_used->tx_hash_fast, a_tx_hash, sizeof(dap_chain_hash_fast_t));
+            strncpy(l_item_used->token_ticker, l_item_tmp->cache_data.token_ticker, DAP_CHAIN_TICKER_SIZE_MAX);
+            HASH_ADD(hh, l_ledger_priv->spent_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_item_used);
+            // Add it to cache
+            char *l_cache_data = DAP_NEW_Z_SIZE(char, DAP_CHAIN_TICKER_SIZE_MAX);
+            strncpy(l_cache_data, l_item_used->token_ticker, DAP_CHAIN_TICKER_SIZE_MAX);
+            l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR);
+            if (!dap_chain_global_db_gr_set(dap_hash_fast_to_str_new(a_tx_hash), l_cache_data, -1, l_gdb_group)) {
+                if(s_debug_more)
+                    log_it(L_WARNING, "Ledger cache mismatch");
+                DAP_DELETE(l_cache_data);
+            }
+            DAP_DELETE(l_gdb_group);
+        }
+        // del struct for hash
+        DAP_DELETE(l_item_tmp);
     }
     else
         // hash not found in the cache
         l_ret = -2;
+    pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
     return l_ret;
 }
 
@@ -2667,15 +2693,15 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
     }
     DAP_DELETE(l_gdb_group);
 
-    // delete threshold txs
-    l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_THRES_STR);
-    HASH_ITER(hh, l_ledger_priv->treshold_txs, l_item_current, l_item_tmp) {
-        HASH_DEL(l_ledger_priv->treshold_txs, l_item_current);
+    // delete spent transactions
+    dap_chain_ledger_tx_spent_item_t *l_spent_item_current, *l_spent_item_tmp;
+    l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR);
+    HASH_ITER(hh, l_ledger_priv->spent_items, l_spent_item_current, l_spent_item_tmp) {
+        HASH_DEL(l_ledger_priv->spent_items, l_spent_item_current);
         if (!a_preserve_db) {
-            dap_chain_hash_fast_to_str(&l_item_current->tx_hash_fast, l_hash_str, l_hash_str_size);
+            dap_chain_hash_fast_to_str(&l_spent_item_current->tx_hash_fast, l_hash_str, l_hash_str_size);
             dap_chain_global_db_gr_del(dap_strdup(l_hash_str), l_gdb_group);
         }
-        DAP_DELETE(l_item_current->tx);
         DAP_DELETE(l_item_current);
     }
     DAP_DELETE(l_gdb_group);
@@ -2691,22 +2717,11 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
     }
     DAP_DELETE(l_gdb_group);
 
-    // delete threshold emissions
-    dap_chain_ledger_token_emission_item_t *l_emission_current, *l_emission_tmp;
-    char *l_emissions_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR);
-    HASH_ITER(hh, l_ledger_priv->treshold_emissions, l_emission_current, l_emission_tmp) {
-        HASH_DEL(l_ledger_priv->treshold_emissions, l_emission_current);
-        if (!a_preserve_db) {
-            dap_chain_hash_fast_to_str(&l_emission_current->datum_token_emission_hash, l_hash_str, l_hash_str_size);
-            dap_chain_global_db_gr_del(dap_strdup(l_hash_str), l_emissions_gdb_group);
-        }
-        DAP_DELETE(l_emission_current->datum_token_emission);
-        DAP_DELETE(l_emission_current);
-    }
-
     // delete tokens & its emissions
     dap_chain_ledger_token_item_t *l_token_current, *l_token_tmp;
+    dap_chain_ledger_token_emission_item_t *l_emission_current, *l_emission_tmp;
     l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR);
+    char *l_emissions_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR);
     HASH_ITER(hh, l_ledger_priv->tokens, l_token_current, l_token_tmp) {
         HASH_DEL(l_ledger_priv->tokens, l_token_current);
         pthread_rwlock_wrlock(&l_token_current->token_emissions_rwlock);
@@ -2729,8 +2744,23 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
     DAP_DELETE(l_gdb_group);
     DAP_DELETE(l_emissions_gdb_group);
 
+
+    // delete threshold emissions
+    HASH_ITER(hh, l_ledger_priv->treshold_emissions, l_emission_current, l_emission_tmp) {
+        HASH_DEL(l_ledger_priv->treshold_emissions, l_emission_current);
+        DAP_DELETE(l_emission_current->datum_token_emission);
+        DAP_DELETE(l_emission_current);
+    }
+    // delete threshold transactions
+    HASH_ITER(hh, l_ledger_priv->treshold_txs, l_item_current, l_item_tmp) {
+        HASH_DEL(l_ledger_priv->treshold_txs, l_item_current);
+        DAP_DELETE(l_item_current->tx);
+        DAP_DELETE(l_item_current);
+    }
+
+
     l_ledger_priv->last_tx.found = true;
-    l_ledger_priv->last_thres_tx.found = true;
+    l_ledger_priv->last_spent_tx.found = true;
     l_ledger_priv->last_emit.found = true;
     l_ledger_priv->last_ticker.found = true;
 
@@ -2872,7 +2902,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c
             if (l_type == TX_ITEM_TYPE_OUT) {
                 const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data;
                 // Check for token name
-                if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_tiker))
+                if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_ticker))
                 {   // if transaction has the out item with requested addr
                     if (!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) {
                         // if 'out' item not used & transaction is valid
@@ -2890,7 +2920,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c
                 const dap_chain_256_tx_out_t *l_tx_out = (const dap_chain_256_tx_out_t*) l_list_tmp->data;
                 // const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data;
                 // Check for token name
-                if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_tiker))
+                if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_ticker))
                 {   // if transaction has the out item with requested addr
                     if (!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) {
                         // if 'out' item not used & transaction is valid
@@ -2931,8 +2961,8 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c
  * a_public_key_size[in] public key size
  * a_tx_first_hash [in/out] hash of the initial transaction/ found transaction, if 0 start from the beginning
  */
-static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
-        const dap_chain_addr_t *a_addr,const char * a_token, dap_chain_hash_fast_t *a_tx_first_hash)
+static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr,
+                                                        const char * a_token, dap_chain_hash_fast_t *a_tx_first_hash)
 {
     if(!a_addr || !a_tx_first_hash)
         return NULL;
@@ -2945,8 +2975,8 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
     HASH_ITER(hh, l_ledger_priv->ledger_items , l_iter_current, l_item_tmp)
     {
         // If a_token is setup we check if its not our token - miss it
-        if (a_token && *l_iter_current->cache_data.token_tiker &&
-                dap_strcmp(l_iter_current->cache_data.token_tiker, a_token))
+        if (a_token && *l_iter_current->cache_data.token_ticker &&
+                dap_strcmp(l_iter_current->cache_data.token_ticker, a_token))
             continue;
         // Now work with it
         dap_chain_datum_tx_t *l_tx = l_iter_current->tx;
@@ -3102,7 +3132,7 @@ dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_le
             l_cur_tx = l_tx_tmp;
             memcpy(a_tx_first_hash, l_tx_hash_tmp, sizeof(dap_chain_hash_fast_t));
             if (a_token_ticker) {
-                strcpy(a_token_ticker, l_iter_current->cache_data.token_tiker);
+                strcpy(a_token_ticker, l_iter_current->cache_data.token_ticker);
             }
             break;
         }
diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h
index d88df0abbbc2b6498b39d7e2f80e8a40ff5f9daa..cce692b50d1f4f8679ad51373e1236c2195ea6f6 100644
--- a/modules/chain/include/dap_chain_ledger.h
+++ b/modules/chain/include/dap_chain_ledger.h
@@ -63,7 +63,8 @@ typedef bool (* dap_chain_ledger_verificator_callback_t)(dap_chain_tx_out_cond_t
 #define DAP_CHAIN_LEDGER_TOKENS_STR              "tokens"
 #define DAP_CHAIN_LEDGER_EMISSIONS_STR           "emissions"
 #define DAP_CHAIN_LEDGER_TXS_STR                 "txs"
-#define DAP_CHAIN_LEDGER_TXS_THRES_STR           "thres_txs"
+#define DAP_CHAIN_LEDGER_TXS_THRES_STR           "thres_txs"    // obsolete
+#define DAP_CHAIN_LEDGER_SPENT_TXS_STR           "spent_txs"
 #define DAP_CHAIN_LEDGER_BALANCES_STR            "balances"
 
 int dap_chain_ledger_init();
diff --git a/modules/global-db/dap_chain_global_db_driver_sqlite.c b/modules/global-db/dap_chain_global_db_driver_sqlite.c
index a234a7061507af93dd8b075129ba094ea340db37..b9060cd5cafd12f93c5ff78426e8b66001076855 100644
--- a/modules/global-db/dap_chain_global_db_driver_sqlite.c
+++ b/modules/global-db/dap_chain_global_db_driver_sqlite.c
@@ -839,12 +839,13 @@ dap_store_obj_t* dap_db_driver_sqlite_read_cond_store_obj(const char *a_group, u
     if(a_count_out)
         l_count_out = (int)*a_count_out;
     char *l_str_query = NULL;
-    if(l_count_out)
+    if (l_count_out) {
         l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE id>='%lld' ORDER BY id ASC LIMIT %d",
                 l_table_name, a_id, l_count_out);
-    else
+    } else {
         l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE id>='%lld' ORDER BY id ASC",
                 l_table_name, a_id);
+    }
 	sqlite3 *s_db = s_sqlite_get_connection();
     if(!s_db){
 		if (l_str_query) sqlite3_free(l_str_query);
@@ -917,20 +918,21 @@ dap_store_obj_t* dap_db_driver_sqlite_read_store_obj(const char *a_group, const
     if(a_count_out)
         l_count_out = *a_count_out;
     char *l_str_query;
-    if(a_key) {
-        if(l_count_out)
+    if (a_key) {
+        if (l_count_out) {
             l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE key='%s' ORDER BY id ASC LIMIT %d",
                     l_table_name, a_key, l_count_out);
-        else
+        } else {
             l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' WHERE key='%s' ORDER BY id ASC",
                     l_table_name, a_key);
-    }
-    else {
-        if(l_count_out)
+        }
+    } else {
+        if (l_count_out) {
             l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' ORDER BY id ASC LIMIT %d",
                     l_table_name, l_count_out);
-        else
+        } else {
             l_str_query = sqlite3_mprintf("SELECT id,ts,key,value FROM '%s' ORDER BY id ASC", l_table_name);
+        }
     }
     int l_ret = dap_db_driver_sqlite_query(s_db, l_str_query, &l_res, NULL);
 
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index c9c0c18513d591ec3d67ec46039f375511b57b49..b643ccfb082eee0092abd0931a925ecf275f3756 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -123,6 +123,11 @@ struct link_dns_request {
     uint_fast16_t tries;
 };
 
+struct net_link {
+    dap_chain_node_info_t *link_info;
+    dap_chain_node_client_t *link;
+};
+
 /**
   * @struct dap_chain_net_pvt
   * @details Private part of chain_net dap object
@@ -146,12 +151,9 @@ typedef struct dap_chain_net_pvt{
 
     //Active synchronizing link
     dap_chain_node_client_t *active_link;
-    // Established links
-    dap_list_t *links;                  // Links list
-    size_t links_connected_count;
 
-    // Prepared links
-    dap_list_t *links_info;             // Links info list
+    dap_list_t *net_links;                  // Links list
+    size_t links_connected_count;
 
     atomic_uint links_dns_requests;
 
@@ -241,6 +243,11 @@ static void s_net_state_link_prepare_success(dap_worker_t * a_worker,dap_chain_n
 static void s_net_state_link_prepare_error(dap_worker_t * a_worker,dap_chain_node_info_t * a_node_info, void * a_arg, int a_errno);
 
 
+// Replace link success/error callbacks
+static void s_net_state_link_replace_success(dap_worker_t *a_worker,dap_chain_node_info_t *a_node_info, void *a_arg);
+static void s_net_state_link_replace_error(dap_worker_t *a_worker,dap_chain_node_info_t *a_node_info, void *a_arg, int a_errno);
+
+
 //static void s_net_proc_kill( dap_chain_net_t * a_net );
 int s_net_load(const char * a_net_name, uint16_t a_acl_idx);
 
@@ -422,9 +429,11 @@ void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const c
         dap_chain_t *l_chain = dap_chain_net_get_chain_by_name(l_net, "gdb");
         dap_chain_id_t l_chain_id = l_chain ? l_chain->id : (dap_chain_id_t) {};
         dap_chain_cell_id_t l_cell_id = l_chain ? l_chain->cells->id : (dap_chain_cell_id_t){};
-        pthread_rwlock_rdlock(&PVT(l_net)->rwlock);
-        for (dap_list_t *l_tmp = PVT(l_net)->links; l_tmp; l_tmp = dap_list_next(l_tmp)) {
-            dap_chain_node_client_t *l_node_client = (dap_chain_node_client_t *)l_tmp->data;
+        pthread_rwlock_rdlock(&PVT(l_net)->rwlock);   
+        for (dap_list_t *l_tmp = PVT(l_net)->net_links; l_tmp; l_tmp = dap_list_next(l_tmp)) {
+            dap_chain_node_client_t *l_node_client = ((struct net_link *)l_tmp->data)->link;
+            if (!l_node_client)
+                continue;
             dap_stream_worker_t *l_stream_worker = dap_client_get_stream_worker(l_node_client->client);
             if (!l_stream_worker)
                 continue;
@@ -473,17 +482,57 @@ static void s_chain_callback_notify(void * a_arg, dap_chain_t *a_chain, dap_chai
     dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg;
     if (PVT(l_net)->state == NET_STATE_ONLINE) {
         pthread_rwlock_rdlock(&PVT(l_net)->rwlock);
-        for (dap_list_t *l_tmp = PVT(l_net)->links; l_tmp; l_tmp = dap_list_next(l_tmp)) {
-            dap_chain_node_client_t *l_node_client = (dap_chain_node_client_t *)l_tmp->data;
-            dap_stream_worker_t * l_worker = dap_client_get_stream_worker( l_node_client->client);
-            if(l_worker)
-                dap_stream_ch_chain_pkt_write_mt(l_worker, l_node_client->ch_chain_uuid, DAP_STREAM_CH_CHAIN_PKT_TYPE_CHAIN,
-                                              l_net->pub.id.uint64, a_chain->id.uint64, a_id.uint64, a_atom, a_atom_size);
+        for (dap_list_t *l_tmp = PVT(l_net)->net_links; l_tmp; l_tmp = dap_list_next(l_tmp)) {
+            dap_chain_node_client_t *l_node_client = ((struct net_link *)l_tmp->data)->link;
+            if (l_node_client) {
+                dap_stream_worker_t * l_worker = dap_client_get_stream_worker( l_node_client->client);
+                if(l_worker)
+                    dap_stream_ch_chain_pkt_write_mt(l_worker, l_node_client->ch_chain_uuid, DAP_STREAM_CH_CHAIN_PKT_TYPE_CHAIN,
+                                                  l_net->pub.id.uint64, a_chain->id.uint64, a_id.uint64, a_atom, a_atom_size);
+            }
         }
         pthread_rwlock_unlock(&PVT(l_net)->rwlock);
     }
 }
 
+static dap_chain_node_info_t *s_get_dns_link_from_cfg(dap_chain_net_t *a_net)
+{
+    dap_chain_net_pvt_t *l_net_pvt = PVT(a_net);
+    struct in_addr l_addr = {};
+    uint16_t i, l_port;
+    if (l_net_pvt->seed_aliases_count) {
+        i = rand() % l_net_pvt->seed_aliases_count;
+        dap_chain_node_addr_t *l_remote_addr = dap_chain_node_alias_find(a_net, l_net_pvt->seed_aliases[i]);
+        if (l_remote_addr){
+            dap_chain_node_info_t *l_remote_node_info = dap_chain_node_info_read(a_net, l_remote_addr);
+            if(l_remote_node_info){
+                l_addr.s_addr = l_remote_node_info ? l_remote_node_info->hdr.ext_addr_v4.s_addr : 0;
+                DAP_DELETE(l_remote_node_info);
+                l_port = DNS_LISTEN_PORT;
+            }else{
+                log_it(L_WARNING,"Can't find node info for node addr "NODE_ADDR_FP_STR,
+                       NODE_ADDR_FP_ARGS(l_remote_addr));
+            }
+        }else{
+            log_it(L_WARNING,"Can't find alias info for seed alias %s",l_net_pvt->seed_aliases[i]);
+        }
+    } else if (l_net_pvt->bootstrap_nodes_count) {
+        i = rand() % l_net_pvt->bootstrap_nodes_count;
+        l_addr = l_net_pvt->bootstrap_nodes_addrs[i];
+        l_port = l_net_pvt->bootstrap_nodes_ports[i];
+    }
+    if (!l_addr.s_addr)
+        return NULL;
+    dap_chain_node_info_t *l_link_node_info = DAP_NEW_Z(dap_chain_node_info_t);
+    if(! l_link_node_info){
+        log_it(L_CRITICAL,"Can't allocate memory for node link info");
+        return NULL;
+    }
+    l_link_node_info->hdr.ext_addr_v4 = l_addr;
+    l_link_node_info->hdr.ext_port = l_port;
+    return l_link_node_info;
+}
+
 /**
  * @brief s_fill_links_from_root_aliases
  * @param a_net
@@ -494,10 +543,10 @@ static void s_fill_links_from_root_aliases(dap_chain_net_t * a_net)
      uint64_t l_own_addr = dap_chain_net_get_cur_addr_int(a_net);
      for (size_t i = 0; i < MIN(s_max_links_count, l_pvt_net->seed_aliases_count); i++) {
          pthread_rwlock_rdlock(&l_pvt_net->rwlock);
-         if (dap_list_length(l_pvt_net->links_info) >= s_max_links_count) {
+         if (dap_list_length(l_pvt_net->net_links) >= s_max_links_count) {
              pthread_rwlock_unlock(&l_pvt_net->rwlock);
              break;
-         }else
+         } else
             pthread_rwlock_unlock(&l_pvt_net->rwlock);
 
          dap_chain_node_addr_t *l_link_addr = dap_chain_node_alias_find(a_net, l_pvt_net->seed_aliases[i]);
@@ -509,8 +558,10 @@ static void s_fill_links_from_root_aliases(dap_chain_net_t * a_net)
          }
          dap_chain_node_info_t *l_link_node_info = dap_chain_node_info_read(a_net, l_link_addr);
          if(l_link_node_info) {
+             struct net_link *l_new_link = DAP_NEW_Z(struct net_link);
+             l_new_link->link_info = l_link_node_info;
              pthread_rwlock_wrlock(&l_pvt_net->rwlock);
-             l_pvt_net->links_info = dap_list_append(l_pvt_net->links_info, l_link_node_info);
+             l_pvt_net->net_links = dap_list_append(l_pvt_net->net_links, l_new_link);
              pthread_rwlock_unlock(&l_pvt_net->rwlock);
          } else {
              log_it(L_WARNING, "Not found link %s."NODE_ADDR_FP_STR" in the node list", a_net->pub.name,
@@ -519,6 +570,95 @@ static void s_fill_links_from_root_aliases(dap_chain_net_t * a_net)
      }
 }
 
+/**
+ * @brief s_net_state_link_replace_error
+ * @param a_worker
+ * @param a_node_info
+ * @param a_arg
+ * @param a_errno
+ */
+static void s_net_state_link_replace_error(dap_worker_t *a_worker, dap_chain_node_info_t *a_node_info, void *a_arg, int a_errno)
+{
+    UNUSED(a_worker);
+    struct link_dns_request *l_dns_request = (struct link_dns_request *)a_arg;
+    dap_chain_net_t *l_net = l_dns_request->net;
+    char l_node_addr_str[INET_ADDRSTRLEN] = {};
+    inet_ntop(AF_INET, &a_node_info->hdr.ext_addr_v4, l_node_addr_str, sizeof (a_node_info->hdr.ext_addr_v4));
+    log_it(L_WARNING,"Link " NODE_ADDR_FP_STR " (%s) replace error with code %d", NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address),
+                                                                                 l_node_addr_str,a_errno );
+    dap_notify_server_send_f_mt("{"
+                            "class:\"NetLinkReplaceError\","
+                            "net_id:0x%016" DAP_UINT64_FORMAT_X ","
+                            "cell_id:0x%016"DAP_UINT64_FORMAT_X","
+                            "address:\""NODE_ADDR_FP_STR"\","
+                            "error: %d"
+                            "}\n", l_net->pub.id.uint64, a_node_info->hdr.cell_id.uint64,
+                                NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address), a_errno);
+    DAP_DELETE(a_node_info);
+    dap_chain_node_info_t *l_link_node_info = NULL;
+    for (int i = 0; i < 1000; i++) {
+        l_link_node_info = s_get_dns_link_from_cfg(l_net);
+        if (l_link_node_info)
+            break;
+    }
+    if (!l_link_node_info) { // We have lost this link forever
+        DAP_DELETE(l_dns_request);
+        return;
+    }
+    if (dap_chain_node_info_dns_request(l_link_node_info->hdr.ext_addr_v4,
+                                        l_link_node_info->hdr.ext_port,
+                                        l_net->pub.name,
+                                        l_link_node_info,  // use it twice
+                                        s_net_state_link_replace_success,
+                                        s_net_state_link_replace_error,
+                                        l_dns_request)) {
+        log_it(L_ERROR, "Can't process node info dns request");
+        DAP_DELETE(l_link_node_info);
+        DAP_DELETE(l_dns_request);
+    }
+}
+
+/**
+ * @brief s_net_state_link_repace_success
+ * @param a_worker
+ * @param a_node_info
+ * @param a_arg
+ */
+
+static void s_net_state_link_replace_success(dap_worker_t *a_worker, dap_chain_node_info_t *a_node_info, void *a_arg)
+{
+    if (s_debug_more) {
+        char l_node_addr_str[INET_ADDRSTRLEN] = {};
+        inet_ntop(AF_INET, &a_node_info->hdr.ext_addr_v4, l_node_addr_str, INET_ADDRSTRLEN);
+        log_it(L_DEBUG,"Link " NODE_ADDR_FP_STR " (%s) replace success", NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address),
+                                                                                     l_node_addr_str);
+    }
+
+    struct link_dns_request *l_dns_request = (struct link_dns_request *)a_arg;
+    dap_chain_net_t *l_net = l_dns_request->net;
+    dap_chain_net_pvt_t *l_net_pvt = PVT(l_net);
+    uint64_t l_own_addr = dap_chain_net_get_cur_addr_int(l_net);
+    if (a_node_info->hdr.address.uint64 == l_own_addr) {
+        s_net_state_link_replace_error(a_worker, a_node_info, a_arg, EWOULDBLOCK);
+        return;
+    }
+    struct net_link *l_new_link = DAP_NEW_Z(struct net_link);
+    l_new_link->link_info = a_node_info;
+    l_new_link->link = dap_chain_net_client_create_n_connect(l_net, a_node_info);
+    pthread_rwlock_wrlock(&l_net_pvt->rwlock);
+    l_net_pvt->net_links = dap_list_append(l_net_pvt->net_links, l_new_link);
+    pthread_rwlock_unlock(&l_net_pvt->rwlock);
+
+    dap_notify_server_send_f_mt("{"
+                            "class:\"NetLinkReplaceSuccess\","
+                            "net_id:0x%016" DAP_UINT64_FORMAT_X ","
+                            "cell_id:0x%016"DAP_UINT64_FORMAT_X","
+                            "address:\""NODE_ADDR_FP_STR"\""
+                        "}\n", l_net->pub.id.uint64, a_node_info->hdr.cell_id.uint64,
+                                NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address));
+    DAP_DELETE(l_dns_request);
+}
+
 /**
  * @brief s_node_link_callback_connected
  * @param a_node_client
@@ -552,28 +692,70 @@ static void s_node_link_callback_connected(dap_chain_node_client_t * a_node_clie
 
 }
 
+static void s_node_link_remove(dap_chain_net_pvt_t *a_net_pvt, dap_chain_node_client_t *a_node_client)
+{
+    for (dap_list_t *it = a_net_pvt->net_links; it; it = it->next) {
+        if (((struct net_link *)it->data)->link == a_node_client) {
+            DAP_DELETE(((struct net_link *)it->data)->link_info);
+            a_net_pvt->net_links = dap_list_delete_link(a_net_pvt->net_links, it);
+            break;
+        }
+    }
+}
+
 /**
  * @brief s_node_link_callback_disconnected
  * @param a_node_client
  * @param a_arg
  */
-static void s_node_link_callback_disconnected(dap_chain_node_client_t * a_node_client, void * a_arg)
-{
-    dap_chain_net_t * l_net = (dap_chain_net_t *) a_arg;
-    dap_chain_net_pvt_t * l_net_pvt = PVT(l_net);
+
+static void s_node_link_callback_disconnected(dap_chain_node_client_t *a_node_client, void *a_arg)
+{ 
+    dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg;
+    dap_chain_net_pvt_t *l_net_pvt = PVT(l_net);
     pthread_rwlock_wrlock(&l_net_pvt->rwlock);
     if (a_node_client->is_connected) {
         a_node_client->is_connected = false;
         log_it(L_INFO, "%s."NODE_ADDR_FP_STR" disconnected.%s",l_net->pub.name,
                NODE_ADDR_FP_ARGS_S(a_node_client->info->hdr.address),
-               l_net_pvt->state_target == NET_STATE_OFFLINE ? "" : " Reconnecting back...");
+               l_net_pvt->state_target == NET_STATE_OFFLINE ? "" : " Replace it...");
         if (l_net_pvt->links_connected_count)
             l_net_pvt->links_connected_count--;
         else
             log_it(L_ERROR, "Links count is zero in disconnected callback, looks smbd decreased it twice or forget to increase on connect/reconnect");
     }
     if (l_net_pvt->state_target != NET_STATE_OFFLINE) {
-        a_node_client->keep_connection = true;
+        for (dap_list_t *it = l_net_pvt->net_links; it; it = it->next) {
+            if (((struct net_link *)it->data)->link == NULL) {  // We have a free prepared link
+                s_node_link_remove(l_net_pvt, a_node_client);
+                ((struct net_link *)it->data)->link = dap_chain_net_client_create_n_connect(l_net,
+                                                        ((struct net_link *)it->data)->link_info);
+                pthread_rwlock_unlock(&l_net_pvt->rwlock);
+                return;
+            }
+        }
+        dap_chain_node_info_t *l_link_node_info = s_get_dns_link_from_cfg(l_net);
+        if (!l_link_node_info) {    // Try to keep this connection
+            a_node_client->keep_connection = true;
+        } else {
+            struct link_dns_request *l_dns_request = DAP_NEW_Z(struct link_dns_request);
+            l_dns_request->net = l_net;
+            if (dap_chain_node_info_dns_request(l_link_node_info->hdr.ext_addr_v4,
+                                                l_link_node_info->hdr.ext_port,
+                                                l_net->pub.name,
+                                                l_link_node_info,  // use it twice
+                                                s_net_state_link_replace_success,
+                                                s_net_state_link_replace_error,
+                                                l_dns_request)) {
+                log_it(L_ERROR, "Can't process node info dns request");
+                DAP_DELETE(l_link_node_info);
+                DAP_DELETE(l_dns_request);
+                a_node_client->keep_connection = true;
+            } else {
+                s_node_link_remove(l_net_pvt, a_node_client);
+                a_node_client->keep_connection = false;
+            }
+        }
     }
     pthread_rwlock_unlock(&l_net_pvt->rwlock);
 }
@@ -643,10 +825,10 @@ static void s_node_link_callback_delete(dap_chain_node_client_t * a_node_client,
         return;
     }
     pthread_rwlock_wrlock(&l_net_pvt->rwlock);
-    for ( dap_list_t * it = l_net_pvt->links; it; it=it->next ){
-        if (it->data == a_node_client) {
+    for ( dap_list_t * it = l_net_pvt->net_links; it; it=it->next ){
+        if (((struct net_link *)it->data)->link == a_node_client) {
             log_it(L_DEBUG,"Replace node client with new one");
-            it->data = dap_chain_net_client_create_n_connect(l_net, a_node_client->info);
+            ((struct net_link *)it->data)->link = dap_chain_net_client_create_n_connect(l_net, a_node_client->info);
         }
     }
     pthread_rwlock_unlock(&l_net_pvt->rwlock);
@@ -678,10 +860,12 @@ static void s_net_state_link_prepare_success(dap_worker_t * a_worker,dap_chain_n
     struct link_dns_request * l_dns_request = (struct link_dns_request *) a_arg;
     dap_chain_net_t * l_net = l_dns_request->net;
     dap_chain_net_pvt_t * l_net_pvt = PVT(l_net);
-    uint64_t l_own_addr =0;
+    uint64_t l_own_addr = dap_chain_net_get_cur_addr_int(l_net);
     if (a_node_info->hdr.address.uint64 != l_own_addr) {
+        struct net_link *l_new_link = DAP_NEW_Z(struct net_link);
+        l_new_link->link_info = a_node_info;
         pthread_rwlock_wrlock(&l_net_pvt->rwlock);
-        l_net_pvt->links_info = dap_list_append(l_net_pvt->links_info, a_node_info);
+        l_net_pvt->net_links = dap_list_append(l_net_pvt->net_links, l_new_link);
         pthread_rwlock_unlock(&l_net_pvt->rwlock);
         l_dns_request->tries = 0;
     }
@@ -778,9 +962,8 @@ static void s_net_links_notify(dap_chain_net_t * a_net )
     dap_string_t * l_str_reply = dap_string_new("[");
 
     size_t i =0;
-    for (dap_list_t * l_item = l_net_pvt->links; l_item;  l_item = l_item->next ) {
-        dap_chain_node_client_t * l_node_client = l_item->data;
-
+    for (dap_list_t * l_item = l_net_pvt->net_links; l_item;  l_item = l_item->next ) {
+        dap_chain_node_client_t * l_node_client = ((struct net_link *)l_item->data)->link;
         if(l_node_client){
             dap_chain_node_info_t * l_info = l_node_client->info;
             char l_ext_addr_v4[INET_ADDRSTRLEN]={};
@@ -836,20 +1019,21 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg)
     switch (l_net_pvt->state) {
         // State OFFLINE where we don't do anything
         case NET_STATE_OFFLINE: {
+            l_net_pvt->links_connected_count = 0;
             // delete all links
-            dap_list_t *l_tmp = l_net_pvt->links;
+            dap_list_t *l_tmp = l_net_pvt->net_links;
             while (l_tmp) {
                 dap_list_t *l_next =l_tmp->next;
-                ((dap_chain_node_client_t *)l_tmp->data)->keep_connection = false;
-                dap_chain_node_client_close(l_tmp->data);
+                dap_chain_node_client_t *l_link = ((struct net_link *)l_tmp->data)->link;
+                if (l_link) {
+                    l_link->keep_connection = false;
+                    dap_chain_node_client_close(l_link);
+                }
+                DAP_DELETE(((struct net_link *)l_tmp->data)->link_info);
                 DAP_DELETE(l_tmp);
                 l_tmp = l_next;
             }
-            l_net_pvt->links = NULL;
-            if(l_net_pvt->links_info){
-                dap_list_free_full(l_net_pvt->links_info, free);
-                l_net_pvt->links_info = NULL;
-            }
+            l_net_pvt->net_links = NULL;
             if ( l_net_pvt->state_target != NET_STATE_OFFLINE ){
                 l_net_pvt->state = NET_STATE_LINKS_PREPARE;
                 l_repeat_after_exit = true;
@@ -871,8 +1055,11 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg)
                 dap_chain_node_info_t *l_link_node_info = DAP_NEW_Z(dap_chain_node_info_t);
                 l_link_node_info->hdr.address.uint64 = l_net_pvt->gdb_sync_nodes_addrs[i].uint64;
                 l_link_node_info->hdr.ext_addr_v4.s_addr = l_net_pvt->gdb_sync_nodes_links_ips[i];
-                l_link_node_info->hdr.ext_port = l_net_pvt->gdb_sync_nodes_links_ports[i];
-                l_net_pvt->links_info = dap_list_append(l_net_pvt->links_info, l_link_node_info);
+                l_link_node_info->hdr.ext_port = l_net_pvt->gdb_sync_nodes_links_ports[i];              
+                struct net_link *l_new_link = DAP_NEW_Z(struct net_link);
+                l_new_link->link_info = l_link_node_info;
+                l_net_pvt->net_links = dap_list_append(l_net_pvt->net_links, l_new_link);
+
             }
             uint64_t l_own_addr = dap_chain_net_get_cur_addr_int(l_net);
             if (l_net_pvt->node_info) {
@@ -880,9 +1067,12 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg)
                     dap_chain_node_info_t *l_link_node_info = dap_chain_node_info_read(l_net, &l_net_pvt->node_info->links[i]);
                     if (!l_link_node_info || l_link_node_info->hdr.address.uint64 == l_own_addr) {
                         continue;   // Do not link with self
-                    }
-                    l_net_pvt->links_info = dap_list_append(l_net_pvt->links_info, l_link_node_info);
-                    if (dap_list_length(l_net_pvt->links_info) >= s_max_links_count) {
+                    }        
+                    struct net_link *l_new_link = DAP_NEW_Z(struct net_link);
+                    l_new_link->link_info = l_link_node_info;
+                    l_net_pvt->net_links = dap_list_append(l_net_pvt->net_links, l_new_link);
+                    if (dap_list_length(l_net_pvt->net_links) >= s_max_links_count) {
+
                         break;
                     }
                 }
@@ -907,74 +1097,44 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg)
                 case NODE_ROLE_FULL:
                 case NODE_ROLE_MASTER:
                 case NODE_ROLE_LIGHT:
-                default: {
+                default: {              
+                    if (!l_net_pvt->seed_aliases_count && ! l_net_pvt->bootstrap_nodes_count) {
+                       log_it(L_ERROR, "No root servers present in configuration file. Can't establish DNS requests");
+                       if (l_net_pvt->net_links) { // We have other links
+                           l_net_pvt->state = NET_STATE_LINKS_CONNECTING;
+                           l_repeat_after_exit = true;
+                       }
+                       break;
+                    }
                     // Get DNS request result from root nodes as synchronization links
                     bool l_sync_fill_root_nodes = false;
-                    uint32_t l_link_id=0;
-                    if (!l_sync_fill_root_nodes){
-                        for (size_t n=0; n< s_required_links_count;n++ ) {
-                            struct in_addr l_addr = {};
-                            uint16_t i, l_port;
-                            if (l_net_pvt->seed_aliases_count) {
-                                i = rand() % l_net_pvt->seed_aliases_count;
-                                dap_chain_node_addr_t *l_remote_addr = dap_chain_node_alias_find(l_net, l_net_pvt->seed_aliases[i]);
-                                if (l_remote_addr){
-                                    dap_chain_node_info_t *l_remote_node_info = dap_chain_node_info_read(l_net, l_remote_addr);
-                                    if(l_remote_node_info){
-                                        l_addr.s_addr = l_remote_node_info ? l_remote_node_info->hdr.ext_addr_v4.s_addr : 0;
-                                        DAP_DELETE(l_remote_node_info);
-                                        l_port = DNS_LISTEN_PORT;
-                                    }else{
-                                        log_it(L_WARNING,"Can't find node info for node addr "NODE_ADDR_FP_STR,
-                                               NODE_ADDR_FP_ARGS(l_remote_addr));
-                                    }
-                                }else{
-                                    log_it(L_WARNING,"Can't find alias info for seed alias %s",l_net_pvt->seed_aliases[i]);
-                                }
-                            } else if (l_net_pvt->bootstrap_nodes_count) {
-                                i = rand() % l_net_pvt->bootstrap_nodes_count;
-                                l_addr = l_net_pvt->bootstrap_nodes_addrs[i];
-                                l_port = l_net_pvt->bootstrap_nodes_ports[i];
-                            } else {
-                                log_it(L_ERROR, "No root servers present in configuration file. Can't establish DNS requests");
-                                if (!dap_list_length(l_net_pvt->links_info)) {   // No links can be prepared, go offline
-                                    l_net_pvt->state_target = NET_STATE_OFFLINE;
-                                }
-                            }
-                            if (l_addr.s_addr) {
-                                dap_chain_node_info_t *l_link_node_info = DAP_NEW_Z(dap_chain_node_info_t);
-                                if(! l_link_node_info){
-                                    log_it(L_CRITICAL,"Can't allocate memory for node link info");
-                                    break;
-                                }
-/*    #ifdef DAP_OS_UNIX
-                                struct in_addr _in_addr = { .s_addr = l_addr.s_addr  };
-    #else
-                                struct in_addr _in_addr = { { .S_addr = l_addr.S_un.S_addr } };
-    #endif
-*/
-                                l_sync_fill_root_nodes = false;
-                                if (l_net_pvt->state_target != NET_STATE_OFFLINE) {
-                                    l_net_pvt->links_dns_requests++;
-                                    struct link_dns_request * l_dns_request = DAP_NEW_Z(struct link_dns_request);
-                                    l_dns_request->net = l_net;
-                                    l_dns_request->link_id = l_link_id;
-                                    if(dap_chain_node_info_dns_request(l_addr, l_port, l_net->pub.name, l_link_node_info,
-                                                                        s_net_state_link_prepare_success,
-                                                                    s_net_state_link_prepare_error,l_dns_request) != 0 ){
-                                        log_it(L_ERROR, "Can't process node info dns request");
-                                        DAP_DEL_Z(l_link_node_info);
-
-                                    }
-                                }else{
-                                    DAP_DEL_Z(l_link_node_info);
-                                }
+                    uint32_t l_link_id = 0;
+                    if (!l_sync_fill_root_nodes) {
+                        for (size_t n = 0; l_net_pvt->links_dns_requests < s_max_links_count; n++) {
+                            dap_chain_node_info_t *l_link_node_info = s_get_dns_link_from_cfg(l_net);
+                            if (!l_link_node_info)
+                                continue;
+                            l_net_pvt->links_dns_requests++;
+                            struct link_dns_request *l_dns_request = DAP_NEW_Z(struct link_dns_request);
+                            l_dns_request->net = l_net;
+                            l_dns_request->link_id = l_link_id++;
+                            if (dap_chain_node_info_dns_request(l_link_node_info->hdr.ext_addr_v4,
+                                                                l_link_node_info->hdr.ext_port,
+                                                                l_net->pub.name,
+                                                                l_link_node_info,  // use it twice
+                                                                s_net_state_link_prepare_success,
+                                                                s_net_state_link_prepare_error,
+                                                                l_dns_request)) {
+                                log_it(L_ERROR, "Can't process node info dns request");
+                                DAP_DEL_Z(l_dns_request);
+                                DAP_DEL_Z(l_link_node_info);
                             }
-                            l_link_id++;
+                            if (n > 1000)   // It's a problem with link prepare
+                                break;
                         }
                     }
-                    if (l_sync_fill_root_nodes){
-                        log_it(L_ATT,"Not found bootstrap addresses, fill seed nodelist from root aliases");
+                    if (l_sync_fill_root_nodes) {
+                        log_it(L_ATT, "Not use bootstrap addresses, fill seed nodelist from root aliases");
                         pthread_rwlock_unlock(&l_net_pvt->rwlock);
                         s_fill_links_from_root_aliases(l_net);
                         pthread_rwlock_wrlock(&l_net_pvt->rwlock);
@@ -985,12 +1145,13 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg)
 
         case NET_STATE_LINKS_CONNECTING: {
             log_it(L_INFO, "%s.state: NET_STATE_LINKS_CONNECTING",l_net->pub.name);
-            for (dap_list_t *l_tmp = l_net_pvt->links_info; l_tmp; l_tmp = dap_list_next(l_tmp)) {
-                dap_chain_node_info_t *l_link_info = (dap_chain_node_info_t *)l_tmp->data;
+            int l_used_links = 0;
+            for (dap_list_t *l_tmp = l_net_pvt->net_links; l_tmp; l_tmp = dap_list_next(l_tmp)) {
+                dap_chain_node_info_t *l_link_info = ((struct net_link *)l_tmp->data)->link_info;
                 dap_chain_node_client_t *l_client = dap_chain_net_client_create_n_connect(l_net, l_link_info);
                 l_client->keep_connection = true;
-                l_net_pvt->links = dap_list_append(l_net_pvt->links, l_client);
-                if (dap_list_length(l_net_pvt->links) == s_required_links_count)
+                ((struct net_link *)l_tmp->data)->link = l_client;
+                if (++l_used_links == s_required_links_count)
                     break;
             }
         } break;
@@ -1026,15 +1187,14 @@ bool dap_chain_net_sync_trylock(dap_chain_net_t *a_net, dap_chain_node_client_t
     pthread_rwlock_rdlock(&l_net_pvt->rwlock);
     bool l_found = false;
     if (l_net_pvt->active_link) {
-        for (dap_list_t *l_links = l_net_pvt->links; l_links; l_links = dap_list_next(l_links)) {
-            if (l_links->data == l_net_pvt->active_link) {
-                dap_chain_node_client_t *l_client = (dap_chain_node_client_t *)l_links->data;
-                if (l_client->state >= NODE_CLIENT_STATE_ESTABLISHED &&
+        for (dap_list_t *l_links = l_net_pvt->net_links; l_links; l_links = dap_list_next(l_links)) {
+            dap_chain_node_client_t *l_client = ((struct net_link *)l_links->data)->link;
+            if (l_client == l_net_pvt->active_link &&
+                        l_client->state >= NODE_CLIENT_STATE_ESTABLISHED &&
                         l_client->state < NODE_CLIENT_STATE_SYNCED &&
                         a_client != l_client) {
-                    l_found = true;
-                    break;
-                }
+                l_found = true;
+                break;
             }
         }
     }
@@ -1232,7 +1392,7 @@ void s_set_reply_text_node_status(char **a_str_reply, dap_chain_net_t * a_net){
     if (PVT(a_net)->state != NET_STATE_OFFLINE)
         l_sync_current_link_text_block = dap_strdup_printf(", active links %u from %u",
                                                            PVT(a_net)->links_connected_count,
-                                                           dap_list_length(PVT(a_net)->links));
+                                                           dap_list_length(PVT(a_net)->net_links));
     dap_chain_node_cli_set_reply_text(a_str_reply,
                                       "Network \"%s\" has state %s (target state %s)%s%s",
                                       a_net->pub.name, c_net_states[PVT(a_net)->state],
@@ -1436,12 +1596,11 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
                 size_t i =0;
                 dap_chain_net_pvt_t * l_net_pvt = PVT(l_net);
                 pthread_rwlock_rdlock(&l_net_pvt->rwlock );
-                size_t l_links_count = dap_list_length(l_net_pvt->links);
+                size_t l_links_count = dap_list_length(l_net_pvt->net_links);
                 dap_string_t *l_reply = dap_string_new("");
                 dap_string_append_printf(l_reply,"Links %zu:\n", l_links_count);
-                for (dap_list_t * l_item = l_net_pvt->links; l_item;  l_item = l_item->next ) {
-                    dap_chain_node_client_t * l_node_client = l_item->data;
-
+                for (dap_list_t * l_item = l_net_pvt->net_links; l_item;  l_item = l_item->next ) {
+                    dap_chain_node_client_t *l_node_client = ((struct net_link *)l_item->data)->link;
                     if(l_node_client){
                         dap_chain_node_info_t * l_info = l_node_client->info;
                         char l_ext_addr_v4[INET_ADDRSTRLEN]={};
@@ -2544,7 +2703,7 @@ void dap_chain_net_proc_mempool (dap_chain_net_t * a_net)
 dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap_chain_hash_fast_t * a_tx_hash,
                                                      dap_chain_net_tx_search_type_t a_search_type)
 {
-    dap_ledger_t * l_ledger = dap_chain_ledger_by_net_name( a_net->pub.name );
+    dap_ledger_t * l_ledger = a_net->pub.ledger;
     dap_chain_datum_tx_t * l_tx = NULL;
 
     switch (a_search_type) {
@@ -2556,7 +2715,7 @@ dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap
                 for ( dap_chain_t * l_chain = a_net->pub.chains; l_chain; l_chain = l_chain->next){
                     if ( l_chain->callback_tx_find_by_hash ){
                         // try to find transaction in chain ( inside shard )
-                        l_tx = l_chain->callback_tx_find_by_hash( l_chain, a_tx_hash );
+                        l_tx = l_chain->callback_tx_find_by_hash(l_chain, a_tx_hash);
                         if (l_tx)
                             break;
                     }
@@ -2566,7 +2725,7 @@ dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap
 
         case TX_SEARCH_TYPE_NET_UNSPENT:
         case TX_SEARCH_TYPE_CELL_UNSPENT:{
-            l_tx = dap_chain_ledger_tx_find_by_hash( l_ledger, a_tx_hash );
+            l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_tx_hash);
         }break;
     }
     return l_tx;
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index 44fdd7abaff7475bb748358fc11b3d81bee9c76e..6c7ff2164fcad12ca13949f3085175dbca11d947 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -91,40 +91,29 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
                                           dap_ledger_t *a_ledger,
                                           dap_string_t *a_str_out,
                                           const char *a_hash_out_type,
-                                          bool save_processed_tx,
-                                          dap_chain_tx_hash_processed_ht_t **a_tx_hash_processed,
-                                          size_t *l_tx_num)
+                                          dap_chain_hash_fast_t *a_tx_hash)
 {
-    dap_chain_hash_fast_t l_tx_hash;
-    dap_hash_fast(a_datum, dap_chain_datum_tx_get_size(a_datum), &l_tx_hash);
-    if (save_processed_tx){
-        dap_chain_tx_hash_processed_ht_t *l_sht = NULL;
-        HASH_FIND(hh, *a_tx_hash_processed, &l_tx_hash, sizeof(dap_chain_hash_fast_t), l_sht);
-        if (l_sht != NULL)
-            return;
-        l_sht = DAP_NEW_Z(dap_chain_tx_hash_processed_ht_t);
-        memcpy(&l_sht->hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t));
-        HASH_ADD(hh, *a_tx_hash_processed, hash, sizeof(dap_chain_hash_fast_t), l_sht);
-        (*l_tx_num)++;
-    }
-    char *l_tx_hash_user_str;
-    char l_tx_hash_str[70];
-    dap_chain_hash_fast_to_str(&l_tx_hash, l_tx_hash_str, 70);
     time_t l_ts_create = (time_t)a_datum->header.ts_created;
+    char *l_hash_str = NULL;
     if(!dap_strcmp(a_hash_out_type, "hex"))
-        l_tx_hash_user_str = dap_strdup(l_tx_hash_str);
+        l_hash_str = dap_chain_hash_fast_to_str_new(a_tx_hash);
     else
-        l_tx_hash_user_str = dap_enc_base58_from_hex_str_to_str(l_tx_hash_str);
+        l_hash_str = dap_enc_base58_encode_hash_to_str(a_tx_hash);
     dap_list_t *l_list_tx_any = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_TOKEN, NULL);
     if(a_ledger == NULL){
-        dap_string_append_printf(a_str_out, "transaction: %s hash: %s\n Items:\n", l_list_tx_any ? "(emit)" : "", l_tx_hash_user_str);
+        dap_string_append_printf(a_str_out, "transaction:%s hash: %s\n Items:\n", l_list_tx_any ? "(emit)" : "", l_hash_str);
     } else {
         char buf[50];
+        const char *l_ticker;
+        if (l_list_tx_any) {
+            l_ticker = ((dap_chain_tx_token_t*)l_list_tx_any->data)->header.ticker;
+        } else {
+            l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash);
+        }
         dap_string_append_printf(a_str_out, "transaction:%s hash: %s\n TS Created: %s Token ticker: %s\n Items:\n",
-                                 l_list_tx_any ? " (emit)" : "", l_tx_hash_user_str, dap_ctime_r(&l_ts_create, buf),
-                                 dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_hash));
+                                 l_list_tx_any ? " (emit)" : "", l_hash_str, dap_ctime_r(&l_ts_create, buf), l_ticker);
     }
-    DAP_DELETE(l_tx_hash_user_str);
+    DAP_DELETE(l_hash_str);
     dap_list_free(l_list_tx_any);
     uint32_t l_tx_items_count = 0;
     uint32_t l_tx_items_size =a_datum->header.tx_items_size;
@@ -132,18 +121,27 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
     char l_tmp_buf[70];
     dap_sign_t *l_sign_tmp;
     dap_chain_hash_fast_t l_pkey_hash_tmp;
+    dap_hash_fast_t *l_hash_tmp = NULL;
     dap_pkey_t *l_pkey_tmp;
     while(l_tx_items_count < l_tx_items_size){
         uint8_t *item = a_datum->tx_items + l_tx_items_count;
         size_t l_item_tx_size = dap_chain_datum_item_tx_get_size(item);
         switch(dap_chain_datum_tx_item_get_type(item)){
         case TX_ITEM_TYPE_IN:
-            l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_in_t*)item)->header.tx_prev_hash);
+            l_hash_tmp = &((dap_chain_tx_in_t*)item)->header.tx_prev_hash;
+            if (dap_hash_fast_is_blank(l_hash_tmp)) {
+                l_hash_str = dap_strdup("BLANK");
+            } else {
+                if (!dap_strcmp(a_hash_out_type, "hex"))
+                    l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp);
+                else
+                    l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp);
+            }
             dap_string_append_printf(a_str_out, "\t IN:\nTx_prev_hash: %s\n"
                                                 "\t\t Tx_out_prev_idx: %u\n",
-                                        l_tx_hash_str,
+                                        l_hash_str,
                                         ((dap_chain_tx_in_t*)item)->header.tx_out_prev_idx);
-            DAP_DELETE(l_hash_str_tmp);
+            DAP_DELETE(l_hash_str);
             break;
         case TX_ITEM_TYPE_OUT:
             dap_string_append_printf(a_str_out, "\t OUT:\n"
@@ -164,16 +162,26 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
             break;
         }
         case TX_ITEM_TYPE_TOKEN:
-            l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_token_t*)item)->header.token_emission_hash);
+            l_hash_tmp = &((dap_chain_tx_token_t*)item)->header.token_emission_hash;
+            if (!dap_strcmp(a_hash_out_type, "hex"))
+                l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp);
+            else
+                l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp);
             dap_string_append_printf(a_str_out, "\t TOKEN:\n"
                                                 "\t\t ticker: %s \n"
                                                 "\t\t token_emission_hash: %s\n"
-                                                "\t\t token_emission_chain_id: 0x%016"DAP_UINT64_FORMAT_x"\n", ((dap_chain_tx_token_t*)item)->header.ticker, l_hash_str_tmp,
+                                                "\t\t token_emission_chain_id: 0x%016"DAP_UINT64_FORMAT_x"\n",
+                                                ((dap_chain_tx_token_t*)item)->header.ticker,
+                                                l_hash_str,
                                                 ((dap_chain_tx_token_t*)item)->header.token_emission_chain_id.uint64);
-            DAP_DELETE(l_hash_str_tmp);
+            DAP_DELETE(l_hash_str);
             break;
         case TX_ITEM_TYPE_TOKEN_EXT:
-            l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_token_ext_t*)item)->header.ext_tx_hash);
+            l_hash_tmp = &((dap_chain_tx_token_ext_t*)item)->header.ext_tx_hash;
+            if (!dap_strcmp(a_hash_out_type, "hex"))
+                l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp);
+            else
+                l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp);
             dap_string_append_printf(a_str_out, "\t TOKEN EXT:\n"
                                          "\t\t Version: %u\n"
                                          "\t\t Ticker: %s\n"
@@ -185,15 +193,15 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
                                      ((dap_chain_tx_token_ext_t*)item)->header.ticker,
                                      ((dap_chain_tx_token_ext_t*)item)->header.ext_chain_id.uint64,
                                      ((dap_chain_tx_token_ext_t*)item)->header.ext_net_id.uint64,
-                                     l_hash_str_tmp,
+                                     l_hash_str,
                                      ((dap_chain_tx_token_ext_t*)item)->header.ext_tx_out_idx);
-            DAP_FREE(l_hash_str_tmp);
+            DAP_DELETE(l_hash_str);
             break;
         case TX_ITEM_TYPE_SIG:
             l_sign_tmp = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*)item);
             dap_string_append_printf(a_str_out, "\t SIG:\n"
                                                 "\t sig_size: %u\n", ((dap_chain_tx_sig_t*)item)->header.sig_size);
-            dap_sign_get_information(l_sign_tmp, a_str_out);
+            dap_sign_get_information(l_sign_tmp, a_str_out, a_hash_out_type);
             break;
         case TX_ITEM_TYPE_RECEIPT:
             dap_string_append_printf(a_str_out, "\t Receipt:\n"
@@ -224,21 +232,24 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
                        sizeof(dap_sign_t));
                 dap_string_append_printf(a_str_out, "Exts:\n"
                                                     "   Provider:\n");
-                dap_sign_get_information(l_provider, a_str_out);
+                dap_sign_get_information(l_provider, a_str_out, a_hash_out_type);
                 dap_string_append_printf(a_str_out, "   Client:\n");
-                dap_sign_get_information(l_client, a_str_out);
+                dap_sign_get_information(l_client, a_str_out, a_hash_out_type);
             } else if (((dap_chain_datum_tx_receipt_t*)item)->exts_size == sizeof(dap_sign_t)) {
                 dap_sign_t *l_provider = DAP_NEW_Z(dap_sign_t);
                 memcpy(l_provider, ((dap_chain_datum_tx_receipt_t*)item)->exts_n_signs, sizeof(dap_sign_t));
                 dap_string_append_printf(a_str_out, "Exts:\n"
                                                     "   Provider:\n");
-                dap_sign_get_information(l_provider, a_str_out);
+                dap_sign_get_information(l_provider, a_str_out, a_hash_out_type);
             }
             break;
         case TX_ITEM_TYPE_PKEY:
             l_pkey_tmp = (dap_pkey_t*)((dap_chain_tx_pkey_t*)item)->pkey;
             dap_hash_fast(l_pkey_tmp->pkey, l_pkey_tmp->header.size, &l_pkey_hash_tmp);
-            l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&l_pkey_hash_tmp);
+            if (!dap_strcmp(a_hash_out_type, "hex"))
+                l_hash_str = dap_chain_hash_fast_to_str_new(&l_pkey_hash_tmp);
+            else
+                l_hash_str = dap_enc_base58_encode_hash_to_str(&l_pkey_hash_tmp);
             dap_string_append_printf(a_str_out, "\t PKey: \n"
                                                 "\t\t SIG type: %s\n"
                                                 "\t\t SIG size: %u\n"
@@ -252,18 +263,22 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
                                      ((dap_chain_tx_pkey_t*)item)->seq_no,
                                      dap_pkey_type_to_str(l_pkey_tmp->header.type),
                                      l_pkey_tmp->header.size,
-                                     l_hash_str_tmp);
-            DAP_FREE(l_hash_str_tmp);
+                                     l_hash_str);
+            DAP_DELETE(l_hash_str);
             break;
         case TX_ITEM_TYPE_IN_COND:
-            l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_in_t*)item)->header.tx_prev_hash);
+            l_hash_tmp = &((dap_chain_tx_in_cond_t*)item)->header.tx_prev_hash;
+            if (!dap_strcmp(a_hash_out_type, "hex"))
+                l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp);
+            else
+                l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp);
             dap_string_append_printf(a_str_out, "\t IN COND:\n\t\tReceipt_idx: %u\n"
                                                 "\t\t Tx_prev_hash: %s\n"
                                                 "\t\t Tx_out_prev_idx: %u\n",
                                      ((dap_chain_tx_in_cond_t*)item)->header.receipt_idx,
-                                     l_hash_str_tmp,
+                                     l_hash_str,
                                      ((dap_chain_tx_in_cond_t*)item)->header.tx_out_prev_idx);
-            DAP_FREE(l_hash_str_tmp);
+            DAP_DELETE(l_hash_str);
             break;
         case TX_ITEM_TYPE_OUT_COND:
             dap_string_append_printf(a_str_out, "\t OUT COND:\n"
@@ -279,18 +294,22 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
                                      dap_chain_tx_out_cond_subtype_to_str(((dap_chain_tx_out_cond_old_t*)item)->header.subtype));
             switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) {
                 case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY:
-                l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash);
+                l_hash_tmp = &((dap_chain_tx_out_cond_old_t*)item)->subtype.srv_pay.pkey_hash;
+                if (!dap_strcmp(a_hash_out_type, "hex"))
+                    l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp);
+                else
+                    l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp);
                 dap_string_append_printf(a_str_out, "\t\t\t unit: 0x%08x\n"
                                                     "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n"
                                                     "\t\t\t pkey: %s\n"
                                                     "\t\t\t max price: %s (%"DAP_UINT64_FORMAT_U") \n",
                                          ((dap_chain_tx_out_cond_old_t*)item)->subtype.srv_pay.unit.uint32,
                                          ((dap_chain_tx_out_cond_old_t*)item)->subtype.srv_pay.srv_uid.uint64,
-                                         l_hash_str_tmp,
+                                         l_hash_str,
                                          dap_chain_balance_to_coins(dap_chain_uint256_from(
                                              ((dap_chain_tx_out_cond_old_t*)item)->subtype.srv_pay.unit_price_max_datoshi)),
                                          ((dap_chain_tx_out_cond_old_t*)item)->subtype.srv_pay.unit_price_max_datoshi);
-                DAP_FREE(l_hash_str_tmp);
+                DAP_DELETE(l_hash_str);
                 break;
                 case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE:
                 dap_string_append_printf(a_str_out, "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n"
@@ -331,18 +350,22 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
             );
             switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) {
             case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY:
-                l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash);
+                l_hash_tmp = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash;
+                if (!dap_strcmp(a_hash_out_type, "hex"))
+                    l_hash_str = dap_chain_hash_fast_to_str_new(l_hash_tmp);
+                else
+                    l_hash_str = dap_enc_base58_encode_hash_to_str(l_hash_tmp);
                 dap_string_append_printf(a_str_out, "\t\t\t unit: 0x%08x\n"
                                                     "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n"
                                                     "\t\t\t pkey: %s\n"
                                                     "\t\t\t max price: %s (%s) \n",
                                          ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit.uint32,
                                          ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.srv_uid.uint64,
-                                         l_hash_str_tmp,
+                                         l_hash_str,
                                          dap_chain_balance_to_coins(((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi),
                                          dap_chain_balance_print(((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi)
                 );
-                DAP_FREE(l_hash_str_tmp);
+                DAP_DELETE(l_hash_str);
                 break;
             case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE:
                 dap_string_append_printf(a_str_out, "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n"
@@ -973,36 +996,19 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger
         size_t l_datum_num = 0, l_token_num = 0, l_emission_num = 0, l_tx_num = 0;
         size_t l_datum_num_global = a_total_datums ? *a_total_datums : 0;
         while(l_atom && l_atom_size) {
-        size_t l_datums_count = 0;
-        dap_chain_datum_t **l_datums =
-                (a_chain->callback_atom_get_datums && l_atom && l_atom_size) ?
-                        a_chain->callback_atom_get_datums(l_atom, l_atom_size, &l_datums_count) : NULL;
-        if(!l_datums) {
-            log_it(L_WARNING, "Not defined callback_atom_get_datums for chain \"%s\"", a_chain->name);
-            return NULL ;
-        }
-        for(size_t l_datum_n = 0; l_datum_n < l_datums_count; l_datum_n++) {
-            dap_chain_datum_t *l_datum = l_datums[l_datum_n];
-            if(!l_datum) { // || l_datum->header.type_id != DAP_CHAIN_DATUM_TX) {
-                // go to next atom
-                //l_atom = a_chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size);
-                continue;
+            size_t l_datums_count = 0;
+            dap_chain_datum_t **l_datums =
+                    (a_chain->callback_atom_get_datums && l_atom && l_atom_size) ?
+                            a_chain->callback_atom_get_datums(l_atom, l_atom_size, &l_datums_count) : NULL;
+            if(!l_datums) {
+                log_it(L_WARNING, "Not defined callback_atom_get_datums for chain \"%s\"", a_chain->name);
+                return NULL ;
+            }
+            for(size_t l_datum_n = 0; l_datum_n < l_datums_count; l_datum_n++) {
+                dap_chain_datum_t *l_datum = l_datums[l_datum_n];
+                if(!l_datum) { // || l_datum->header.type_id != DAP_CHAIN_DATUM_TX) {
+                    continue;
             }
-        /*dap_chain_atom_iter_t *l_atom_iter = a_chain->callback_atom_iter_create(a_chain);
-        dap_chain_atom_ptr_t l_atom = a_chain->callback_atom_iter_get_first(l_atom_iter);
-        size_t l_atom_size = a_chain->callback_atom_get_size(l_atom);
-        size_t l_datum_num = 0, l_token_num = 0, l_emission_num = 0, l_tx_num = 0;
-        while(l_atom && l_atom_size) {
-            dap_chain_datum_t *l_datum =
-                    a_chain->callback_atom_get_datum ?
-                            a_chain->callback_atom_get_datum(l_atom) : (dap_chain_datum_t*) l_atom;
-            if(!l_datum) {
-                // go to next transaction
-                l_atom = a_chain->callback_atom_iter_get_next(l_atom_iter);
-                l_atom_size = a_chain->callback_atom_get_size(l_atom);
-                log_it(L_ERROR, "datum=NULL for atom=0x%x", l_atom);
-                continue;
-            }*/
             char l_time_str[70];
             // get time of create datum
             if(dap_time_to_str_rfc822(l_time_str, 71, l_datum->header.ts_create) < 1)
@@ -1107,7 +1113,7 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger
                     if(!a_filter_token_name || !dap_strcmp(l_token_em->hdr.ticker, a_filter_token_name)) {
                         char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_em->hdr.address));
                         // filter for addr
-                        if(dap_strcmp(a_filtr_addr_base58,l_token_emission_address_str)) {
+                        if (a_filtr_addr_base58 && dap_strcmp(a_filtr_addr_base58, l_token_emission_address_str)) {
                              break;
                         }
                         if ( l_token_em->hdr.version == 1 ) { // && l_token_em->hdr.type_256 ) { // 256
@@ -1171,10 +1177,19 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger
                         l_tx_num++;
                         break;
                     }
-
                     dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datum->data;
                     //calc tx hash
-                    s_dap_chain_datum_tx_out_data(l_tx, a_ledger, l_str_out, a_hash_out_type, true, &a_tx_hash_processed, &l_tx_num);
+                    dap_chain_hash_fast_t l_tx_hash;
+                    dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
+                    dap_chain_tx_hash_processed_ht_t *l_sht = NULL;
+                    HASH_FIND(hh, a_tx_hash_processed, &l_tx_hash, sizeof(dap_chain_hash_fast_t), l_sht);
+                    if (l_sht != NULL)
+                        break;
+                    l_sht = DAP_NEW_Z(dap_chain_tx_hash_processed_ht_t);
+                    memcpy(&l_sht->hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t));
+                    HASH_ADD(hh, a_tx_hash_processed, hash, sizeof(dap_chain_hash_fast_t), l_sht);
+                    l_tx_num++;
+                    s_dap_chain_datum_tx_out_data(l_tx, a_ledger, l_str_out, a_hash_out_type, &l_tx_hash);
                 } break;
 
                 default:
@@ -1243,7 +1258,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
     const char * l_hash_out_type = NULL;
     dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type);
     if(!l_hash_out_type)
-        l_hash_out_type = "base58";
+        l_hash_out_type = "hex";
     if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) {
         dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>");
         return -1;
@@ -1298,7 +1313,8 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
         //const char *l_chain_group = dap_chain_gdb_get_group(l_chain);
         dap_chain_hash_fast_t l_tx_hash;
         if(l_tx_hash_str) {
-            if(dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash) < 0) {
+            if (dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash) &&
+                    dap_enc_base58_hex_to_hash(l_tx_hash_str, &l_tx_hash)) {
                 l_tx_hash_str = NULL;
                 dap_chain_node_cli_set_reply_text(a_str_reply, "tx hash not recognized");
                 return -1;
@@ -1392,9 +1408,13 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
         int l_sub_cmd = SUBCMD_NONE;
         if (dap_chain_node_cli_find_option_val(a_argv, 2, 3, "coins", NULL ))
                 l_sub_cmd = SUBCMD_LIST_COIN;
+        if (l_sub_cmd == SUBCMD_NONE) {
+            dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'list' requires subcommand 'coins'");
+            return -5;
+        }
         dap_chain_node_cli_find_option_val(a_argv, 3, a_argc, "-net", &l_net_str);
         if (l_net_str == NULL){
-            dap_chain_node_cli_set_reply_text(a_str_reply, "Command requires key -net");
+            dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'list' requires key -net");
             return -1;
         }
         dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str);
@@ -1417,38 +1437,43 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
         dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-hash", &l_tx_hash_str);
         //get net
         dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_str);
+        //get search type
+        const char *l_unspent_str = NULL;
+        dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-unspent", &l_unspent_str);
         //check input
         if (l_tx_hash_str == NULL){
-            dap_chain_node_cli_set_reply_text(a_str_reply, "command requires key -hash");
+            dap_chain_node_cli_set_reply_text(a_str_reply, "Subcommand 'info' requires key -hash");
             return -1;
         }
         if (l_net_str == NULL){
-            dap_chain_node_cli_set_reply_text(a_str_reply, "command requires key -net");
-            return -1;
-        }
-        dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str);
-        if (l_ledger == NULL){
-            dap_chain_node_cli_set_reply_text(a_str_reply, "Can't get ledger for net %s", l_net_str);
+            dap_chain_node_cli_set_reply_text(a_str_reply, "Subcommand 'info' requires key -net");
+            return -2;
+        }     
+        dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
+        if (!l_net) {
+            dap_chain_node_cli_set_reply_text(a_str_reply, "Can't find net %s", l_net_str);
             return -2;
         }
         dap_chain_hash_fast_t *l_tx_hash = DAP_NEW(dap_chain_hash_fast_t);
-        if(dap_chain_hash_fast_from_str(l_tx_hash_str, l_tx_hash)){
+        if (dap_chain_hash_fast_from_str(l_tx_hash_str, l_tx_hash) &&
+                dap_enc_base58_hex_to_hash(l_tx_hash_str, l_tx_hash)) {
             dap_chain_node_cli_set_reply_text(a_str_reply, "Can't get hash_fast from %s", l_tx_hash_str);
-            return -2;
+            return -4;
         }
-        dap_chain_datum_tx_t *l_datum_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, l_tx_hash);
+        dap_chain_datum_tx_t *l_datum_tx = dap_chain_net_get_tx_by_hash(l_net, l_tx_hash,
+                                                                        l_unspent_str ? TX_SEARCH_TYPE_NET_UNSPENT : TX_SEARCH_TYPE_NET);
         if (l_datum_tx == NULL){
             dap_chain_node_cli_set_reply_text(a_str_reply, "Can't get datum from transaction hash %s", l_tx_hash_str);
-            return -2;
+            return -5;
         }
         dap_string_t *l_str = dap_string_new("");
-        s_dap_chain_datum_tx_out_data(l_datum_tx, l_ledger, l_str, l_hash_out_type, false, NULL, NULL);
+        s_dap_chain_datum_tx_out_data(l_datum_tx, l_net->pub.ledger, l_str, l_hash_out_type, l_tx_hash);
         dap_chain_node_cli_set_reply_text(a_str_reply, l_str->str);
         dap_string_free(l_str, true);
     }
     else{
-        dap_chain_node_cli_set_reply_text(a_str_reply, "command requires parameter 'list' or 'tx' or 'info'");
-        return -1;
+        dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'ledger' requires parameter 'list' or 'tx' or 'info'");
+        return -6;
     }
     return 0;
 }
diff --git a/modules/net/dap_chain_node_dns_client.c b/modules/net/dap_chain_node_dns_client.c
index af3c5a5684acea9c28e4fb477d6447249d503f57..419841a1c9e00d0c5f51f1f13b19828c64c2aa1f 100644
--- a/modules/net/dap_chain_node_dns_client.c
+++ b/modules/net/dap_chain_node_dns_client.c
@@ -219,6 +219,7 @@ int dap_chain_node_info_dns_request(struct in_addr a_addr, uint16_t a_port, char
     }
     l_dns_client->dns_request = DAP_NEW_Z(dap_dns_buf_t);
     if( ! l_dns_client->dns_request){
+        DAP_DELETE(l_dns_client->buf);
         DAP_DELETE(l_dns_client);
         return -3;
     }
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index 8d81a7e50ad12638cb31c4215a9f356d47ac6548..3f4e854118bc6e7eaea764467bf7ec4f8f283edb 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -55,7 +55,6 @@
 
 typedef struct dap_chain_cs_dag_event_item {
     dap_chain_hash_fast_t hash;
-    dap_chain_hash_fast_t hash_event_content;
     time_t ts_added;
     dap_chain_cs_dag_event_t *event;
     size_t event_size;
@@ -96,9 +95,8 @@ static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create_from(dap_chain_t
 
 static dap_chain_atom_ptr_t s_chain_callback_atom_iter_find_by_hash(dap_chain_atom_iter_t * a_atom_iter ,
                                                                        dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size);
-static dap_chain_datum_tx_t* s_chain_callback_atom_iter_find_by_tx_hash(dap_chain_t * a_chain ,
-                                                                       dap_chain_hash_fast_t * a_atom_hash);
-
+static dap_chain_datum_tx_t* s_chain_callback_atom_find_by_tx_hash(dap_chain_t *a_chain,
+                                                                   dap_chain_hash_fast_t *a_tx_hash);
 static dap_chain_datum_t** s_chain_callback_atom_get_datum(dap_chain_atom_ptr_t a_event, size_t a_atom_size, size_t *a_datums_count);
 //    Get event(s) from dag
 static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_first( dap_chain_atom_iter_t * a_atom_iter, size_t *a_atom_size ); //    Get the fisrt event from dag
@@ -147,7 +145,7 @@ int dap_chain_cs_dag_init(void)
             "\tdoesn't changes after sign add to event. \n\n"
         "dag -net <chain net name> -chain <chain name> event dump -event <event hash> -from < events | events_lasts | round.new  | round.<Round id in hex> > [-H hex|base58(default)]\n"
             "\tDump event info\n\n"
-        "dag -net <chain net name> -chain <chain name> event list -from < events | events_lasts | round.new  | round.<Round id in hex> \n\n"
+        "dag -net <chain net name> -chain <chain name> event list -from < events | events_lasts | round.new | round.<Round id in hex> \n\n"
             "\tShow event list \n\n"
         "dag -net <chain net name> -chain <chain name> round complete\n\n"
                                         "\tComplete the current new round, verify it and if everything is ok - publish new events in chain\n\n"
@@ -212,8 +210,7 @@ int dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
     a_chain->callback_atom_iter_get_lasts = s_chain_callback_atom_iter_get_lasts;
 
     a_chain->callback_atom_find_by_hash = s_chain_callback_atom_iter_find_by_hash;
-    a_chain->callback_tx_find_by_hash = s_chain_callback_atom_iter_find_by_tx_hash;
-
+    a_chain->callback_tx_find_by_hash = s_chain_callback_atom_find_by_tx_hash;
 
     a_chain->callback_add_datums = s_chain_callback_datums_pool_proc;
 
@@ -355,9 +352,9 @@ static int s_dap_chain_add_atom_to_ledger(dap_chain_cs_dag_t * a_dag, dap_ledger
             l_tx_event->ts_added = a_event_item->ts_added;
             l_tx_event->event = a_event_item->event;
             l_tx_event->event_size = a_event_item->event_size;
-            memcpy(&l_tx_event->hash, &a_event_item->hash, sizeof (l_tx_event->hash) );
+            dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_event->hash);
             int l_err = pthread_rwlock_wrlock(l_events_rwlock);
-            HASH_ADD(hh,PVT(a_dag)->tx_events, hash, sizeof (l_tx_event->hash), l_tx_event);
+            HASH_ADD(hh,PVT(a_dag)->tx_events, hash, sizeof(l_tx_event->hash), l_tx_event);
             if (l_err != EDEADLK) {
                 pthread_rwlock_unlock(l_events_rwlock);
             }
@@ -1233,16 +1230,16 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_find_by_hash(dap_chain_at
 }
 
 
-static dap_chain_datum_tx_t* s_chain_callback_atom_iter_find_by_tx_hash(dap_chain_t * a_chain ,
-                                                                       dap_chain_hash_fast_t * a_atom_hash)
+static dap_chain_datum_tx_t* s_chain_callback_atom_find_by_tx_hash(dap_chain_t *a_chain,
+                                                                   dap_chain_hash_fast_t *a_tx_hash)
 {
     dap_chain_cs_dag_t * l_dag = DAP_CHAIN_CS_DAG( a_chain );
     dap_chain_cs_dag_event_item_t * l_event_item = NULL;
     pthread_rwlock_rdlock(&PVT(l_dag)->events_rwlock);
-    HASH_FIND(hh, PVT(l_dag)->tx_events,a_atom_hash,sizeof(*a_atom_hash),l_event_item);
+    HASH_FIND(hh, PVT(l_dag)->tx_events, a_tx_hash, sizeof(*a_tx_hash), l_event_item);
     pthread_rwlock_unlock(&PVT(l_dag)->events_rwlock);
     if ( l_event_item ){
-        dap_chain_datum_t * l_datum = dap_chain_cs_dag_event_get_datum(l_event_item->event, l_event_item->event_size) ;
+        dap_chain_datum_t *l_datum = dap_chain_cs_dag_event_get_datum(l_event_item->event, l_event_item->event_size);
         return l_datum ? l_datum->header.data_size ? (dap_chain_datum_tx_t*) l_datum->data : NULL :NULL;
     }else
         return NULL;
diff --git a/modules/type/dag/dap_chain_cs_dag_event.c b/modules/type/dag/dap_chain_cs_dag_event.c
index bcdb5ce1e101de818a5964e4f35298b1e32fe55e..8ec8716bf12c8e858c95699163eccac9fa824f32 100644
--- a/modules/type/dag/dap_chain_cs_dag_event.c
+++ b/modules/type/dag/dap_chain_cs_dag_event.c
@@ -198,7 +198,7 @@ bool dap_chain_cs_dag_event_gdb_set(char *a_event_hash_str, dap_chain_cs_dag_eve
     return ret;
 }
 
-dap_chain_cs_dag_event_t* dap_chain_cs_dag_event_gdb_get(char *a_event_hash_str, uint32_t * a_event_size, const char *a_group,
+dap_chain_cs_dag_event_t* dap_chain_cs_dag_event_gdb_get(const char *a_event_hash_str, size_t *a_event_size, const char *a_group,
                                                             dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg) {
     size_t l_event_round_item_size = 0;
     dap_chain_cs_dag_event_round_item_t* l_event_round_item = 
diff --git a/modules/type/dag/include/dap_chain_cs_dag.h b/modules/type/dag/include/dap_chain_cs_dag.h
index ac2ac6074724c973673dd968cab86f8c58677e5e..48d9cd9d153f0bd66395ad4c15517bc87180fe51 100644
--- a/modules/type/dag/include/dap_chain_cs_dag.h
+++ b/modules/type/dag/include/dap_chain_cs_dag.h
@@ -36,7 +36,7 @@ typedef dap_chain_cs_dag_event_t * (*dap_chain_cs_dag_callback_event_create_t)(d
                                                                                dap_chain_hash_fast_t *,
                                                                                size_t, size_t*);
 
-typedef int (*dap_chain_cs_dag_callback_get_round_cfg_t)(dap_chain_cs_dag_t *, dap_chain_cs_dag_event_round_cfg_t *);
+typedef void (*dap_chain_cs_dag_callback_get_round_cfg_t)(dap_chain_cs_dag_t *, dap_chain_cs_dag_event_round_cfg_t *);
 typedef void (*dap_chain_cs_dag_callback_set_event_round_cfg_t)(dap_chain_cs_dag_t *, dap_chain_cs_dag_event_round_cfg_t *);
 
 typedef struct dap_chain_cs_dag_hal_item {
diff --git a/modules/type/dag/include/dap_chain_cs_dag_event.h b/modules/type/dag/include/dap_chain_cs_dag_event.h
index 244c2fbd965cb7b60d94a0e7adc9ae7341c88576..7b188243ab36a9d110804607aff41dcd1ab67366 100644
--- a/modules/type/dag/include/dap_chain_cs_dag_event.h
+++ b/modules/type/dag/include/dap_chain_cs_dag_event.h
@@ -145,6 +145,6 @@ static inline uint32_t dap_chain_cs_dag_event_round_item_get_size(dap_chain_cs_d
 bool dap_chain_cs_dag_event_gdb_set(char *a_event_hash_str, dap_chain_cs_dag_event_t * a_event, uint32_t a_event_size,
                                         const char *a_group, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg);
 
-dap_chain_cs_dag_event_t* dap_chain_cs_dag_event_gdb_get(char *a_event_hash_str, uint32_t * a_event_size,
+dap_chain_cs_dag_event_t* dap_chain_cs_dag_event_gdb_get(const char *a_event_hash_str, size_t *a_event_size,
                                                         const char *a_group, dap_chain_cs_dag_event_round_cfg_t * a_event_round_cfg);