diff --git a/dap-sdk b/dap-sdk
index 02a8df370be77507ea281fc19d8fcc49114e31f3..37c3f575570953da1cbf58d72402612cf3cfc0eb 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 02a8df370be77507ea281fc19d8fcc49114e31f3
+Subproject commit 37c3f575570953da1cbf58d72402612cf3cfc0eb
diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index 61dcf4d4841f0a4c46fe07c8981ffd168607a965..b193c742b87b6d13b3ad8a8b2145828d87c12dfd 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -205,24 +205,14 @@ typedef struct dap_chain_ledger_tx_item {
         char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
         byte_t padding[6];
         byte_t multichannel;
-        byte_t pad[15];
+        dap_time_t ts_spent;
+        byte_t pad[7];
         // 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
     } DAP_ALIGN_PACKED 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;
-    struct {
-        dap_time_t spent_time;
-        char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
-        char padding[22];
-        dap_chain_hash_fast_t tx_hash_spent_fast; // spent outs list
-    } DAP_ALIGN_PACKED cache_data;
-    UT_hash_handle hh;
-} dap_chain_ledger_tx_spent_item_t;
-
 typedef struct dap_chain_ledger_tokenizer {
     char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
     uint256_t sum;
@@ -290,7 +280,6 @@ typedef struct dap_ledger_private {
     dap_chain_ledger_token_emission_item_t * threshold_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;
     dap_chain_ledger_stake_lock_item_t *emissions_for_stake_lock;
     dap_ledger_wallet_balance_t *balance_accounts;
@@ -853,161 +842,167 @@ static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_datum_tx_t *a_t
     DAP_DELETE(l_tx_hash_str);
 }
 
-char * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type)
-{
-        dap_string_t *l_str_out =dap_string_new(NULL);
-        if (!l_str_out) {
-        log_it(L_CRITICAL, "Memory allocation error");
-            return NULL;
+static void s_dump_datum_tx_for_addr(dap_chain_ledger_tx_item_t *a_item, bool a_unspent, dap_ledger_t *a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, dap_string_t *a_str_out) {
+    if (a_unspent && a_item->cache_data.ts_spent) {
+        // With 'unspent' flag spent ones are ignored
+        return;
+    }
+    dap_chain_datum_tx_t *l_tx = a_item->tx;
+    dap_chain_hash_fast_t *l_tx_hash = &a_item->tx_hash_fast;
+    dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_ALL, NULL);
+    if (!l_list_in_items) { // a bad tx
+        return;
+    }
+    dap_chain_addr_t *l_src_addr = NULL;
+    bool l_base_tx = false;
+    const char *l_src_token = NULL;
+    int l_src_subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED;
+    dap_list_t *l_in_item;
+    DL_FOREACH(l_list_in_items, l_in_item) {
+        //assert(it->data);
+        dap_chain_hash_fast_t *l_tx_prev_hash;
+        int l_tx_prev_out_idx;
+        dap_chain_datum_tx_t *l_tx_prev = NULL;
+        if (*(byte_t*)l_in_item->data == TX_ITEM_TYPE_IN) {
+            dap_chain_tx_in_t *l_tx_in = (dap_chain_tx_in_t*)l_in_item->data;
+            l_tx_prev_hash = &l_tx_in->header.tx_prev_hash;
+            l_tx_prev_out_idx = l_tx_in->header.tx_out_prev_idx;
+        } else { // TX_ITEM_TYPE_IN_COND
+            dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t*)l_in_item->data;
+            l_tx_prev_hash = &l_tx_in_cond->header.tx_prev_hash;
+            l_tx_prev_out_idx = l_tx_in_cond->header.tx_out_prev_idx;
+        }
+        if (dap_hash_fast_is_blank(l_tx_prev_hash)) {
+            l_base_tx = true;
+            dap_chain_tx_in_ems_t *l_token = (dap_chain_tx_in_ems_t *)dap_chain_datum_tx_item_get(
+                                                                    l_tx, NULL, TX_ITEM_TYPE_IN_EMS, NULL);
+            if (l_token)
+                l_src_token = l_token->header.ticker;
+            break;
         }
-
-        //dap_chain_tx_hash_processed_ht_t *l_tx_data_ht = NULL;
-        dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp;
-        dap_ledger_private_t * l_ledger_pvt = PVT(a_ledger);
-
-        pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
-        //unsigned test = dap_chain_ledger_count(a_ledger);
-        HASH_ITER(hh, l_ledger_pvt->ledger_items, l_tx_item, l_tx_tmp) {
-
-            dap_chain_datum_tx_t *l_tx = l_tx_item->tx;
-            dap_chain_hash_fast_t *l_tx_hash = &l_tx_item->tx_hash_fast;
-            dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_ALL, NULL);
-            if (!l_list_in_items) { // a bad tx
+        l_tx_prev = dap_chain_ledger_tx_find_by_hash (a_ledger,l_tx_prev_hash);
+        if (l_tx_prev) {
+            uint8_t *l_prev_out_union = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_tx_prev_out_idx);
+            if (!l_prev_out_union)
                 continue;
+            switch (*l_prev_out_union) {
+            case TX_ITEM_TYPE_OUT:
+                l_src_addr = &((dap_chain_tx_out_t *)l_prev_out_union)->addr;
+                break;
+            case TX_ITEM_TYPE_OUT_EXT:
+                l_src_addr = &((dap_chain_tx_out_ext_t *)l_prev_out_union)->addr;
+                l_src_token = (const char *)(((dap_chain_tx_out_ext_t *)l_prev_out_union)->token);
+                break;
+            case TX_ITEM_TYPE_OUT_COND:
+                l_src_subtype = ((dap_chain_tx_out_cond_t *)l_prev_out_union)->header.subtype;
+            default:
+                break;
             }
-            dap_chain_addr_t *l_src_addr = NULL;
-            bool l_base_tx = false;
-            const char *l_src_token = NULL;
-            int l_src_subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED;
-            dap_list_t *l_in_item;
-            DL_FOREACH(l_list_in_items, l_in_item) {
-                //assert(it->data);
-                dap_chain_hash_fast_t *l_tx_prev_hash;
-                int l_tx_prev_out_idx;
-                dap_chain_datum_tx_t *l_tx_prev = NULL;
-                if (*(byte_t*)l_in_item->data == TX_ITEM_TYPE_IN) {
-                    dap_chain_tx_in_t *l_tx_in = (dap_chain_tx_in_t*)l_in_item->data;
-                    l_tx_prev_hash = &l_tx_in->header.tx_prev_hash;
-                    l_tx_prev_out_idx = l_tx_in->header.tx_out_prev_idx;
-                } else { // TX_ITEM_TYPE_IN_COND
-                    dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t*)l_in_item->data;
-                    l_tx_prev_hash = &l_tx_in_cond->header.tx_prev_hash;
-                    l_tx_prev_out_idx = l_tx_in_cond->header.tx_out_prev_idx;
-                }
-                if (dap_hash_fast_is_blank(l_tx_prev_hash)) {
-                    l_base_tx = true;
-                    dap_chain_tx_in_ems_t *l_token = (dap_chain_tx_in_ems_t *)dap_chain_datum_tx_item_get(
-                                                                            l_tx, NULL, TX_ITEM_TYPE_IN_EMS, NULL);
-                    if (l_token)
-                        l_src_token = l_token->header.ticker;
-                    break;
-                }
-                l_tx_prev = dap_chain_ledger_tx_find_by_hash (a_ledger,l_tx_prev_hash);
-                if (l_tx_prev) {
-                    uint8_t *l_prev_out_union = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_tx_prev_out_idx);
-                    if (!l_prev_out_union)
-                        continue;
-                    switch (*l_prev_out_union) {
-                    case TX_ITEM_TYPE_OUT:
-                        l_src_addr = &((dap_chain_tx_out_t *)l_prev_out_union)->addr;
-                        break;
-                    case TX_ITEM_TYPE_OUT_EXT:
-                        l_src_addr = &((dap_chain_tx_out_ext_t *)l_prev_out_union)->addr;
-                        l_src_token = (const char *)(((dap_chain_tx_out_ext_t *)l_prev_out_union)->token);
-                        break;
-                    case TX_ITEM_TYPE_OUT_COND:
-                        l_src_subtype = ((dap_chain_tx_out_cond_t *)l_prev_out_union)->header.subtype;
-                    default:
-                        break;
-                    }
-                }
-                else
-                {
-                    continue; //temporary stub
-                }
-                if (!l_src_token){
-                    l_src_token = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, l_tx_prev_hash);
-                    l_src_token = l_tx_item->cache_data.token_ticker;
-                }
-                if (l_src_addr && memcmp(l_src_addr, a_addr, sizeof(dap_chain_addr_t)))
-                    break;  //it's not our addr
-            }
-            dap_list_free(l_list_in_items);
+        }
+        else
+        {
+            continue; //temporary stub
+        }
+        if (!l_src_token){
+            l_src_token = a_item->cache_data.token_ticker;
+        }
+        if (l_src_addr && memcmp(l_src_addr, a_addr, sizeof(dap_chain_addr_t)))
+            break;  //it's not our addr
+    }
+    dap_list_free(l_list_in_items);
 
