diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index 6786fcbe1f958c8e8ddecbeff500cdad8e80df7e..f68cc9d280414fe37020a9c9827d850746b08b61 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -5374,6 +5374,68 @@ uint256_t dap_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_cha
     return l_ret_value;
 }
 
+dap_ledger_datum_iter_t *dap_ledger_datum_iter_create(dap_chain_net_t *a_net)
+{
+    dap_ledger_datum_iter_t *l_ret = DAP_NEW_Z(dap_ledger_datum_iter_t);
+    if(!l_ret){
+        log_it(L_CRITICAL, "Memory allocation error!");
+        return NULL;
+    }
+    l_ret->net = a_net;
+    return l_ret;
+}
+
+void dap_ledger_datum_iter_delete(dap_ledger_datum_iter_t *a_iter)
+{
+    DAP_DELETE(a_iter);
+}
+
+dap_chain_datum_tx_t *dap_ledger_datum_iter_get_first(dap_ledger_datum_iter_t *a_iter)
+{
+    dap_ledger_private_t *l_ledger_pvt = PVT(a_iter->net->pub.ledger);
+    pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
+    a_iter->cur_ledger_tx_item = l_ledger_pvt->ledger_items;
+    a_iter->cur = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx;
+    a_iter->cur_hash = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx_hash_fast;
+    a_iter->is_unspent = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->cache_data.ts_spent ? false : true;
+    a_iter->ret_code = 0;
+    pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
+    return a_iter->cur;
+}
+
+dap_chain_datum_tx_t *dap_ledger_datum_iter_get_next(dap_ledger_datum_iter_t *a_iter)
+{
+    dap_ledger_private_t *l_ledger_pvt = PVT(a_iter->net->pub.ledger);
+    pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
+    a_iter->cur_ledger_tx_item = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->hh.next;
+    if (a_iter->cur_ledger_tx_item){
+        a_iter->cur = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx;
+        a_iter->cur_hash = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx_hash_fast;
+        a_iter->ret_code = 0;
+        a_iter->is_unspent = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->cache_data.ts_spent ? false : true;
+    } else {
+        a_iter->cur = NULL;
+        memset(&a_iter->cur_hash, 0, sizeof(dap_hash_fast_t));
+        a_iter->ret_code = 0;
+        a_iter->is_unspent = false;
+    }
+    pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
+    return a_iter->cur;
+}
+
+dap_chain_datum_tx_t *dap_ledger_datum_iter_get_last(dap_ledger_datum_iter_t *a_iter)
+{
+    dap_ledger_private_t *l_ledger_pvt = PVT(a_iter->net->pub.ledger);
+    pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
+    a_iter->cur_ledger_tx_item = l_ledger_pvt->ledger_items->hh.prev;
+    a_iter->cur = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx;
+    a_iter->cur_hash = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx_hash_fast;
+    a_iter->is_unspent = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->cache_data.ts_spent ? false : true;
+    a_iter->ret_code = 0;
+    pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
+    return a_iter->cur;
+}
+
 /**
  * @brief dap_ledger_get_list_tx_outs_with_val
  * @param a_ledger
diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c
index ab49811d50dac2f171eae90fd44ce3fc88ac4b07..561878d9bf5350ded688591f114eb19906dd77f4 100644
--- a/modules/net/dap_chain_net_tx.c
+++ b/modules/net/dap_chain_net_tx.c
@@ -47,7 +47,7 @@ typedef struct cond_all_by_srv_uid_arg{
     dap_time_t time_to;
 } cond_all_by_srv_uid_arg_t;
 
-static void s_tx_cond_all_with_spends_by_srv_uid_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, void *a_arg)
+static void s_tx_cond_all_with_spends_by_srv_uid_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg)
 {
     cond_all_with_spends_by_srv_uid_arg_t *l_arg = (cond_all_with_spends_by_srv_uid_arg_t*)a_arg;
     dap_chain_datum_tx_t *l_tx = a_tx;
@@ -83,7 +83,7 @@ static void s_tx_cond_all_with_spends_by_srv_uid_callback(dap_chain_net_t* a_net
                 }
                 size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
                 dap_chain_datum_tx_t * l_tx_dup = DAP_DUP_SIZE(l_tx,l_tx_size);
-                dap_hash_fast(l_tx_dup,l_tx_size, &l_item_in->tx_hash);
+                l_item_in->tx_hash = *a_tx_hash;
 
                 l_item_in->tx = l_tx_dup;
                 // Calc same offset from tx duplicate
@@ -104,7 +104,7 @@ static void s_tx_cond_all_with_spends_by_srv_uid_callback(dap_chain_net_t* a_net
                 }
                 size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
                 dap_chain_datum_tx_t * l_tx_dup = DAP_DUP_SIZE(l_tx,l_tx_size);
-                dap_hash_fast(l_tx,l_tx_size, &l_item->tx_hash);
+                l_item->tx_hash = *a_tx_hash;
                 l_item->tx = l_tx_dup;
                 // Calc same offset from tx duplicate
                 l_item->out_cond = (dap_chain_tx_out_cond_t*) (l_tx_dup->tx_items + l_tx_items_pos);
@@ -188,27 +188,19 @@ void dap_chain_net_get_tx_all(dap_chain_net_t * a_net, dap_chain_net_tx_search_t
 {
     assert(a_tx_callback);
     switch (a_search_type) {
-        case TX_SEARCH_TYPE_NET_UNSPENT:{
-            size_t l_tx_count = dap_ledger_count(a_net->pub.ledger);
-            dap_list_t *l_txs_list = dap_ledger_get_txs(a_net->pub.ledger, l_tx_count, 1, false, true);
-            dap_list_t *l_temp = l_txs_list;
-            while(l_temp){
-                    dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_temp->data;
-                    a_tx_callback(a_net, l_tx, a_arg);
-                    l_temp = dap_list_next(l_temp);
-            }
-            break;
-        }
+        case TX_SEARCH_TYPE_NET_UNSPENT:
         case TX_SEARCH_TYPE_NET:
         case TX_SEARCH_TYPE_LOCAL:{
-            size_t l_tx_count = dap_ledger_count(a_net->pub.ledger);
-            dap_list_t *l_txs_list = dap_ledger_get_txs(a_net->pub.ledger, l_tx_count, 1, false, false);
-            dap_list_t *l_temp = l_txs_list;
-            while(l_temp){
-                dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_temp->data;
-                a_tx_callback(a_net, l_tx, a_arg);
-                l_temp = dap_list_next(l_temp);
+            dap_ledger_datum_iter_t *l_iter = dap_ledger_datum_iter_create(a_net);
+            dap_ledger_datum_iter_get_first(l_iter);
+            while(l_iter->cur){
+                if (a_search_type != TX_SEARCH_TYPE_NET_UNSPENT ||
+                    (a_search_type == TX_SEARCH_TYPE_NET_UNSPENT && l_iter->is_unspent)){
+                    a_tx_callback(a_net, l_iter->cur, &l_iter->cur_hash, a_arg);
+                }
+                dap_ledger_datum_iter_get_next(l_iter);
             }
+            dap_ledger_datum_iter_delete(l_iter);
         break;
         }
         case TX_SEARCH_TYPE_CELL_SPENT:
@@ -218,39 +210,32 @@ void dap_chain_net_get_tx_all(dap_chain_net_t * a_net, dap_chain_net_tx_search_t
         case TX_SEARCH_TYPE_BLOCKCHAIN:{
             // pass all chains
             for ( dap_chain_t * l_chain = a_net->pub.chains; l_chain; l_chain = l_chain->next){
-                dap_chain_cell_t * l_cell, *l_cell_tmp;
-                // Go through all cells
-                HASH_ITER(hh,l_chain->cells,l_cell, l_cell_tmp){
-                    dap_chain_atom_iter_t * l_atom_iter = l_chain->callback_atom_iter_create(l_chain,l_cell->id, false  );
-                    // try to find transaction in chain ( inside shard )
-                    size_t l_atom_size = 0;
-                    dap_chain_atom_ptr_t l_atom = l_chain->callback_atom_iter_get_first(l_atom_iter, &l_atom_size);
+//                dap_chain_cell_t * l_cell, *l_cell_tmp;
+//                // Go through all cells
+//                HASH_ITER(hh,l_chain->cells,l_cell, l_cell_tmp){
+                dap_chain_datum_iter_t * l_datum_iter = l_chain->callback_datum_iter_create(l_chain);
+                l_chain->callback_datum_iter_get_first(l_datum_iter);
 
                     // Check atoms in chain
-                    while(l_atom && l_atom_size) {
-                        size_t l_datums_count = 0;
-                        dap_chain_datum_t **l_datums = l_chain->callback_atom_get_datums(l_atom, l_atom_size, &l_datums_count);
-                        // transaction
-                        dap_chain_datum_tx_t *l_tx = NULL;
-
-                        for (size_t i = 0; i < l_datums_count; i++) {
-                            // Check if its transaction
-                            if (l_datums && (l_datums[i]->header.type_id == DAP_CHAIN_DATUM_TX)) {
-                                l_tx = (dap_chain_datum_tx_t *) l_datums[i]->data;
-                            }
-
-                            // If found TX
-
-                            if ( l_tx ) {
-                                a_tx_callback(a_net, l_tx, a_arg);
-                            }
-                        }
-                        DAP_DEL_Z(l_datums);
-                        // go to next atom
-                        l_atom = l_chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size);
+                while(l_datum_iter->cur) {
+                    dap_chain_datum_t *l_datum = l_datum_iter->cur;
+                    // transaction
+                    dap_chain_datum_tx_t *l_tx = NULL;
+                    // Check if its transaction
+                    if (l_datum && (l_datum->header.type_id == DAP_CHAIN_DATUM_TX)) {
+                        l_tx = (dap_chain_datum_tx_t *) l_datum->data;
                     }
-                    l_chain->callback_atom_iter_delete(l_atom_iter);
+
+                    // If found TX
+                    if ( l_tx ) {
+                        a_tx_callback(a_net, l_tx, l_datum_iter->cur_hash, a_arg);
+                    }
+
+                    // go to next datum
+                    l_chain->callback_datum_iter_get_next(l_datum_iter);
                 }
+                l_chain->callback_datum_iter_delete(l_datum_iter);
+//                }
             }
         } break;
     }
@@ -275,14 +260,14 @@ struct get_tx_cond_all_from_tx
  * @param a_tx
  * @param a_arg
  */