-            bool l_header_printed = false;
-            dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
-            if(!l_list_out_items)
-                continue;
-            for(dap_list_t *l_list_out = l_list_out_items; l_list_out; l_list_out = dap_list_next(l_list_out)) {
-                assert(l_list_out->data);
-                dap_chain_addr_t *l_dst_addr = NULL;
-                dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_out->data;
-                uint256_t l_value;
-                switch (l_type) {
-                case TX_ITEM_TYPE_OUT:
-                    l_dst_addr = &((dap_chain_tx_out_t *)l_list_out->data)->addr;
-                    l_value = ((dap_chain_tx_out_t *)l_list_out->data)->header.value;
-                    break;
-                case TX_ITEM_TYPE_OUT_EXT:
-                    l_dst_addr = &((dap_chain_tx_out_ext_t *)l_list_out->data)->addr;
-                    l_value = ((dap_chain_tx_out_ext_t *)l_list_out->data)->header.value;
-                    break;
-                case TX_ITEM_TYPE_OUT_COND:
-                    l_value = ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.value;
-                default:
-                    break;
-                }
-                if (l_src_addr && l_dst_addr && !memcmp(l_dst_addr, l_src_addr, sizeof(dap_chain_addr_t)))
-                    continue;   // send to self
-                if (l_src_addr && !memcmp(l_src_addr, a_addr, sizeof(dap_chain_addr_t))) {
-                    if (!l_header_printed) {
-                        s_tx_header_print(l_str_out, l_tx, a_hash_out_type, l_tx_hash);
-                        l_header_printed = true;
-                    }
-                    //const char *l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash);
-                    const char *l_dst_addr_str = l_dst_addr ? dap_chain_addr_to_str(l_dst_addr)
-                                                            : dap_chain_tx_out_cond_subtype_to_str(
-                                                                  ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.subtype);
-                    char *l_value_str = dap_chain_balance_print(l_value);
-                    dap_string_append_printf(l_str_out, "\tsend %s %s to %s\n",
-                                             l_value_str,
-                                             l_src_token ? l_src_token : "UNKNOWN",
-                                             l_dst_addr_str);
-                    if (l_dst_addr)
-                        DAP_DELETE(l_dst_addr_str);
-                    DAP_DELETE(l_value_str);
-                }
-                if (l_dst_addr && !memcmp(l_dst_addr, a_addr, sizeof(dap_chain_addr_t))) {
-                    if (!l_header_printed) {
-                       s_tx_header_print(l_str_out, l_tx, a_hash_out_type, l_tx_hash);
-                       l_header_printed = true;
-                    }
-                    const char *l_dst_token = (l_type == TX_ITEM_TYPE_OUT_EXT) ?
-                                (const char *)(((dap_chain_tx_out_ext_t *)l_list_out->data)->token) : NULL;
-                    const char *l_src_addr_str = l_base_tx ? "emission"
-                                                           : (l_src_addr ? dap_chain_addr_to_str(l_src_addr)
-                                                                         : dap_chain_tx_out_cond_subtype_to_str(
-                                                                               l_src_subtype));
-                    char *l_value_str = dap_chain_balance_print(l_value);
-                    dap_string_append_printf(l_str_out, "\trecv %s %s from %s\n",
-                                             l_value_str,
-                                             l_dst_token ? l_dst_token :
-                                                           (l_src_token ? l_src_token : "UNKNOWN"),
-                                             l_src_addr_str);
-                    if (l_src_addr)
-                        DAP_DELETE(l_src_addr_str);
-                    DAP_DELETE(l_value_str);
-                }
-            }
-            dap_list_free(l_list_out_items);
+    bool l_header_printed = false;
+    dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
+    if(!l_list_out_items)
+        return;
+    for(dap_list_t *l_list_out = l_list_out_items; l_list_out; l_list_out = dap_list_next(l_list_out)) {
+        assert(l_list_out->data);
+        dap_chain_addr_t *l_dst_addr = NULL;
+        dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_out->data;
+        uint256_t l_value;
+        switch (l_type) {
+        case TX_ITEM_TYPE_OUT:
+            l_dst_addr = &((dap_chain_tx_out_t *)l_list_out->data)->addr;
+            l_value = ((dap_chain_tx_out_t *)l_list_out->data)->header.value;
+            break;
+        case TX_ITEM_TYPE_OUT_EXT:
+            l_dst_addr = &((dap_chain_tx_out_ext_t *)l_list_out->data)->addr;
+            l_value = ((dap_chain_tx_out_ext_t *)l_list_out->data)->header.value;
+            break;
+        case TX_ITEM_TYPE_OUT_COND:
+            l_value = ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.value;
+        default:
+            break;
         }
-        pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
+        if (l_src_addr && l_dst_addr && !memcmp(l_dst_addr, l_src_addr, sizeof(dap_chain_addr_t)))
+            continue;   // send to self
+        if (l_src_addr && !memcmp(l_src_addr, a_addr, sizeof(dap_chain_addr_t))) {
+            if (!l_header_printed) {
+                s_tx_header_print(a_str_out, l_tx, a_hash_out_type, l_tx_hash);
+                l_header_printed = true;
+            }
+            //const char *l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash);
+            const char *l_dst_addr_str = l_dst_addr ? dap_chain_addr_to_str(l_dst_addr)
+                                                    : dap_chain_tx_out_cond_subtype_to_str(
+                                                          ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.subtype);
+            char *l_value_str = dap_chain_balance_print(l_value);
+            dap_string_append_printf(a_str_out, "\tsend %s %s to %s\n",
+                                     l_value_str,
+                                     l_src_token ? l_src_token : "UNKNOWN",
+                                     l_dst_addr_str);
+            if (l_dst_addr)
+                DAP_DELETE(l_dst_addr_str);
+            DAP_DELETE(l_value_str);
+        }
+        if (l_dst_addr && !memcmp(l_dst_addr, a_addr, sizeof(dap_chain_addr_t))) {
+            if (!l_header_printed) {
+               s_tx_header_print(a_str_out, l_tx, a_hash_out_type, l_tx_hash);
+               l_header_printed = true;
+            }
+            const char *l_dst_token = (l_type == TX_ITEM_TYPE_OUT_EXT) ?
+                        (const char *)(((dap_chain_tx_out_ext_t *)l_list_out->data)->token) : NULL;
+            const char *l_src_addr_str = l_base_tx ? "emission"
+                                                   : (l_src_addr ? dap_chain_addr_to_str(l_src_addr)
+                                                                 : dap_chain_tx_out_cond_subtype_to_str(
+                                                                       l_src_subtype));
+            char *l_value_str = dap_chain_balance_print(l_value);
+            dap_string_append_printf(a_str_out, "\trecv %s %s from %s\n",
+                                     l_value_str,
+                                     l_dst_token ? l_dst_token :
+                                                   (l_src_token ? l_src_token : "UNKNOWN"),
+                                     l_src_addr_str);
+            if (l_src_addr)
+                DAP_DELETE(l_src_addr_str);
+            DAP_DELETE(l_value_str);
+        }
+    }
+    dap_list_free(l_list_out_items);
+}
+
+char *dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only)
+{
+    dap_string_t *l_str_out = dap_string_new(NULL);
+    if (!l_str_out) {
+    log_it(L_CRITICAL, "Memory allocation error");
+        return NULL;
+    }
 
-        // if no history
-        if(!l_str_out->len)
-            dap_string_append(l_str_out, "\tempty");
-        char *l_ret_str = l_str_out ? dap_string_free(l_str_out, false) : NULL;
-        return l_ret_str;
+    //dap_chain_tx_hash_processed_ht_t *l_tx_data_ht = NULL;
+    dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp;
+    dap_ledger_private_t * l_ledger_pvt = PVT(a_ledger);
+
+    pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
+    //unsigned test = dap_chain_ledger_count(a_ledger);
+    HASH_ITER(hh, l_ledger_pvt->ledger_items, l_tx_item, l_tx_tmp) {
+        s_dump_datum_tx_for_addr(l_tx_item, a_unspent_only, a_ledger, a_addr, a_hash_out_type, l_str_out);
+    }
+    pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
+
+    // if no history
+    if(!l_str_out->len)
+        dap_string_append(l_str_out, "\tempty");
+    char *l_ret_str = l_str_out ? dap_string_free(l_str_out, false) : NULL;
+    return l_ret_str;
 }
 
 /**
@@ -1104,26 +1099,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
         return -1;
     }
 
-    dap_chain_datum_token_t *l_token = NULL;
-    size_t l_token_size = a_token_size;
-
-    switch (a_token->type) {
-        case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_SIMPLE:
-        case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL:
-        case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE:
-        case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_DECL:
-        case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE:
-        case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PUBLIC:
-            l_token = dap_chain_datum_token_read((byte_t *) a_token, &l_token_size);
-            break;
-        default:
-            l_token = DAP_DUP_SIZE(a_token, a_token_size);
-            if ( !l_token ) {
-        log_it(L_CRITICAL, "Memory allocation error");
-                return -6;
-            }
-            break;
-    }
+    dap_chain_datum_token_t *l_token = a_token;
 
     dap_chain_ledger_token_item_t *l_token_item;
     pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
@@ -1131,15 +1107,17 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
     pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
 
     if (l_token_item) {
-        if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) {
+        if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE
+                && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE
+                && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE) {
             log_it(L_ERROR, "Duplicate token declaration for ticker '%s'", l_token->ticker);
-            DAP_DEL_Z(l_token);
+            DAP_DELETE(l_token);
             return -3;
         }
-        if (s_ledger_token_update_check(l_token_item, l_token, l_token_size)) {
-            if (!s_ledger_update_token_add_in_hash_table(l_token_item, l_token, l_token_size)) {
+        if (s_ledger_token_update_check(l_token_item, l_token, a_token_size)) {
+            if (!s_ledger_update_token_add_in_hash_table(l_token_item, l_token, a_token_size)) {
                 log_it(L_ERROR, "Failed to update token with ticker '%s' in ledger", l_token->ticker);
-                DAP_DEL_Z(l_token);
+                DAP_DELETE(l_token);
                 return -5;
             }
             if (!IS_ZERO_256(l_token->total_supply)) {
@@ -1163,7 +1141,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
 
     if (!l_token_item) {
         size_t l_auth_signs_total, l_auth_signs_valid;
-        dap_sign_t **l_signs = dap_chain_datum_token_signs_parse(l_token, l_token_size, &l_auth_signs_total, &l_auth_signs_valid);
+        dap_sign_t **l_signs = dap_chain_datum_token_signs_parse(l_token, a_token_size, &l_auth_signs_total, &l_auth_signs_valid);
         if (!l_signs || !l_auth_signs_total) {
             log_it(L_ERROR, "No auth signs in token '%s' datum!", l_token->ticker);
             DAP_DEL_Z(l_token);
@@ -1212,11 +1190,13 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
     }
 
 
-    l_token_item->datum_token_size  = l_token_size;
+    l_token_item->datum_token_size  = a_token_size;
     l_token_item->datum_token       = l_token;
     l_token_item->datum_token->type = l_token->type;
 
-    if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE) {
+    if(l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE
+            && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE
+            && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE) {
         pthread_rwlock_wrlock(&PVT(a_ledger)->tokens_rwlock);
         HASH_ADD_STR(PVT(a_ledger)->tokens, ticker, l_token_item);
         pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
@@ -1243,15 +1223,15 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
             debug_if(s_debug_more, L_INFO, "Private token %s declared, total_supply: %s, total_signs_valid: %hu, signs_total: %hu",
                     l_token->ticker, l_balance_dbg,
                     l_token->signs_valid, l_token->signs_total);
-            l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size);
-            s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size);
+            l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size);
+            s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size);
             break;
         case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE:
             debug_if(s_debug_more, L_INFO, "CF20 token %s declared, total_supply: %s, total_signs_valid: %hu, signs_total: %hu",
                     l_token->ticker, l_balance_dbg,
                     l_token->signs_valid, l_token->signs_total);
-            l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size);
-            s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size);
+            l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size);
+            s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size);
             break;
         default:
             /* Bogdanoff, unknown token subtype declaration. What shall we TODO? */
@@ -1274,15 +1254,15 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
             debug_if(s_debug_more, L_INFO, "Private token %s updated, total_supply: %s, total_signs_valid: %hu, signs_total: %hu",
                     l_token->ticker, l_balance_dbg,
                     l_token->signs_valid, l_token->signs_total);
-            l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size);
-            s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size);
+            l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size);
+            s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size);
             break;
         case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE:
             debug_if(s_debug_more, L_INFO, "CF20 token %s updated, total_supply: %s, total_signs_valid: %hu, signs_total: %hu",
                     l_token->ticker, l_balance_dbg,
                     l_token->signs_valid, l_token->signs_total);
-            l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, l_token_size);
-            s_tsd_sign_apply(a_ledger, l_token_item, l_token, l_token_size);
+            l_res_token_tsd_parse = s_token_tsd_parse(a_ledger, l_token_item, l_token, a_token_size);
+            s_tsd_sign_apply(a_ledger, l_token_item, l_token, a_token_size);
             break;
         default:
             /* Bogdanoff, unknown token type update. What shall we TODO? */
@@ -1380,11 +1360,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite
 
                     // Check if its correct
                     dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data;
-                    int l_add_addr_check;
-                    if (  (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=1){
-                        if(s_debug_more)
-                            log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD (code %d)",
-                               l_add_addr_check);
+                    if (dap_chain_addr_check_sum(l_add_addr)) {
+                        debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD");
                         return -12;
                     }
                     // Check if its already present
@@ -1422,11 +1399,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite
                 if( l_tsd->size == sizeof (dap_chain_addr_t) ){
                     // Check if its correct
                     dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data;
-                    int l_add_addr_check;
-                    if (  (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=0){
-                        if(s_debug_more)
-                            log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE (code %d)",
-                               l_add_addr_check);
+                    if (dap_chain_addr_check_sum(l_add_addr)) {
+                        debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE");
                         return -12;
                     }
                     bool l_was_found=false;
@@ -1473,12 +1447,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite
                                           (a_token_item->tx_recv_block_size + 1) * sizeof(*a_token_item->tx_recv_block));
                     // Check if its correct
                     dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data;
-                    int l_add_addr_check;
-                    if ((l_add_addr_check=dap_chain_addr_check_sum(l_add_addr)) != 1) {
-                        if(s_debug_more)
-                            log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD (code %d)",
-                               l_add_addr_check);
-                        DAP_DELETE(l_addrs);
+                    if (dap_chain_addr_check_sum(l_add_addr)) {
+                        debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD");
                         return -12;
                     }
                     // Check if its already present
@@ -1516,11 +1486,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite
                 if( l_tsd->size == sizeof (dap_chain_addr_t) ){
                     // Check if its correct
                     dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data;
-                    int l_add_addr_check;
-                    if (  (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=0){
-                        if(s_debug_more)
-                            log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE (code %d)",
-                               l_add_addr_check);
+                    if (dap_chain_addr_check_sum(l_add_addr)) {
+                        debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE");
                         return -12;
                     }
                     bool l_was_found=false;
@@ -1565,12 +1532,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite
                                 : DAP_REALLOC(a_token_item->tx_send_allow,(a_token_item->tx_send_allow_size+1)*sizeof (*a_token_item->tx_send_allow) );
                     // Check if its correct
                     dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data;
-                    int l_add_addr_check;
-                    if (  (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr)) != 1){
-                        if(s_debug_more)
-                            log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD (code %d)",
-                               l_add_addr_check);
-                        DAP_DELETE(l_addrs);
+                    if (dap_chain_addr_check_sum(l_add_addr)) {
+                        debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD");
                         return -12;
                     }
                     // Check if its already present
@@ -1604,11 +1567,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite
                 if( l_tsd->size == sizeof (dap_chain_addr_t) ){
                     // Check if its correct
                     dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data;
-                    int l_add_addr_check;
-                    if (  (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=0){
-                        if(s_debug_more)
-                            log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE (code %d)",
-                               l_add_addr_check);
+                    if (dap_chain_addr_check_sum(l_add_addr)) {
+                        debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE");
                         return -12;
                     }
                     bool l_was_found=false;
@@ -1649,18 +1609,13 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite
             //Blocked tx sender addres list add, remove or clear
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD:{
                 if( l_tsd->size == sizeof (dap_chain_addr_t) ){
-                    dap_chain_addr_t * l_addrs = a_token_item->tx_send_block ? DAP_NEW_Z_SIZE( dap_chain_addr_t,
-                                                                                              sizeof(*a_token_item->tx_send_block) )
-                                : DAP_REALLOC(a_token_item->tx_send_block,(a_token_item->tx_send_block_size+1)*sizeof (*a_token_item->tx_send_block) );
+                    dap_chain_addr_t *l_addrs = a_token_item->tx_send_block
+                            ? DAP_NEW_Z_SIZE(dap_chain_addr_t, sizeof(*a_token_item->tx_send_block))
+                            : DAP_REALLOC(a_token_item->tx_send_block, (a_token_item->tx_send_block_size + 1) * sizeof(*a_token_item->tx_send_block));
                     // Check if its correct
                     dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data;
-                    int l_add_addr_check;
-                    if ((l_add_addr_check=dap_chain_addr_check_sum(l_add_addr)) != 1) {
-                        if(s_debug_more)
-                            log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD (code %d)",
-                               l_add_addr_check);
-                        if (l_addrs)
-                            DAP_DELETE(l_addrs);
+                    if (dap_chain_addr_check_sum(l_add_addr)) {
+                        debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD");
                         return -12;
                     }
                     // Check if its already present
@@ -1695,11 +1650,8 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite
                 if( l_tsd->size == sizeof (dap_chain_addr_t) ){
                     // Check if its correct
                     dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data;
-                    int l_add_addr_check;
-                    if (  (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=0){
-                        if(s_debug_more)
-                            log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE (code %d)",
-                               l_add_addr_check);
+                    if (dap_chain_addr_check_sum(l_add_addr)) {
+                        debug_if(s_debug_more, L_ERROR, "Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE");
                         return -12;
                     }
                     bool l_was_found=false;
@@ -1815,17 +1767,24 @@ static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_
     return 0;
 }
 
-int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size)
+int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size)
 {
+    dap_chain_datum_token_t *l_token = dap_chain_datum_token_read(a_token, &a_token_size);
+
     if (PVT(a_ledger)->load_mode) {
         dap_chain_ledger_token_item_t *l_token_item;
         pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
-        HASH_FIND_STR(PVT(a_ledger)->tokens, a_token->ticker, l_token_item);
+        HASH_FIND_STR(PVT(a_ledger)->tokens, l_token->ticker, l_token_item);
         pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
-        if (l_token_item && a_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE)
+        if (l_token_item
+                && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE
+                && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE
+                && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE) {
+            DAP_DELETE(l_token);
             return 0;
+        }
     }
-    return dap_chain_ledger_token_add(a_ledger, a_token, a_token_size);
+    return dap_chain_ledger_token_add(a_ledger, l_token, a_token_size);
 }
 
 dap_string_t *dap_chain_ledger_threshold_info(dap_ledger_t *a_ledger)
@@ -1883,7 +1842,7 @@ dap_string_t *dap_chain_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_c
     dap_string_t *l_str_ret = dap_string_new("");
     pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock);
     HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp){
-        if (!memcmp(l_threshold_hash,&l_tx_item->tx_hash_fast, sizeof(dap_chain_hash_fast_t))){
+        if (!memcmp(l_threshold_hash, &l_tx_item->tx_hash_fast, sizeof(dap_chain_hash_fast_t))){
             char l_tx_hash_str[70]={0};
             dap_chain_hash_fast_to_str(l_threshold_hash,l_tx_hash_str,sizeof(l_tx_hash_str));
             dap_string_append(l_str_ret, "Hash was found in ledger tx threshold:");
@@ -2271,43 +2230,6 @@ static bool s_load_cache_gdb_loaded_balances_callback(dap_global_db_instance_t *
     return true;
 }
 
-/**
- * @brief s_load_cache_gdb_loaded_spent_txs_callback
- * @param a_global_db_context
- * @param a_rc
- * @param a_group
- * @param a_key
- * @param a_values_total
- * @param a_values_shift
- * @param a_values_count
- * @param a_values
- * @param a_arg
- */
-static bool s_load_cache_gdb_loaded_spent_txs_callback(dap_global_db_instance_t *a_dbi,
-                                                       int a_rc, const char *a_group,
-                                                       const size_t a_values_total, const size_t a_values_count,
-                                                       dap_global_db_obj_t *a_values, void *a_arg)
-{
-    dap_ledger_t * l_ledger = (dap_ledger_t*) a_arg;
-    dap_ledger_private_t * l_ledger_pvt = PVT(l_ledger);
-
-    for (size_t i = 0; i < a_values_count; i++) {
-        dap_chain_ledger_tx_spent_item_t *l_tx_spent_item = DAP_NEW_Z(dap_chain_ledger_tx_spent_item_t);
-        if ( !l_tx_spent_item ) {
-        log_it(L_CRITICAL, "Memory allocation error");
-            return false;
-        }
-        dap_chain_hash_fast_from_str(a_values[i].key, &l_tx_spent_item->tx_hash_fast);
-        l_tx_spent_item->cache_data = *(typeof(l_tx_spent_item->cache_data)*)a_values[i].value;
-        HASH_ADD(hh, l_ledger_pvt->spent_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_tx_spent_item);
-    }
-
-    char *l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_LEDGER_BALANCES_STR);
-    dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_balances_callback, l_ledger);
-    DAP_DELETE(l_gdb_group);
-    return true;
-}
-
 /**
  * @brief s_load_cache_gdb_loaded_txs_callback
  * @param a_global_db_context
@@ -2345,10 +2267,6 @@ static bool s_load_cache_gdb_loaded_txs_callback(dap_global_db_instance_t *a_dbi
         l_tx_item->ts_added = dap_nanotime_now();
         HASH_ADD_INORDER(hh, l_ledger_pvt->ledger_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_tx_item, s_sort_ledger_tx_item);
     }
-
-    char *l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR);
-    dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_spent_txs_callback, l_ledger);
-    DAP_DELETE(l_gdb_group);
     return true;
 }
 
@@ -2469,6 +2387,7 @@ static bool s_load_cache_gdb_loaded_tokens_callback(dap_global_db_instance_t *a_
             log_it(L_WARNING, "Corrupted token with ticker [%s], need to 'ledger reload' to update cache", a_values[i].key);
             continue;
         }
+        // TODO: rework! Old token types may be passed unchecked!
         dap_chain_ledger_token_add(l_ledger, l_token, l_token_size);
         dap_chain_ledger_token_item_t *l_token_item = NULL;
         HASH_FIND_STR(l_ledger_pvt->tokens, l_token->ticker, l_token_item);
@@ -3162,15 +3081,8 @@ const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,
     HASH_VALUE(a_tx_hash, sizeof(*a_tx_hash), l_hash_value);
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
     HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->ledger_items, a_tx_hash, sizeof(*a_tx_hash), l_hash_value, l_item);
-    if (l_item) {
-        pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
-        return l_item->cache_data.token_ticker;
-    }
-    dap_chain_ledger_tx_spent_item_t *l_spent_item;
-    HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->spent_items, a_tx_hash, sizeof(*a_tx_hash), l_hash_value, l_spent_item);
     pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
-    return l_spent_item ? l_spent_item->cache_data.token_ticker : NULL;
-
+    return l_item ? l_item->cache_data.token_ticker : NULL;
 }
 
 /**
@@ -3300,7 +3212,7 @@ void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chai
  * return transaction, or NULL if transaction not found in the cache
  */
 static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger,
-        dap_chain_hash_fast_t *a_tx_hash, dap_chain_ledger_tx_item_t **a_item_out)
+        dap_chain_hash_fast_t *a_tx_hash, dap_chain_ledger_tx_item_t **a_item_out, bool a_unspent_only)
 {
     if(!a_tx_hash)
         return NULL;
@@ -3314,9 +3226,11 @@ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger,
     HASH_FIND(hh, l_ledger_pvt->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item);
     pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
     if(l_tx_item) {
-        l_tx_ret = l_tx_item->tx;
-        if(a_item_out)
-            *a_item_out = l_tx_item;
+        if (!a_unspent_only || !l_tx_item->cache_data.ts_spent) {
+            l_tx_ret = l_tx_item->tx;
+            if(a_item_out)
+                *a_item_out = l_tx_item;
+        }
     }
     return l_tx_ret;
 }
@@ -3327,18 +3241,14 @@ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger,
  * @return
  */
 
-dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash)
+dap_chain_datum_tx_t *dap_chain_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash)
 {
-    return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL);
+    return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL, true);
 }
 
-void *dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash)
+dap_chain_datum_tx_t *dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash)
 {
-    dap_chain_ledger_tx_spent_item_t *l_tx_item;
-    pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock);
-    HASH_FIND(hh, PVT(a_ledger)->spent_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item);
-    pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock);
-    return l_tx_item;
+    return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL, false);
 }
 
 dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash)
@@ -3353,28 +3263,17 @@ dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger
     while (l_tx_hash) {
         HASH_VALUE(l_tx_hash, sizeof(*l_tx_hash), l_hash_value);
         HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->ledger_items, l_tx_hash, sizeof(*l_tx_hash), l_hash_value, l_item);
-        if (l_item) {
-            int l_out_num = 0;
-            dap_chain_datum_tx_out_cond_get(l_item->tx, a_cond_type, &l_out_num);
-            if (l_out_num != -1 && l_out_num < MAX_OUT_ITEMS) {
-                if (dap_hash_fast_is_blank(&l_item->cache_data.tx_hash_spent_fast[l_out_num]))
-                    break;      // We have unused conditional output
-                else {
-                    l_tx_hash = &l_item->cache_data.tx_hash_spent_fast[l_out_num];
-                    continue;   // Conditional output is used out
-                }
-            } else {            // No conditional output found
-                l_tx_hash = NULL;
-                break;
-            }
+        if (!l_item) {
+            l_tx_hash = NULL;
+            break;      // Not found in ledger
+        }
+        int l_out_num = 0;
+        if (dap_hash_fast_is_blank(&l_item->cache_data.tx_hash_spent_fast[l_out_num]) || !dap_chain_datum_tx_out_cond_get(l_item->tx, a_cond_type, &l_out_num))
+            break;      // Unused conditional output found, that's what we need
+        else {
+            l_tx_hash = &l_item->cache_data.tx_hash_spent_fast[l_out_num];
+            continue;   // Conditional output is used out
         }
-        dap_chain_ledger_tx_spent_item_t *l_spent_item;
-        HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->spent_items, l_tx_hash, sizeof(*l_tx_hash), l_hash_value, l_spent_item);
-        if (l_spent_item && // We have condional output with spent item
-                !dap_hash_fast_is_blank(&l_spent_item->cache_data.tx_hash_spent_fast)) {
-            l_tx_hash = &l_spent_item->cache_data.tx_hash_spent_fast;
-        } else
-            l_tx_hash = NULL;   // We can't find pointed hash in the ledger or it's a not conditional tx
     }
     pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
     return l_tx_hash;