-static void s_get_tx_cond_chain_callback(dap_chain_net_t UNUSED_ARG *a_net, dap_chain_datum_tx_t *a_tx, void *a_arg)
+static void s_get_tx_cond_chain_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg)
 {
     struct get_tx_cond_all_from_tx * l_args = (struct get_tx_cond_all_from_tx* ) a_arg;
 
     if( l_args->ret ){
         int l_item_idx = 0;
         byte_t *l_tx_item;
-        dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
+        dap_hash_fast_t * l_tx_hash = a_tx_hash;
         // Get items from transaction
         while ((l_tx_item = dap_chain_datum_tx_item_get(a_tx, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL)) != NULL){
             dap_chain_tx_in_cond_t * l_in_cond = (dap_chain_tx_in_cond_t *) l_tx_item;
@@ -306,7 +291,7 @@ static void s_get_tx_cond_chain_callback(dap_chain_net_t UNUSED_ARG *a_net, dap_
         }
         DAP_DELETE(l_tx_hash);
     }else if(a_tx){
-        dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
+        dap_hash_fast_t * l_tx_hash = a_tx_hash;
         if (!l_tx_hash) {
             log_it(L_CRITICAL, "Memory allocation error");
             return;
@@ -347,7 +332,7 @@ dap_list_t * dap_chain_net_get_tx_cond_chain(dap_chain_net_t * a_net, dap_hash_f
     }
     l_args->tx_begin_hash = a_tx_hash;
     l_args->srv_uid = a_srv_uid;
-    dap_chain_net_get_tx_all(a_net,TX_SEARCH_TYPE_NET,s_get_tx_cond_chain_callback, l_args);
+    dap_chain_net_get_tx_all(a_net,TX_SEARCH_TYPE_NET, s_get_tx_cond_chain_callback, l_args);
     dap_list_t * l_ret = l_args->ret;
     DAP_DELETE(l_args);
     return l_ret;
@@ -370,8 +355,10 @@ struct get_tx_cond_all_for_addr
  * @param a_tx
  * @param a_arg
  */
-static void s_get_tx_cond_all_for_addr_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_datum_tx, void *a_arg)
+static void s_get_tx_cond_all_for_addr_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_datum_tx, dap_hash_fast_t *a_hash, void *a_arg)
 {
+    UNUSED(a_net);
+    UNUSED(a_hash);
     struct get_tx_cond_all_for_addr * l_args = (struct get_tx_cond_all_for_addr* ) a_arg;
     int l_item_idx = 0;
     dap_chain_datum_tx_item_t *l_tx_item;
@@ -473,7 +460,11 @@ dap_list_t * dap_chain_net_get_tx_cond_all_for_addr(dap_chain_net_t * a_net, dap
     return l_ret;
 }
 
-static void s_tx_cond_all_by_srv_uid_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, void *a_arg){
+static void s_tx_cond_all_by_srv_uid_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg)
+{
+    UNUSED(a_net);
+    UNUSED(a_tx_hash);
+
     cond_all_by_srv_uid_arg_t *l_ret = (cond_all_by_srv_uid_arg_t *)a_arg;
     dap_chain_datum_tx_t *l_tx = a_tx;
 
diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h
index 129086c4b023b80fe2659ba9d28a8caa99fa1176..a7995926180af9004a4207ee8d3d22484c871510 100644
--- a/modules/net/include/dap_chain_ledger.h
+++ b/modules/net/include/dap_chain_ledger.h
@@ -114,6 +114,15 @@ typedef enum dap_ledger_token_decl_add_err{
     DAP_LEDGER_TOKEN_DECL_ADD_UNKNOWN /* MAX */
 } dap_ledger_token_decl_add_err_t;
 
+typedef struct dap_ledger_datum_iter {
+    dap_chain_net_t *net;
+    dap_chain_datum_tx_t *cur;
+    dap_chain_hash_fast_t cur_hash;
+    bool is_unspent;
+    int ret_code;
+    void *cur_ledger_tx_item;
+} dap_ledger_datum_iter_t;
+
 typedef bool (*dap_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner);
 typedef void (*dap_ledger_updater_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_cond);
 typedef void (* dap_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx);
@@ -350,6 +359,12 @@ dap_list_t * dap_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a
 
 //bool dap_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);
 
+dap_ledger_datum_iter_t *dap_ledger_datum_iter_create(dap_chain_net_t *a_net);
+void dap_ledger_datum_iter_delete(dap_ledger_datum_iter_t *a_iter);
+dap_chain_datum_tx_t *dap_ledger_datum_iter_get_first(dap_ledger_datum_iter_t *a_iter);
+dap_chain_datum_tx_t *dap_ledger_datum_iter_get_next(dap_ledger_datum_iter_t *a_iter);
+dap_chain_datum_tx_t *dap_ledger_datum_iter_get_last(dap_ledger_datum_iter_t *a_iter);
+
 void dap_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_ledger_tx_add_notify_t a_callback, void *a_arg);
 void dap_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_ledger_bridged_tx_notify_t a_callback, void *a_arg);
 
diff --git a/modules/net/include/dap_chain_net_tx.h b/modules/net/include/dap_chain_net_tx.h
index f886a4b36884e1f71683806d9c3d3c698cd65ac0..e3a7b6af511d408e41ead6709f0baf0ad48437e4 100644
--- a/modules/net/include/dap_chain_net_tx.h
+++ b/modules/net/include/dap_chain_net_tx.h
@@ -58,7 +58,7 @@ typedef struct dap_chain_datum_tx_spends_items{
     dap_chain_datum_tx_spends_item_t * tx_outs;
     dap_chain_datum_tx_spends_item_t * tx_ins;
 } dap_chain_datum_tx_spends_items_t;
-typedef void (dap_chain_net_tx_hash_callback_t)(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, void *a_arg);
+typedef void (dap_chain_net_tx_hash_callback_t)(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg);
 
 
 // TX functions
diff --git a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
index d2f4542abeb9acbba96c2d0ecd789df6a7709836..8d6e6d513badc7924b8ecee6fb6d14388be98682 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
@@ -2094,7 +2094,7 @@ struct get_tx_cond_pos_del_from_tx
  * @param a_tx
  * @param a_arg
  */
-static void s_get_tx_filter_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, void *a_arg)
+static void s_get_tx_filter_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg)
 {
     struct get_tx_cond_pos_del_from_tx * l_args = (struct get_tx_cond_pos_del_from_tx* ) a_arg;
     int l_out_idx_tmp = 0;
@@ -2105,8 +2105,7 @@ static void s_get_tx_filter_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_
     if (dap_chain_addr_is_blank(&l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr) ||
             l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr.uint64 == 0)
         return;
-    dap_hash_fast_t l_datum_hash;
-    dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_datum_hash);
+    dap_hash_fast_t l_datum_hash = *a_tx_hash;
     if (dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_datum_hash, l_out_idx_tmp, NULL))
         return;
     dap_chain_net_srv_stake_item_t *l_stake = NULL;
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index c1e8f25e29b52063fb2cb9f098c6c6d47c1eaeb7..e1a549718545a8bfb56a3f51e79d956909143669 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1724,9 +1724,10 @@ size_t l_tx_total;
     return  0;
 }
 
-void s_tx_is_order_check(dap_chain_net_t *a_net, dap_chain_datum_tx_t *a_tx, void *a_arg)
+void s_tx_is_order_check (dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg)
 {
     UNUSED(a_net);
+    UNUSED(a_tx_hash);
     dap_list_t **l_tx_list_ptr = a_arg;
     if (dap_chain_datum_tx_out_cond_get(a_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE , NULL) &&
             !dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_IN_COND, NULL))