@@ -3783,16 +3682,20 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                     break;
                 }
                 if (!EQUAL_256(l_value_expected, l_stake_lock_ems_value)) {
-                    char *l_value_expected_str = dap_chain_balance_print(l_value_expected);
-                    char *l_locked_value_str = dap_chain_balance_print(l_stake_lock_ems_value);
-
-                    debug_if(s_debug_more, L_WARNING, "Value %s != %s expected for [%s]",l_locked_value_str, l_value_expected_str,
-                             l_tx_in_ems->header.ticker);
-
-                    DAP_DEL_Z(l_value_expected_str);
-                    DAP_DEL_Z(l_locked_value_str);
-                    l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE;
-                    break;
+                    // !!! A terrible legacy crutch, TODO !!!
+                    SUM_256_256(l_value_expected, GET_256_FROM_64(10), &l_value_expected);
+                    if (!EQUAL_256(l_value_expected, l_stake_lock_ems_value)) {
+                            char *l_value_expected_str = dap_chain_balance_print(l_value_expected);
+                            char *l_locked_value_str = dap_chain_balance_print(l_stake_lock_ems_value);
+
+                            debug_if(s_debug_more, L_WARNING, "Value %s != %s expected for [%s]",l_locked_value_str, l_value_expected_str,
+                                     l_tx_in_ems->header.ticker);
+
+                            DAP_DEL_Z(l_value_expected_str);
+                            DAP_DEL_Z(l_locked_value_str);
+                            l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE;
+                            break;
+                    }
                 }
                 if (!l_girdled_ems) {
                     // check tiker
@@ -3822,17 +3725,15 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
         } else { //It's not the emission TX
             // Get previous transaction in the cache by hash
             dap_chain_ledger_tx_item_t *l_item_out = NULL;
-            l_tx_prev = s_find_datum_tx_by_hash(a_ledger, &l_tx_prev_hash, &l_item_out);
+            l_tx_prev = s_find_datum_tx_by_hash(a_ledger, &l_tx_prev_hash, &l_item_out, false);
             if (!l_tx_prev) { // Unchained transaction or previous TX was already spent and removed from ledger
-                dap_chain_ledger_tx_spent_item_t *l_used_item = dap_chain_ledger_tx_spent_find_by_hash(a_ledger, &l_tx_prev_hash);
-                if (l_used_item) {
-                    l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED;
-                    debug_if(s_debug_more, L_INFO, "All 'out' items of previous tx %s were already spent", l_tx_prev_hash_str);
-                    break;
-                }
                 debug_if(s_debug_more && !a_from_threshold, L_DEBUG, "No previous transaction was found for hash %s", l_tx_prev_hash_str);
                 l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS;
                 break;
+            } else if (l_item_out->cache_data.ts_spent) {
+                l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED;
+                debug_if(s_debug_more, L_INFO, "All 'out' items of previous tx %s were already spent", l_tx_prev_hash_str);
+                break;
             }
             bound_item->item_out = l_item_out;
             l_token = l_item_out->cache_data.token_ticker;
@@ -4615,29 +4516,10 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
             l_cache_used_outs[i].timestamp = dap_nanotime_now();
         }
 
-        // delete previous transactions from cache because all out is used
-        if(l_prev_item_out->cache_data.n_outs_used == l_prev_item_out->cache_data.n_outs) {
-            dap_chain_hash_fast_t *l_tx_prev_hash_to_del = &l_prev_item_out->tx_hash_fast; //&bound_item->tx_prev_hash;
-            char l_tx_prev_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-            dap_chain_hash_fast_to_str(l_tx_prev_hash_to_del, l_tx_prev_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
-            // remove from memory ledger
-            int res = dap_chain_ledger_tx_remove(a_ledger, l_tx_prev_hash_to_del, a_tx->header.ts_created);
-            switch (res) {
-            case 1:
-                debug_if(s_debug_more, L_INFO, "Deleted prev tx %s from ledger", l_tx_prev_hash_str);
-                break;
-            case -2:
-                debug_if(s_debug_more, L_ERROR, "Can't delete previous transactions %s: hash not found", l_tx_prev_hash_str);
-                l_ret = -100;
-                l_outs_used = i;
-                goto FIN;
-            default:
-                debug_if(s_debug_more, L_ERROR, "Can't delete previous transaction %s, res code %d", l_tx_prev_hash_str, res);
-                l_ret = -101;
-                l_outs_used = i;
-                goto FIN;
-            }
-        }
+        // mark previous transactions as used with the extra timestamp
+        if(l_prev_item_out->cache_data.n_outs_used == l_prev_item_out->cache_data.n_outs)
+            l_prev_item_out->cache_data.ts_spent = a_tx->header.ts_created;
+
         // go to next previous transaction
         l_list_tmp = dap_list_next(l_list_tmp);
     }
@@ -4847,84 +4729,10 @@ int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
             pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock);
             return DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS;
         }
-        dap_chain_ledger_tx_spent_item_t *l_tx_spent_item;
-        HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->spent_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_spent_item);
-        pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock);
-        if (l_tx_spent_item)
-            return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED;
     }
     return dap_chain_ledger_tx_add(a_ledger, a_tx, a_tx_hash, false);
 }
 
-/**
- * Delete transaction from the cache
- *
- * return 1 OK, -1 error, -2 tx_hash not found
- */
-int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, dap_time_t a_spent_time)
-{
-    if(!a_tx_hash)
-        return -1;
-    int l_ret = -1;
-    dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    dap_chain_ledger_tx_item_t *l_item_tmp;
-    unsigned l_hash_value;
-    HASH_VALUE(a_tx_hash, sizeof(*a_tx_hash), l_hash_value);
-    pthread_rwlock_wrlock(&l_ledger_pvt->ledger_rwlock);
-    HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item_tmp);
-    if(l_item_tmp != NULL) {
-        HASH_DEL(l_ledger_pvt->ledger_items, l_item_tmp);
-        if (PVT(a_ledger)->cached) {
-            // Remove it from cache
-            char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_STR);
-            char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-            dap_chain_hash_fast_to_str(a_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
-            dap_global_db_del(l_gdb_group, l_tx_hash_str, NULL, NULL);
-            DAP_DELETE(l_gdb_group);
-        }
-        l_ret = 1;
-        dap_chain_ledger_tx_spent_item_t *l_item_used;
-        HASH_FIND_BYHASHVALUE(hh, l_ledger_pvt->spent_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, 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);
-            if ( !l_item_used ) {
-                log_it(L_CRITICAL, "Memory allocation error");
-                if (l_item_tmp->tx)
-                    DAP_DELETE(l_item_tmp->tx);
-                if (l_item_tmp)
-                    DAP_DELETE(l_item_tmp);
-                pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
-                return -1;
-            }
-            l_item_used->tx_hash_fast = *a_tx_hash;
-            l_item_used->cache_data.spent_time = a_spent_time;
-            strncpy(l_item_used->cache_data.token_ticker, l_item_tmp->cache_data.token_ticker, DAP_CHAIN_TICKER_SIZE_MAX);
-            int l_out_num = 0;
-            dap_chain_datum_tx_out_cond_get(l_item_tmp->tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_ALL, &l_out_num);
-            if (l_out_num != -1 && l_out_num < MAX_OUT_ITEMS)
-                l_item_used->cache_data.tx_hash_spent_fast = l_item_tmp->cache_data.tx_hash_spent_fast[l_out_num];
-            HASH_ADD_BYHASHVALUE(hh, l_ledger_pvt->spent_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_hash_value, l_item_used);
-           if (PVT(a_ledger)->cached) {
-                // Add it to cache
-                char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR);
-                char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-                dap_chain_hash_fast_to_str(a_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
-                if (dap_global_db_set(l_gdb_group, l_tx_hash_str, &l_item_used->cache_data, sizeof(l_item_used->cache_data), false, NULL, NULL))
-                    debug_if(s_debug_more, L_WARNING, "Ledger cache mismatch");
-                DAP_DELETE(l_gdb_group);
-           }
-        }
-        // delete tx & its item
-        DAP_DEL_Z(l_item_tmp->tx);
-        DAP_DELETE(l_item_tmp);
-    }
-    else
-        // hash not found in the cache
-        l_ret = -2;
-    pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
-    return l_ret;
-}
-
 /**
  * Delete all transactions from the cache
  */
@@ -4952,12 +4760,6 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
         DAP_DELETE(l_gdb_group);
     }
 
-    /* Delete spent transactions */
-    dap_chain_ledger_tx_spent_item_t *l_spent_item_current, *l_spent_item_tmp;
-    HASH_ITER(hh, l_ledger_pvt->spent_items, l_spent_item_current, l_spent_item_tmp) {
-        HASH_DEL(l_ledger_pvt->spent_items, l_spent_item_current);
-        DAP_DEL_Z(l_item_current);
-    }
     if (!a_preserve_db) {
         l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR);
         dap_global_db_del(l_gdb_group, NULL, NULL, NULL);
@@ -5034,7 +4836,6 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
     }
 
     l_ledger_pvt->ledger_items         = NULL;
-    l_ledger_pvt->spent_items          = NULL;
     l_ledger_pvt->balance_accounts     = NULL;
     l_ledger_pvt->tokens               = NULL;
     l_ledger_pvt->threshold_emissions  = NULL;
@@ -5122,9 +4923,8 @@ size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_
 bool dap_chain_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, int a_idx_out, dap_hash_fast_t *a_out_spender)
 {
     dap_chain_ledger_tx_item_t *l_item_out = NULL;
-    //dap_chain_datum_tx_t *l_tx =
-    s_find_datum_tx_by_hash(a_ledger, a_tx_hash, &l_item_out);
-    return s_ledger_tx_hash_is_used_out_item(l_item_out, a_idx_out, a_out_spender);
+    /*dap_chain_datum_tx_t *l_tx =*/ s_find_datum_tx_by_hash(a_ledger, a_tx_hash, &l_item_out, false);
+    return l_item_out ? s_ledger_tx_hash_is_used_out_item(l_item_out, a_idx_out, a_out_spender) : true;
 }
 
 /**
@@ -5163,7 +4963,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c
 {
     uint256_t balance = uint256_0;
 
-    if(!a_addr || !dap_chain_addr_check_sum(a_addr))
+    if(!a_addr || dap_chain_addr_check_sum(a_addr))
         return balance;
 
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
@@ -5629,9 +5429,10 @@ int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype,
     return 0;
 }
 
-dap_list_t * dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse)
+dap_list_t *dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only)
 {
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
+    pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock);
     size_t l_offset = a_page < 2 ? 0 : a_count * (a_page - 1);
     if (!l_ledger_pvt->ledger_items || l_offset > HASH_COUNT(l_ledger_pvt->ledger_items)){
         return NULL;
@@ -5642,11 +5443,13 @@ dap_list_t * dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, si
     dap_chain_ledger_tx_item_t *l_item_current, *l_item_tmp;
     HASH_ITER(hh, l_ledger_pvt->ledger_items, l_item_current, l_item_tmp) {
         if (l_counter++ >= l_offset) {
-            l_list = a_reverse
-                    ? dap_list_prepend(l_list, l_item_current->tx)
-                    : dap_list_append(l_list, l_item_current->tx);
+            if (!a_unspent_only || !l_item_current->cache_data.ts_spent)
+                l_list = a_reverse
+                        ? dap_list_prepend(l_list, l_item_current->tx)
+                        : dap_list_append(l_list, l_item_current->tx);
         }
     }
+    pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock);
     return l_list;
 }
 
diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h
index 5b4e11f4f511733763a736706e9ada35705e9d8f..12dbb04da3fb9f6164f6541d45c2b11005f29d8d 100644
--- a/modules/chain/include/dap_chain_ledger.h
+++ b/modules/chain/include/dap_chain_ledger.h
@@ -200,7 +200,7 @@ char* dap_chain_ledger_tx_check_err_str(int a_code);
  *
  */
 
-char * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type);
+char * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only);
 
 /**
  * Check token ticker existance
@@ -215,7 +215,7 @@ dap_chain_datum_token_t *dap_chain_ledger_token_ticker_check(dap_ledger_t * a_le
  */
 
 int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size);
-int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size);
+int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size);
 int dap_chain_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size);
 char *dap_chain_ledger_token_decl_add_err_code_to_str(int a_code);
 dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger);
@@ -262,13 +262,6 @@ bool dap_chain_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
 int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash,
                                     bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker);
 
-/**
- * Delete transaction from the cache
- *
- * return 1 OK, -1 error, -2 tx_hash not found
- */
-int dap_chain_ledger_tx_remove(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, dap_time_t a_spent_time);
-
 /**
  * Delete all transactions from the cache
  */
@@ -283,7 +276,6 @@ void dap_chain_ledger_load_end(dap_ledger_t *a_ledger);
  * Return number transactions from the cache
  */
 unsigned dap_chain_ledger_count(dap_ledger_t *a_ledger);
-
 uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts_from, dap_time_t a_ts_to);
 size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to);
 void dap_chain_ledger_set_tps_start_time(dap_ledger_t *a_ledger);
@@ -309,7 +301,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c
  * return transaction, or NULL if transaction not found in the cache
  */
 dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash);
-void *dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash);
+dap_chain_datum_tx_t* dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash);
 dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash);
 
  // Get the transaction in the cache by the addr in out item
@@ -346,7 +338,7 @@ int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype,
                                      dap_chain_ledger_updater_callback_t a_callback_added);
 
 // Getting a list of transactions from the ledger.
-dap_list_t * dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse);
+dap_list_t * dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only);
 
 //bool dap_chain_ledger_fee_verificator(dap_ledger_t* a_ledger, dap_chain_tx_out_cond_t* a_cond, dap_chain_datum_tx_t* a_tx, bool a_owner);
 
diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
index fc4c89d08ea95a5ff462bb9acad1eddd8fa3c2d2..2c6ffd5ea1bd2bd5dbccac73442a4207583677fb 100644
--- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
+++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
@@ -241,7 +241,7 @@ static void s_service_start(dap_stream_ch_t* a_ch , dap_stream_ch_chain_net_srv_
 
     if ( ! l_net ) {
         // Network not found
-        log_it( L_WARNING, "Can't find net with id %"DAP_UINT64_FORMAT_U, a_request->hdr.srv_uid.uint64);
+        log_it( L_WARNING, "Can't find net with id 0x%016"DAP_UINT64_FORMAT_x"", a_request->hdr.srv_uid.uint64);
         l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NOT_FOUND;
         if(a_ch)
             dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err));
diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c
index 08b1c2aa279131b4b4386c7c11feea6471292c6f..8ccb6fd45271b4aa2e91409d7b2b457c1473d2bc 100644
--- a/modules/common/dap_chain_common.c
+++ b/modules/common/dap_chain_common.c
@@ -131,17 +131,14 @@ dap_chain_addr_t* dap_chain_addr_from_str(const char *a_str)
     size_t l_str_len = (a_str) ? strlen(a_str) : 0;
     if(l_str_len <= 0)
         return NULL;
-    if (dap_strcmp(a_str, "null") == 0) {
+    if (!dap_strcmp(a_str, "null") || !dap_strcmp(a_str, "0")) {
         return DAP_NEW_Z(dap_chain_addr_t);
     }
     size_t l_ret_size = DAP_ENC_BASE58_DECODE_SIZE(l_str_len);
-    dap_chain_addr_t * l_addr = DAP_NEW_Z_SIZE(dap_chain_addr_t, l_ret_size);
-    if(dap_enc_base58_decode(a_str, l_addr) == sizeof(dap_chain_addr_t) &&
-       dap_chain_addr_check_sum(l_addr)==1)
-        return l_addr;
-    else
-        DAP_DELETE(l_addr);
-    return NULL;
+    dap_chain_addr_t *l_addr = DAP_NEW_Z_SIZE(dap_chain_addr_t, l_ret_size);
+    return (dap_enc_base58_decode(a_str, l_addr) == sizeof(dap_chain_addr_t)) && !dap_chain_addr_check_sum(l_addr)
+            ? l_addr
+            : ({ DAP_DELETE(l_addr); NULL; });
 }
 
 bool dap_chain_addr_is_blank(const dap_chain_addr_t *a_addr)
@@ -247,19 +244,18 @@ void dap_chain_addr_fill(dap_chain_addr_t *a_addr, dap_sign_type_t a_type, dap_c
 /**
  * @brief dap_chain_addr_check_sum
  * @param a_addr
- * @return 1 Ok, -1 Invalid a_addr or checksum
+ * @return 0 - Ok, otherwise - Invalid a_addr or checksum
  */
 int dap_chain_addr_check_sum(const dap_chain_addr_t *a_addr)
 {
     if(!a_addr)
         return -1;
-    if (dap_chain_addr_is_blank(a_addr)) return 1;
+    if (dap_chain_addr_is_blank(a_addr))
+        return 0;
     dap_chain_hash_fast_t l_checksum;
     // calc checksum
     dap_hash_fast(a_addr, sizeof(dap_chain_addr_t) - sizeof(dap_chain_hash_fast_t), &l_checksum);
-    if(!memcmp(a_addr->checksum.raw, l_checksum.raw, sizeof(l_checksum.raw)))
-        return 1;
-    return -1;
+    return memcmp(a_addr->checksum.raw, l_checksum.raw, sizeof(l_checksum.raw));
 }
 
 
diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c
index c7090dea095c6c0e67ae2b2cc189375cd0c1396d..4566139492d26ceec1df06cc892001b4d3aa1508 100644
--- a/modules/common/dap_chain_datum_token.c
+++ b/modules/common/dap_chain_datum_token.c
@@ -184,9 +184,12 @@ dap_chain_datum_token_t *dap_chain_datum_token_read(const byte_t *a_token_serial
         *a_token_size = l_token_size;
         return l_token;
     }
+    case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL:
+    case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE:
+        return DAP_DUP_SIZE(a_token_serial, *a_token_size);
     default:
         log_it(L_NOTICE, "Unknown token type '%d' read", ((dap_chain_datum_token_t*)a_token_serial)->type);
-        return DAP_DUP_SIZE(a_token_serial, *a_token_size);
+        return NULL;
     }
 }
 
diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c
index 22a5c1557310575d029546262bc505bbcd3bba37..64e09ba41a5304fa982667ef72dc667f4388616f 100644
--- a/modules/common/dap_chain_datum_tx_items.c
+++ b/modules/common/dap_chain_datum_tx_items.c
@@ -806,7 +806,7 @@ uint8_t *dap_chain_datum_tx_item_get_nth(dap_chain_datum_tx_t *a_tx, dap_chain_t
 dap_chain_tx_out_cond_t *dap_chain_datum_tx_out_cond_get(dap_chain_datum_tx_t *a_tx, dap_chain_tx_item_type_t a_cond_type, int *a_out_num)
 {
     dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, NULL), *l_item;
-    int l_prev_cond_idx = a_out_num ? *a_out_num : 0;
+    int l_prev_cond_idx = 0;
     dap_chain_tx_out_cond_t *l_res = NULL;
     for (dap_list_t *l_item = l_list_out_items; l_item; l_item = l_item->next, ++l_prev_cond_idx) {
         // Start from *a_out_num + 1 item if a_out_num != NULL
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index a7b58980f1a8c53d79a6a7a5ee9dc497c5a67624..2b5537d75603ad2ce45d7e11dc4c0f9ccbca829f 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -147,7 +147,7 @@ char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_fr
 {
     // check valid param
     if(!a_chain | !a_key_from || ! a_addr_from || !a_key_from->priv_key_data || !a_key_from->priv_key_data_size ||
-            !dap_chain_addr_check_sum(a_addr_from) || (a_addr_to && !dap_chain_addr_check_sum(a_addr_to)) || IS_ZERO_256(a_value))
+            dap_chain_addr_check_sum(a_addr_from) || (a_addr_to && dap_chain_addr_check_sum(a_addr_to)) || IS_ZERO_256(a_value))
         return NULL;
 
     const char *l_native_ticker = dap_chain_net_by_id(a_chain->net_id)->pub.native_ticker;
@@ -394,7 +394,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
 {
     // check valid paramdap_chain_mempool_tx_coll_fee_create
     if(!a_chain | !a_key_from || !a_addr_from || !a_key_from->priv_key_data || !a_key_from->priv_key_data_size ||
-            !dap_chain_addr_check_sum(a_addr_from) || !dap_chain_addr_check_sum(a_addr_to) ||
+            dap_chain_addr_check_sum(a_addr_from) || dap_chain_addr_check_sum(a_addr_to) ||
             IS_ZERO_256(a_value) || !a_tx_num){
         log_it(L_ERROR, "Wrong parameters in dap_chain_mempool_tx_create_massive() call");
         return -1;
@@ -628,7 +628,7 @@ char* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *a_net, dap_chain_h
         return NULL;
     }
 
-    if ( ! dap_chain_addr_check_sum (a_addr_to) ){
+    if (dap_chain_addr_check_sum (a_addr_to)) {
         log_it(L_ERROR, "Wrong address_to checksum");
         if (a_ret_status)
             *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_WRONG_ADDR;
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 2527796b69d0f2b96e35111808fbbc26ed06f43b..46e24a3c8e9cb8b16f14c25a1d42c6c6a9440266 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -176,7 +176,6 @@ typedef struct dap_chain_net_pvt{
     uint16_t seed_nodes_count;
     struct sockaddr_in *seed_nodes_ipv4;
     struct sockaddr_in6 *seed_nodes_ipv6;       // TODO
-
     _Atomic(dap_chain_net_state_t) state, state_target;
     uint16_t acl_idx;
 
@@ -262,8 +261,8 @@ int dap_chain_net_init()
     dap_chain_node_client_init();
     dap_chain_node_net_ban_list_init();
     dap_cli_server_cmd_add ("net", s_cli_net, "Network commands",
-        "net list [chains -n <chain net name>]"
-            "\tList all networks or list all chains in selected network"
+        "net list [chains -net <chain net name>]\n"
+            "\tList all networks or list all chains in selected network\n"
         "net -net <chain net name> [-mode {update | all}] go {online | offline | sync}\n"
             "\tFind and establish links and stay online. \n"
             "\tMode \"update\" is by default when only new chains and gdb are updated. Mode \"all\" updates everything from zero\n"
@@ -274,7 +273,7 @@ int dap_chain_net_init()
         "net -net <chain net name> [-mode {update | all}] sync {all | gdb | chains}\n"
             "\tSyncronyze gdb, chains or everything\n"
             "\tMode \"update\" is by default when only new chains and gdb are updated. Mode \"all\" updates everything from zero\n"
-        "net -net <chain net name> link {list | add | del | info | disconnect_all}\n"
+        "net -net <chain net name> link {list | add | del | info [-addr] | disconnect_all}\n"
             "\tList, add, del, dump or establish links\n"
         "net -net <chain net name> ca add {-cert <cert name> | -hash <cert hash>}\n"
             "\tAdd certificate to list of authority cetificates in GDB group\n"
@@ -387,7 +386,7 @@ dap_chain_net_state_t dap_chain_net_get_target_state(dap_chain_net_t *a_net)
 dap_chain_node_info_t *dap_chain_net_balancer_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 = {};
+    struct in_addr l_addr = { };
     uint16_t i, l_port = 0;
     if (l_net_pvt->seed_nodes_count) {
         i = dap_random_uint16() % l_net_pvt->seed_nodes_count;
@@ -1488,9 +1487,17 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
         if (dap_strcmp(l_list_cmd,"chains")==0){
             const char * l_net_str = NULL;
             dap_chain_net_t* l_net = NULL;
-            dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-net", &l_net_str);
+            if (dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-net", &l_net_str) && !l_net_str) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Parameter '-net' require <net name>");
+                return -1;
+            }
 
             l_net = dap_chain_net_by_name(l_net_str);
+            if (l_net_str && !l_net) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Wrong <net name>, use 'net list' "
+                                                            "command to display a list of available networks");
+                return -1;
+            }
 
             if (l_net){
                 dap_string_append(l_string_ret,"Chains:\n");
@@ -1524,6 +1531,12 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
             }
 
         }else{
+            // plug for wrong command arguments
+            if (argc > 2) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "To many arguments for 'net list' command see help");
+                return -1;
+            }
+
             dap_string_append(l_string_ret,"Networks:\n");
             // show list of nets
             dap_chain_net_item_t * l_net_item, *l_net_item_tmp;
@@ -2087,7 +2100,7 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx)
                  ,dap_config_get_item_str(l_cfg , "general" , "name" ));
     l_net_item->chain_net = l_net;
     l_net_item->net_id.uint64 = l_net->pub.id.uint64;
-    HASH_ADD_STR(s_net_items, name,l_net_item);
+    HASH_ADD_STR(s_net_items, name, l_net_item);
     HASH_ADD(hh2, s_net_ids, net_id, sizeof(l_net_item->net_id), l_net_item);
 
     // Maximum number of prepared connections to other nodes
@@ -3142,7 +3155,7 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t
             return dap_chain_net_anchor_load(l_anchor, a_chain);
         }
         case DAP_CHAIN_DATUM_TOKEN_DECL:
-            return dap_chain_ledger_token_load(l_ledger, (dap_chain_datum_token_t *)a_datum->data, a_datum->header.data_size);
+            return dap_chain_ledger_token_load(l_ledger, a_datum->data, a_datum->header.data_size);
 
         case DAP_CHAIN_DATUM_TOKEN_EMISSION:
             return dap_chain_ledger_token_emission_load(l_ledger, a_datum->data, a_datum->header.data_size, a_datum_hash);
diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c
index 1b83023b261119586544b5d193a85c21b9d5e6a4..9f983be66b01e70a7d89a74304cc092ef8ab8d1a 100644
--- a/modules/net/dap_chain_net_tx.c
+++ b/modules/net/dap_chain_net_tx.c
@@ -93,7 +93,7 @@ dap_chain_datum_tx_spends_items_t * dap_chain_net_get_tx_cond_all_with_spends_by
 
                                 if(a_search_type == TX_SEARCH_TYPE_CELL_SPENT || a_search_type == TX_SEARCH_TYPE_NET_SPENT ){
                                     dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx);
-                                    bool l_is_spent = dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash);
+                                    bool l_is_spent = !!dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash);
                                     DAP_DELETE(l_tx_hash);
                                     if(!l_is_spent)
                                         continue;
@@ -524,8 +524,8 @@ dap_list_t * dap_chain_net_get_tx_cond_all_by_srv_uid(dap_chain_net_t * a_net, c
                                         continue;
 
                                 if(a_search_type == TX_SEARCH_TYPE_CELL_SPENT || a_search_type == TX_SEARCH_TYPE_NET_SPENT ){
-                                    dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx);
-                                    bool l_is_spent = dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash);
+                                    dap_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx);
+                                    bool l_is_spent = !!dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash);
                                     DAP_DELETE(l_tx_hash);
                                     if(!l_is_spent)
                                         continue;
diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c
index e6b33293972fd172f559570878756351da6e93ba..eeb9a77da79c3818bbc184e2975138c9788bacc5 100644
--- a/modules/net/dap_chain_node_cli.c
+++ b/modules/net/dap_chain_node_cli.c
@@ -302,7 +302,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
             "ledger list threshold [-hash <tx_treshold_hash>] -net <net_name>\n"
             "ledger list balance -net <net_name>\n"
             "ledger info -hash <tx_hash> -net <net_name> [-unspent]\n"
-            "ledger tx -all -net <net_name>\n"
+            "ledger tx -all -net <net_name> [-unspent]\n"
             "ledger tx {-addr <addr> | -w <wallet_name> | -tx <tx_hash>} -net <net_name>\n");
 
     // Token info
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 23bc259eee04eb7912f797b2de21bbe4c9642fb9..b48ae81e5d1f988a987341f5be09902fcf10c392 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -2876,7 +2876,10 @@ int com_mempool_list(int a_argc, char **a_argv, char **a_str_reply)
     const char * l_hash_out_type = "hex";
     dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type);
     dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net);
-    dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_base58);
+    if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_base58) && !l_addr_base58) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Parameter '-addr' require <addr>");
+        return -1;
+    }
     l_fast = (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "-fast") != -1) ? true : false;
     if(!l_net)
         return -1;
@@ -5336,7 +5339,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, char **a_str_reply)
                     }
                     //CHECK value fee
                     l_list_used_out_fee = dap_chain_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_native_token,
-                                                                                                  l_addr_from, l_value_need_fee, &l_value_transfer_fee);
+                                                                                     l_addr_from, l_value_need_fee, &l_value_transfer_fee);
                     if(!l_list_used_out_fee) {
                         log_it(L_WARNING, "Not enough funds in previous tx to transfer");
                         dap_string_append_printf(l_err_str, "Can't create in transaction. Not enough funds in previous tx "
@@ -5672,8 +5675,7 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply)
         return -10;
     }
 
-    // Check, if network ID is same as ID in destination wallet address. If not - operation is cancelled.
-    if (l_addr_to->net_id.uint64 != l_net->pub.id.uint64) {
+    if (l_addr_to->net_id.uint64 != l_net->pub.id.uint64 && !dap_chain_addr_is_blank(l_addr_to)) {
         bool l_found = false;
         for (dap_list_t *it = l_net->pub.bridged_networks; it; it = it->next) {
             if (((dap_chain_net_id_t *)it->data)->uint64 == l_addr_to->net_id.uint64) {
@@ -6081,7 +6083,7 @@ int com_print_log(int a_argc, char **a_argv, char **a_str_reply)
         dap_cli_server_cmd_set_reply_text(a_str_reply, "requires valid parameter 'l_ts_after'");
         return -1;
     }
-    if(!l_limit) {
+    if(l_limit <= 0) {
         dap_cli_server_cmd_set_reply_text(a_str_reply, "requires valid parameter 'limit'");
         return -1;
     }
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index 6c74cdc842725fc7e4c8f755f1428e15b34c6aef..b478c2ea7bc0df288083923e0165afdff2517d13 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -113,7 +113,9 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
         switch (*(dap_chain_tx_item_type_t*)l_item->data) {
         case TX_ITEM_TYPE_OUT:
         case TX_ITEM_TYPE_OUT_OLD:
-        case TX_ITEM_TYPE_OUT_EXT: {
+        case TX_ITEM_TYPE_OUT_EXT:
+        case TX_ITEM_TYPE_OUT_COND_OLD:
+        case TX_ITEM_TYPE_OUT_COND: {
             dap_hash_fast_t l_spender = { };
             if (dap_chain_ledger_tx_hash_is_used_out_item(a_ledger, a_tx_hash, l_out_idx, &l_spender)) {
                 char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' };
@@ -467,8 +469,14 @@ static char* dap_db_chain_history_token_list(dap_chain_t * a_chain, const char *
                 dap_chain_datum_t *l_datum = l_datums[l_datum_n];
                 if (!l_datum || l_datum->header.type_id != DAP_CHAIN_DATUM_TOKEN_DECL)
                     continue;
-                if (a_token_name && dap_strcmp(((dap_chain_datum_token_t *)l_datum->data)->ticker, a_token_name))
-                    continue;
+                if (a_token_name) {
+                    size_t l_token_size = l_datum->header.data_size;
+                    dap_chain_datum_token_t *l_token = dap_chain_datum_token_read(l_datum->data, &l_token_size);
+                    int l_cmp = dap_strcmp(l_token->ticker, a_token_name);
+                    DAP_DELETE(l_token);
+                    if (l_cmp)
+                        continue;
+                }
                 dap_chain_datum_dump(l_str_out, l_datum, a_hash_out_type, a_chain->net_id);
                 (*a_token_num)++;
             }
@@ -707,6 +715,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
         dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-w", &l_wallet_name);
         dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-net", &l_net_str);
         dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-tx", &l_tx_hash_str);
+        bool l_unspent_flag = dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-unspent", NULL);
         dap_chain_tx_hash_processed_ht_t *l_list_tx_hash_processd = NULL;
 
         if(!l_is_all && !l_addr_base58 && !l_wallet_name && !l_tx_hash_str) {
@@ -760,13 +769,13 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
         char *l_str_out = NULL;
         dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str);
         if(l_is_all) {
-            size_t l_tx_count = dap_chain_ledger_count(l_ledger);
+            size_t l_tx_count = dap_chain_ledger_count(l_ledger), l_tx_count_spent_count = 0;
             if (!l_tx_count) {
                 dap_string_append_printf(l_str_ret, "Network ledger %s contains no transactions.\n", l_ledger->net_name);
             } else {
                 dap_string_append_printf(l_str_ret, "There are %zu transactions in the network ledger %s:\n",
                                          l_tx_count, l_ledger->net_name);
-                dap_list_t *l_txs_list = dap_chain_ledger_get_txs(l_ledger, l_tx_count, 1, true);
+                dap_list_t *l_txs_list = dap_chain_ledger_get_txs(l_ledger, l_tx_count, 1, true, l_unspent_flag);
                 for (dap_list_t *iter = l_txs_list; iter; iter = dap_list_next(iter)) {
                     dap_chain_datum_tx_t *l_tx = iter->data;
                     dap_hash_fast_t l_tx_hash = { };
@@ -778,23 +787,26 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
         } else {
             if(l_addr)
             {
-                l_str_out = dap_ledger_token_tx_item_list(l_ledger,l_addr,l_hash_out_type);
+                l_str_out = dap_ledger_token_tx_item_list(l_ledger, l_addr, l_hash_out_type, l_unspent_flag);
                 char *l_addr_str = dap_chain_addr_to_str(l_addr);
                 dap_string_append_printf(l_str_ret, "history for addr %s:\n%s\n", l_addr_str,
                         l_str_out ? l_str_out : " empty");
                 DAP_DELETE(l_addr_str);
-            }else if(l_tx_hash_str) {
-                dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger,&l_tx_hash);
-                if(l_tx){
+            } else if(l_tx_hash_str) {
+                dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &l_tx_hash);
+                if (!l_tx && !l_unspent_flag) {
+                    l_tx = dap_chain_ledger_tx_spent_find_by_hash(l_ledger, &l_tx_hash);
+                }
+                if(l_tx) {
                     size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
                     dap_hash_fast_t l_tx_hash = { };
                     dap_hash_fast(l_tx, l_tx_size, &l_tx_hash);
                     s_dap_chain_datum_tx_out_data(l_tx, l_ledger, l_str_ret, l_hash_out_type, &l_tx_hash);
                     dap_string_append_printf(l_str_ret, "history for tx hash %s:\n%s\n", l_tx_hash_str,
                             l_str_out ? l_str_out : " empty");
-                }
-                else
+                } else {
                     dap_string_append_printf(l_str_ret, "There is not transaction %s in the network ledger\n",l_tx_hash_str);
+                }
             }            
         }
         DAP_DELETE(l_str_out);
@@ -882,8 +894,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
         //get net
         dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_str);
         //get search type
-        const char *l_unspent_str = NULL;
-        dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-unspent", &l_unspent_str);
+        bool l_unspent_flag = dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-unspent", NULL);
         //check input
         if (l_tx_hash_str == NULL){
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Subcommand 'info' requires key -hash");
@@ -904,7 +915,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
             return -4;
         }
         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);
+                                                                        l_unspent_flag ? TX_SEARCH_TYPE_NET_UNSPENT : TX_SEARCH_TYPE_NET);
         if (l_datum_tx == NULL) {
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find datum for transaction hash %s in chains", l_tx_hash_str);
             return -5;
diff --git a/modules/net/dap_chain_node_ping.c b/modules/net/dap_chain_node_ping.c
index c92605d93ebe91ddcabfb84f246615810df00819..7bfc4acc011f124eabbb2c3e844c2ce852c36bf4 100644
--- a/modules/net/dap_chain_node_ping.c
+++ b/modules/net/dap_chain_node_ping.c
@@ -77,6 +77,11 @@
 
 #define LOG_TAG "chain_node_ping"
 
+typedef struct s_dap_chain_node_ping_background_arg{
+    dap_chain_net_t *net;
+    dap_list_t *node_list;
+}s_dap_chain_node_ping_background_arg_t;
+
 static void* node_ping_proc(void *a_arg)
 {
     if(!a_arg)
@@ -200,9 +205,11 @@ static void* node_ping_background_proc(void *a_arg)
 {
     if (!a_arg)
         return 0;
-    dap_chain_net_t *l_net = (dap_chain_net_t*)a_arg;
-    dap_list_t *l_node_list = (dap_list_t*)(a_arg + sizeof(dap_chain_net_t*));
+    s_dap_chain_node_ping_background_arg_t  *l_arg = (s_dap_chain_node_ping_background_arg_t*)a_arg;
+    dap_chain_net_t *l_net = l_arg->net;
+    dap_list_t *l_node_list = l_arg->node_list;
     dap_chain_node_addr_t l_node_addr = { 0 };
+    s_node_addr_ping = DAP_NEW(dap_chain_node_addr_t);
 
     // select the nearest node from the list
     unsigned int l_nodes_count = dap_list_length(l_node_list);
@@ -220,6 +227,11 @@ static void* node_ping_background_proc(void *a_arg)
     while(l_node_list) {
         dap_chain_node_addr_t *l_node_addr = l_node_list->data;
         dap_chain_node_info_t *l_node_info = dap_chain_node_info_read(l_net, l_node_addr);
+        if (!l_node_info) {
+            log_it(L_ERROR, "Can't extract node info");
+            l_node_list = dap_list_next(l_node_list);
+            continue;
+        }
 
         char *host4 = DAP_NEW_STACK_SIZE(char, INET_ADDRSTRLEN);
         struct sockaddr_in sa4 = { .sin_family = AF_INET, .sin_addr = l_node_info->hdr.ext_addr_v4 };
@@ -256,7 +268,7 @@ static void* node_ping_background_proc(void *a_arg)
         int res = wait_node_ping(l_threads[l_thread_id], l_timeout_full_ms);
         if(res > 0 && res < best_node_reply) {
             best_node_pos = l_thread_id;
-            s_node_addr_ping = l_node_list->data;
+            s_node_addr_ping->uint64 = l_nodes_addr[l_thread_id];
             best_node_reply = res;
         }
         struct timespec l_time_stop;
@@ -277,23 +289,27 @@ static void* node_ping_background_proc(void *a_arg)
         log_it(L_CRITICAL, "Memory allocation error");
         dap_list_free_full(l_node_list0, NULL);
         DAP_DEL_Z(s_node_addr_ping);
+        DAP_DELETE(a_arg);
         return 0;
     }
     memcpy(l_node_addr_tmp, s_node_addr_tr, sizeof(dap_chain_node_addr_t));
     DAP_DELETE(s_node_addr_tr);
     s_node_addr_tr = l_node_addr_tmp;
+    DAP_DELETE(l_node_addr_tmp);
 
     l_node_addr_tmp = DAP_NEW(dap_chain_node_addr_t);
     if (!l_node_addr_tmp) {
         log_it(L_CRITICAL, "Memory allocation error");
         dap_list_free_full(l_node_list0, NULL);
         DAP_DEL_Z(s_node_addr_ping);
+        DAP_DELETE(a_arg);
         return 0;
     }
     memcpy(l_node_addr_tmp, s_node_addr_ping, sizeof(dap_chain_node_addr_t));
     DAP_DELETE(s_node_addr_ping);
     s_node_addr_ping = l_node_addr_tmp;
     dap_list_free_full(l_node_list0, NULL);
+    DAP_DELETE(a_arg);
     return 0;
 }
 
@@ -322,14 +338,18 @@ int dap_chain_node_ping_background_start(dap_chain_net_t *a_net, dap_list_t *a_n
         l_node_list_tmp = dap_list_next(l_node_list_tmp);
     }
     // start searching for better nodes
-    uint8_t *l_arg = DAP_NEW_SIZE(uint8_t, sizeof(dap_chain_net_t*) + sizeof(dap_list_t*));
+    s_dap_chain_node_ping_background_arg_t *l_arg = DAP_NEW(s_dap_chain_node_ping_background_arg_t);
+//    uint8_t *l_arg = DAP_NEW_SIZE(uint8_t, sizeof(dap_chain_net_t*) + sizeof(dap_list_t*));
+
     if (!l_arg) {
         log_it(L_CRITICAL, "Memory allocation error");
         dap_list_free_full(l_node_list, NULL);
         return -1;
     }
-    memcpy(l_arg, &a_net, sizeof(dap_chain_net_t*));
-    memcpy(l_arg + sizeof(dap_chain_net_t*), &l_node_list, sizeof(dap_list_t*));
+    l_arg->net = a_net;
+    l_arg->node_list = l_node_list;
+//    memcpy(l_arg, &a_net, sizeof(dap_chain_net_t*));
+//    memcpy(l_arg + sizeof(dap_chain_net_t*), &l_node_list, sizeof(dap_list_t*));
     pthread_create(&s_thread, NULL, node_ping_background_proc, l_arg);
     return 0;
 }
diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h
index 807382e720e0a9f2098ae0af2eeb57a7ea33e710..523b3e4717ecc053b5a02749e70cc12463ce4467 100644
--- a/modules/net/include/dap_chain_net.h
+++ b/modules/net/include/dap_chain_net.h
@@ -39,6 +39,7 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_chain_node.h"
 #include "dap_chain_ledger.h"
 #include "dap_chain_net_decree.h"
+#include "dap_chain_net_tx.h"
 #include "dap_chain_datum_decree.h"
 #include "dap_chain_datum_anchor.h"
 #include "dap_chain_datum_tx.h"
@@ -184,6 +185,7 @@ dap_chain_net_t **dap_chain_net_list(uint16_t *a_size);
 
 int dap_chain_net_verify_datum_for_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, dap_hash_fast_t *a_datum_hash);
 char *dap_chain_net_verify_datum_err_code_to_str(dap_chain_datum_t *a_datum, int a_code);
+
 void dap_chain_add_mempool_notify_callback(dap_chain_t *a_chain, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg);
 void dap_chain_net_add_nodelist_notify_callback(dap_chain_net_t *a_net, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg);
 void dap_chain_net_srv_order_add_notify_callback(dap_chain_net_t *a_net, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg);
diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c
index 83c929b3aec8c13bcb788b2cb70d9c7a169e181e..06f9791035761c49979bc45e0b4b7c9a05d46f0f 100644
--- a/modules/net/srv/dap_chain_net_srv.c
+++ b/modules/net/srv/dap_chain_net_srv.c
@@ -829,6 +829,7 @@ static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out
 }
 
 int dap_chain_net_srv_price_apply_from_my_order(dap_chain_net_srv_t *a_srv, const char *a_config_section){
+
 //    const char *l_wallet_path = dap_config_get_item_str_default(g_config, "resources", "wallets_path", NULL);
 //    const char *l_wallet_name = dap_config_get_item_str_default(g_config, a_config_section, "wallet", NULL);
 
@@ -838,6 +839,7 @@ int dap_chain_net_srv_price_apply_from_my_order(dap_chain_net_srv_t *a_srv, cons
     if (!l_wallet_addr || !l_cert_name || !l_net_name){
         return -2;
     }
+
 //    dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_name, l_wallet_path);
 //    if (!l_wallet) {
 //        return -3;
@@ -890,7 +892,7 @@ int dap_chain_net_srv_price_apply_from_my_order(dap_chain_net_srv_t *a_srv, cons
                     continue;
                 }
             }
-//            l_price->wallet = l_wallet;
+//          l_price->wallet = l_wallet;
             l_price->wallet_addr = dap_chain_addr_from_str(l_wallet_addr);
             if(!l_price->wallet_addr){
                 log_it(L_ERROR, "Can't get wallet addr from wallet_addr in config file.");
@@ -909,6 +911,18 @@ int dap_chain_net_srv_price_apply_from_my_order(dap_chain_net_srv_t *a_srv, cons
                 return -101;
             }
 
+            dap_hash_fast_t order_pkey_hash = { }, price_pkey_hash = { };
+            dap_sign_get_pkey_hash((dap_sign_t*)l_order->ext_n_sign + l_order->ext_size, &order_pkey_hash);
+            dap_hash_fast(l_price->receipt_sign_cert->enc_key->pub_key_data,
+                          l_price->receipt_sign_cert->enc_key->pub_key_data_size, &price_pkey_hash);
+            if (dap_hash_fast_compare(&order_pkey_hash, &price_pkey_hash))
+            {
+                log_it(L_ERROR, "pkey in order not equal to pkey in config.");
+                DAP_DEL_Z(l_order);
+                DAP_DELETE(l_price);
+                dap_global_db_objs_delete(l_orders, l_orders_count);
+                continue;
+            }
 
             // TODO: find most advantageous for us order
             DL_APPEND(a_srv->pricelist, l_price);
@@ -1125,7 +1139,6 @@ void dap_chain_net_srv_del_all(void)
     pthread_mutex_lock(&s_srv_list_mutex);
     HASH_ITER(hh, s_srv_list , l_sdata, l_sdata_tmp)
     {
-        // Clang bug at this, l_sdata should change at every loop cycle
         HASH_DEL(s_srv_list, l_sdata);
         pthread_mutex_destroy(&l_sdata->srv->banlist_mutex);
         DAP_DELETE(l_sdata->srv);
diff --git a/modules/net/srv/dap_chain_net_srv_client.c b/modules/net/srv/dap_chain_net_srv_client.c
index a234d08e04af2107ea2ea6a843ee068cb4ea2ec0..d05c7c95c99ed5a8db7f0613a703e93dc69fdef1 100644
--- a/modules/net/srv/dap_chain_net_srv_client.c
+++ b/modules/net/srv/dap_chain_net_srv_client.c
@@ -48,12 +48,15 @@ dap_chain_net_srv_client_t *dap_chain_net_srv_client_create_n_connect(dap_chain_
     if (a_callbacks)
         l_ret->callbacks = *a_callbacks;
     l_ret->callbacks_arg = a_callbacks_arg;
+    
     dap_chain_node_client_callbacks_t l_callbacks = {
         .connected = s_srv_client_callback_connected,
         .disconnected = s_srv_client_callback_disconnected,
         .delete = s_srv_client_callback_deleted
     };
+
     dap_chain_node_info_t *l_info = DAP_NEW_Z(dap_chain_node_info_t);
+
     if (!l_info) {
         log_it(L_CRITICAL, "Memory allocation error");
         DAP_DEL_Z(l_ret);
@@ -69,6 +72,10 @@ dap_chain_net_srv_client_t *dap_chain_net_srv_client_create_n_connect(dap_chain_
     DAP_DELETE(l_info);
     return l_ret;
 }
+void dap_chain_net_srv_client_close(dap_chain_net_srv_client_t *a_client){
+    if (a_client->node_client)
+        dap_chain_node_client_close_mt( a_client->node_client );
+}
 
 ssize_t dap_chain_net_srv_client_write(dap_chain_net_srv_client_t *a_client, uint8_t a_type, void *a_pkt_data, size_t a_pkt_data_size)
 {
@@ -108,8 +115,6 @@ static void s_srv_client_callback_deleted(dap_chain_node_client_t *a_node_client
     UNUSED(a_node_client);
     log_it(L_INFO, "Service client deleted");
     dap_chain_net_srv_client_t *l_srv_client = (dap_chain_net_srv_client_t *)a_arg;
-    if (l_srv_client->callbacks.deleted)
-        l_srv_client->callbacks.deleted(l_srv_client, l_srv_client->callbacks_arg);
     DAP_DELETE(l_srv_client);
 }
 
diff --git a/modules/net/srv/include/dap_chain_net_srv_client.h b/modules/net/srv/include/dap_chain_net_srv_client.h
index b5da5a6b9532e5eda2ef87124830cbd16de2bebe..50e19d2562d1b58a99e9e4987784e86e07f86b1c 100644
--- a/modules/net/srv/include/dap_chain_net_srv_client.h
+++ b/modules/net/srv/include/dap_chain_net_srv_client.h
@@ -64,4 +64,7 @@ typedef struct dap_chain_net_srv_client {
 dap_chain_net_srv_client_t *dap_chain_net_srv_client_create_n_connect(dap_chain_net_t *a_net, char *a_addr, uint16_t a_port,
                                                                       dap_chain_net_srv_client_callbacks_t *a_callbacks,
                                                                       void *a_callbacks_arg);
+
+void dap_chain_net_srv_client_close(dap_chain_net_srv_client_t *a_client);
+
 ssize_t dap_chain_net_srv_client_write(dap_chain_net_srv_client_t *a_client, uint8_t a_type, void *a_pkt_data, size_t a_pkt_data_size);
diff --git a/modules/service/datum/dap_chain_net_srv_datum.c b/modules/service/datum/dap_chain_net_srv_datum.c
index 190df48fdd2a8f6821eda60c3d6e9510ae5e81e0..87db2ea5442cffc33a5645090153962a6b518e3a 100644
--- a/modules/service/datum/dap_chain_net_srv_datum.c
+++ b/modules/service/datum/dap_chain_net_srv_datum.c
@@ -120,6 +120,10 @@ static int s_srv_datum_cli(int argc, char ** argv, char **a_str_reply) {
     }
 
     const char * l_system_datum_folder = dap_config_get_item_str(g_config, "resources", "datum_folder");
+    if (!l_system_datum_folder){
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Configuration wasn't loaded");
+        return -6;
+    }
 
     const char * l_datum_cmd_str = NULL;
     dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "datum", &l_datum_cmd_str);
diff --git a/modules/service/stake/dap_chain_net_srv_stake_lock.c b/modules/service/stake/dap_chain_net_srv_stake_lock.c
index a0ba00a627ef9bd5e1e0ff9eb410fa6c039f7e78..c4a00a6fd5a48944d2ef1d6b1c67d3fa53191a3a 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_lock.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c
@@ -343,7 +343,7 @@ static enum error_code s_cli_hold(int a_argc, char **a_argv, int a_arg_index, da
 static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, dap_string_t *output_line)
 {
     const char *l_net_str, *l_ticker_str, *l_wallet_str, *l_tx_str, *l_tx_burning_str, *l_chain_str, *l_value_fee_str;
-    l_net_str = l_ticker_str = l_wallet_str = l_tx_str = l_tx_burning_str = l_chain_str = NULL;
+    l_net_str = l_ticker_str = l_wallet_str = l_tx_str = l_tx_burning_str = l_chain_str = l_value_fee_str = NULL;
     dap_chain_net_t						*l_net				=	NULL;
     const char							*l_wallets_path		=	dap_chain_wallet_get_path(g_config);
     char l_delegated_ticker_str[DAP_CHAIN_TICKER_SIZE_MAX] 	=	{};
@@ -985,8 +985,14 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_
             DAP_DEL_Z(str3);
         }
 
-        if (!EQUAL_256(l_blank_out_value, l_value_delegated))
-            return false;
+        if (!EQUAL_256(l_blank_out_value, l_value_delegated)) {
+            // !!! A terrible legacy crutch, TODO !!!
+            SUM_256_256(l_value_delegated, GET_256_FROM_64(10), &l_value_delegated);
+            if (!EQUAL_256(l_blank_out_value, l_value_delegated)) {
+                log_it(L_ERROR, "Burning and delegated value mismatch");
+                return false;
+            }
+        }
     }
 
     return true;
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 6528b2e4b5870cc8f885f2ff72ff75dba627044b..9fcd359d8f2aa7ac083ffc10136b6946889c2f8b 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1156,7 +1156,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, c
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Incorrect chain address");
                     return -14;
                 }
-                if (dap_chain_addr_check_sum(l_addr) != 1 ) {
+                if (dap_chain_addr_check_sum(l_addr)) {
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Incorrect chain address");
                     return -15;
                 }
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index 1139f1dac85a04db0afc3ac97f9a71f856d6e2d3..1dc1d60663d010b728d4ffaaa85730c040870bcf 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -20,7 +20,6 @@
     You should have received a copy of the GNU General Public License
     along with any DAP SDK based project.  If not, see <http://www.gnu.org/licenses/>.
 */
-
 #include <pthread.h>
 #include "dap_common.h"
 #include "dap_enc_base58.h"
@@ -176,7 +175,7 @@ int dap_chain_cs_blocks_init()
                 "\t\tDump block info\n\n"
 
             "block -net <net_name> -chain <chain_name> list [-from_hash <block_hash>] [-to_hash <block_hash>]"
-            "[-from_dt <datetime>] [-to_dt <datetime>] [-cert <priv_cert_name> -unspent]\n"
+            "[-from_dt <in YYMMDD>] [-to_dt <in YYMMDD>] [-cert <priv_cert_name> -unspent]\n"
                 "\t\t List blocks\n\n"
         "Commission collect:\n"
             "block -net <net_name> -chain <chain_name> fee collect\n"
@@ -613,13 +612,20 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
             }
         }break;
         case SUBCMD_LIST:{
-                const char * l_cert_name = NULL;
-                bool l_unspent_fl = false;
+                const char * l_cert_name, *l_from_hash_name, *l_to_hash_name, *l_from_dt_name, *l_to_dt_name;
+                l_cert_name = l_from_hash_name = l_to_hash_name = l_from_dt_name = l_to_dt_name = NULL;
+                bool l_unspent_fl = false,l_hash_fl = false;
                 size_t l_block_count = 0;
                 dap_cert_t * l_cert = NULL;
-                dap_pkey_t * l_pub_key = NULL;
+                dap_pkey_t * l_pub_key = NULL;                
+                dap_hash_fast_t l_from_hash;
+                dap_hash_fast_t l_to_hash;
 
                 dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-cert", &l_cert_name);
+                dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-from_hash", &l_from_hash_name);
+                dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_hash", &l_to_hash_name);
+                dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-from_dt", &l_from_dt_name);
+                dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_dt", &l_to_dt_name);
 
                 if(l_cert_name) {
 
@@ -640,6 +646,39 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
                     if(dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-unspent", NULL))
                         l_unspent_fl = true;
                 }
+                if(l_to_hash_name){
+                    dap_chain_hash_fast_from_hex_str(l_to_hash_name, &l_to_hash);
+                }
+                if(l_from_hash_name){
+                    dap_chain_hash_fast_from_hex_str(l_from_hash_name, &l_from_hash);
+                }
+                if(l_from_dt_name){
+                    char l_from_data_month[3] = {l_from_dt_name[2], l_from_dt_name[3], 0};
+                    int l_from_time_month = atoi(l_from_data_month);
+                    if (l_from_time_month < 1 || l_from_time_month > 12)
+                        return -21;
+                    char l_from_data_day[3] = {l_from_dt_name[4], l_from_dt_name[5], 0};
+                    int l_from_time_day = atoi(l_from_data_day);
+                    if (l_from_time_day < 1 || l_from_time_day > 31)
+                        return -21;
+                }
+                if(l_to_dt_name){
+                    char l_to_data_month[3] = {l_to_dt_name[2], l_to_dt_name[3], 0};
+                    int l_to_time_month = atoi(l_to_data_month);
+                    if (l_to_time_month < 1 || l_to_time_month > 12)
+                        return -21;
+                    char l_to_data_day[3] = {l_to_dt_name[4], l_to_dt_name[5], 0};
+                    int l_to_time_day = atoi(l_to_data_day);
+                    if (l_to_time_day < 1 || l_to_time_day > 31)
+                        return -21;
+                }
+
+                dap_time_t l_from_data = dap_time_from_str_simplified(l_from_dt_name);
+                struct tm *u;
+                time_t l_to_data = (time_t)dap_time_from_str_simplified(l_to_dt_name);
+                u = localtime(&l_to_data);
+                u->tm_mday += 1;
+                dap_time_t l_to_data_p_one_day = mktime(u);
 
                 pthread_rwlock_rdlock(&PVT(l_blocks)->rwlock);
                 dap_string_t * l_str_tmp = dap_string_new(NULL);             
@@ -650,6 +689,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
                     dap_sign_t * l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0);
                     if(l_cert)
                     {
+                        l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0);
                         if(!dap_pkey_compare_with_sign(l_pub_key, l_sign))
                             continue;
                         if(l_unspent_fl){
@@ -669,19 +709,34 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
                             if(!fl_found)
                                 continue;
                         }
+                    }                    
+                    if(l_to_dt_name && (l_to_data_p_one_day < l_ts))
+                        break;
+                    if(dap_hash_fast_compare(&l_from_hash,&l_block_cache->block_hash))
+                        l_hash_fl = true;
+                    if((l_from_hash_name && !l_hash_fl) ||
+                       (l_from_dt_name && (l_from_data > l_ts)))
+                    {
+                        if(l_to_hash_name && dap_hash_fast_compare(&l_to_hash,&l_block_cache->block_hash))
+                            break;
+                        continue;
                     }
 
                     dap_string_append_printf(l_str_tmp,"\t%s: ts_create=%s",
                                                  l_block_cache->block_hash_str, l_buf);
                     l_block_count++;
-                }
+                    if(l_to_hash_name && dap_hash_fast_compare(&l_to_hash,&l_block_cache->block_hash))
+                        break;
+                }                
                 if(l_cert){
                     dap_string_append_printf(l_str_tmp,"%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks signed with %s certificate :\n",
                                              l_net->pub.name,l_chain->name,l_block_count,l_cert_name);
                 }
-                else
-                    dap_string_append_printf(l_str_tmp,"%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks :\n",
-                                             l_net->pub.name,l_chain->name,PVT(l_blocks)->blocks_count);
+                else if(l_to_hash_name || l_from_hash_name || l_from_dt_name || l_to_dt_name){
+                    dap_string_append_printf(l_str_tmp,"%"DAP_UINT64_FORMAT_U" filtered blocks shown :\n",l_block_count);
+                }
+                dap_string_append_printf(l_str_tmp,"%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks :\n",
+                                         l_net->pub.name,l_chain->name,PVT(l_blocks)->blocks_count);
 
                 pthread_rwlock_unlock(&PVT(l_blocks)->rwlock);
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str);