diff --git a/modules/chain/include/dap_chain_tx.h b/modules/chain/include/dap_chain_tx.h
index 3bb0eb0ded723f70dd2571e2ab3abcff98a0c8d1..50b05aaeba48c696d6840d5ac0f41b10d0c826fa 100644
--- a/modules/chain/include/dap_chain_tx.h
+++ b/modules/chain/include/dap_chain_tx.h
@@ -45,10 +45,10 @@ typedef struct dap_chain_tx
     dap_chain_datum_token_t *token;
 
     // Inputs
-    dap_chain_datum_tx_item_t * in;
+    byte_t * in;
     dap_chain_tx_in_cond_t * in_cond;
     // Outputs
-    dap_chain_datum_tx_item_t * out;
+    byte_t * out;
     dap_chain_tx_out_cond_t * out_cond;
 
     // Previous
diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c
index ac6ec1a215dfd49513b18386a5a47bc71ffa9100..2dd5bfa8320b2d4464b8b748d2efc2ec0901852c 100644
--- a/modules/chain/tests/dap_chain_ledger_tests.c
+++ b/modules/chain/tests/dap_chain_ledger_tests.c
@@ -107,7 +107,7 @@ dap_chain_datum_tx_t *dap_ledger_test_create_tx_full(dap_enc_key_t *a_key_from,
     dap_chain_addr_fill_from_key(&l_addr, a_key_from, a_ledger->net->pub.id);
     dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash(a_ledger, a_hash_prev);
     int l_out_idx = 0;
-    dap_chain_tx_out_t *l_tx_prev_out = (dap_chain_tx_out_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, TX_ITEM_TYPE_OUT, NULL);
+    dap_chain_tx_out_t *l_tx_prev_out = (dap_chain_tx_out_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, NULL, TX_ITEM_TYPE_OUT, NULL);
     dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
     dap_chain_tx_in_t *l_in = dap_chain_datum_tx_item_in_create(a_hash_prev, 0);
     dap_chain_tx_out_t *l_out = dap_chain_datum_tx_item_out_create(a_addr_to, a_value);
@@ -129,7 +129,7 @@ dap_chain_datum_tx_t *dap_ledger_test_create_tx_cond(dap_enc_key_t *a_key_from,
     dap_chain_addr_fill_from_key(&l_addr, a_key_from, a_ledger->net->pub.id);
     dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash(a_ledger, a_hash_prev);
     int l_out_idx = 0;
-    dap_chain_tx_out_t *l_tx_prev_out = (dap_chain_tx_out_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, TX_ITEM_TYPE_OUT, NULL);
+    dap_chain_tx_out_t *l_tx_prev_out = (dap_chain_tx_out_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, NULL, TX_ITEM_TYPE_OUT, NULL);
     dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
     dap_chain_tx_in_t *l_in = dap_chain_datum_tx_item_in_create(a_hash_prev, 0);
     dap_chain_net_srv_uid_t l_srv_uid = {.uint64 = 1};
@@ -157,7 +157,7 @@ dap_chain_datum_tx_t *dap_ledger_test_create_spend_tx_cond(dap_enc_key_t *a_key_
     dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash(a_ledger, a_hash_prev);
      // get previous cond out
     int l_out_idx = 0;
-    dap_chain_tx_out_cond_t *l_tx_prev_out = (dap_chain_tx_out_cond_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, TX_ITEM_TYPE_OUT_COND, NULL);
+    dap_chain_tx_out_cond_t *l_tx_prev_out = (dap_chain_tx_out_cond_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, NULL, TX_ITEM_TYPE_OUT_COND, NULL);
 
     dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
     dap_chain_tx_in_cond_t *l_in_cond = dap_chain_datum_tx_item_in_cond_create(a_hash_prev, 1, 0);
@@ -199,7 +199,7 @@ dap_chain_datum_tx_t *dap_ledger_test_create_return_from_tx_cond(dap_chain_hash_
     dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash(a_ledger, a_hash_prev);
      // get previous cond out
     int l_out_idx = 1;
-    dap_chain_tx_out_cond_t *l_tx_prev_out = (dap_chain_tx_out_cond_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, TX_ITEM_TYPE_OUT_COND, NULL);
+    dap_chain_tx_out_cond_t *l_tx_prev_out = (dap_chain_tx_out_cond_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, NULL, TX_ITEM_TYPE_OUT_COND, NULL);
 
     dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
     dap_chain_tx_in_cond_t *l_in_cond = dap_chain_datum_tx_item_in_cond_create(a_hash_prev, 1, 0);
@@ -222,7 +222,7 @@ dap_chain_datum_tx_t *dap_ledger_test_create_stake_tx_cond(dap_enc_key_t *a_key_
     dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash(a_ledger, a_hash_prev);
      // get previous cond out
     int l_out_idx = 0;
-    dap_chain_tx_out_t *l_tx_prev_out = (dap_chain_tx_out_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, TX_ITEM_TYPE_OUT, NULL);
+    dap_chain_tx_out_t *l_tx_prev_out = (dap_chain_tx_out_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, NULL, TX_ITEM_TYPE_OUT, NULL);
     
     dap_chain_addr_t l_addr_to = {0};
     dap_chain_addr_fill_from_key(&l_addr_to, a_key_from, a_ledger->net->pub.id);
@@ -275,7 +275,7 @@ dap_chain_datum_tx_t *dap_ledger_test_create_unstake_tx_cond(dap_enc_key_t *a_ke
         return NULL;
 
     l_out_idx = 4;
-    dap_chain_tx_out_ext_t *l_tx_prev_out_ext = (dap_chain_tx_out_ext_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, TX_ITEM_TYPE_OUT_EXT, NULL);
+    dap_chain_tx_out_ext_t *l_tx_prev_out_ext = (dap_chain_tx_out_ext_t *)dap_chain_datum_tx_item_get(l_tx_prev, &l_out_idx, NULL, TX_ITEM_TYPE_OUT_EXT, NULL);
 
     dap_chain_addr_t l_addr_to = {0};
     dap_chain_addr_fill_from_key(&l_addr_to, a_key_from, a_ledger->net->pub.id);
diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c
index 558c9f504d2fb9c22f79e949241d3a9c020a158d..dc14ef6c110868477f3698ea8f89ab26865be81e 100644
--- a/modules/common/dap_chain_datum.c
+++ b/modules/common/dap_chain_datum.c
@@ -35,6 +35,7 @@
 #include "dap_chain_datum_hashtree_roots.h"
 #include "dap_enc_base58.h"
 #include "dap_sign.h"
+#include "dap_tsd.h"
 
 #define LOG_TAG "dap_chain_datum"
 
@@ -62,8 +63,8 @@ dap_chain_datum_t *dap_chain_datum_create(uint16_t a_type_id, const void *a_data
 }
 void dap_datum_token_dump_tsd_to_json(json_object * json_obj_out, dap_chain_datum_token_t *a_token, size_t a_token_size, const char *a_hash_out_type)
 {
-    dap_tsd_t *l_tsd = dap_chain_datum_token_tsd_get(a_token, a_token_size);
-    if (l_tsd == NULL) {
+    dap_tsd_t *l_tsd_begin = dap_chain_datum_token_tsd_get(a_token, a_token_size);
+    if (!l_tsd_begin) {
         json_object_object_add(json_obj_out, "status", json_object_new_string("<CORRUPTED TSD SECTION>"));
         return;
     }
@@ -87,18 +88,8 @@ void dap_datum_token_dump_tsd_to_json(json_object * json_obj_out, dap_chain_datu
         } break;
     default: break;
     }
-    size_t l_tsd_size = 0;
-    for (size_t l_offset = 0; l_offset < l_tsd_total_size; l_offset += l_tsd_size) {
-        l_tsd = (dap_tsd_t *) (((byte_t*)l_tsd) + l_tsd_size);
-        l_tsd_size = l_tsd ? dap_tsd_size(l_tsd) : 0;
-        if (l_tsd_size == 0) {
-            log_it(L_ERROR,"Wrong zero TSD size, exiting s_datum_token_dump_tsd()");
-            return;
-        } else if (l_tsd_size+l_offset > l_tsd_total_size) {
-            log_it(L_WARNING, "<CORRUPTED TSD> too big size %u when left maximum %zu",
-                   l_tsd->size, l_tsd_total_size - l_offset);
-            return;
-        }
+    dap_tsd_t *l_tsd; size_t l_tsd_size;
+    dap_tsd_iter(l_tsd, l_tsd_size, l_tsd_begin, l_tsd_total_size) {
         switch(l_tsd->type) {
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS: {
             uint16_t l_t = 0;
@@ -226,7 +217,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                              dap_chain_net_id_t a_net_id)
 {
     bool l_is_first = false;
-    dap_chain_tx_in_t *l_in_item = (dap_chain_tx_in_t *)dap_chain_datum_tx_item_get(a_datum, NULL, TX_ITEM_TYPE_IN, NULL);
+    dap_chain_tx_in_t *l_in_item = (dap_chain_tx_in_t *)dap_chain_datum_tx_item_get(a_datum, NULL, NULL, TX_ITEM_TYPE_IN, NULL);
     if (l_in_item && dap_hash_fast_is_blank(&l_in_item->header.tx_prev_hash))
         l_is_first = true;
     char l_tmp_buf[DAP_TIME_STR_SIZE];
@@ -237,22 +228,15 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
     dap_string_append_printf(a_str_out, "transaction:%s hash %s\n TS Created: %s%s%s\n Items:\n",
                              l_is_first ? " (emit)" : "", l_hash_str, l_tmp_buf,
                              a_ticker ? " Token ticker: " : "", a_ticker ? a_ticker : "");
-    uint32_t l_tx_items_count = 0;
-    uint32_t l_tx_items_size = a_datum->header.tx_items_size;
-    dap_hash_fast_t *l_hash_tmp = NULL;
-    while (l_tx_items_count < l_tx_items_size) {
-        uint8_t *item = a_datum->tx_items + l_tx_items_count;
-        size_t l_item_tx_size = dap_chain_datum_item_tx_get_size(item);
-        switch(dap_chain_datum_tx_item_get_type(item)){
+    dap_hash_fast_t l_hash_tmp = { };
+    byte_t *item; size_t l_size;
+    TX_ITEM_ITER_TX(item, l_size, a_datum) {
+        switch (*item) {
         case TX_ITEM_TYPE_IN:
-            l_hash_tmp = &((dap_chain_tx_in_t*)item)->header.tx_prev_hash;
-            if (dap_hash_fast_is_blank(l_hash_tmp)) {
-                l_hash_str = "BLANK";
-            } else {
-                l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                        ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                        : dap_chain_hash_fast_to_str_static(l_hash_tmp);
-            }
+            l_hash_tmp = ((dap_chain_tx_in_t*)item)->header.tx_prev_hash;
+            l_hash_str = !dap_hash_fast_is_blank(&l_hash_tmp) 
+                ? dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp) : dap_chain_hash_fast_to_str_static(&l_hash_tmp)
+                : "BLANK";
             dap_string_append_printf(a_str_out, "\t IN:\nTx_prev_hash: %s\n"
                                                 "\t\t Tx_out_prev_idx: %u\n",
                                         l_hash_str,
@@ -280,10 +264,10 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                                         l_addr_str);
         } break;
         case TX_ITEM_TYPE_IN_EMS: {
-            l_hash_tmp = &((dap_chain_tx_in_ems_t*)item)->header.token_emission_hash;
+            l_hash_tmp = ((dap_chain_tx_in_ems_t*)item)->header.token_emission_hash;
             l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                    ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                    : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                    ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp)
+                    : dap_chain_hash_fast_to_str_static(&l_hash_tmp);
             dap_string_append_printf(a_str_out, "\t IN_EMS:\n"
                                                 "\t\t ticker: %s \n"
                                                 "\t\t token_emission_hash: %s\n"
@@ -315,10 +299,10 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
         } break; */
 
         case TX_ITEM_TYPE_IN_REWARD: {
-            l_hash_tmp = &((dap_chain_tx_in_reward_t *)item)->block_hash;
+            l_hash_tmp = ((dap_chain_tx_in_reward_t *)item)->block_hash;
             l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                    ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                    : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                    ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp)
+                    : dap_chain_hash_fast_to_str_static(&l_hash_tmp);
             dap_string_append_printf(a_str_out, "\t IN_REWARD:\n"
                                                 "\t\t block_hash: %s\n",
                                                 l_hash_str);
@@ -393,10 +377,10 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                                      ((dap_chain_tx_tsd_t*)item)->header.size);
         } break;
         case TX_ITEM_TYPE_IN_COND:
-            l_hash_tmp = &((dap_chain_tx_in_cond_t*)item)->header.tx_prev_hash;
+            l_hash_tmp = ((dap_chain_tx_in_cond_t*)item)->header.tx_prev_hash;
             l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                    ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                    : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                    ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp)
+                    : dap_chain_hash_fast_to_str_static(&l_hash_tmp);
             dap_string_append_printf(a_str_out, "\t IN COND:\n\t\tReceipt_idx: %u\n"
                                                 "\t\t Tx_prev_hash: %s\n"
                                                 "\t\t Tx_out_prev_idx: %u\n",
@@ -421,10 +405,10 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                 case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: {
                     const char *l_coins_str, *l_value_str =
                         dap_uint256_to_char( ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi, &l_coins_str );
-                    l_hash_tmp = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash;
+                    l_hash_tmp = ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash;
                     l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                            ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                            : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                            ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp)
+                            : dap_chain_hash_fast_to_str_static(&l_hash_tmp);
                     dap_string_append_printf(a_str_out, "\t\t\t unit: 0x%08x\n"
                                                         "\t\t\t pkey: %s\n"
                                                         "\t\t\t max price: %s (%s)\n",
@@ -436,10 +420,10 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                 case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: {
                     dap_chain_node_addr_t *l_signer_node_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signer_node_addr;
                     dap_chain_addr_t *l_signing_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signing_addr;
-                    l_hash_tmp = &l_signing_addr->data.hash_fast;
+                    l_hash_tmp = l_signing_addr->data.hash_fast;
                     l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                            ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                            : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                            ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp)
+                            : dap_chain_hash_fast_to_str_static(&l_hash_tmp);
                     dap_string_append_printf(a_str_out, "\t\t\t signing_addr: %s\n"
                                                         "\t\t\t with pkey hash %s\n"
                                                         "\t\t\t signer_node_addr: "NODE_ADDR_FP_STR"\n",
@@ -477,8 +461,8 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                                      l_value_str);
         } break;
         case TX_ITEM_TYPE_VOTING:{
-            int l_tsd_size = 0;
-            dap_chain_tx_tsd_t *l_item = (dap_chain_tx_tsd_t *)dap_chain_datum_tx_item_get(a_datum, 0, TX_ITEM_TYPE_TSD, &l_tsd_size);
+            size_t l_tsd_size = 0;
+            dap_chain_tx_tsd_t *l_item = (dap_chain_tx_tsd_t *)dap_chain_datum_tx_item_get(a_datum, NULL, (byte_t*)item + l_size, TX_ITEM_TYPE_TSD, &l_tsd_size);
             if (!l_item || !l_tsd_size)
                     break;
             dap_chain_datum_tx_voting_params_t *l_voting_params = dap_chain_voting_parse_tsd(a_datum);
@@ -516,13 +500,6 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
             dap_string_append_printf(a_str_out, " This transaction have unknown item type \n");
             break;
         }
-        l_tx_items_count += l_item_tx_size;
-        // Freeze protection
-        if(!l_item_tx_size)
-        {
-            break;
-        }
-
     }
     dap_string_append_printf(a_str_out, "\n");
     return true;
@@ -547,7 +524,7 @@ bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum,
                              dap_chain_net_id_t a_net_id)
 {
     bool l_is_first = false;
-    dap_chain_tx_in_t *l_in_item = (dap_chain_tx_in_t *)dap_chain_datum_tx_item_get(a_datum, NULL, TX_ITEM_TYPE_IN, NULL);
+    dap_chain_tx_in_t *l_in_item = (dap_chain_tx_in_t *)dap_chain_datum_tx_item_get(a_datum, NULL, NULL, TX_ITEM_TYPE_IN, NULL);
     if (l_in_item && dap_hash_fast_is_blank(&l_in_item->header.tx_prev_hash))
         l_is_first = true;
     char l_tmp_buf[DAP_TIME_STR_SIZE];
@@ -563,24 +540,17 @@ bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum,
     json_object_object_add(json_obj_out, "TS Created", json_object_new_string(l_tmp_buf));
     json_object_object_add(json_obj_out, "Token ticker", a_ticker ? json_object_new_string(a_ticker) : json_object_new_string(""));
     //json_object_array_add(json_arr_items, json_obj_tx);
-    
-    uint32_t l_tx_items_count = 0;
-    uint32_t l_tx_items_size = a_datum->header.tx_items_size;
-    dap_hash_fast_t *l_hash_tmp = NULL;
-    while (l_tx_items_count < l_tx_items_size) {
+
+    dap_hash_fast_t l_hash_tmp = { };
+    byte_t *item; size_t l_size;
+    TX_ITEM_ITER_TX(item, l_size, a_datum) {
         json_object* json_obj_item = json_object_new_object();
-        uint8_t *item = a_datum->tx_items + l_tx_items_count;
-        size_t l_item_tx_size = dap_chain_datum_item_tx_get_size(item);
-        switch(dap_chain_datum_tx_item_get_type(item)){
+        switch (*item) {
         case TX_ITEM_TYPE_IN:
-            l_hash_tmp = &((dap_chain_tx_in_t*)item)->header.tx_prev_hash;
-            if (dap_hash_fast_is_blank(l_hash_tmp)) {
-                l_hash_str = "BLANK";
-            } else {
-                l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                        ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                        : dap_chain_hash_fast_to_str_static(l_hash_tmp);
-            }
+            l_hash_tmp = ((dap_chain_tx_in_t*)item)->header.tx_prev_hash;
+            l_hash_str = !dap_hash_fast_is_blank(&l_hash_tmp)
+                ? dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp) : dap_chain_hash_fast_to_str_static(&l_hash_tmp)
+                : "BLANK";
             json_object_object_add(json_obj_item,"item type", json_object_new_string("IN"));
             json_object_object_add(json_obj_item,"Tx prev hash", json_object_new_string(l_hash_str));
             json_object_object_add(json_obj_item,"Tx out prev idx", json_object_new_uint64(((dap_chain_tx_in_t*)item)->header.tx_out_prev_idx));
@@ -603,10 +573,10 @@ bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum,
         } break;
         case TX_ITEM_TYPE_IN_EMS: {
             char l_tmp_buff[70]={0};
-            l_hash_tmp = &((dap_chain_tx_in_ems_t*)item)->header.token_emission_hash;
+            l_hash_tmp = ((dap_chain_tx_in_ems_t*)item)->header.token_emission_hash;
             l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                    ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                    : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                    ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp)
+                    : dap_chain_hash_fast_to_str_static(&l_hash_tmp);
             json_object_object_add(json_obj_item,"item type", json_object_new_string("IN_EMS"));
             json_object_object_add(json_obj_item,"ticker", json_object_new_string(((dap_chain_tx_in_ems_t*)item)->header.ticker));
             json_object_object_add(json_obj_item,"token_emission_hash", json_object_new_string(l_hash_str));
@@ -636,10 +606,10 @@ bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum,
         } break; */
 
         case TX_ITEM_TYPE_IN_REWARD: {
-            l_hash_tmp = &((dap_chain_tx_in_reward_t *)item)->block_hash;
+            l_hash_tmp = ((dap_chain_tx_in_reward_t *)item)->block_hash;
             l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                    ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                    : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                    ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp)
+                    : dap_chain_hash_fast_to_str_static(&l_hash_tmp);
             json_object_object_add(json_obj_item,"item type", json_object_new_string("IN_REWARD"));
             json_object_object_add(json_obj_item,"block_hash", json_object_new_string(l_hash_str));
         } break;
@@ -704,10 +674,10 @@ bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum,
         } break;
         case TX_ITEM_TYPE_IN_COND:
             json_object_object_add(json_obj_item,"item type", json_object_new_string("IN COND"));
-            l_hash_tmp = &((dap_chain_tx_in_cond_t*)item)->header.tx_prev_hash;
+            l_hash_tmp = ((dap_chain_tx_in_cond_t*)item)->header.tx_prev_hash;
             l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                    ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                    : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                    ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp)
+                    : dap_chain_hash_fast_to_str_static(&l_hash_tmp);
             json_object_object_add(json_obj_item,"Receipt_idx", json_object_new_uint64(((dap_chain_tx_in_cond_t*)item)->header.receipt_idx));
             json_object_object_add(json_obj_item,"Tx_prev_hash", json_object_new_string(l_hash_str));
             json_object_object_add(json_obj_item,"Tx_out_prev_idx", json_object_new_uint64(((dap_chain_tx_in_cond_t*)item)->header.tx_out_prev_idx));
@@ -729,10 +699,10 @@ bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum,
                 case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: {
                     const char *l_coins_str, *l_value_str =
                         dap_uint256_to_char( ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi, &l_coins_str );
-                    l_hash_tmp = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash;
+                    l_hash_tmp = ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash;
                     l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                            ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                            : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                            ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp)
+                            : dap_chain_hash_fast_to_str_static(&l_hash_tmp);
                     sprintf(l_tmp_buff,"0x%08x",((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit.uint32);
                     json_object_object_add(json_obj_item,"unit", json_object_new_string(l_tmp_buff));
                     json_object_object_add(json_obj_item,"pkey", json_object_new_string(l_hash_str));
@@ -743,10 +713,10 @@ bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum,
                 case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: {
                     dap_chain_node_addr_t *l_signer_node_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signer_node_addr;
                     dap_chain_addr_t *l_signing_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signing_addr;
-                    l_hash_tmp = &l_signing_addr->data.hash_fast;
+                    l_hash_tmp = l_signing_addr->data.hash_fast;
                     l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                            ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
-                            : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                            ? dap_enc_base58_encode_hash_to_str_static(&l_hash_tmp)
+                            : dap_chain_hash_fast_to_str_static(&l_hash_tmp);
                     json_object_object_add(json_obj_item,"signing_addr", json_object_new_string(dap_chain_addr_to_str_static(l_signing_addr)));
                     json_object_object_add(json_obj_item,"with pkey hash", json_object_new_string(l_hash_str));                    
                     sprintf(l_tmp_buff,""NODE_ADDR_FP_STR"",NODE_ADDR_FP_ARGS(l_signer_node_addr));
@@ -779,8 +749,8 @@ bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum,
             
         } break;
         case TX_ITEM_TYPE_VOTING:{
-            int l_tsd_size = 0;
-            dap_chain_tx_tsd_t *l_item = (dap_chain_tx_tsd_t *)dap_chain_datum_tx_item_get(a_datum, 0, TX_ITEM_TYPE_TSD, &l_tsd_size);
+            size_t l_tsd_size = 0;
+            dap_chain_tx_tsd_t *l_item = (dap_chain_tx_tsd_t *)dap_chain_datum_tx_item_get(a_datum, NULL, (byte_t*)item + l_size, TX_ITEM_TYPE_TSD, &l_tsd_size);
             if (!l_item || !l_tsd_size)
                     break;
             dap_chain_datum_tx_voting_params_t *l_voting_params = dap_chain_voting_parse_tsd(a_datum);
@@ -825,13 +795,6 @@ bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum,
             break;
         }
         json_object_array_add(json_arr_items, json_obj_item);
-        l_tx_items_count += l_item_tx_size;
-        // Freeze protection
-        if(!l_item_tx_size)
-        {
-            break;
-        }
-
     }
     json_object_object_add(json_obj_out, "ITEMS", json_arr_items);
     return true;
diff --git a/modules/common/dap_chain_datum_anchor.c b/modules/common/dap_chain_datum_anchor.c
index a87618bb02b8308c80bf19bab1b72da2027df42a..b3b4ea6da8e3e026c44b7803a10908be46d05371 100644
--- a/modules/common/dap_chain_datum_anchor.c
+++ b/modules/common/dap_chain_datum_anchor.c
@@ -36,27 +36,16 @@ int dap_chain_datum_anchor_get_hash_from_data(dap_chain_datum_anchor_t* a_anchor
         log_it(L_WARNING,"Wrong arguments");
         return -1;
     }
-
-    size_t l_tsd_offset = 0, tsd_data_size = a_anchor->header.data_size;
-
-    while(l_tsd_offset < tsd_data_size){
-        dap_tsd_t *l_tsd = (dap_tsd_t*)a_anchor->data_n_sign + l_tsd_offset;
-        size_t l_tsd_size = l_tsd->size + sizeof(dap_tsd_t);
-        if(l_tsd_size > tsd_data_size){
-            log_it(L_WARNING,"TSD size is greater than all data size. It's possible corrupt data.");
-            return -1;
-        }
-        if (l_tsd->type == DAP_CHAIN_DATUM_ANCHOR_TSD_TYPE_DECREE_HASH){
-            if(l_tsd->size > sizeof(dap_hash_fast_t)){
-                log_it(L_WARNING,"Wrong fee tsd data size.");
-                return -1;
-            }
+    dap_tsd_t *l_tsd; size_t l_tsd_size;
+    dap_tsd_iter(l_tsd, l_tsd_size, a_anchor->data_n_sign, a_anchor->header.data_size) {
+        if (l_tsd->type == DAP_CHAIN_DATUM_ANCHOR_TSD_TYPE_DECREE_HASH) {
+            if (l_tsd->size > sizeof(dap_hash_fast_t))
+                return log_it(L_WARNING,"Wrong fee tsd data size"), -1;
             _dap_tsd_get_scalar(l_tsd, l_out_hash);
             return 0;
         }
-        l_tsd_offset += l_tsd_size;
     }
-    return -100;
+    return -2;
 }
 
 void dap_chain_datum_anchor_certs_dump(dap_string_t * a_str_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type)
diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c
index 6f2bcabbb6ca33a4fc82cdf4410e1cdb157ec065..405ae8ffdcfdb53593a021f8850321c84fe33fbc 100644
--- a/modules/common/dap_chain_datum_decree.c
+++ b/modules/common/dap_chain_datum_decree.c
@@ -68,18 +68,17 @@ int dap_chain_datum_decree_get_fee_addr(dap_chain_datum_decree_t *a_decree, dap_
     return l_tsd && l_tsd->size == sizeof(dap_chain_addr_t) ? ( _dap_tsd_get_scalar(l_tsd, a_fee_wallet), 0 ) : 1;
 }
 
-static void *s_cb_copy_pkeys(const void *a_pkey, UNUSED_ARG void *a_data) {
-    return DAP_DUP_SIZE(a_pkey, dap_pkey_get_size(a_pkey));
-}
-
 dap_list_t *dap_chain_datum_decree_get_owners(dap_chain_datum_decree_t *a_decree, uint16_t *a_owners_num)
 {
     dap_return_val_if_fail(a_decree && a_owners_num, NULL);
-    dap_list_t *l_tsd_list = dap_tsd_find_all(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER);
-    if ( !(*a_owners_num = (uint16_t)dap_list_length(l_tsd_list)) )
-        return NULL;
-    dap_list_t *l_ret = dap_list_copy_deep(l_tsd_list, s_cb_copy_pkeys, NULL);
-    dap_list_free(l_tsd_list);
+    dap_list_t *l_ret = NULL;
+    dap_tsd_t *l_tsd; size_t l_tsd_size;
+    dap_tsd_iter(l_tsd, l_tsd_size, a_decree->data_n_signs, a_decree->header.data_size) {
+        if (l_tsd->type == DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER)
+            l_ret = dap_list_append( l_ret, DAP_DUP_SIZE(l_tsd->data, dap_pkey_get_size((dap_pkey_t*)l_tsd->data)) );
+    }
+    if (a_owners_num)
+        *a_owners_num = (uint16_t)dap_list_length(l_ret);
     return l_ret;
 }
 
@@ -173,153 +172,150 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
     const char *l_subtype_str = dap_chain_datum_decree_subtype_to_str(a_decree->header.sub_type);
     dap_string_append_printf(a_str_out, "subtype: %s\n", l_subtype_str);
     dap_string_append_printf(a_str_out, "TSD:\n");
-    for (size_t l_offset = 0; l_offset < a_decree->header.data_size;) {
-        dap_tsd_t *l_tsd = (dap_tsd_t *)((byte_t*)a_decree->data_n_signs + l_offset);
-        l_offset += dap_tsd_size(l_tsd);
+    dap_tsd_t *l_tsd; size_t l_tsd_size;
+    dap_tsd_iter(l_tsd, l_tsd_size, a_decree->data_n_signs, a_decree->header.data_size) {
         switch(l_tsd->type) {
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE:
-                if (l_tsd->size != sizeof(uint256_t)){
-                    dap_string_append_printf(a_str_out, "\tValue: <WRONG SIZE>\n");
-                    break;
-                }
-                uint256_t l_value = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_value);
-                const char *l_value_str = dap_uint256_to_char(l_value, NULL);
-                dap_string_append_printf(a_str_out, "\tValue: %s\n", l_value_str);
-                break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN:
-            break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE:
-                if (l_tsd->size != sizeof(uint256_t)){
-                    dap_string_append_printf(a_str_out, "\tFee: <WRONG SIZE>\n");
-                    break;
-                }
-                uint256_t l_fee_value = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_fee_value);
-                const char *l_fee_value_str = dap_uint256_to_char(l_fee_value, NULL);
-                dap_string_append_printf(a_str_out, "\tFee: %s\n", l_fee_value_str);
-                break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER:
-                if (l_tsd->size != sizeof(dap_pkey_t)) {
-                    dap_string_append_printf(a_str_out, "\tOwner fingerprint: <WRONG SIZE>\n");
-                    break;
-                }
-                dap_pkey_t *l_owner_pkey = /*DAP_NEW_STACK_SIZE(dap_pkey_t, l_tsd->size);
-                memcpy(l_owner_pkey, l_tsd->data, l_tsd->size);*/ _dap_tsd_get_object(l_tsd, dap_pkey_t);
-                char *l_owner_pkey_str;
-                dap_get_data_hash_str_static(l_owner_pkey->pkey, l_owner_pkey->header.size, l_owner_pkey_str);
-                dap_string_append_printf(a_str_out, "\tOwner fingerprint: %s\n", l_owner_pkey_str);
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE:
+            if (l_tsd->size != sizeof(uint256_t)){
+                dap_string_append_printf(a_str_out, "\tValue: <WRONG SIZE>\n");
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER:
-                if (l_tsd->size != sizeof(uint256_t)) {
-                    dap_string_append_printf(a_str_out, "\tOwner min: <WRONG SIZE>\n");
-                    break;
-                }
-                uint256_t l_owner_min = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_owner_min);
-                const char *l_owner_min_str = dap_uint256_to_char(l_owner_min, NULL);
-                dap_string_append_printf(a_str_out, "\tOwner min: %s\n", l_owner_min_str);
+            }
+            uint256_t l_value = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_value);
+            const char *l_value_str = dap_uint256_to_char(l_value, NULL);
+            dap_string_append_printf(a_str_out, "\tValue: %s\n", l_value_str);
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN:
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE:
+            if (l_tsd->size != sizeof(uint256_t)){
+                dap_string_append_printf(a_str_out, "\tFee: <WRONG SIZE>\n");
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET:
-                if (l_tsd->size != sizeof(dap_chain_addr_t)) {
-                    dap_string_append_printf(a_str_out, "\tWallet for fee: <WRONG SIZE>\n");
-                    break;
-                }
-                dap_chain_addr_t *l_addr_fee_wallet = /*{ };
-                _dap_tsd_get_scalar(l_tsd, &l_addr_fee_wallet);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t);
-                dap_string_append_printf(a_str_out, "\tWallet for fee: %s\n", dap_chain_addr_to_str_static(l_addr_fee_wallet));
+            }
+            uint256_t l_fee_value = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_fee_value);
+            const char *l_fee_value_str = dap_uint256_to_char(l_fee_value, NULL);
+            dap_string_append_printf(a_str_out, "\tFee: %s\n", l_fee_value_str);
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER:
+            if (l_tsd->size != sizeof(dap_pkey_t)) {
+                dap_string_append_printf(a_str_out, "\tOwner fingerprint: <WRONG SIZE>\n");
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH:
-                if (l_tsd->size != sizeof(dap_hash_fast_t)) {
-                    dap_string_append_printf(a_str_out, "\tHash: <WRONG SIZE>\n");
-                    break;
-                }
-                dap_hash_fast_t *l_stake_tx = /*{ };
-                _dap_tsd_get_scalar(l_tsd, &l_stake_tx);*/ _dap_tsd_get_object(l_tsd, dap_hash_fast_t);
-                const char *l_stake_tx_hash = dap_strcmp(a_hash_out_type, "hex")
-                        ? dap_enc_base58_encode_hash_to_str_static(l_stake_tx)
-                        : dap_chain_hash_fast_to_str_static(l_stake_tx);
-                dap_string_append_printf(a_str_out, "\tHash: %s\n", l_stake_tx_hash);
+            }
+            dap_pkey_t *l_owner_pkey = /*DAP_NEW_STACK_SIZE(dap_pkey_t, l_tsd->size);
+            memcpy(l_owner_pkey, l_tsd->data, l_tsd->size);*/ _dap_tsd_get_object(l_tsd, dap_pkey_t);
+            char *l_owner_pkey_str;
+            dap_get_data_hash_str_static(l_owner_pkey->pkey, l_owner_pkey->header.size, l_owner_pkey_str);
+            dap_string_append_printf(a_str_out, "\tOwner fingerprint: %s\n", l_owner_pkey_str);
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER:
+            if (l_tsd->size != sizeof(uint256_t)) {
+                dap_string_append_printf(a_str_out, "\tOwner min: <WRONG SIZE>\n");
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE:
-                if (l_tsd->size != sizeof(uint256_t)){
-                    dap_string_append_printf(a_str_out, "\tStake value: <WRONG SIZE>\n");
-                    break;
-                }
-                uint256_t l_stake_value = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_stake_value);
-                const char *l_stake_value_str = dap_uint256_to_char(l_stake_value, NULL);
-                dap_string_append_printf(a_str_out, "\tStake value: %s\n", l_stake_value_str);
+            }
+            uint256_t l_owner_min = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_owner_min);
+            const char *l_owner_min_str = dap_uint256_to_char(l_owner_min, NULL);
+            dap_string_append_printf(a_str_out, "\tOwner min: %s\n", l_owner_min_str);
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET:
+            if (l_tsd->size != sizeof(dap_chain_addr_t)) {
+                dap_string_append_printf(a_str_out, "\tWallet for fee: <WRONG SIZE>\n");
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR:
-                if (l_tsd->size != sizeof(dap_chain_addr_t)) {
-                    dap_string_append_printf(a_str_out, "\tSigning addr: <WRONG SIZE>\n");
-                    break;
-                }
-                dap_chain_addr_t *l_stake_addr_signing = /*{ };
-                _dap_tsd_get_scalar(l_tsd, &l_stake_addr_signing);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t);
-                dap_string_append_printf(a_str_out, "\tSigning addr: %s\n", dap_chain_addr_to_str_static(l_stake_addr_signing));
-                dap_chain_hash_fast_t l_pkey_signing = l_stake_addr_signing->data.hash_fast;
-                const char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex")
-                        ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_signing)
-                        : dap_chain_hash_fast_to_str_static(&l_pkey_signing);
-                dap_string_append_printf(a_str_out, "\tSigning pkey fingerprint: %s\n", l_pkey_signing_str);
+            }
+            dap_chain_addr_t *l_addr_fee_wallet = /*{ };
+            _dap_tsd_get_scalar(l_tsd, &l_addr_fee_wallet);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t);
+            dap_string_append_printf(a_str_out, "\tWallet for fee: %s\n", dap_chain_addr_to_str_static(l_addr_fee_wallet));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH:
+            if (l_tsd->size != sizeof(dap_hash_fast_t)) {
+                dap_string_append_printf(a_str_out, "\tHash: <WRONG SIZE>\n");
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
-                if (l_tsd->size != sizeof(dap_chain_node_addr_t)){
-                    dap_string_append_printf(a_str_out, "\tNode addr: <WRONG SIZE>\n");
-                    break;
-                }
-                dap_chain_node_addr_t *l_node_addr = _dap_tsd_get_object(l_tsd, dap_chain_node_addr_t);
-                dap_string_append_printf(a_str_out, "\tNode addr: "NODE_ADDR_FP_STR"\n",
-                                         NODE_ADDR_FP_ARGS(l_node_addr));
+            }
+            dap_hash_fast_t *l_stake_tx = /*{ };
+            _dap_tsd_get_scalar(l_tsd, &l_stake_tx);*/ _dap_tsd_get_object(l_tsd, dap_hash_fast_t);
+            const char *l_stake_tx_hash = dap_strcmp(a_hash_out_type, "hex")
+                ? dap_enc_base58_encode_hash_to_str_static(l_stake_tx)
+                : dap_chain_hash_fast_to_str_static(l_stake_tx);
+            dap_string_append_printf(a_str_out, "\tHash: %s\n", l_stake_tx_hash);
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE:
+            if (l_tsd->size != sizeof(uint256_t)){
+                dap_string_append_printf(a_str_out, "\tStake value: <WRONG SIZE>\n");
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE:
-                if (l_tsd->size != sizeof(uint256_t)) {
-                    dap_string_append_printf(a_str_out, "\tMin value: <WRONG SIZE>\n");
-                    break;
-                }
-                uint256_t l_min_value = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_min_value);
-                const char *l_min_value_str = dap_uint256_to_char(l_min_value, NULL);
-                dap_string_append_printf(a_str_out, "\tMin value: %s\n", l_min_value_str);
+            }
+            uint256_t l_stake_value = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_stake_value);
+            const char *l_stake_value_str = dap_uint256_to_char(l_stake_value, NULL);
+            dap_string_append_printf(a_str_out, "\tStake value: %s\n", l_stake_value_str);
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR:
+            if (l_tsd->size != sizeof(dap_chain_addr_t)) {
+                dap_string_append_printf(a_str_out, "\tSigning addr: <WRONG SIZE>\n");
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT:
-                if (l_tsd->size != sizeof(uint256_t)) {
-                    dap_string_append_printf(a_str_out, "\tMin signers count: <WRONG SIZE>\n");
-                    break;
-                }
-                uint256_t l_min_signers_count = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_min_signers_count);
-                const char *l_min_signers_count_str = dap_uint256_to_char(l_min_signers_count, NULL);
-                dap_string_append_printf(a_str_out, "\tMin signers count: %s\n", l_min_signers_count_str);
+            }
+            dap_chain_addr_t *l_stake_addr_signing = /*{ };
+            _dap_tsd_get_scalar(l_tsd, &l_stake_addr_signing);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t);
+            dap_string_append_printf(a_str_out, "\tSigning addr: %s\n", dap_chain_addr_to_str_static(l_stake_addr_signing));
+            dap_chain_hash_fast_t l_pkey_signing = l_stake_addr_signing->data.hash_fast;
+            const char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex")
+                    ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_signing)
+                    : dap_chain_hash_fast_to_str_static(&l_pkey_signing);
+            dap_string_append_printf(a_str_out, "\tSigning pkey fingerprint: %s\n", l_pkey_signing_str);
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
+            if (l_tsd->size != sizeof(dap_chain_node_addr_t)){
+                dap_string_append_printf(a_str_out, "\tNode addr: <WRONG SIZE>\n");
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING:
-                dap_string_append_printf(a_str_out, "\tHost address: %s\n", dap_tsd_get_string(l_tsd));
+            }
+            dap_chain_node_addr_t *l_node_addr = _dap_tsd_get_object(l_tsd, dap_chain_node_addr_t);
+            dap_string_append_printf(a_str_out, "\tNode addr: "NODE_ADDR_FP_STR"\n", NODE_ADDR_FP_ARGS(l_node_addr));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE:
+            if (l_tsd->size != sizeof(uint256_t)) {
+                dap_string_append_printf(a_str_out, "\tMin value: <WRONG SIZE>\n");
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION:
-                if (l_tsd->size != sizeof(uint8_t)){
-                    dap_string_append_printf(a_str_out, "\tAction: <WRONG SIZE>\n");
-                    break;
-                }
-                uint8_t l_action = 0;
-                _dap_tsd_get_scalar(l_tsd, &l_action);
-                dap_string_append_printf(a_str_out, "\tAction: %s\n", l_action ? "add (enable)" : "delete (disable)");
+            }
+            uint256_t l_min_value = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_min_value);
+            const char *l_min_value_str = dap_uint256_to_char(l_min_value, NULL);
+            dap_string_append_printf(a_str_out, "\tMin value: %s\n", l_min_value_str);
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT:
+            if (l_tsd->size != sizeof(uint256_t)) {
+                dap_string_append_printf(a_str_out, "\tMin signers count: <WRONG SIZE>\n");
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE:
-                if (l_tsd->size != sizeof(uint32_t)){
-                    dap_string_append_printf(a_str_out, "\tSignature type: <WRONG SIZE>\n");
-                    break;
-                }
-                uint32_t l_type = 0;
-                _dap_tsd_get_scalar(l_tsd, &l_type);
-                dap_sign_type_t l_sign_type = { .type = l_type };
-                dap_string_append_printf(a_str_out, "\tSignature type: %s\n", dap_sign_type_to_str(l_sign_type));
+            }
+            uint256_t l_min_signers_count = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_min_signers_count);
+            const char *l_min_signers_count_str = dap_uint256_to_char(l_min_signers_count, NULL);
+            dap_string_append_printf(a_str_out, "\tMin signers count: %s\n", l_min_signers_count_str);
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING:
+            dap_string_append_printf(a_str_out, "\tHost address: %s\n", dap_tsd_get_string(l_tsd));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION:
+            if (l_tsd->size != sizeof(uint8_t)){
+                dap_string_append_printf(a_str_out, "\tAction: <WRONG SIZE>\n");
                 break;
-            default:
-                dap_string_append_printf(a_str_out, "\t<UNKNOWN_TYPE_TSD_SECTION>\n");
+            }
+            uint8_t l_action = 0;
+            _dap_tsd_get_scalar(l_tsd, &l_action);
+            dap_string_append_printf(a_str_out, "\tAction: %s\n", l_action ? "add (enable)" : "delete (disable)");
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE:
+            if (l_tsd->size != sizeof(uint32_t)){
+                dap_string_append_printf(a_str_out, "\tSignature type: <WRONG SIZE>\n");
                 break;
+            }
+            uint32_t l_type = 0;
+            _dap_tsd_get_scalar(l_tsd, &l_type);
+            dap_sign_type_t l_sign_type = { .type = l_type };
+            dap_string_append_printf(a_str_out, "\tSignature type: %s\n", dap_sign_type_to_str(l_sign_type));
+            break;
+        default:
+            dap_string_append_printf(a_str_out, "\t<UNKNOWN_TYPE_TSD_SECTION>\n");
+            break;
         }
     }
     dap_chain_datum_decree_certs_dump(a_str_out, a_decree->data_n_signs + a_decree->header.data_size,
@@ -378,154 +374,151 @@ void dap_chain_datum_decree_dump_json(json_object *a_json_out, dap_chain_datum_d
     const char *l_subtype_str = dap_chain_datum_decree_subtype_to_str(a_decree->header.sub_type);
     json_object_object_add(a_json_out, "subtype", json_object_new_string(l_subtype_str));
     json_object_object_add(a_json_out, "TSD", json_object_new_string(""));
-    for (size_t l_offset = 0; l_offset < a_decree->header.data_size;) {
-        dap_tsd_t *l_tsd = (dap_tsd_t *)((byte_t*)a_decree->data_n_signs + l_offset);
-        l_offset += dap_tsd_size(l_tsd);
+    dap_tsd_t *l_tsd; size_t l_tsd_size;
+    dap_tsd_iter(l_tsd, l_tsd_size, a_decree->data_n_signs, a_decree->header.data_size) {
         switch(l_tsd->type) {
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE:
-                if (l_tsd->size > sizeof(uint256_t)){
-                    json_object_object_add(a_json_out, "Value", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                uint256_t l_value = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_value);
-                const char *l_value_str = dap_uint256_to_char(l_value, NULL);
-                json_object_object_add(a_json_out, "Value", json_object_new_string(l_value_str));
-                break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN:
-            break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE:
-                if (l_tsd->size > sizeof(uint256_t)){
-                    json_object_object_add(a_json_out, "Fee", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                uint256_t l_fee_value = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_fee_value);
-                const char *l_fee_value_str = dap_uint256_to_char(l_fee_value, NULL);
-                json_object_object_add(a_json_out, "Fee", json_object_new_string(l_fee_value_str));
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE:
+            if (l_tsd->size > sizeof(uint256_t)){
+                json_object_object_add(a_json_out, "Value", json_object_new_string("WRONG SIZE"));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER:
-                if (l_tsd->size < sizeof(dap_pkey_t)) {
-                    json_object_object_add(a_json_out, "Owner fingerprint", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                dap_pkey_t *l_owner_pkey = /*DAP_NEW_STACK_SIZE(dap_pkey_t, l_tsd->size);
-                memcpy(l_owner_pkey, l_tsd->data, l_tsd->size);*/ _dap_tsd_get_object(l_tsd, dap_pkey_t);
-                char *l_owner_pkey_str;
-                dap_get_data_hash_str_static(l_owner_pkey->pkey, l_owner_pkey->header.size, l_owner_pkey_str);
-                json_object_object_add(a_json_out, "Owner fingerprint", json_object_new_string(l_owner_pkey_str));
-                break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER:
-                if (l_tsd->size > sizeof(uint256_t)){
-                    json_object_object_add(a_json_out, "Owner min", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                uint256_t l_owner_min = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_owner_min);
-                const char *l_owner_min_str = dap_uint256_to_char(l_owner_min, NULL);
-                json_object_object_add(a_json_out, "Owner min", json_object_new_string(l_owner_min_str));
+            }
+            uint256_t l_value = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_value);
+            const char *l_value_str = dap_uint256_to_char(l_value, NULL);
+            json_object_object_add(a_json_out, "Value", json_object_new_string(l_value_str));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN:
+        break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE:
+            if (l_tsd->size > sizeof(uint256_t)){
+                json_object_object_add(a_json_out, "Fee", json_object_new_string("WRONG SIZE"));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET:
-                if (l_tsd->size > sizeof(dap_chain_addr_t)) {
-                    json_object_object_add(a_json_out, "Wallet for fee", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                dap_chain_addr_t *l_addr_fee_wallet = /*{ };
-                _dap_tsd_get_scalar(l_tsd, &l_addr_fee_wallet);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t);
-                json_object_object_add(a_json_out, "Wallet for fee", json_object_new_string(dap_chain_addr_to_str_static(l_addr_fee_wallet)));
+            }
+            uint256_t l_fee_value = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_fee_value);
+            const char *l_fee_value_str = dap_uint256_to_char(l_fee_value, NULL);
+            json_object_object_add(a_json_out, "Fee", json_object_new_string(l_fee_value_str));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER:
+            if (l_tsd->size < sizeof(dap_pkey_t)) {
+                json_object_object_add(a_json_out, "Owner fingerprint", json_object_new_string("WRONG SIZE"));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH:
-                if (l_tsd->size > sizeof(dap_hash_fast_t)) {
-                    json_object_object_add(a_json_out, "Stake tx", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                dap_hash_fast_t *l_stake_tx = /*{ };
-                _dap_tsd_get_scalar(l_tsd, &l_stake_tx);*/ _dap_tsd_get_object(l_tsd, dap_hash_fast_t);
-                const char *l_stake_tx_hash = dap_strcmp(a_hash_out_type, "hex")
-                        ? dap_enc_base58_encode_hash_to_str_static(l_stake_tx)
-                        : dap_chain_hash_fast_to_str_static(l_stake_tx);
-                json_object_object_add(a_json_out, "Stake tx", json_object_new_string(l_stake_tx_hash));
+            }
+            dap_pkey_t *l_owner_pkey = /*DAP_NEW_STACK_SIZE(dap_pkey_t, l_tsd->size);
+            memcpy(l_owner_pkey, l_tsd->data, l_tsd->size);*/ _dap_tsd_get_object(l_tsd, dap_pkey_t);
+            char *l_owner_pkey_str;
+            dap_get_data_hash_str_static(l_owner_pkey->pkey, l_owner_pkey->header.size, l_owner_pkey_str);
+            json_object_object_add(a_json_out, "Owner fingerprint", json_object_new_string(l_owner_pkey_str));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER:
+            if (l_tsd->size > sizeof(uint256_t)){
+                json_object_object_add(a_json_out, "Owner min", json_object_new_string("WRONG SIZE"));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE:
-                if (l_tsd->size > sizeof(uint256_t)){
-                    json_object_object_add(a_json_out, "Stake value", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                uint256_t l_stake_value = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_stake_value);
-                const char *l_stake_value_str = dap_uint256_to_char(l_stake_value, NULL);
-                json_object_object_add(a_json_out, "Stake value", json_object_new_string(l_stake_value_str));
+            }
+            uint256_t l_owner_min = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_owner_min);
+            const char *l_owner_min_str = dap_uint256_to_char(l_owner_min, NULL);
+            json_object_object_add(a_json_out, "Owner min", json_object_new_string(l_owner_min_str));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET:
+            if (l_tsd->size > sizeof(dap_chain_addr_t)) {
+                json_object_object_add(a_json_out, "Wallet for fee", json_object_new_string("WRONG SIZE"));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR:
-                if (l_tsd->size > sizeof(dap_chain_addr_t)) {
-                    json_object_object_add(a_json_out, "Signing addr", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                dap_chain_addr_t *l_stake_addr_signing = /*{ };
-                _dap_tsd_get_scalar(l_tsd, &l_stake_addr_signing);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t);
-                json_object_object_add(a_json_out, "Signing addr", json_object_new_string(dap_chain_addr_to_str_static(l_stake_addr_signing)));
-                dap_chain_hash_fast_t l_pkey_signing = l_stake_addr_signing->data.hash_fast;
-                const char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex")
-                        ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_signing)
-                        : dap_chain_hash_fast_to_str_static(&l_pkey_signing);
-                json_object_object_add(a_json_out, "Signing pkey fingerprint", json_object_new_string(l_pkey_signing_str));
+            }
+            dap_chain_addr_t *l_addr_fee_wallet = /*{ };
+            _dap_tsd_get_scalar(l_tsd, &l_addr_fee_wallet);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t);
+            json_object_object_add(a_json_out, "Wallet for fee", json_object_new_string(dap_chain_addr_to_str_static(l_addr_fee_wallet)));
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH:
+            if (l_tsd->size > sizeof(dap_hash_fast_t)) {
+                json_object_object_add(a_json_out, "Stake tx", json_object_new_string("WRONG SIZE"));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
-                if(l_tsd->size > sizeof(dap_chain_node_addr_t)){
-                    json_object_object_add(a_json_out, "Node addr", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                dap_chain_node_addr_t *l_node_addr = _dap_tsd_get_object(l_tsd, dap_chain_node_addr_t);
-                sprintf(l_tmp_buff, NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS(l_node_addr));
-                json_object_object_add(a_json_out, "Node addr", json_object_new_string(l_tmp_buff));
+            }
+            dap_hash_fast_t *l_stake_tx = /*{ };
+            _dap_tsd_get_scalar(l_tsd, &l_stake_tx);*/ _dap_tsd_get_object(l_tsd, dap_hash_fast_t);
+            const char *l_stake_tx_hash = dap_strcmp(a_hash_out_type, "hex")
+                    ? dap_enc_base58_encode_hash_to_str_static(l_stake_tx)
+                    : dap_chain_hash_fast_to_str_static(l_stake_tx);
+            json_object_object_add(a_json_out, "Stake tx", json_object_new_string(l_stake_tx_hash));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE:
+            if (l_tsd->size > sizeof(uint256_t)){
+                json_object_object_add(a_json_out, "Stake value", json_object_new_string("WRONG SIZE"));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE:
-                if (l_tsd->size > sizeof(uint256_t)) {
-                    json_object_object_add(a_json_out, "Min value", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                uint256_t l_min_value = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_min_value);
-                const char *l_min_value_str = dap_uint256_to_char(l_min_value, NULL);
-                json_object_object_add(a_json_out, "Min value", json_object_new_string(l_min_value_str));
+            }
+            uint256_t l_stake_value = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_stake_value);
+            const char *l_stake_value_str = dap_uint256_to_char(l_stake_value, NULL);
+            json_object_object_add(a_json_out, "Stake value", json_object_new_string(l_stake_value_str));
+            break;
+       case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR:
+            if (l_tsd->size > sizeof(dap_chain_addr_t)) {
+                json_object_object_add(a_json_out, "Signing addr", json_object_new_string("WRONG SIZE"));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT:
-                if (l_tsd->size > sizeof(uint256_t)) {
-                    json_object_object_add(a_json_out, "Min signers count", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                uint256_t l_min_signers_count = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_min_signers_count);
-                const char *l_min_signers_count_str = dap_uint256_to_char(l_min_signers_count, NULL);
-                json_object_object_add(a_json_out, "Min signers count", json_object_new_string(l_min_signers_count_str));
+            }
+            dap_chain_addr_t *l_stake_addr_signing = /*{ };
+            _dap_tsd_get_scalar(l_tsd, &l_stake_addr_signing);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t);
+            json_object_object_add(a_json_out, "Signing addr", json_object_new_string(dap_chain_addr_to_str_static(l_stake_addr_signing)));
+            dap_chain_hash_fast_t l_pkey_signing = l_stake_addr_signing->data.hash_fast;
+            const char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex")
+                    ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_signing)
+                    : dap_chain_hash_fast_to_str_static(&l_pkey_signing);
+            json_object_object_add(a_json_out, "Signing pkey fingerprint", json_object_new_string(l_pkey_signing_str));
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
+            if(l_tsd->size > sizeof(dap_chain_node_addr_t)){
+                json_object_object_add(a_json_out, "Node addr", json_object_new_string("WRONG SIZE"));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING:
-                json_object_object_add(a_json_out, "Host address", json_object_new_string(dap_tsd_get_string(l_tsd)));
+            }
+            dap_chain_node_addr_t *l_node_addr = _dap_tsd_get_object(l_tsd, dap_chain_node_addr_t);
+            sprintf(l_tmp_buff, NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS(l_node_addr));
+            json_object_object_add(a_json_out, "Node addr", json_object_new_string(l_tmp_buff));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE:
+            if (l_tsd->size > sizeof(uint256_t)) {
+                json_object_object_add(a_json_out, "Min value", json_object_new_string("WRONG SIZE"));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION:
-                if (l_tsd->size != sizeof(uint8_t)) {
-                    json_object_object_add(a_json_out, "Action", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                uint8_t l_action = 0;
-                _dap_tsd_get_scalar(l_tsd, &l_action);
-                json_object_object_add(a_json_out, "tAction", l_action ?
-                                           json_object_new_string("add (enable)") : json_object_new_string("delete (disable)"));
+            }
+            uint256_t l_min_value = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_min_value);
+            const char *l_min_value_str = dap_uint256_to_char(l_min_value, NULL);
+            json_object_object_add(a_json_out, "Min value", json_object_new_string(l_min_value_str));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT:
+            if (l_tsd->size > sizeof(uint256_t)) {
+                json_object_object_add(a_json_out, "Min signers count", json_object_new_string("WRONG SIZE"));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE:
-                if (l_tsd->size != sizeof(uint32_t)) {
-                    json_object_object_add(a_json_out, "Signature type", json_object_new_string("WRONG SIZE"));
-                    break;
-                }
-                uint32_t l_type = 0;
-                _dap_tsd_get_scalar(l_tsd, &l_type);
-                dap_sign_type_t l_sign_type = { .type = l_type };
-                json_object_object_add(a_json_out, "Signature type", json_object_new_string(dap_sign_type_to_str(l_sign_type)));
+            }
+            uint256_t l_min_signers_count = uint256_0;
+            _dap_tsd_get_scalar(l_tsd, &l_min_signers_count);
+            const char *l_min_signers_count_str = dap_uint256_to_char(l_min_signers_count, NULL);
+            json_object_object_add(a_json_out, "Min signers count", json_object_new_string(l_min_signers_count_str));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING:
+            json_object_object_add(a_json_out, "Host address", json_object_new_string(dap_tsd_get_string(l_tsd)));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION:
+            if (l_tsd->size != sizeof(uint8_t)) {
+                json_object_object_add(a_json_out, "Action", json_object_new_string("WRONG SIZE"));
                 break;
-            default:
-                json_object_object_add(a_json_out, "UNKNOWN_TYPE_TSD_SECTION", json_object_new_string(""));
+            }
+            uint8_t l_action = 0;
+            _dap_tsd_get_scalar(l_tsd, &l_action);
+            json_object_object_add(a_json_out, "tAction", l_action ?
+                                        json_object_new_string("add (enable)") : json_object_new_string("delete (disable)"));
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE:
+            if (l_tsd->size != sizeof(uint32_t)) {
+                json_object_object_add(a_json_out, "Signature type", json_object_new_string("WRONG SIZE"));
                 break;
+            }
+            uint32_t l_type = 0;
+            _dap_tsd_get_scalar(l_tsd, &l_type);
+            dap_sign_type_t l_sign_type = { .type = l_type };
+            json_object_object_add(a_json_out, "Signature type", json_object_new_string(dap_sign_type_to_str(l_sign_type)));
+            break;
+        default:
+            json_object_object_add(a_json_out, "UNKNOWN_TYPE_TSD_SECTION", json_object_new_string(""));
+            break;
         }
     }
     dap_chain_datum_decree_certs_dump_json(a_json_out, a_decree->data_n_signs + a_decree->header.data_size,
diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c
index f3a442a4189620c66144907d8057be89c22760a2..6383d27db0479a2dd3bc5989408c38783f10b479 100644
--- a/modules/common/dap_chain_datum_token.c
+++ b/modules/common/dap_chain_datum_token.c
@@ -403,16 +403,16 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_add_tsd(dap_chain_dat
 
 byte_t *dap_chain_emission_get_tsd(dap_chain_datum_token_emission_t *a_emission, int a_type, size_t *a_size)
 {
+    if (a_size)
+        *a_size = 0;
     if (!a_emission || a_emission->hdr.type != DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH ||
             a_emission->data.type_auth.tsd_total_size == 0)
         return NULL;
-    dap_tsd_t *l_tsd = NULL;
-    if (!(l_tsd = dap_tsd_find(a_emission->tsd_n_signs, a_emission->data.type_auth.tsd_total_size, a_type))) {
+    dap_tsd_t *l_tsd = dap_tsd_find(a_emission->tsd_n_signs, a_emission->data.type_auth.tsd_total_size, a_type);
+    if (!l_tsd)
         return NULL;
-    } else {
-        if (a_size)
-            *a_size = l_tsd->size;
-    }
+    else if (a_size)
+        *a_size = l_tsd->size;
     return l_tsd->data;
 }
 
diff --git a/modules/common/dap_chain_datum_tx.c b/modules/common/dap_chain_datum_tx.c
index 38d7ac9670839eccb3bdca241a9cd954a8e1d07b..da5891bf377eb70149dbca855fd49261f1523fb3 100644
--- a/modules/common/dap_chain_datum_tx.c
+++ b/modules/common/dap_chain_datum_tx.c
@@ -40,12 +40,9 @@
 dap_chain_datum_tx_t* dap_chain_datum_tx_create(void)
 {
     dap_chain_datum_tx_t *tx = DAP_NEW_Z(dap_chain_datum_tx_t);
-    if (!tx) {
-        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-        return 0;
-    }
-    tx->header.ts_created = time(NULL);
-    return tx;
+    return tx 
+        ? tx->header.ts_created = time(NULL), tx
+        : ( log_it(L_CRITICAL, "%s", c_error_memory_alloc), NULL );
 }
 
 /**
@@ -53,8 +50,7 @@ dap_chain_datum_tx_t* dap_chain_datum_tx_create(void)
  */
 void dap_chain_datum_tx_delete(dap_chain_datum_tx_t *a_tx)
 {
-    if(a_tx)
-        DAP_DELETE(a_tx);
+    DAP_DELETE(a_tx);
 }
 
 /**
@@ -64,9 +60,7 @@ void dap_chain_datum_tx_delete(dap_chain_datum_tx_t *a_tx)
  */
 size_t dap_chain_datum_tx_get_size(dap_chain_datum_tx_t *a_tx)
 {
-    if(!a_tx)
-        return 0;
-    return (sizeof(dap_chain_datum_tx_t) + a_tx->header.tx_items_size);
+    return a_tx ? sizeof(dap_chain_datum_tx_t) + a_tx->header.tx_items_size : 0;
 }
 
 /**
@@ -76,35 +70,30 @@ size_t dap_chain_datum_tx_get_size(dap_chain_datum_tx_t *a_tx)
  */
 int dap_chain_datum_tx_add_item(dap_chain_datum_tx_t **a_tx, const void *a_item)
 {
-    size_t size = dap_chain_datum_item_tx_get_size(a_item);
-    if(!size || !a_tx || !*a_tx)
-        return -1;
-    dap_chain_datum_tx_t *tx_cur = *a_tx;
-    size_t l_new_size = dap_chain_datum_tx_get_size(tx_cur) + size;
-    tx_cur = (dap_chain_datum_tx_t*)DAP_REALLOC(tx_cur, l_new_size);
-    if (!tx_cur)
+    size_t size = 0;
+    if ( !a_tx || !*a_tx || !(size = dap_chain_datum_item_tx_get_size(a_item, 0)) )
         return -1;
-    memcpy((uint8_t*) tx_cur->tx_items + tx_cur->header.tx_items_size, a_item, size);
-    tx_cur->header.tx_items_size += size;
-    *a_tx = tx_cur;
+    dap_chain_datum_tx_t *tx_new = DAP_REALLOC( *a_tx, dap_chain_datum_tx_get_size(*a_tx) + size );
+    if (!tx_new)
+        return -2;
+    memcpy((uint8_t*) tx_new->tx_items + tx_new->header.tx_items_size, a_item, size);
+    tx_new->header.tx_items_size += size;
+    *a_tx = tx_new;
     return 1;
 }
 
+#define dap_chain_datum_tx_add_new_generic(a_tx, type, a_item) \
+    ({ type* item = a_item; item ? ( dap_chain_datum_tx_add_item(a_tx, item), DAP_DELETE(item), 1 ) : -1; })
+
 /**
  * Create 'in' item and insert to transaction
  *
  * return 1 Ok, -1 Error
  */
-int dap_chain_datum_tx_add_in_item(dap_chain_datum_tx_t **a_tx, dap_chain_hash_fast_t *a_tx_prev_hash,
-        uint32_t a_tx_out_prev_idx)
+int dap_chain_datum_tx_add_in_item(dap_chain_datum_tx_t **a_tx, dap_chain_hash_fast_t *a_tx_prev_hash, uint32_t a_tx_out_prev_idx)
 {
-    dap_chain_tx_in_t *l_tx_in = dap_chain_datum_tx_item_in_create(a_tx_prev_hash, a_tx_out_prev_idx);
-    if(l_tx_in) {
-        dap_chain_datum_tx_add_item(a_tx, (const uint8_t *)l_tx_in);
-        DAP_DELETE(l_tx_in);
-        return 1;
-    }
-    return -1;
+    return dap_chain_datum_tx_add_new_generic( a_tx, dap_chain_tx_in_t,
+        dap_chain_datum_tx_item_in_create(a_tx_prev_hash, a_tx_out_prev_idx) );
 }
 
 /**
@@ -138,13 +127,8 @@ int dap_chain_datum_tx_add_in_cond_item(dap_chain_datum_tx_t **a_tx, dap_chain_h
                                         uint32_t a_tx_out_prev_idx,
                                         uint32_t a_receipt_idx)
 {
-    dap_chain_tx_in_cond_t *l_tx_in_cond
-            = dap_chain_datum_tx_item_in_cond_create(a_tx_prev_hash, a_tx_out_prev_idx, a_receipt_idx);
-    if (!l_tx_in_cond)
-        return -1;
-    dap_chain_datum_tx_add_item(a_tx, (uint8_t*)l_tx_in_cond);
-    DAP_DELETE(l_tx_in_cond);
-    return 0;
+    return dap_chain_datum_tx_add_new_generic( a_tx, dap_chain_tx_in_cond_t,
+        dap_chain_datum_tx_item_in_cond_create(a_tx_prev_hash, a_tx_out_prev_idx, a_receipt_idx) );
 }
 
 uint256_t dap_chain_datum_tx_add_in_cond_item_list(dap_chain_datum_tx_t **a_tx, dap_list_t *a_list_used_out_cound)
@@ -153,7 +137,7 @@ uint256_t dap_chain_datum_tx_add_in_cond_item_list(dap_chain_datum_tx_t **a_tx,
    uint256_t l_value_to_items = { };
    DL_FOREACH(a_list_used_out_cound, l_item_out) {
        dap_chain_tx_used_out_item_t *l_item = l_item_out->data;
-       if (!dap_chain_datum_tx_add_in_cond_item(a_tx, &l_item->tx_hash_fast, l_item->num_idx_out,0)) {
+       if (1 == dap_chain_datum_tx_add_in_cond_item(a_tx, &l_item->tx_hash_fast, l_item->num_idx_out,0)) {
            SUM_256_256(l_value_to_items, l_item->value, &l_value_to_items);
        }
    }
@@ -162,12 +146,8 @@ uint256_t dap_chain_datum_tx_add_in_cond_item_list(dap_chain_datum_tx_t **a_tx,
 
 int dap_chain_datum_tx_add_in_reward_item(dap_chain_datum_tx_t **a_tx, dap_chain_hash_fast_t *a_block_hash)
 {
-    dap_chain_tx_in_reward_t *l_tx_in_reward = dap_chain_datum_tx_item_in_reward_create(a_block_hash);
-    if (!l_tx_in_reward)
-        return -1;
-    dap_chain_datum_tx_add_item(a_tx, (uint8_t*)l_tx_in_reward);
-    DAP_DELETE(l_tx_in_reward);
-    return 1;
+    return dap_chain_datum_tx_add_new_generic( a_tx, dap_chain_tx_in_reward_t,
+        dap_chain_datum_tx_item_in_reward_create(a_block_hash) );
 }
 
 /**
@@ -177,46 +157,33 @@ int dap_chain_datum_tx_add_in_reward_item(dap_chain_datum_tx_t **a_tx, dap_chain
  */
 int dap_chain_datum_tx_add_fee_item(dap_chain_datum_tx_t **a_tx, uint256_t a_value)
 {
-    dap_chain_tx_out_cond_t *l_tx_out_fee = dap_chain_datum_tx_item_out_cond_create_fee(a_value);
-    if (l_tx_out_fee) {
-        dap_chain_datum_tx_add_item(a_tx, (const uint8_t *)l_tx_out_fee);
-        DAP_DELETE(l_tx_out_fee);
-        return 1;
-    }
-    return -1;
+    return dap_chain_datum_tx_add_new_generic( a_tx, dap_chain_tx_out_cond_t,
+        dap_chain_datum_tx_item_out_cond_create_fee(a_value) );
 }
 
 int dap_chain_datum_tx_get_fee_value(dap_chain_datum_tx_t *a_tx, uint256_t *a_value)
 {
     if (!a_value)
         return -2;
-    int l_ret = -1;
-    dap_list_t *l_items_list = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_COND, NULL), *l_item;
-    DL_FOREACH(l_items_list, l_item) {
-        dap_chain_tx_out_cond_t *l_out_item = (dap_chain_tx_out_cond_t*)l_item->data;
-        if (l_out_item->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE){
-            *a_value = l_out_item->header.value;
-            l_ret = 0;
+    byte_t *l_item; size_t l_tx_item_size;
+    dap_chain_tx_out_cond_t *l_out_item;
+    TX_ITEM_ITER_TX(l_item, l_tx_item_size, a_tx) {
+        switch (*l_item) {
+        case TX_ITEM_TYPE_OUT_COND:
+            l_out_item = (dap_chain_tx_out_cond_t*)l_item;
+            if (l_out_item->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE)
+                return (*a_value = l_out_item->header.value), 0;
+        default:
             break;
         }
     }
-    dap_list_free(l_items_list);
-    return l_ret;
+    return -1;
 }
 
 dap_sign_t *dap_chain_datum_tx_get_sign(dap_chain_datum_tx_t *a_tx, int a_sign_num)
 {
     dap_return_val_if_fail(a_tx, NULL);
-    if (!a_sign_num) {
-        dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
-        return dap_chain_datum_tx_item_sign_get_sig(l_tx_sig);
-    }
-    dap_list_t *l_items_list = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_SIG, NULL);
-    if (dap_list_length(l_items_list) <= (uint64_t)a_sign_num)
-        return NULL;
-    dap_sign_t *l_ret = dap_list_nth_data(l_items_list, a_sign_num);
-    dap_list_free(l_items_list);
-    return l_ret;
+    return dap_chain_datum_tx_item_sign_get_sig( (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get_nth(a_tx, TX_ITEM_TYPE_SIG, a_sign_num) );
 }
 
 /**
@@ -226,13 +193,8 @@ dap_sign_t *dap_chain_datum_tx_get_sign(dap_chain_datum_tx_t *a_tx, int a_sign_n
  */
 int dap_chain_datum_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint256_t a_value)
 {
-    dap_chain_tx_out_t *l_tx_out = dap_chain_datum_tx_item_out_create(a_addr, a_value);
-    if(l_tx_out) {
-        dap_chain_datum_tx_add_item(a_tx, (const uint8_t *)l_tx_out);
-        DAP_DELETE(l_tx_out);
-        return 1;
-    }
-    return -1;
+    return dap_chain_datum_tx_add_new_generic( a_tx, dap_chain_tx_out_t,
+        dap_chain_datum_tx_item_out_create(a_addr, a_value) );
 }
 
 /**
@@ -242,13 +204,8 @@ int dap_chain_datum_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain
  */
 int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint256_t a_value, const char *a_token)
 {
-    dap_chain_tx_out_ext_t *l_tx_out = dap_chain_datum_tx_item_out_ext_create(a_addr, a_value, a_token);
-    if(l_tx_out) {
-        dap_chain_datum_tx_add_item(a_tx, (const uint8_t *)l_tx_out);
-        DAP_DELETE(l_tx_out);
-        return 1;
-    }
-    return -1;
+    return dap_chain_datum_tx_add_new_generic( a_tx, dap_chain_tx_out_ext_t,
+        dap_chain_datum_tx_item_out_ext_create(a_addr, a_value, a_token) );
 }
 
 /**
@@ -259,14 +216,8 @@ int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_c
 int dap_chain_datum_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_pkey_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
         uint256_t a_value, uint256_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, const void *a_cond, size_t a_cond_size)
 {
-    dap_chain_tx_out_cond_t *l_tx_out = dap_chain_datum_tx_item_out_cond_create_srv_pay(
-                a_key, a_srv_uid,a_value, a_value_max_per_unit, a_unit, a_cond, a_cond_size );
-    if(l_tx_out) {
-        dap_chain_datum_tx_add_item(a_tx, (const uint8_t *) l_tx_out);
-        DAP_DELETE(l_tx_out);
-        return 1;
-    }
-    return -1;
+    return dap_chain_datum_tx_add_new_generic( a_tx, dap_chain_tx_out_cond_t,
+        dap_chain_datum_tx_item_out_cond_create_srv_pay( a_key, a_srv_uid,a_value, a_value_max_per_unit, a_unit, a_cond, a_cond_size ));
 }
 
 
@@ -277,18 +228,8 @@ int dap_chain_datum_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_pkey_t
  */
 int dap_chain_datum_tx_add_sign_item(dap_chain_datum_tx_t **a_tx, dap_enc_key_t *a_key)
 {
-    if(!a_tx || !a_key)
-        return -1;
-    // sign all previous items in transaction
-    const void *l_data = (*a_tx)->tx_items;
-    const size_t l_data_size = (*a_tx)->header.tx_items_size;
-    dap_chain_tx_sig_t *l_tx_sig = dap_chain_datum_tx_item_sign_create(a_key, l_data, l_data_size);
-    if(l_tx_sig) {
-        int l_ret = dap_chain_datum_tx_add_item(a_tx, (const uint8_t*) l_tx_sig);
-        DAP_DELETE(l_tx_sig);
-        return l_ret;
-    }
-    return -1;
+    return a_tx && a_key ? dap_chain_datum_tx_add_new_generic( a_tx, dap_chain_tx_sig_t,
+        dap_chain_datum_tx_item_sign_create( a_key, (*a_tx)->tx_items, (*a_tx)->header.tx_items_size )) : -1;
 }
 
 /**
@@ -300,32 +241,17 @@ int dap_chain_datum_tx_verify_sign(dap_chain_datum_tx_t *a_tx)
 {
     dap_return_val_if_pass(!a_tx, -1);
     int l_ret = 0;
-    uint32_t tx_items_pos = 0, tx_items_size = a_tx->header.tx_items_size;
-    while(tx_items_pos < tx_items_size) {
-        uint8_t *item = a_tx->tx_items + tx_items_pos;
-        size_t l_item_tx_size = dap_chain_datum_item_tx_get_size(item);
-        if(!l_item_tx_size || l_item_tx_size > tx_items_size)
-            return -2;
-        if(dap_chain_datum_tx_item_get_type(item) == TX_ITEM_TYPE_SIG) {
-            dap_chain_tx_sig_t *l_item_tx_sig = (dap_chain_tx_sig_t*) item;
-            dap_sign_t *l_sign = (dap_sign_t*) l_item_tx_sig->sig;
-            if ( ( l_sign->header.sign_size + l_sign->header.sign_pkey_size +sizeof (l_sign->header) )
-                  > l_item_tx_size ){
-                log_it(L_WARNING,"Incorrect signature's header, possible corrupted data");
-                return -3;
-            }
-            if ((l_ret = dap_sign_verify_all(l_sign, tx_items_size, a_tx->tx_items, tx_items_pos))) {
-                // invalid signature
-                tx_items_pos += l_item_tx_size;
+    byte_t *l_item; size_t l_size;
+    dap_sign_t *l_sign;
+    TX_ITEM_ITER_TX(l_item, l_size, a_tx) {
+        if (*l_item == TX_ITEM_TYPE_SIG) {
+            l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*)l_item);
+            const size_t l_offset = (size_t)(l_item - a_tx->tx_items);
+            if ( 0 != ( l_ret = dap_sign_get_size(l_sign) > l_size
+                    ? log_it(L_WARNING, "Incorrect signature header, possible corrupted data"), -3
+                    : dap_sign_verify_all(l_sign, a_tx->header.tx_items_size - l_offset, a_tx->tx_items, l_offset) ))
                 break;
-            }
         }
-        // sign item or items must be at the end, therefore ret will be changed later anyway
-        else
-            l_ret = -4;
-        // go to text item
-        tx_items_pos += l_item_tx_size;
     }
-    assert(tx_items_pos == tx_items_size);
     return l_ret;
 }
diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c
index 68fb6e0e49f2806c0bb32518922eaa7a3b883682..6bcc83c9e4325fe0750c24cbed8c92c97c725687 100644
--- a/modules/common/dap_chain_datum_tx_items.c
+++ b/modules/common/dap_chain_datum_tx_items.c
@@ -36,98 +36,6 @@
 
 #define LOG_TAG "dap_chain_datum_tx_items"
 
-static size_t dap_chain_tx_in_get_size(const dap_chain_tx_in_t *a_item)
-{
-    (void) a_item;
-    size_t size = sizeof(dap_chain_tx_in_t); // + item->header.sig_size;
-    return size;
-}
-
-static size_t dap_chain_tx_in_cond_get_size(const dap_chain_tx_in_cond_t *a_item)
-{
-    UNUSED(a_item);
-    size_t size = sizeof(dap_chain_tx_in_cond_t);
-    return size;
-}
-
-static size_t dap_chain_tx_out_old_get_size(const dap_chain_tx_out_old_t *a_item)
-{
-    (void) a_item;
-    size_t size = sizeof(dap_chain_tx_out_old_t);
-    return size;
-}
-
-// 256
-static size_t dap_chain_tx_out_get_size(const dap_chain_tx_out_t *a_item)
-{
-    (void) a_item;
-    size_t size = sizeof(dap_chain_tx_out_t);
-    return size;
-}
-
-// 256
-static size_t dap_chain_tx_out_ext_get_size(const dap_chain_tx_out_ext_t *a_item)
-{
-    (void) a_item;
-    size_t size = sizeof(dap_chain_tx_out_ext_t);
-    return size;
-}
-
-static size_t dap_chain_tx_out_cond_get_size(const dap_chain_tx_out_cond_t *a_item)
-{
-    size_t size = sizeof(dap_chain_tx_out_cond_t) + a_item->tsd_size;
-    return size;
-}
-
-static size_t dap_chain_tx_pkey_get_size(const dap_chain_tx_pkey_t *a_item)
-{
-    size_t size = sizeof(dap_chain_tx_pkey_t) + a_item->header.sig_size;
-    return size;
-}
-
-static size_t dap_chain_tx_sig_get_size(const dap_chain_tx_sig_t *a_item)
-{
-    size_t size = sizeof(dap_chain_tx_sig_t) + a_item->header.sig_size;
-    return size;
-}
-
-static size_t dap_chain_tx_in_ems_get_size(const dap_chain_tx_in_ems_t *a_item)
-{
-    (void) a_item;
-    size_t size = sizeof(dap_chain_tx_in_ems_t);
-    return size;
-}
-
-static size_t dap_chain_tx_in_reward_get_size(const dap_chain_tx_in_reward_t UNUSED_ARG *a_item)
-{
-    size_t size = sizeof(dap_chain_tx_in_reward_t);
-    return size;
-}
-
-static size_t dap_chain_datum_tx_receipt_get_size(const dap_chain_datum_tx_receipt_t *a_item)
-{
-    size_t size = a_item->size;
-    return size;
-}
-
-static size_t dap_chain_tx_tsd_get_size(const dap_chain_tx_tsd_t *a_item)
-{
-    return sizeof(dap_chain_tx_tsd_t) + a_item->header.size;
-}
-
-static size_t dap_chain_tx_voting_get_size(const dap_chain_tx_voting_t *a_item)
-{
-    (void) a_item;
-    size_t size = sizeof(dap_chain_tx_voting_t);
-    return size;
-}
-
-static size_t dap_chain_tx_vote_get_size(const dap_chain_tx_vote_t *a_item)
-{
-    (void) a_item;
-    size_t size = sizeof(dap_chain_tx_vote_t);
-    return size;
-}
 /**
  * Get item type by item name
  *
@@ -188,73 +96,45 @@ dap_chain_tx_out_cond_subtype_t dap_chain_tx_out_cond_subtype_from_str(const cha
     return DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED;
 }
 
-/**
- * Get item type
- *
- * return type, or TX_ITEM_TYPE_ANY if error
- */
-dap_chain_tx_item_type_t dap_chain_datum_tx_item_get_type(const void *a_item)
-{
-    dap_chain_tx_item_type_t type = a_item ? *(dap_chain_tx_item_type_t *)a_item : TX_ITEM_TYPE_UNKNOWN;
-    return type;
-}
-
 /**
  * Get item size
  *
  * return size, 0 Error
  */
-size_t dap_chain_datum_item_tx_get_size(const void *a_item)
-{
-    dap_chain_tx_item_type_t type = dap_chain_datum_tx_item_get_type(a_item);
-    size_t size = 0;
-    switch (type) {
-    case TX_ITEM_TYPE_IN: // Transaction inputs
-        size = dap_chain_tx_in_get_size((const dap_chain_tx_in_t*) a_item);
-        break;
-    case TX_ITEM_TYPE_OUT_OLD: //64
-        size = dap_chain_tx_out_old_get_size((const dap_chain_tx_out_old_t*) a_item);
-        break;
-    case TX_ITEM_TYPE_OUT: // Transaction outputs
-        size = dap_chain_tx_out_get_size((const dap_chain_tx_out_t*) a_item);
-        break;
-    case TX_ITEM_TYPE_OUT_EXT: // Exchange transaction outputs
-        size = dap_chain_tx_out_ext_get_size((const dap_chain_tx_out_ext_t*) a_item);
-        break;
-    case TX_ITEM_TYPE_RECEIPT: // Receipt:
-        size = dap_chain_datum_tx_receipt_get_size((const dap_chain_datum_tx_receipt_t *)a_item);
-        break;
-    case TX_ITEM_TYPE_IN_COND: // Transaction inputs with condition
-        size = dap_chain_tx_in_cond_get_size((const dap_chain_tx_in_cond_t*) a_item);
-        break;
-    case TX_ITEM_TYPE_OUT_COND: // Condtional output
-        size = dap_chain_tx_out_cond_get_size((const dap_chain_tx_out_cond_t *)a_item);
-        break;
-    case TX_ITEM_TYPE_PKEY: // Transaction public keys
-        size = dap_chain_tx_pkey_get_size((const dap_chain_tx_pkey_t*) a_item);
-        break;
-    case TX_ITEM_TYPE_SIG: // Transaction signatures
-        size = dap_chain_tx_sig_get_size((const dap_chain_tx_sig_t*) a_item);
-        break;
-    case TX_ITEM_TYPE_IN_EMS: // token emission pointer
-        size = dap_chain_tx_in_ems_get_size((const dap_chain_tx_in_ems_t*) a_item);
-        break;
-    case TX_ITEM_TYPE_IN_REWARD: // block emission pointer
-        size = dap_chain_tx_in_reward_get_size((const dap_chain_tx_in_reward_t *)a_item);
-        break;
-    case TX_ITEM_TYPE_TSD:
-        size = dap_chain_tx_tsd_get_size((const dap_chain_tx_tsd_t*)a_item);
-        break;
-    case TX_ITEM_TYPE_VOTING:
-        size = dap_chain_tx_voting_get_size((const dap_chain_tx_voting_t*)a_item);
-        break;
-    case TX_ITEM_TYPE_VOTE:
-        size = dap_chain_tx_vote_get_size((const dap_chain_tx_vote_t*)a_item);
-        break;
-    default:
-        return 0;
+
+size_t dap_chain_datum_item_tx_get_size(const byte_t *a_item, size_t a_max_size) {
+    dap_return_val_if_fail(a_item, TX_ITEM_TYPE_UNKNOWN);
+    size_t l_ret = 0;
+#define m_tx_item_size(t) ( !a_max_size || sizeof(t) <= a_max_size ? sizeof(t) : 0 )
+#define m_tx_item_size_ext(t, size_field)                                                                                       \
+    ( !a_max_size ||                                                                                                            \
+    ( sizeof(t) < a_max_size && a_max_size > ((t*)a_item)->size_field && sizeof(t) <= a_max_size - ((t*)a_item)->size_field )   \
+        ? sizeof(t) + ((t*)a_item)->size_field : 0 );
+
+    switch (*a_item) {
+    case TX_ITEM_TYPE_IN:       return m_tx_item_size(dap_chain_tx_in_t);
+    case TX_ITEM_TYPE_OUT_OLD:  return m_tx_item_size(dap_chain_tx_out_old_t);
+    case TX_ITEM_TYPE_OUT:      return m_tx_item_size(dap_chain_tx_out_t);
+    case TX_ITEM_TYPE_OUT_EXT:  return m_tx_item_size(dap_chain_tx_out_ext_t);
+    case TX_ITEM_TYPE_IN_COND:  return m_tx_item_size(dap_chain_tx_in_cond_t);
+    case TX_ITEM_TYPE_IN_EMS:   return m_tx_item_size(dap_chain_tx_in_ems_t);
+    case TX_ITEM_TYPE_IN_REWARD:return m_tx_item_size(dap_chain_tx_in_reward_t);
+    case TX_ITEM_TYPE_VOTING:   return m_tx_item_size(dap_chain_tx_voting_t);
+    case TX_ITEM_TYPE_VOTE:     return m_tx_item_size(dap_chain_tx_vote_t);
+    // Access data size by struct field
+    case TX_ITEM_TYPE_TSD:           return m_tx_item_size_ext(dap_chain_tx_tsd_t, header.size);
+    case TX_ITEM_TYPE_OUT_COND: return m_tx_item_size_ext(dap_chain_tx_out_cond_t, tsd_size);
+    case TX_ITEM_TYPE_PKEY:         return m_tx_item_size_ext(dap_chain_tx_pkey_t, header.sig_size);
+    case TX_ITEM_TYPE_SIG:           return m_tx_item_size_ext(dap_chain_tx_sig_t, header.sig_size);
+    // Receipt size calculation is non-trivial...
+    case TX_ITEM_TYPE_RECEIPT: {
+        typedef dap_chain_datum_tx_receipt_t t;
+        return !a_max_size || ( sizeof(t) < a_max_size && ((t*)a_item)->size < a_max_size ) ? ((t*)a_item)->size : 0;
     }
-    return size;
+    default: return 0;
+    }
+#undef m_tx_item_size
+#undef m_tx_item_size_ext
 }
 
 /**
@@ -542,7 +422,7 @@ dap_chain_tx_sig_t* dap_chain_datum_tx_item_sign_create(dap_enc_key_t *a_key, co
  */
 dap_sign_t* dap_chain_datum_tx_item_sign_get_sig(dap_chain_tx_sig_t *a_tx_sig)
 {
-    return a_tx_sig && a_tx_sig->header.sig_size ? (dap_sign_t*)a_tx_sig->sig : NULL;
+    return a_tx_sig && a_tx_sig->header.sig_size > sizeof(dap_sign_t) ? (dap_sign_t*)a_tx_sig->sig : NULL;
 }
 
 /**
@@ -571,41 +451,49 @@ byte_t *dap_chain_datum_tx_item_get_data(dap_chain_tx_tsd_t *a_tx_tsd, int *a_ty
  * return item data, NULL Error index or bad format transaction
  */
 uint8_t* dap_chain_datum_tx_item_get( dap_chain_datum_tx_t *a_tx, int *a_item_idx,
-        dap_chain_tx_item_type_t a_type, int *a_item_out_size)
-{
-    if(!a_tx)
-        return NULL;
-    uint32_t l_tx_items_pos = 0, l_tx_items_size = a_tx->header.tx_items_size;
-    int l_item_idx = 0;
-    while (l_tx_items_pos < l_tx_items_size) {
-        uint8_t *l_item = a_tx->tx_items + l_tx_items_pos;
-        int l_item_size = dap_chain_datum_item_tx_get_size(l_item);
-        if(!l_item_size)
-            return NULL;
-        // check index
-        if(!a_item_idx || l_item_idx >= *a_item_idx) {
-            // check type
-            dap_chain_tx_item_type_t l_type = dap_chain_datum_tx_item_get_type(l_item);
-            if (a_type == TX_ITEM_TYPE_ANY || a_type == l_type ||
-                    (a_type == TX_ITEM_TYPE_OUT_ALL && l_type == TX_ITEM_TYPE_OUT) ||
-                    (a_type == TX_ITEM_TYPE_OUT_ALL && l_type == TX_ITEM_TYPE_OUT_OLD) ||
-                    (a_type == TX_ITEM_TYPE_OUT_ALL && l_type == TX_ITEM_TYPE_OUT_COND) ||
-                    (a_type == TX_ITEM_TYPE_OUT_ALL && l_type == TX_ITEM_TYPE_OUT_EXT) ||
-                    (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN) ||
-                    (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN_COND) ||
-                    (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN_EMS) ||
-                    (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN_REWARD)) {
-                if(a_item_idx)
-                    *a_item_idx = l_item_idx;
-                if(a_item_out_size)
-                    *a_item_out_size = l_item_size;
-                return l_item;
-            }
+        byte_t *a_iter, dap_chain_tx_item_type_t a_type, size_t *a_item_out_size)
+{
+    if (!a_tx)
+        return NULL;
+    int i = a_item_idx ? *a_item_idx : 0, j = -1;
+    byte_t  *l_end = a_tx->tx_items + a_tx->header.tx_items_size,
+            *l_begin = i || !a_iter || a_iter < a_tx->tx_items || a_iter > l_end ? a_tx->tx_items : a_iter;
+    size_t l_left_size = (size_t)(l_end - l_begin), l_tx_item_size;
+    byte_t *l_item;
+#define m_item_idx_n_size(item, idx, size) ({       \
+    if (a_item_idx) *a_item_idx = idx;              \
+    if (a_item_out_size) *a_item_out_size = size;   \
+    item;                                           \
+})
+    TX_ITEM_ITER(l_item, l_tx_item_size, l_begin, l_left_size) {
+        if (++j < i)
+            continue;
+        switch (a_type) {
+        case TX_ITEM_TYPE_ANY:
+            break;
+        case TX_ITEM_TYPE_OUT_ALL:
+            switch (*l_item) {
+            case TX_ITEM_TYPE_OUT: case TX_ITEM_TYPE_OUT_OLD: case TX_ITEM_TYPE_OUT_COND: case TX_ITEM_TYPE_OUT_EXT:
+                break;
+            default:
+                continue;
+            } break;
+        case TX_ITEM_TYPE_IN_ALL:
+            switch (*l_item) {
+            case TX_ITEM_TYPE_IN: case TX_ITEM_TYPE_IN_COND: case TX_ITEM_TYPE_IN_EMS: case TX_ITEM_TYPE_IN_REWARD:
+                break;
+            default:
+                continue; 
+            } break;
+        default:
+            if (*l_item == a_type)
+                break;
+            else continue;
         }
-        l_tx_items_pos += l_item_size;
-        l_item_idx++;
+        return m_item_idx_n_size(l_item, j, l_tx_item_size);
     }
-    return NULL;
+    return m_item_idx_n_size(NULL, -1, 0);
+#undef m_item_idx_n_size
 }
 
 /**
@@ -619,33 +507,23 @@ uint8_t* dap_chain_datum_tx_item_get( dap_chain_datum_tx_t *a_tx, int *a_item_id
 dap_list_t* dap_chain_datum_tx_items_get(dap_chain_datum_tx_t *a_tx, dap_chain_tx_item_type_t a_type, int *a_item_count)
 {
     dap_list_t *items_list = NULL;
-    int l_items_count = 0, l_item_idx_start = 0;
-    uint8_t *l_tx_item;
-
-    // Get a_type items from transaction
-    while ((l_tx_item = dap_chain_datum_tx_item_get(a_tx, &l_item_idx_start, a_type, NULL)) != NULL)
-    {
+    uint8_t *l_tx_item = NULL;
+    size_t l_size; int i, q = 0;
+    TX_ITEM_ITER_TX_TYPE(l_tx_item, a_type, l_size, i, a_tx) {
         items_list = dap_list_append(items_list, l_tx_item);
-        ++l_items_count;
-        ++l_item_idx_start;
+        ++q;
     }
-
-    if(a_item_count)
-        *a_item_count = l_items_count;
-
-    return items_list;
+    return (a_item_count ? (*a_item_count = q) : 0), items_list;
 }
 
 uint8_t *dap_chain_datum_tx_item_get_nth(dap_chain_datum_tx_t *a_tx, dap_chain_tx_item_type_t a_type, int a_item_idx)
 {
-    uint8_t *l_tx_item = NULL;
-    int l_item_idx = 0;
-    for (int l_type_idx = 0; l_type_idx <= a_item_idx; ++l_type_idx, ++l_item_idx) {
-        l_tx_item = dap_chain_datum_tx_item_get(a_tx, &l_item_idx, a_type, NULL);
-        if (!l_tx_item)
-            break;
+    uint8_t *l_tx_item = NULL; size_t l_size; int i;
+    TX_ITEM_ITER_TX_TYPE(l_tx_item, a_type, l_size, i, a_tx) {
+        if (!a_item_idx--)
+            return l_tx_item;
     }
-    return l_tx_item;
+    return NULL; 
 }
 
 /**
@@ -656,193 +534,149 @@ uint8_t *dap_chain_datum_tx_item_get_nth(dap_chain_datum_tx_t *a_tx, dap_chain_t
  * a_out_num[out] found index of item in transaction, -1 if not found
  * return tx_out_cond, or NULL
  */
-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 = 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
-        if (a_out_num && l_prev_cond_idx < *a_out_num)
-            continue;
-        if (*(byte_t*)l_item->data == TX_ITEM_TYPE_OUT_COND &&
-                ((dap_chain_tx_out_cond_t*)l_item->data)->header.subtype == a_cond_type) {
-            l_res = l_item->data;
+dap_chain_tx_out_cond_t *dap_chain_datum_tx_out_cond_get(dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_subtype_t a_cond_subtype, int *a_out_num)
+{
+    int l_idx = a_out_num && *a_out_num > 0 ? -*a_out_num : 0;
+    byte_t *l_item; size_t l_tx_item_size;
+    TX_ITEM_ITER_TX(l_item, l_tx_item_size, a_tx) {
+        switch (*l_item) {
+        case TX_ITEM_TYPE_OUT_COND:
+            if ( l_idx >= 0 && ((dap_chain_tx_out_cond_t*)l_item)->header.subtype == a_cond_subtype )
+                return (a_out_num ? (*a_out_num = l_idx) : 0), (dap_chain_tx_out_cond_t*)l_item;
+        case TX_ITEM_TYPE_OUT: case TX_ITEM_TYPE_OUT_OLD: case TX_ITEM_TYPE_OUT_EXT:
+            ++l_idx;
+        default:
             break;
         }
     }
-    dap_list_free(l_list_out_items);
-    if (a_out_num) {
-        *a_out_num = l_res ? l_prev_cond_idx : -1;
-    }
-    return l_res;
-}
-
-uint8_t *dap_chain_datum_tx_out_get_by_out_idx(dap_chain_datum_tx_t *a_tx, int a_out_num)
-{
-    uint8_t *l_ret = NULL;
-    dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, NULL), *l_item;
-    if (!l_list_out_items)
-        return NULL;
-
-    l_item = dap_list_nth(l_list_out_items, a_out_num);
-
-    if(!l_item){
-        dap_list_free(l_list_out_items);
-        return NULL;
-    }
-
-    l_ret = l_item->data;
-    dap_list_free(l_list_out_items);
-    return l_ret;
-
+    return (a_out_num ? (*a_out_num = -1) : 0), NULL;
 }
 
 void dap_chain_datum_tx_group_items_free( dap_chain_datum_tx_item_groups_t *a_items_groups)
 {   
-    if (a_items_groups->items_in) dap_list_free(a_items_groups->items_in);
-    if (a_items_groups->items_in_cond) dap_list_free(a_items_groups->items_in_cond);
-    if (a_items_groups->items_in_reward) dap_list_free(a_items_groups->items_in_reward);
-    if (a_items_groups->items_sig) dap_list_free(a_items_groups->items_sig);
-    if (a_items_groups->items_out) dap_list_free(a_items_groups->items_out);
-    if (a_items_groups->items_out_ext) dap_list_free(a_items_groups->items_out_ext);
-    if (a_items_groups->items_out_cond) dap_list_free(a_items_groups->items_out_cond);
-    if (a_items_groups->items_out_cond_srv_fee) dap_list_free(a_items_groups->items_out_cond_srv_fee);
-    if (a_items_groups->items_out_cond_srv_pay) dap_list_free(a_items_groups->items_out_cond_srv_pay);
-    if (a_items_groups->items_out_cond_srv_xchange) dap_list_free(a_items_groups->items_out_cond_srv_xchange);
-    if (a_items_groups->items_out_cond_srv_stake_pos_delegate) dap_list_free(a_items_groups->items_out_cond_srv_stake_pos_delegate);
-    if (a_items_groups->items_out_cond_srv_stake_lock) dap_list_free(a_items_groups->items_out_cond_srv_stake_lock);
-    if (a_items_groups->items_in_ems) dap_list_free(a_items_groups->items_in_ems);
-    if (a_items_groups->items_vote) dap_list_free(a_items_groups->items_vote);
-    if (a_items_groups->items_voting) dap_list_free(a_items_groups->items_voting);
-    if (a_items_groups->items_tsd) dap_list_free(a_items_groups->items_tsd);
-    if (a_items_groups->items_pkey) dap_list_free(a_items_groups->items_pkey);
-    if (a_items_groups->items_receipt) dap_list_free(a_items_groups->items_receipt);
-    if (a_items_groups->items_unknown) dap_list_free(a_items_groups->items_unknown);
-    if (a_items_groups->items_out_old) dap_list_free(a_items_groups->items_out_old);
-    if (a_items_groups->items_out_cond_unknonwn) dap_list_free(a_items_groups->items_out_cond_unknonwn);
-    if (a_items_groups->items_out_cond_undefined) dap_list_free(a_items_groups->items_out_cond_undefined);
-    if (a_items_groups->items_out_all) dap_list_free(a_items_groups->items_out_all);
-    if (a_items_groups->items_in_all) dap_list_free(a_items_groups->items_in_all);
+    dap_list_free(a_items_groups->items_in);
+    dap_list_free(a_items_groups->items_in_cond);
+    dap_list_free(a_items_groups->items_in_reward);
+    dap_list_free(a_items_groups->items_sig);
+    dap_list_free(a_items_groups->items_out);
+    dap_list_free(a_items_groups->items_out_ext);
+    dap_list_free(a_items_groups->items_out_cond);
+    dap_list_free(a_items_groups->items_out_cond_srv_fee);
+    dap_list_free(a_items_groups->items_out_cond_srv_pay);
+    dap_list_free(a_items_groups->items_out_cond_srv_xchange);
+    dap_list_free(a_items_groups->items_out_cond_srv_stake_pos_delegate);
+    dap_list_free(a_items_groups->items_out_cond_srv_stake_lock);
+    dap_list_free(a_items_groups->items_in_ems);
+    dap_list_free(a_items_groups->items_vote);
+    dap_list_free(a_items_groups->items_voting);
+    dap_list_free(a_items_groups->items_tsd);
+    dap_list_free(a_items_groups->items_pkey);
+    dap_list_free(a_items_groups->items_receipt);
+    dap_list_free(a_items_groups->items_unknown);
+    dap_list_free(a_items_groups->items_out_old);
+    dap_list_free(a_items_groups->items_out_cond_unknonwn);
+    dap_list_free(a_items_groups->items_out_cond_undefined);
+    dap_list_free(a_items_groups->items_out_all);
+    dap_list_free(a_items_groups->items_in_all);
 }
 
 #define DAP_LIST_SAPPEND(X, Y) X = dap_list_append(X,Y)
 bool dap_chain_datum_tx_group_items(dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_res_group)
 {   
-    
     if(!a_tx || !a_res_group)
         return NULL;
     
-    uint32_t l_tx_items_pos = 0, l_tx_items_size = a_tx->header.tx_items_size;
-
-    int l_item_idx = 0;
-
-    while (l_tx_items_pos < l_tx_items_size) {
-
-        uint8_t *l_item = a_tx->tx_items + l_tx_items_pos;
-        int l_item_size = dap_chain_datum_item_tx_get_size(l_item);
-        
-        if(!l_item_size)
-            return false;
-        
-        dap_chain_tx_item_type_t l_type = dap_chain_datum_tx_item_get_type(l_item);
-        
-        switch (l_type)
-        {
-            case TX_ITEM_TYPE_IN:
-                DAP_LIST_SAPPEND(a_res_group->items_in, l_item);
-                DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
-                break;
-
-            case TX_ITEM_TYPE_IN_COND:
-                DAP_LIST_SAPPEND(a_res_group->items_in_cond, l_item);
-                DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
-                break;
+    byte_t *l_item; size_t l_tx_item_size;
+    TX_ITEM_ITER_TX(l_item, l_tx_item_size, a_tx) {
+        switch (*l_item) {
+        case TX_ITEM_TYPE_IN:
+            DAP_LIST_SAPPEND(a_res_group->items_in, l_item);
+            DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
+            break;
 
-            case TX_ITEM_TYPE_IN_REWARD:
-                DAP_LIST_SAPPEND(a_res_group->items_in_reward, l_item);
-                DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
-                break;
+        case TX_ITEM_TYPE_IN_COND:
+            DAP_LIST_SAPPEND(a_res_group->items_in_cond, l_item);
+            DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
+            break;
 
-            case TX_ITEM_TYPE_IN_EMS:
-                DAP_LIST_SAPPEND(a_res_group->items_in_ems, l_item);
-                DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
-                break;
+        case TX_ITEM_TYPE_IN_REWARD:
+            DAP_LIST_SAPPEND(a_res_group->items_in_reward, l_item);
+            DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
+            break;
 
-            case TX_ITEM_TYPE_OUT_OLD:
-                DAP_LIST_SAPPEND(a_res_group->items_out_old, l_item);
-                DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
-                break;
+        case TX_ITEM_TYPE_IN_EMS:
+            DAP_LIST_SAPPEND(a_res_group->items_in_ems, l_item);
+            DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
+            break;
 
-            case TX_ITEM_TYPE_OUT_EXT:
-                DAP_LIST_SAPPEND(a_res_group->items_out_ext, l_item);
-                DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
-                break;
+        case TX_ITEM_TYPE_OUT_OLD:
+            DAP_LIST_SAPPEND(a_res_group->items_out_old, l_item);
+            DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
+            break;
 
-            case TX_ITEM_TYPE_OUT:
-                DAP_LIST_SAPPEND(a_res_group->items_out, l_item);
-                DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
-                break;
+        case TX_ITEM_TYPE_OUT_EXT:
+            DAP_LIST_SAPPEND(a_res_group->items_out_ext, l_item);
+            DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
+            break;
 
-            case TX_ITEM_TYPE_OUT_COND: {
-                switch ( ((dap_chain_tx_out_cond_t *)l_item)->header.subtype )
-                {
-                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED:
-                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_undefined, l_item);
-                        break;
-                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY:
-                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_pay, l_item);
-                        break;
-                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE:
-                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_xchange, l_item);
-                        break;
-                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE:
-                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_stake_pos_delegate, l_item);
-                        break;
-                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE:
-                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_fee, l_item);
-                        break;
-                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK:
-                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_stake_lock, l_item);
-                        break;
-                    default:
-                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_unknonwn, l_item);
-                        break;
-                }
-
-                DAP_LIST_SAPPEND(a_res_group->items_out_cond, l_item);
-                DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
-                }
-                break;
+        case TX_ITEM_TYPE_OUT:
+            DAP_LIST_SAPPEND(a_res_group->items_out, l_item);
+            DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
+            break;
 
-            case TX_ITEM_TYPE_PKEY:
-                DAP_LIST_SAPPEND(a_res_group->items_pkey, l_item);
+        case TX_ITEM_TYPE_OUT_COND: {
+            switch ( ((dap_chain_tx_out_cond_t *)l_item)->header.subtype ) {
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED:
+                DAP_LIST_SAPPEND(a_res_group->items_out_cond_undefined, l_item);
                 break;
-            case TX_ITEM_TYPE_SIG:
-                DAP_LIST_SAPPEND(a_res_group->items_sig, l_item);
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY:
+                DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_pay, l_item);
                 break;
-            case TX_ITEM_TYPE_RECEIPT:
-                DAP_LIST_SAPPEND(a_res_group->items_receipt, l_item);
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE:
+                DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_xchange, l_item);
                 break;
-            case TX_ITEM_TYPE_TSD:
-                DAP_LIST_SAPPEND(a_res_group->items_tsd, l_item);
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE:
+                DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_stake_pos_delegate, l_item);
                 break;
-
-            case TX_ITEM_TYPE_VOTING:
-                DAP_LIST_SAPPEND(a_res_group->items_voting, l_item);
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE:
+                DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_fee, l_item);
                 break;
-
-            case TX_ITEM_TYPE_VOTE:
-                DAP_LIST_SAPPEND(a_res_group->items_vote, l_item);
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK:
+                DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_stake_lock, l_item);
                 break;
             default:
-                DAP_LIST_SAPPEND(a_res_group->items_unknown, l_item);
+                DAP_LIST_SAPPEND(a_res_group->items_out_cond_unknonwn, l_item);
+                break;
+            }
+            DAP_LIST_SAPPEND(a_res_group->items_out_cond, l_item);
+            DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
+            }
+            break;
+
+        case TX_ITEM_TYPE_PKEY:
+            DAP_LIST_SAPPEND(a_res_group->items_pkey, l_item);
+            break;
+        case TX_ITEM_TYPE_SIG:
+            DAP_LIST_SAPPEND(a_res_group->items_sig, l_item);
+            break;
+        case TX_ITEM_TYPE_RECEIPT:
+            DAP_LIST_SAPPEND(a_res_group->items_receipt, l_item);
+            break;
+        case TX_ITEM_TYPE_TSD:
+            DAP_LIST_SAPPEND(a_res_group->items_tsd, l_item);
+            break;
+
+        case TX_ITEM_TYPE_VOTING:
+            DAP_LIST_SAPPEND(a_res_group->items_voting, l_item);
+            break;
+
+        case TX_ITEM_TYPE_VOTE:
+            DAP_LIST_SAPPEND(a_res_group->items_vote, l_item);
+            break;
+        default:
+            DAP_LIST_SAPPEND(a_res_group->items_unknown, l_item);
         }
-        
-        l_tx_items_pos += l_item_size;
-        l_item_idx++;
     }
-    
     return true;
 
 }
diff --git a/modules/common/dap_chain_datum_tx_voting.c b/modules/common/dap_chain_datum_tx_voting.c
index 305ed3937eb719693ef64506a8077d511d13ccea..1823d1add0c172b6abd0d088a91f44d6694bd5cc 100644
--- a/modules/common/dap_chain_datum_tx_voting.c
+++ b/modules/common/dap_chain_datum_tx_voting.c
@@ -31,26 +31,21 @@ dap_chain_datum_tx_voting_params_t* dap_chain_voting_parse_tsd(dap_chain_datum_t
 {
     if (!a_tx)
         return NULL;
-
-    dap_list_t* l_tsd_list = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_TSD, NULL);
-    dap_chain_datum_tx_voting_params_t *l_voting_parms = DAP_NEW_Z_SIZE(dap_chain_datum_tx_voting_params_t,
-                                                                        sizeof(dap_chain_datum_tx_voting_params_t));
-    char *l_buf_string = NULL;
-    dap_list_t* l_temp = l_tsd_list;
-    while (l_temp){
-        dap_tsd_t *l_tsd = (dap_tsd_t *)((dap_chain_tx_tsd_t*)l_temp->data)->tsd;
+    dap_chain_datum_tx_voting_params_t *l_voting_parms = DAP_NEW_Z(dap_chain_datum_tx_voting_params_t);
+    char *l_buf_string;
+    byte_t *l_item; size_t l_tx_item_size;
+    TX_ITEM_ITER_TX(l_item, l_tx_item_size, a_tx) {
+        if (*l_item != TX_ITEM_TYPE_TSD)
+            continue;
+        dap_tsd_t *l_tsd = (dap_tsd_t*)((dap_chain_tx_tsd_t*)l_item)->tsd;
         switch(l_tsd->type){
         case VOTING_TSD_TYPE_QUESTION:
             l_buf_string = DAP_NEW_Z_SIZE(char, l_tsd->size + 1);
-            memcpy(l_buf_string, l_tsd->data, l_tsd->size);
-            l_buf_string[l_tsd->size] = '\0';
-            l_voting_parms->voting_question = l_buf_string;
+            l_voting_parms->voting_question = memcpy(l_buf_string, l_tsd->data, l_tsd->size);
             break;
         case VOTING_TSD_TYPE_ANSWER:
             l_buf_string = DAP_NEW_Z_SIZE(char, l_tsd->size + 1);
-            memcpy(l_buf_string, l_tsd->data, l_tsd->size);
-            l_buf_string[l_tsd->size] = '\0';
-            l_voting_parms->answers_list = dap_list_append(l_voting_parms->answers_list, l_buf_string);
+            l_voting_parms->answers_list = dap_list_append(l_voting_parms->answers_list, memcpy(l_buf_string, l_tsd->data, l_tsd->size));
             l_voting_parms->answers_count++;
             break;
         case VOTING_TSD_TYPE_EXPIRE:
@@ -68,11 +63,7 @@ dap_chain_datum_tx_voting_params_t* dap_chain_voting_parse_tsd(dap_chain_datum_t
         default:
             break;
         }
-
-        l_temp = l_temp->next;
     }
-    dap_list_free(l_tsd_list);
-
     return l_voting_parms;
 }
 
@@ -151,29 +142,17 @@ dap_chain_tx_voting_t *dap_chain_datum_tx_item_voting_create(void)
 }
 
 const char *s_tx_voting_get_answer_text_by_idx(dap_chain_datum_tx_t *a_tx, uint64_t a_idx) {
-    dap_list_t *l_answers_list = NULL;
-    size_t l_anwers_count = 0;
-    dap_list_t* l_tsd_list = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_TSD, NULL);
-    dap_list_t* l_temp = l_tsd_list;
-    while (l_temp){
-        dap_tsd_t* l_tsd = (dap_tsd_t *)((dap_chain_tx_tsd_t*)l_temp->data)->tsd;
-        if (l_tsd->type == VOTING_TSD_TYPE_ANSWER) {
-            char *l_buf_string = DAP_NEW_Z_SIZE(char, l_tsd->size + 1);
-            memcpy(l_buf_string, l_tsd->data, l_tsd->size);
-            l_buf_string[l_tsd->size] = '\0';
-            l_answers_list = dap_list_append(l_answers_list, l_buf_string);
-            l_anwers_count++;
-        }
-        l_temp = l_temp->next;
+    byte_t *l_item; size_t l_tx_item_size;
+    dap_tsd_t *l_tsd;
+    TX_ITEM_ITER_TX(l_item, l_tx_item_size, a_tx) {
+        if ( *l_item != TX_ITEM_TYPE_TSD
+            || ( l_tsd = (dap_tsd_t*)((dap_chain_tx_tsd_t*)l_item)->tsd, l_tsd->type != VOTING_TSD_TYPE_ANSWER )
+            || a_idx-- )
+            continue;
+        char *l_ret = DAP_NEW_Z_SIZE(char, l_tsd->size + 1);
+        return memcpy(l_ret, l_tsd->data, l_tsd->size);
     }
-    dap_list_free(l_tsd_list);
-    if (l_anwers_count < a_idx) {
-        dap_list_free_full(l_answers_list, NULL);
-        return NULL;
-    }
-    char *l_ret = dap_strdup(dap_list_nth_data(l_answers_list, a_idx));
-    dap_list_free_full(l_answers_list, NULL);
-    return l_ret;
+    return NULL;
 }
 
 json_object *dap_chain_datum_tx_item_voting_tsd_to_json(dap_chain_datum_tx_t* a_tx)
@@ -181,45 +160,36 @@ json_object *dap_chain_datum_tx_item_voting_tsd_to_json(dap_chain_datum_tx_t* a_
     if (!a_tx)
         return NULL;
 
-    json_object *l_object = json_object_new_object();
-    json_object *l_answer_array_object = json_object_new_array();
-    json_object *l_json_obj = NULL;
-    dap_list_t* l_tsd_list = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_TSD, NULL);
-    dap_list_t* l_temp = l_tsd_list;
-    while (l_temp){
-        dap_tsd_t* l_tsd = (dap_tsd_t *)((dap_chain_tx_tsd_t*)l_temp->data)->tsd;
-        switch(l_tsd->type){
+    json_object *l_object = json_object_new_object(), *l_answer_array_object = json_object_new_array();
+    byte_t *l_item; size_t l_tx_item_size;
+    dap_tsd_t *l_tsd;
+    TX_ITEM_ITER_TX(l_item, l_tx_item_size, a_tx) {
+        if (*l_item != TX_ITEM_TYPE_TSD)
+            continue;
+        l_tsd = (dap_tsd_t*)((dap_chain_tx_tsd_t*)l_item)->tsd;
+        switch(l_tsd->type) {
         case VOTING_TSD_TYPE_QUESTION:
-            l_json_obj = json_object_new_string_len((char*)l_tsd->data, l_tsd->size);
-            json_object_object_add(l_object, "question", l_json_obj);
+            json_object_object_add(l_object, "question", json_object_new_string_len((char*)l_tsd->data, l_tsd->size));
             break;
         case VOTING_TSD_TYPE_ANSWER:
-            l_json_obj = json_object_new_string_len((char*)l_tsd->data, l_tsd->size);
-            json_object_array_add(l_answer_array_object, l_json_obj);
+            json_object_array_add(l_answer_array_object, json_object_new_string_len((char*)l_tsd->data, l_tsd->size));
             break;
         case VOTING_TSD_TYPE_EXPIRE:
-            l_json_obj = json_object_new_uint64(*(uint64_t*)l_tsd->data);
-            json_object_object_add(l_object, "exired", l_json_obj);
+            json_object_object_add(l_object, "exired", json_object_new_uint64(*(uint64_t*)l_tsd->data));
             break;
         case VOTING_TSD_TYPE_MAX_VOTES_COUNT:
-            l_json_obj = json_object_new_uint64(*(uint64_t*)l_tsd->data);
-            json_object_object_add(l_object, "maxVotes", l_json_obj);
+            json_object_object_add(l_object, "maxVotes", json_object_new_uint64(*(uint64_t*)l_tsd->data));
             break;
         case VOTING_TSD_TYPE_DELEGATED_KEY_REQUIRED:
-            l_json_obj = json_object_new_boolean(*(bool*)l_tsd->data);
-            json_object_object_add(l_object, "delegateKeyRequired", l_json_obj);
+            json_object_object_add(l_object, "delegateKeyRequired", json_object_new_boolean(*(bool*)l_tsd->data));
             break;
         case VOTING_TSD_TYPE_VOTE_CHANGING_ALLOWED:
-            l_json_obj = json_object_new_boolean(*(bool*)l_tsd->data);
-            json_object_object_add(l_object, "voteChangingAllowed", l_json_obj);
+            json_object_object_add(l_object, "voteChangingAllowed", json_object_new_boolean(*(bool*)l_tsd->data));
             break;
         default:
             break;
         }
-        l_temp = l_temp->next;
     }
-    dap_list_free(l_tsd_list);
-
     json_object_object_add(l_object, "answers", l_answer_array_object);
     return l_object;
 }
diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h
index 3ae8e849771803033be56fcf2e743d3f1c36b8aa..f3c8a93b92ebc504a91ae28894983090920a8539 100644
--- a/modules/common/include/dap_chain_common.h
+++ b/modules/common/include/dap_chain_common.h
@@ -199,6 +199,7 @@ extern "C" {
 size_t dap_chain_hash_slow_to_str(dap_chain_hash_slow_t * a_hash, char * a_str, size_t a_str_max);
 
 const char *dap_chain_addr_to_str_static(const dap_chain_addr_t *a_addr);
+#define dap_chain_addr_to_str dap_chain_addr_to_str_static
 dap_chain_addr_t* dap_chain_addr_from_str(const char *str);
 bool dap_chain_addr_is_blank(const dap_chain_addr_t *a_addr);
 
diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h
index e8a6ec192e5cdd3764526e9b2340aa223d5563d9..cd161e671ca1c367dfcc80b26e830bdedfe955ad 100644
--- a/modules/common/include/dap_chain_datum_tx.h
+++ b/modules/common/include/dap_chain_datum_tx.h
@@ -33,13 +33,28 @@
   * @struct dap_chain_datum_tx
   * @brief Transaction section, consists from lot of tx_items
   */
-typedef struct dap_chain_datum_tx{
+typedef struct dap_chain_datum_tx {
     struct {
         dap_time_t ts_created;
-        uint32_t tx_items_size; // size of next sequencly lying tx_item sections would be decided to belong this transaction
+        uint32_t tx_items_size; // total size of sequential tx_items
     } DAP_ALIGN_PACKED header;
     uint8_t tx_items[];
 } DAP_ALIGN_PACKED dap_chain_datum_tx_t;
+
+#define TX_ITEM_ITER(item, item_size, data, total_size)                                                             \
+    for ( byte_t *l_pos = (byte_t*)(data), *l_end = l_pos + (total_size) > l_pos ? l_pos + (total_size) : l_pos;    \
+          !!( item = l_pos < l_end                                                                                  \
+          && (item_size = dap_chain_datum_item_tx_get_size(l_pos, l_end - l_pos))                                   \
+            ? l_pos : NULL );                                                           \
+        l_pos += item_size )
+
+#define TX_ITEM_ITER_TX(item, item_size, tx) \
+    TX_ITEM_ITER(item, item_size, tx->tx_items, tx->header.tx_items_size)
+
+#define TX_ITEM_ITER_TX_TYPE(item, item_type, item_size, item_index, tx)                                            \
+    for ( item_size = 0, item_index = 0, item = NULL;                                                                            \
+        !!( item = dap_chain_datum_tx_item_get(tx, &item_index, (byte_t*)item + item_size, item_type, &item_size) );\
+        item_index = 0 )
 /**
  * Create empty transaction
  *
@@ -161,12 +176,8 @@ int dap_chain_datum_tx_get_fee_value (dap_chain_datum_tx_t *a_tx, uint256_t *a_v
  * @param a_tx
  * @return
  */
-DAP_STATIC_INLINE dap_chain_hash_fast_t* dap_chain_node_datum_tx_calc_hash(dap_chain_datum_tx_t *a_tx)
+DAP_STATIC_INLINE dap_hash_fast_t dap_chain_node_datum_tx_calc_hash(dap_chain_datum_tx_t *a_tx)
 {
-    dap_chain_hash_fast_t *tx_hash = DAP_NEW_Z(dap_chain_hash_fast_t);
-    if (!tx_hash) {
-        return NULL;
-    }
-    dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), tx_hash);
-    return tx_hash;
+    dap_hash_fast_t l_res;
+    return dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_res), l_res;
 }
diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h
index e0799f815b712d1bc3bdb74e21ccad07c47effd3..a30e32c44bbe86603e5ae1bfd523af2295980fc4 100644
--- a/modules/common/include/dap_chain_datum_tx_items.h
+++ b/modules/common/include/dap_chain_datum_tx_items.h
@@ -44,47 +44,6 @@
 #include "dap_chain_datum_tx_tsd.h"
 #include "dap_chain_datum_tx_in_reward.h"
 
-/**
- * Get item type
- *
- * return type, or TX_ITEM_TYPE_ANY if error
- */
-dap_chain_tx_item_type_t dap_chain_datum_tx_item_get_type(const void *a_item);
-
-typedef struct dap_chain_datum_tx_item
-{
-    dap_chain_tx_item_type_t type;
-    byte_t data[];
-} DAP_ALIGN_PACKED dap_chain_datum_tx_item_t;
-
-/**
- * Get item name by item type
- *
- * return name, or UNDEFINED
- */
-DAP_STATIC_INLINE const char * dap_chain_datum_tx_item_type_to_str(dap_chain_tx_item_type_t a_item_type)
-{
-    switch(a_item_type){
-        case TX_ITEM_TYPE_IN: return "TX_ITEM_TYPE_IN";
-        case TX_ITEM_TYPE_OUT_OLD: return "TX_ITEM_TYPE_OUT_OLD";
-        case TX_ITEM_TYPE_OUT: return "TX_ITEM_TYPE_OUT"; // 256
-        case TX_ITEM_TYPE_OUT_EXT: return "TX_ITEM_TYPE_OUT_EXT"; // 256
-        case TX_ITEM_TYPE_PKEY: return "TX_ITEM_TYPE_PKEY";
-        case TX_ITEM_TYPE_SIG: return "TX_ITEM_TYPE_SIG";
-        case TX_ITEM_TYPE_IN_EMS: return "TX_ITEM_TYPE_IN_EMS";
-        case TX_ITEM_TYPE_IN_REWARD: return "TX_ITEM_TYPE_IN_REWARD";
-        case TX_ITEM_TYPE_IN_COND: return "TX_ITEM_TYPE_IN_COND";
-        case TX_ITEM_TYPE_OUT_COND: return "TX_ITEM_TYPE_OUT_COND"; // 256
-        case TX_ITEM_TYPE_RECEIPT: return "TX_ITEM_TYPE_RECEIPT";
-        case TX_ITEM_TYPE_TSD: return "TX_ITEM_TYPE_TSD";
-        case TX_ITEM_TYPE_OUT_ALL: return "TX_ITEM_TYPE_OUT_OLDALL";
-        case TX_ITEM_TYPE_ANY: return "TX_ITEM_TYPE_ANY";
-        case TX_ITEM_TYPE_VOTING: return "TX_ITEM_TYPE_VOTING";
-        case TX_ITEM_TYPE_VOTE: return "TX_ITEM_TYPE_VOTE";
-        default: return "UNDEFINED";
-    }
-}
-
 typedef struct dap_chain_datum_tx_item_groups {
 
     dap_list_t *items_in_all;
@@ -118,6 +77,34 @@ typedef struct dap_chain_datum_tx_item_groups {
 
 } dap_chain_datum_tx_item_groups_t;
 
+/**
+ * Get item name by item type
+ *
+ * return name, or UNDEFINED
+ */
+DAP_STATIC_INLINE const char * dap_chain_datum_tx_item_type_to_str(dap_chain_tx_item_type_t a_item_type)
+{
+    switch(a_item_type){
+        case TX_ITEM_TYPE_IN: return "TX_ITEM_TYPE_IN";
+        case TX_ITEM_TYPE_OUT_OLD: return "TX_ITEM_TYPE_OUT_OLD";
+        case TX_ITEM_TYPE_OUT: return "TX_ITEM_TYPE_OUT"; // 256
+        case TX_ITEM_TYPE_OUT_EXT: return "TX_ITEM_TYPE_OUT_EXT"; // 256
+        case TX_ITEM_TYPE_PKEY: return "TX_ITEM_TYPE_PKEY";
+        case TX_ITEM_TYPE_SIG: return "TX_ITEM_TYPE_SIG";
+        case TX_ITEM_TYPE_IN_EMS: return "TX_ITEM_TYPE_IN_EMS";
+        case TX_ITEM_TYPE_IN_REWARD: return "TX_ITEM_TYPE_IN_REWARD";
+        case TX_ITEM_TYPE_IN_COND: return "TX_ITEM_TYPE_IN_COND";
+        case TX_ITEM_TYPE_OUT_COND: return "TX_ITEM_TYPE_OUT_COND"; // 256
+        case TX_ITEM_TYPE_RECEIPT: return "TX_ITEM_TYPE_RECEIPT";
+        case TX_ITEM_TYPE_TSD: return "TX_ITEM_TYPE_TSD";
+        case TX_ITEM_TYPE_OUT_ALL: return "TX_ITEM_TYPE_OUT_OLDALL";
+        case TX_ITEM_TYPE_ANY: return "TX_ITEM_TYPE_ANY";
+        case TX_ITEM_TYPE_VOTING: return "TX_ITEM_TYPE_VOTING";
+        case TX_ITEM_TYPE_VOTE: return "TX_ITEM_TYPE_VOTE";
+        default: return "UNDEFINED";
+    }
+}
+
 bool dap_chain_datum_tx_group_items(dap_chain_datum_tx_t *a_tx,  dap_chain_datum_tx_item_groups_t *a_res_group);
 void dap_chain_datum_tx_group_items_free( dap_chain_datum_tx_item_groups_t *a_group);
 
@@ -140,7 +127,7 @@ dap_chain_tx_out_cond_subtype_t dap_chain_tx_out_cond_subtype_from_str(const cha
  *
  * return size, 0 Error
  */
-size_t dap_chain_datum_item_tx_get_size(const void *a_item);
+size_t dap_chain_datum_item_tx_get_size(const byte_t *a_item, size_t a_max_size);
 
 /**
  * Create item dap_chain_tx_in_ems_t
@@ -223,7 +210,9 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap
 
 json_object* dap_chain_datum_tx_item_out_cond_srv_xchange_to_json(dap_chain_tx_out_cond_t* a_srv_xchange);
 
-DAP_STATIC_INLINE uint32_t dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size() { return sizeof(dap_chain_addr_t) + sizeof(uint256_t) + 2 * sizeof(dap_tsd_t); }
+DAP_STATIC_INLINE uint32_t dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size() {
+    return sizeof(dap_chain_addr_t) + sizeof(uint256_t) + 2 * sizeof(dap_tsd_t);
+}
 
 /**
  * Create item dap_chain_tx_out_cond_t for stake service
@@ -272,13 +261,14 @@ byte_t *dap_chain_datum_tx_item_get_data(dap_chain_tx_tsd_t *a_tx_tsd, int *a_ty
  * return item data, NULL Error index or bad format transaction
  */
 uint8_t* dap_chain_datum_tx_item_get( dap_chain_datum_tx_t *a_tx, int *a_item_idx_start,
-        dap_chain_tx_item_type_t a_type, int *a_item_out_size);
+        byte_t *a_iter, dap_chain_tx_item_type_t a_type, size_t *a_item_out_size);
 // Get Nth item of pointed type
 uint8_t *dap_chain_datum_tx_item_get_nth(dap_chain_datum_tx_t *a_tx, dap_chain_tx_item_type_t a_type, int a_item_idx);
 // Get all item from transaction by type
 dap_list_t* dap_chain_datum_tx_items_get(dap_chain_datum_tx_t *a_tx, dap_chain_tx_item_type_t a_type, int *a_item_count);
 // Get conditional out item with it's idx
-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_chain_tx_out_cond_t *dap_chain_datum_tx_out_cond_get(dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_subtype_t a_cond_subtype, int *a_out_num);
 // Get output by output index
-uint8_t *dap_chain_datum_tx_out_get_by_out_idx(dap_chain_datum_tx_t *a_tx, int a_out_num);
+#define dap_chain_datum_tx_out_get_by_out_idx(a_tx, a_out_num) \
+    dap_chain_datum_tx_item_get(a_tx, &a_out_num, NULL, TX_ITEM_TYPE_OUT_ALL, NULL);
 
diff --git a/modules/common/include/dap_chain_datum_tx_voting.h b/modules/common/include/dap_chain_datum_tx_voting.h
index 331cb806f80f929b7b33af509b38b3e8117bfafa..f51628e59c791fd2281b0a6dbe1bf089cf7ad6cc 100644
--- a/modules/common/include/dap_chain_datum_tx_voting.h
+++ b/modules/common/include/dap_chain_datum_tx_voting.h
@@ -22,9 +22,10 @@
 #pragma once
 
 #include <stdint.h>
+#include "dap_chain.h"
 #include "dap_chain_common.h"
-#include "dap_chain_datum_tx.h"
-#include "dap_chain_datum_tx_items.h"
+//#include "dap_chain_datum_tx.h"
+//#include "dap_chain_datum_tx_items.h"
 #include "dap_chain_ledger.h"
 #include "dap_time.h"
 #include "dap_list.h"
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index 25089be78b596aaf5d68cfa27a41e24d3034ee38..57f643aa4f203f000bb24b2f702a1b804a1fab33 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -1981,7 +1981,7 @@ static int s_session_directive_apply(dap_chain_esbocs_directive_t *a_directive,
     switch (a_directive->type) {
     case DAP_CHAIN_ESBOCS_DIRECTIVE_KICK:
     case DAP_CHAIN_ESBOCS_DIRECTIVE_LIFT: {
-        dap_chain_addr_t *l_key_addr = (dap_chain_addr_t *)(((dap_tsd_t *)a_directive->tsd)->data);
+        dap_chain_addr_t *l_key_addr = (dap_chain_addr_t *)((dap_tsd_t *)a_directive->tsd)->data;
         int l_status = dap_chain_net_srv_stake_key_delegated(l_key_addr);
         const char *l_key_str = dap_chain_addr_to_str_static(l_key_addr);
         if (l_status == 0) {
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index b2980610c5cd2286628bfebcd70f9232bc3a8b33..8fc3ad433d34ad4c9d290455a8c7292d15091d75 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -588,7 +588,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
     log_it(L_DEBUG, "Create %"DAP_UINT64_FORMAT_U" transactions, summary %s", a_tx_num, l_balance);
     dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger;
     dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker,
-                                                                          a_addr_from, l_value_need, &l_value_transfer);
+                                                                       a_addr_from, l_value_need, &l_value_transfer);
     if (!l_list_used_out) {
         log_it(L_WARNING,"Not enough funds to transfer");
         DAP_DELETE(l_objs);
@@ -596,8 +596,8 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
     }
     
     dap_chain_hash_fast_t l_tx_new_hash = {0};
-    for (size_t i=0; i< a_tx_num ; i++){
-        log_it(L_DEBUG, "Prepare tx %zu",i);
+    for (size_t i=0; i < a_tx_num; ++i){
+        log_it(L_DEBUG, "Prepare tx %zu", i);
         // find the transactions from which to take away coins
 
         // create empty transaction
@@ -613,7 +613,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
             dap_chain_hash_fast_to_str(&l_item->tx_hash_fast, l_in_hash_str, sizeof(l_in_hash_str));
 
             l_balance = dap_uint256_to_char(l_item->value, NULL);
-            if (dap_chain_datum_tx_add_in_item(&l_tx_new, &l_item->tx_hash_fast, l_item->num_idx_out)) {
+            if (1 == dap_chain_datum_tx_add_in_item(&l_tx_new, &l_item->tx_hash_fast, l_item->num_idx_out)) {
                 SUM_256_256(l_value_to_items, l_item->value, &l_value_to_items);
                 log_it(L_DEBUG, "Added input %s with %s datoshi", l_in_hash_str, l_balance);
             } else {
@@ -688,48 +688,35 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
         }
         // now tx is formed - calc size and hash
         size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx_new);
-
         dap_hash_fast(l_tx_new, l_tx_size, &l_tx_new_hash);
         // If we have value back - update balance cache
         if (!IS_ZERO_256(l_value_back)) {
             //log_it(L_DEBUG,"We have value back %"DAP_UINT64_FORMAT_U" now lets see how many outputs we have", l_value_back);
-            int l_item_count = 0;
-            dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get( l_tx_new, TX_ITEM_TYPE_OUT_ALL,
-                    &l_item_count);
-            dap_list_t *l_list_tmp = l_list_out_items;
-            int l_out_idx_tmp = 0; // current index of 'out' item
-            //log_it(L_DEBUG,"We have %d outputs in new TX", l_item_count);
-            while(l_list_tmp) {
-                dap_chain_tx_out_t *l_out = l_list_tmp->data;
-                if( ! l_out){
-                    log_it(L_WARNING, "Output is NULL, continue check outputs...");
-                    l_out_idx_tmp++;
-                    continue;
-                }
-                if (l_out->header.type == TX_ITEM_TYPE_OUT_COND) {
-                    l_list_tmp = l_list_tmp->next;
-                    l_out_idx_tmp++;
+            int l_out_idx = 0;
+            byte_t *l_item; size_t l_size;
+            TX_ITEM_ITER_TX(l_item, l_size, l_tx_new) {
+                switch (*l_item) {
+                case TX_ITEM_TYPE_OUT_COND:
+                    ++l_out_idx;
                     continue;
-                }
-                if ( memcmp(&l_out->addr, a_addr_from, sizeof (*a_addr_from))==0 ){
-                    dap_chain_tx_used_out_item_t *l_item_back = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
-                    if (!l_item_back) {
-                        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                        dap_list_free_full(l_list_used_out, NULL);
-                        DAP_DELETE(l_objs);
-                        return -6;
+                case TX_ITEM_TYPE_OUT: case TX_ITEM_TYPE_OUT_OLD: case TX_ITEM_TYPE_OUT_EXT:
+                    if ( dap_chain_addr_compare(a_addr_from, &((dap_chain_tx_out_t*)l_item)->addr) ) {
+                        ++l_out_idx;
+                        continue;
                     }
+                    dap_chain_tx_used_out_item_t *l_item_back = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
                     *l_item_back = (dap_chain_tx_used_out_item_t) {
-                            .tx_hash_fast   = l_tx_new_hash,
-                            .num_idx_out    = l_out_idx_tmp,
-                            .value          = l_value_back
+                        .tx_hash_fast   = l_tx_new_hash,
+                        .num_idx_out    = l_out_idx,
+                        .value          = l_value_back
                     };
                     l_list_used_out = dap_list_prepend(l_list_used_out, l_item_back);
                     log_it(L_DEBUG,"Found change back output, stored back in UTXO table");
                     break;
-                 }
-                l_list_tmp = l_list_tmp->next;
-                l_out_idx_tmp++;
+                default:
+                    continue;
+                }
+                break; // Chargeback out found, exit iteration
             }
         }
         SUBTRACT_256_256(l_value_transfer, l_value_pack, &l_value_transfer);
@@ -802,20 +789,20 @@ char* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *a_net, dap_chain_h
             *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_WRONG_ADDR;
         return NULL;
     }
-    dap_chain_hash_fast_t *l_tx_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, a_tx_prev_hash);
-    if (!l_tx_final_hash) {
+    dap_chain_hash_fast_t l_tx_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, a_tx_prev_hash);
+    if ( dap_hash_fast_is_blank(&l_tx_final_hash) ) {
         log_it(L_WARNING, "Requested conditional transaction is already used out");
         if (a_ret_status)
             *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_CANT_FIND_FINAL_TX_HASH;
         return NULL;
     }
-    if (dap_strcmp(a_net->pub.native_ticker, dap_ledger_tx_get_token_ticker_by_hash(l_ledger, l_tx_final_hash))) {
+    if (dap_strcmp(a_net->pub.native_ticker, dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_final_hash))) {
         log_it(L_WARNING, "Pay for service should be only in native token ticker");
         if (a_ret_status)
             *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_NOT_NATIVE_TOKEN;
         return NULL;
     }
-    dap_chain_datum_tx_t *l_tx_cond = dap_ledger_tx_find_by_hash(l_ledger, l_tx_final_hash);
+    dap_chain_datum_tx_t *l_tx_cond = dap_ledger_tx_find_by_hash(l_ledger, &l_tx_final_hash);
     int l_out_cond_idx = 0;
     dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_cond, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, &l_out_cond_idx);
     if (!l_out_cond) {
@@ -844,7 +831,7 @@ char* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *a_net, dap_chain_h
     dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
     dap_chain_datum_tx_add_item(&l_tx, (byte_t*)a_receipt);
     // add 'in_cond' items
-    if (dap_chain_datum_tx_add_in_cond_item(&l_tx, l_tx_final_hash, l_out_cond_idx, 0)) {
+    if (1 != dap_chain_datum_tx_add_in_cond_item(&l_tx, &l_tx_final_hash, l_out_cond_idx, 0)) {
         dap_chain_datum_tx_delete(l_tx);
         log_it( L_ERROR, "Can`t add tx cond input");
         if (a_ret_status)
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index a35ddf846bfc8c4505bf940474bf40bc6ad3181f..e55e10c626bd8b583c78e32971cf788597e45e50 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -602,29 +602,36 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
     bool l_was_tx_recv_allow_copied = false, l_was_tx_recv_block_copied = false,
          l_was_tx_send_allow_copied = false, l_was_tx_send_block_copied = false;
 
-    int ret = DAP_LEDGER_CHECK_OK;
+#define m_ret_cleanup(ret_code) ({                              \
+    DAP_DELETE_COUNT(l_new_pkeys, l_new_signs_total);       \
+    DAP_DEL_MULTY(l_new_tx_recv_allow, l_new_tx_recv_block, \
+                  l_new_tx_send_allow, l_new_tx_send_block, \
+                  l_new_pkeys, l_new_pkey_hashes);          \
+    ret_code; })
+#if 0
+    dap_tsd_t *l_tsd; size_t l_tsd_size;
+    dap_tsd_iter(l_tsd, l_tsd_size, a_tsd, a_tsd_total_size) {
+#else
     uint64_t l_tsd_size = 0;
     dap_tsd_t *l_tsd = (dap_tsd_t *)a_tsd;
     for (uint64_t l_offset = 0; l_offset < a_tsd_total_size; l_offset += l_tsd_size) {
         if (l_offset + sizeof(dap_tsd_t) > a_tsd_total_size || l_offset + sizeof(dap_tsd_t) < l_offset) {
             log_it(L_WARNING, "Incorrect TSD section size, less than header");
-            ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-            goto ret_n_clear;
+            return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
         }
         l_tsd = (dap_tsd_t *)((byte_t *)l_tsd + l_tsd_size);
         l_tsd_size = dap_tsd_size(l_tsd);
         if (l_offset + l_tsd_size > a_tsd_total_size || l_offset + l_tsd_size < l_offset) {
             log_it(L_WARNING, "Wrong TSD size %zu, exiting TSD parse", l_tsd_size);
-            ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-            goto ret_n_clear;
+            return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
         }
+#endif
         switch (l_tsd->type) {
         // set flags
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS: {
             if (l_tsd->size != sizeof(uint16_t)) {
                 log_it(L_WARNING, "Wrong SET_FLAGS TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!a_apply)
                 break;
@@ -635,8 +642,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS: {
             if (l_tsd->size != sizeof(uint16_t)) {
                 log_it(L_WARNING, "Wrong UNSET_FLAGS TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!a_apply)
                 break;
@@ -647,20 +653,17 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY: { // 256
             if (l_tsd->size != sizeof(uint256_t)) {
                 log_it(L_WARNING, "Wrong TOTAL_SUPPLY TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!a_item_apply_to) {
                 log_it(L_WARNING, "Unexpected TOTAL_SUPPLY TSD section in datum token declaration");
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_FORBIDDEN;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_FORBIDDEN);
             }
             uint256_t l_new_supply = dap_tsd_get_scalar(l_tsd, uint256_t);
             if (!IS_ZERO_256(a_item_apply_to->total_supply) && !IS_ZERO_256(l_new_supply) &&
                     compare256(a_item_apply_to->total_supply, l_new_supply) < 0) { //compare old 'total_supply' can be updated
                 log_it(L_WARNING, "Can't update token with ticker '%s' because the new 'total_supply' can't be smaller than the old one", a_item_apply_to->ticker);
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_SUPPLY;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_SUPPLY);
             }
             if (!a_apply)
                 break;
@@ -671,15 +674,13 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
                 log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_ADD TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
             dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t);
             if (dap_chain_addr_check_sum(l_add_addr)) {
                 log_it(L_WARNING, "Wrong address checksum in TSD param TX_RECEIVER_ALLOWED_ADD");
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR);
             }
             if (!l_new_tx_recv_allow && l_new_tx_recv_allow_size && !l_was_tx_recv_allow_copied) {
                 assert(a_item_apply_to->tx_recv_allow);
@@ -687,8 +688,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 l_new_tx_recv_allow = DAP_DUP_SIZE(a_item_apply_to->tx_recv_allow, l_new_tx_recv_allow_size * sizeof(dap_chain_addr_t));
                 if (!l_new_tx_recv_allow) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
             }
             l_was_tx_recv_allow_copied = true;
@@ -697,8 +697,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 if (dap_chain_addr_compare(l_new_tx_recv_allow + i, l_add_addr)) { // Found
                     log_it(L_WARNING, "TSD param TX_RECEIVER_ALLOWED_ADD has address %s thats already present in list",
                                                                     dap_chain_addr_to_str_static(l_add_addr));
-                    ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH);
                 }
             }
             l_new_tx_recv_allow = l_new_tx_recv_allow
@@ -706,8 +705,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                     : DAP_NEW_Z(dap_chain_addr_t);
             if (!l_new_tx_recv_allow) {
                 log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
             }
             l_new_tx_recv_allow[l_new_tx_recv_allow_size++] = *l_add_addr;
         } break;
@@ -715,15 +713,13 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
                 log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
             dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t);
             if (dap_chain_addr_check_sum(l_add_addr)) {
                 log_it(L_WARNING, "Wrong address checksum in TSD param TX_RECEIVER_ALLOWED_REMOVE");
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR);
             }
             if (!l_new_tx_recv_allow && l_new_tx_recv_allow_size && !l_was_tx_recv_allow_copied) {
                 assert(a_item_apply_to->tx_recv_allow);
@@ -731,8 +727,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 l_new_tx_recv_allow = DAP_DUP_SIZE(a_item_apply_to->tx_recv_allow, l_new_tx_recv_allow_size * sizeof(dap_chain_addr_t));
                 if (!l_new_tx_recv_allow) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
             }
             l_was_tx_recv_allow_copied = true;
@@ -744,8 +739,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
             if (i == l_new_tx_recv_allow_size) {
                 log_it(L_WARNING, "TSD param TX_RECEIVER_ALLOWED_REMOVE has address %s thats not present in list",
                         dap_chain_addr_to_str_static(l_add_addr));
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH);
             }
             // Addr removing
             if (--l_new_tx_recv_allow_size > i)
@@ -762,8 +756,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_CLEAR: {
             if (l_tsd->size != 0) {
                 log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             DAP_DEL_Z(l_new_tx_recv_allow);
             l_new_tx_recv_allow_size = 0;
@@ -774,15 +767,13 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
                 log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_ADD TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
             dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t);
             if (dap_chain_addr_check_sum(l_add_addr)) {
                 log_it(L_WARNING, "Wrong address checksum in TSD param TX_RECEIVER_BLOCKED_ADD");
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR);
             }
             if (!l_new_tx_recv_block && l_new_tx_recv_block_size && !l_was_tx_recv_block_copied) {
                 assert(a_item_apply_to->tx_recv_block);
@@ -790,8 +781,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 l_new_tx_recv_block = DAP_DUP_SIZE(a_item_apply_to->tx_recv_block, l_new_tx_recv_block_size * sizeof(dap_chain_addr_t));
                 if (!l_new_tx_recv_block) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
             }
             l_was_tx_recv_block_copied = true;
@@ -800,8 +790,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 if (dap_chain_addr_compare(l_new_tx_recv_block + i, l_add_addr)) { // Found
                     log_it(L_WARNING, "TSD param TX_RECEIVER_BLOCKED_ADD has address %s thats already present in list",
                                                                     dap_chain_addr_to_str_static(l_add_addr));
-                    ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH);
                 }
             }
             l_new_tx_recv_block = l_new_tx_recv_block
@@ -809,8 +798,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                     : DAP_NEW_Z(dap_chain_addr_t);
             if (!l_new_tx_recv_block) {
                 log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
             }
             l_new_tx_recv_block[l_new_tx_recv_block_size++] = *l_add_addr;
         } break;
@@ -818,15 +806,13 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
                 log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
             dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t);
             if (dap_chain_addr_check_sum(l_add_addr)) {
                 log_it(L_WARNING, "Wrong address checksum in TSD param TX_RECEIVER_BLOCKED_REMOVE");
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR);
             }
             if (!l_new_tx_recv_block && l_new_tx_recv_block_size && !l_was_tx_recv_block_copied) {
                 assert(a_item_apply_to->tx_recv_block);
@@ -834,8 +820,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 l_new_tx_recv_block = DAP_DUP_SIZE(a_item_apply_to->tx_recv_block, l_new_tx_recv_block_size * sizeof(dap_chain_addr_t));
                 if (!l_new_tx_recv_block) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
             }
             l_was_tx_recv_block_copied = true;
@@ -847,8 +832,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
             if (i == l_new_tx_recv_block_size) {
                 log_it(L_WARNING, "TSD param TX_RECEIVER_BLOCKED_REMOVE has address %s thats not present in list",
                         dap_chain_addr_to_str_static(l_add_addr));
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH);
             }
             // Addr removing
             if (--l_new_tx_recv_block_size > i)
@@ -865,8 +849,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_CLEAR: {
             if (l_tsd->size != 0) {
                 log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             DAP_DEL_Z(l_new_tx_recv_block);
             l_new_tx_recv_block_size = 0;
@@ -877,15 +860,13 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
                 log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_ADD TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
             dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t);
             if (dap_chain_addr_check_sum(l_add_addr)) {
                 log_it(L_WARNING, "Wrong address checksum in TSD param TX_SENDER_ALLOWED_ADD");
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR);
             }
             if (!l_new_tx_send_allow && l_new_tx_send_allow_size && !l_was_tx_send_allow_copied) {
                 assert(a_item_apply_to->tx_send_allow);
@@ -893,8 +874,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 l_new_tx_send_allow = DAP_DUP_SIZE(a_item_apply_to->tx_send_allow, l_new_tx_send_allow_size * sizeof(dap_chain_addr_t));
                 if (!l_new_tx_send_allow) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
             }
             l_was_tx_send_allow_copied = true;
@@ -903,8 +883,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 if (dap_chain_addr_compare(l_new_tx_send_allow + i, l_add_addr)) { // Found
                     log_it(L_WARNING, "TSD param TX_SENDER_ALLOWED_ADD has address %s thats already present in list",
                                                                     dap_chain_addr_to_str_static(l_add_addr));
-                    ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH);
                 }
             }
             l_new_tx_send_allow = l_new_tx_send_allow
@@ -912,8 +891,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                     : DAP_NEW_Z(dap_chain_addr_t);
             if (!l_new_tx_send_allow) {
                 log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
             }
             l_new_tx_send_allow[l_new_tx_send_allow_size++] = *l_add_addr;
         } break;
@@ -921,15 +899,13 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
                 log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
             dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t);
             if (dap_chain_addr_check_sum(l_add_addr)) {
                 log_it(L_WARNING, "Wrong address checksum in TSD param TX_SENDER_ALLOWED_REMOVE");
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR);
 
             }
             if (!l_new_tx_send_allow && l_new_tx_send_allow_size && !l_was_tx_send_allow_copied) {
@@ -938,8 +914,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 l_new_tx_send_allow = DAP_DUP_SIZE(a_item_apply_to->tx_send_allow, l_new_tx_send_allow_size * sizeof(dap_chain_addr_t));
                 if (!l_new_tx_send_allow) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
             }
             l_was_tx_send_allow_copied = true;
@@ -951,8 +926,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
             if (i == l_new_tx_send_allow_size) {
                 log_it(L_WARNING, "TSD param TX_SENDER_ALLOWED_REMOVE has address %s thats not present in list",
                         dap_chain_addr_to_str_static(l_add_addr));
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH);
             }
             // Addr removing
             if (--l_new_tx_send_allow_size > i)
@@ -969,8 +943,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_CLEAR: {
             if (l_tsd->size != 0) {
                 log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             DAP_DEL_Z(l_new_tx_send_allow);
             l_new_tx_send_allow_size = 0;
@@ -981,15 +954,13 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
                 log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_ADD TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
             dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t);
             if (dap_chain_addr_check_sum(l_add_addr)) {
                 log_it(L_WARNING, "Wrong address checksum in TSD param TX_SENDER_BLOCKED_ADD");
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR);
             }
             if (!l_new_tx_send_block && l_new_tx_send_block_size && !l_was_tx_send_block_copied) {
                 assert(a_item_apply_to->tx_send_block);
@@ -997,8 +968,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 l_new_tx_send_block = DAP_DUP_SIZE(a_item_apply_to->tx_send_block, l_new_tx_send_block_size * sizeof(dap_chain_addr_t));
                 if (!l_new_tx_send_block) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
             }
             l_was_tx_send_block_copied = true;
@@ -1007,8 +977,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 if (dap_chain_addr_compare(l_new_tx_send_block + i, l_add_addr)) { // Found
                     log_it(L_WARNING, "TSD param TX_SENDER_BLOCKED_ADD has address %s thats already present in list",
                                                                     dap_chain_addr_to_str_static(l_add_addr));
-                    ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH);
                 }
             }
             if (!a_apply)
@@ -1018,8 +987,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                     : DAP_NEW_Z(dap_chain_addr_t);
             if (!l_new_tx_send_block) {
                 log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
             }
             l_new_tx_send_block[l_new_tx_send_block_size++] = *l_add_addr;
         } break;
@@ -1027,15 +995,13 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
                 log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
             dap_chain_addr_t *l_add_addr = dap_tsd_get_object(l_tsd, dap_chain_addr_t);
             if (dap_chain_addr_check_sum(l_add_addr)) {
                 log_it(L_WARNING, "Wrong address checksum in TSD param TX_SENDER_BLOCKED_REMOVE");
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR);
             }
             if (!l_new_tx_send_block && l_new_tx_send_block_size && !l_was_tx_send_block_copied) {
                 assert(a_item_apply_to->tx_send_block);
@@ -1043,8 +1009,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 l_new_tx_send_block = DAP_DUP_SIZE(a_item_apply_to->tx_send_block, l_new_tx_send_block_size * sizeof(dap_chain_addr_t));
                 if (!l_new_tx_send_block) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
             }
             l_was_tx_send_block_copied = true;
@@ -1056,8 +1021,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
             if (i == l_new_tx_send_block_size) {
                 log_it(L_WARNING, "TSD param TX_SENDER_BLOCKED_REMOVE has address %s thats not present in list",
                         dap_chain_addr_to_str_static(l_add_addr));
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH);
             }
             // Addr removing
             if (--l_new_tx_send_block_size > i)
@@ -1074,8 +1038,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_CLEAR: {
             if (l_tsd->size != 0) {
                 log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             DAP_DEL_Z(l_new_tx_send_block);
             l_new_tx_send_block_size = 0;
@@ -1085,8 +1048,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION: {
             if (l_tsd->size == 0 || l_tsd->data[l_tsd->size - 1] != 0) {
                 log_it(L_ERROR, "Wrong TOKEN_DESCRIPTION TSD format or size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!a_apply)
                 break;
@@ -1098,8 +1060,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: {
             if (l_tsd->size != sizeof(uint16_t)) {
                 log_it(L_WARNING, "Wrong SIGNS_VALID TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             l_new_signs_valid = dap_tsd_get_scalar(l_tsd, uint16_t);
         } break;
@@ -1107,8 +1068,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD: {
             if (l_tsd->size < sizeof(dap_pkey_t) || l_tsd->size != dap_pkey_get_size((dap_pkey_t *)l_tsd->data)) {
                 log_it(L_WARNING, "Wrong TOTAL_PKEYS_ADD TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!l_new_pkeys && l_new_signs_total && !l_was_pkeys_copied) {
                 assert(a_item_apply_to->auth_pkeys);
@@ -1117,23 +1077,20 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 l_new_pkeys = DAP_NEW_SIZE(dap_pkey_t *, l_new_signs_total * sizeof(dap_pkey_t *));
                 if (!l_new_pkeys) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
                 for (size_t i = 0; i < l_new_signs_total; i++) {
                     l_new_pkeys[i] = DAP_DUP_SIZE(a_item_apply_to->auth_pkeys[i], dap_pkey_get_size(a_item_apply_to->auth_pkeys[i]));
                     if (!l_new_pkeys[i]) {
                         log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                        ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                        goto ret_n_clear;
+                        return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                     }
                 }
                 assert(!l_new_pkey_hashes);
                 l_new_pkey_hashes = DAP_DUP_SIZE(a_item_apply_to->auth_pkey_hashes, l_new_signs_total * sizeof(dap_hash_t));
                 if (!l_new_pkey_hashes) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
             }
             l_was_pkeys_copied = true;
@@ -1144,8 +1101,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 l_pkey_type_correction = dap_pkey_type_from_sign_type(l_sign_type);
                 if (l_pkey_type_correction.type == DAP_PKEY_TYPE_NULL) {
                     log_it(L_WARNING, "Unknonw public key type %hu", l_new_auth_pkey->header.type.type);
-                    ret = DAP_LEDGER_CHECK_PARSE_ERROR;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_PARSE_ERROR);
                 }
             }
             // Check if its already present
@@ -1155,23 +1111,20 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 if (dap_pkey_compare(l_new_auth_pkey, l_new_pkeys[i])) {
                     log_it(L_WARNING, "TSD param TOTAL_PKEYS_ADD has pkey %s thats already present in list",
                                                                     dap_hash_fast_to_str_static(&l_new_auth_pkey_hash));
-                    ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_PKEY_MISMATCH;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_PKEY_MISMATCH);
                 }
             }
             l_new_pkeys = l_new_pkeys ? DAP_REALLOC(l_new_pkeys, (l_new_signs_total + 1) * sizeof(dap_pkey_t *))
                                       : DAP_NEW_Z(dap_pkey_t *);
             if (!l_new_pkeys) {
                 log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
             }
             // Pkey adding
             l_new_pkeys[l_new_signs_total] = DAP_DUP_SIZE(l_new_auth_pkey, dap_pkey_get_size(l_new_auth_pkey));
             if (!l_new_pkeys[l_new_signs_total]) {
                 log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
             }
             if (l_pkey_type_correction.type != DAP_PKEY_TYPE_NULL)
                 l_new_pkeys[l_new_signs_total]->header.type = l_pkey_type_correction;
@@ -1180,8 +1133,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                                                   : DAP_NEW_Z(dap_hash_t);
             if (!l_new_pkey_hashes) {
                 log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
             }
             l_new_pkey_hashes[l_new_signs_total++] = l_new_auth_pkey_hash;
         } break;
@@ -1189,8 +1141,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE: {
             if (l_tsd->size != sizeof(dap_hash_t)) {
                 log_it(L_WARNING, "Wrong TOTAL_PKEYS_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!l_new_pkeys && l_new_signs_total && !l_was_pkeys_copied) {
                 assert(a_item_apply_to->auth_pkeys);
@@ -1199,23 +1150,20 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
                 l_new_pkeys = DAP_NEW_SIZE(dap_pkey_t *, l_new_signs_total * sizeof(dap_pkey_t *));
                 if (!l_new_pkeys) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
                 for (size_t i = 0; i < l_new_signs_total; i++) {
                     l_new_pkeys[i] = DAP_DUP_SIZE(a_item_apply_to->auth_pkeys[i], dap_pkey_get_size(a_item_apply_to->auth_pkeys[i]));
                     if (!l_new_pkeys[i]) {
                         log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                        ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                        goto ret_n_clear;
+                        return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                     }
                 }
                 assert(!l_new_pkey_hashes);
                 l_new_pkey_hashes = DAP_DUP_SIZE(a_item_apply_to->auth_pkey_hashes, l_new_signs_total * sizeof(dap_hash_t));
                 if (!l_new_pkey_hashes) {
                     log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    ret = DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY;
-                    goto ret_n_clear;
+                    return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY);
                 }
             }
             l_was_pkeys_copied = true;
@@ -1228,8 +1176,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
             if (i == l_new_signs_total) {
                 log_it(L_WARNING, "TSD param TOTAL_PKEYS_REMOVE has public key hash %s thats not present in list",
                                                     dap_hash_fast_to_str_static(&l_new_auth_pkey_hash));
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_PKEY_MISMATCH;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_PKEY_MISMATCH);
             }
             // Pkey removing
             DAP_DELETE(l_new_pkeys[i]);
@@ -1248,14 +1195,12 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK: {
             if (a_current_datum->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE) {
                 log_it(L_WARNING, "TSD section DELEGATE_EMISSION_FROM_STAKE_LOCK allowed for NATIVE subtype only");
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_FORBIDDEN;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_FORBIDDEN);
             }
             if (l_tsd->size != sizeof(dap_chain_datum_token_tsd_delegate_from_stake_lock_t) &&
                     l_tsd->size != sizeof(dap_chain_datum_token_tsd_delegate_from_stake_lock_t) + 256 /* Legacy size */) {
                 log_it(L_WARNING, "Wrong DELEGATE_EMISSION_FROM_STAKE_LOCK TSD size %zu, exiting TSD parse", l_tsd_size);
-                ret = DAP_LEDGER_CHECK_INVALID_SIZE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_delegate = dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t);
             const char *l_basic_token_ticker = (const char *)l_delegate->ticker_token_from;
@@ -1263,20 +1208,17 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
             dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker, l_basic_token_ticker);
             if (dap_strcmp(l_delegated_ticker, a_current_datum->ticker)) {
                 log_it(L_WARNING, "Unexpected delegated token ticker %s (expected %s)", a_current_datum->ticker, l_delegated_ticker);
-                ret = DAP_LEDGER_TOKEN_ADD_CHECK_TSD_OTHER_TICKER_EXPECTED;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_TOKEN_ADD_CHECK_TSD_OTHER_TICKER_EXPECTED);
             }
             dap_ledger_token_item_t *l_basic_token = NULL;
             HASH_FIND_STR(PVT(a_ledger)->tokens, l_basic_token_ticker, l_basic_token);
             if (!l_basic_token) {
                 log_it(L_WARNING, "Basic token ticker %s for delegated token isn't found", l_basic_token_ticker);
-                ret = DAP_LEDGER_CHECK_TICKER_NOT_FOUND;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_TICKER_NOT_FOUND);
             }
             if (IS_ZERO_256(l_delegate->emission_rate)) {
                 log_it(L_WARNING, "Emission rate for delegated toke should not be a zero");
-                ret = DAP_LEDGER_CHECK_ZERO_VALUE;
-                goto ret_n_clear;
+                return m_ret_cleanup(DAP_LEDGER_CHECK_ZERO_VALUE);
             }
             if (!a_apply)
                 break;
@@ -1288,54 +1230,47 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         default:
             log_it(L_ERROR, "Unexpected TSD type %hu", l_tsd->type);
-            ret = DAP_LEDGER_CHECK_PARSE_ERROR;
-            goto ret_n_clear;
-        }
-    }
-    if (l_new_signs_total < l_new_signs_valid) {
-        ret = DAP_LEDGER_CHECK_NOT_ENOUGH_VALID_SIGNS;
-        goto ret_n_clear;
-    }
-    if (a_apply) {
-        if (l_was_tx_recv_allow_copied) {
-            a_item_apply_to->tx_recv_allow_size = l_new_tx_recv_allow_size;
-            DAP_DEL_Z(a_item_apply_to->tx_recv_allow);
-            a_item_apply_to->tx_recv_allow = l_new_tx_recv_allow;
-        }
-        if (l_was_tx_recv_block_copied) {
-            a_item_apply_to->tx_recv_block_size = l_new_tx_recv_block_size;
-            DAP_DEL_Z(a_item_apply_to->tx_recv_block);
-            a_item_apply_to->tx_recv_block = l_new_tx_recv_block;
-        }
-        if (l_was_tx_send_allow_copied) {
-            a_item_apply_to->tx_send_allow_size = l_new_tx_send_allow_size;
-            DAP_DEL_Z(a_item_apply_to->tx_send_allow);
-            a_item_apply_to->tx_send_allow = l_new_tx_send_allow;
-        }
-        if (l_was_tx_send_block_copied) {
-            a_item_apply_to->tx_send_block_size = l_new_tx_send_block_size;
-            DAP_DEL_Z(a_item_apply_to->tx_send_block);
-            a_item_apply_to->tx_send_block = l_new_tx_send_block;
-        }
-        a_item_apply_to->auth_signs_valid = l_new_signs_valid;
-        if (l_was_pkeys_copied) {
-            for (size_t i = 0; i < a_item_apply_to->auth_signs_total; i++)
-                DAP_DELETE(a_item_apply_to->auth_pkeys[i]);
-            DAP_DEL_Z(a_item_apply_to->auth_pkeys);
-            DAP_DEL_Z(a_item_apply_to->auth_pkey_hashes);
-            a_item_apply_to->auth_signs_total = l_new_signs_total;
-            a_item_apply_to->auth_pkeys = l_new_pkeys;
-            a_item_apply_to->auth_pkey_hashes = l_new_pkey_hashes;
-        }
-        return DAP_LEDGER_CHECK_OK;
+            return m_ret_cleanup(DAP_LEDGER_CHECK_PARSE_ERROR);
+        }
+    }
+    if (l_new_signs_total < l_new_signs_valid)
+        return m_ret_cleanup(DAP_LEDGER_CHECK_NOT_ENOUGH_VALID_SIGNS);
+
+    if (!a_apply)
+        return m_ret_cleanup(DAP_LEDGER_CHECK_OK);
+#undef m_ret_cleanup
+
+    if (l_was_tx_recv_allow_copied) {
+        a_item_apply_to->tx_recv_allow_size = l_new_tx_recv_allow_size;
+        DAP_DEL_Z(a_item_apply_to->tx_recv_allow);
+        a_item_apply_to->tx_recv_allow = l_new_tx_recv_allow;
+    }
+    if (l_was_tx_recv_block_copied) {
+        a_item_apply_to->tx_recv_block_size = l_new_tx_recv_block_size;
+        DAP_DEL_Z(a_item_apply_to->tx_recv_block);
+        a_item_apply_to->tx_recv_block = l_new_tx_recv_block;
+    }
+    if (l_was_tx_send_allow_copied) {
+        a_item_apply_to->tx_send_allow_size = l_new_tx_send_allow_size;
+        DAP_DEL_Z(a_item_apply_to->tx_send_allow);
+        a_item_apply_to->tx_send_allow = l_new_tx_send_allow;
+    }
+    if (l_was_tx_send_block_copied) {
+        a_item_apply_to->tx_send_block_size = l_new_tx_send_block_size;
+        DAP_DEL_Z(a_item_apply_to->tx_send_block);
+        a_item_apply_to->tx_send_block = l_new_tx_send_block;
+    }
+    a_item_apply_to->auth_signs_valid = l_new_signs_valid;
+    if (l_was_pkeys_copied) {
+        for (size_t i = 0; i < a_item_apply_to->auth_signs_total; i++)
+            DAP_DELETE(a_item_apply_to->auth_pkeys[i]);
+        DAP_DEL_Z(a_item_apply_to->auth_pkeys);
+        DAP_DEL_Z(a_item_apply_to->auth_pkey_hashes);
+        a_item_apply_to->auth_signs_total = l_new_signs_total;
+        a_item_apply_to->auth_pkeys = l_new_pkeys;
+        a_item_apply_to->auth_pkey_hashes = l_new_pkey_hashes;
     }
-    // Checks passed
-ret_n_clear:
-    if (l_new_pkeys)
-        for (size_t i = 0; i < l_new_signs_total; i++)
-            DAP_DELETE(l_new_pkeys[i]);
-    DAP_DEL_MULTY(l_new_tx_recv_allow, l_new_tx_recv_block, l_new_tx_send_allow, l_new_tx_send_block, l_new_pkeys, l_new_pkey_hashes);
-    return ret;
+    return DAP_LEDGER_CHECK_OK;
 }
 
 /**
@@ -1833,127 +1768,119 @@ static void s_tx_header_print(json_object *a_json_out, dap_chain_datum_tx_t *a_t
     json_object_object_add(a_json_out, "time ", json_object_new_string(l_time_str));
 }
 
-static void s_dump_datum_tx_for_addr(dap_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, json_object *json_arr_out) {
+static void s_dump_datum_tx_for_addr(dap_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, json_object *json_arr_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;
+    dap_chain_hash_fast_t l_tx_hash = a_item->tx_hash_fast;
+    dap_chain_addr_t l_src_addr = { }, l_dst_addr = { };
     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;
+    dap_hash_fast_t l_tx_prev_hash = { };
+    byte_t *l_item; size_t l_size; int idx, l_tx_prev_out_idx;
+    TX_ITEM_ITER_TX_TYPE(l_item, TX_ITEM_TYPE_IN_ALL, l_size, idx, l_tx) {
+        switch (*l_item) {
+        case TX_ITEM_TYPE_IN: {
+            dap_chain_tx_in_t *l_tx_in = (dap_chain_tx_in_t*)l_item;
+            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;
+        } break;
+        case TX_ITEM_TYPE_IN_COND: {
+            dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t*)l_item;
+            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;
+        } break;
+        default:
+            continue;
         }
-        if (dap_hash_fast_is_blank(l_tx_prev_hash)) {
+        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);
+            dap_chain_tx_in_ems_t *l_token = (dap_chain_tx_in_ems_t*)
+                dap_chain_datum_tx_item_get(l_tx, NULL, NULL, TX_ITEM_TYPE_IN_EMS, NULL);
             if (l_token)
                 l_src_token = l_token->header.ticker;
             break;
         }
-        l_tx_prev = dap_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
+        dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash(a_ledger, &l_tx_prev_hash);
+        if ( !l_tx_prev )
+            continue;
+        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;
         }
-        if (!l_src_token){
+        if ( !dap_chain_addr_compare(&l_src_addr, a_addr) )
+            break;  //it's not our addr
+        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)
-        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;
+    l_item = NULL;
+    TX_ITEM_ITER_TX_TYPE(l_item, TX_ITEM_TYPE_OUT_ALL, l_size, idx, l_tx) {
+        dap_chain_tx_item_type_t l_type = *l_item;
         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;
+            l_dst_addr = ((dap_chain_tx_out_t*)l_item)->addr;
+            l_value = ((dap_chain_tx_out_t*)l_item)->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;
+            l_dst_addr = ((dap_chain_tx_out_ext_t*)l_item)->addr;
+            l_value = ((dap_chain_tx_out_ext_t *)l_item)->header.value;
             break;
         case TX_ITEM_TYPE_OUT_COND:
-            l_value = ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.value;
+            l_value = ((dap_chain_tx_out_cond_t *)l_item)->header.value;
         default:
             break;
         }
-        if (l_src_addr && l_dst_addr && !memcmp(l_dst_addr, l_src_addr, sizeof(dap_chain_addr_t)))
+        if ( !dap_chain_addr_is_blank(&l_src_addr) && !dap_chain_addr_is_blank(&l_dst_addr) 
+            && dap_chain_addr_compare(&l_dst_addr, &l_src_addr) )
             continue;   // send to self
-        if (l_src_addr && !memcmp(l_src_addr, a_addr, sizeof(dap_chain_addr_t))) {
+        if ( dap_chain_addr_compare(&l_src_addr, a_addr)) {
             json_object * l_json_obj_datum = json_object_new_object();
             if (!l_header_printed) {
-                s_tx_header_print(l_json_obj_datum, l_tx, a_hash_out_type, l_tx_hash);
+                s_tx_header_print(l_json_obj_datum, l_tx, a_hash_out_type, &l_tx_hash);
                 l_header_printed = true;
             }
             //const char *l_token_ticker = dap_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_static(l_dst_addr)
-                                                    : dap_chain_tx_out_cond_subtype_to_str(
-                                                          ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.subtype);
+            const char *l_dst_addr_str = !dap_chain_addr_is_blank(&l_dst_addr) 
+                ? dap_chain_addr_to_str_static(&l_dst_addr)
+                : dap_chain_tx_out_cond_subtype_to_str( ((dap_chain_tx_out_cond_t *)l_item)->header.subtype );
             json_object_object_add(l_json_obj_datum, "send", json_object_new_string(dap_uint256_to_char(l_value, NULL)));
             json_object_object_add(l_json_obj_datum, "to addr", json_object_new_string(l_dst_addr_str));
             json_object_object_add(l_json_obj_datum, "token", l_src_token ? json_object_new_string(l_src_token) : json_object_new_string("UNKNOWN"));
             json_object_array_add(json_arr_out, l_json_obj_datum);
         }
-        if (l_dst_addr && !memcmp(l_dst_addr, a_addr, sizeof(dap_chain_addr_t))) {
+        if ( dap_chain_addr_compare(&l_dst_addr, a_addr) ) {
             json_object * l_json_obj_datum = json_object_new_object();
             if (!l_header_printed) {
-               s_tx_header_print(l_json_obj_datum, l_tx, a_hash_out_type, l_tx_hash);
+               s_tx_header_print(l_json_obj_datum, 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_static(l_src_addr)
-                                                                 : dap_chain_tx_out_cond_subtype_to_str(
-                                                                       l_src_subtype));
+                        (const char *)(((dap_chain_tx_out_ext_t *)l_item)->token) : NULL;
+            const char *l_src_addr_str = l_base_tx 
+                ? "emission"
+                : ( !dap_chain_addr_is_blank(&l_src_addr) 
+                    ? dap_chain_addr_to_str_static(&l_src_addr)
+                    : dap_chain_tx_out_cond_subtype_to_str(l_src_subtype) );
             json_object_object_add(l_json_obj_datum, "recv ", json_object_new_string(dap_uint256_to_char(l_value, NULL)));
             json_object_object_add(l_json_obj_datum, "token ", l_dst_token ? json_object_new_string(l_dst_token) :
                                   (l_src_token ? json_object_new_string(l_src_token) : json_object_new_string("UNKNOWN")));
@@ -1961,7 +1888,6 @@ static void s_dump_datum_tx_for_addr(dap_ledger_tx_item_t *a_item, bool a_unspen
             json_object_array_add(json_arr_out, l_json_obj_datum);
         }
     }
-    dap_list_free(l_list_out_items);
 }
 
 json_object *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)
@@ -3185,14 +3111,11 @@ const char *dap_ledger_get_description_by_ticker(dap_ledger_t *a_ledger, const c
  *
  * 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, const dap_chain_hash_fast_t *a_tx_hash,
+dap_chain_datum_tx_t* dap_ledger_tx_find_datum_by_hash(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash,
                                                      dap_ledger_tx_item_t **a_item_out, bool a_unspent_only)
 {
-    if(!a_tx_hash)
+    if ( !a_tx_hash || dap_hash_fast_is_blank(a_tx_hash) )
         return NULL;
-
-//    log_it( L_ERROR, "s_find_datum_tx_by_hash( )...");
-
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
     dap_chain_datum_tx_t *l_tx_ret = NULL;
     dap_ledger_tx_item_t *l_tx_item = NULL;
@@ -3209,84 +3132,51 @@ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger, con
     return l_tx_ret;
 }
 
-/**
- * @brief dap_ledger_tx_find_by_hash
- * @param a_tx_hash
- * @return
- */
-
-dap_chain_datum_tx_t *dap_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash)
+dap_hash_fast_t dap_ledger_get_first_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_cond_out)
 {
-    return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL, false);
+    dap_hash_fast_t l_hash = { }, l_hash_tmp;
+    if (!a_ledger || !a_cond_out || !a_tx){
+        log_it(L_ERROR, "Argument is NULL in dap_ledger_get_first_chain_tx_hash()");
+        return l_hash;
+    }
+    dap_chain_datum_tx_t *l_prev_tx = a_tx;
+    dap_chain_tx_in_cond_t *l_in_cond = NULL;
+    dap_chain_tx_out_cond_t *l_out_cond = NULL;
+    
+    size_t l_size = 0;
+    while (( l_in_cond = (dap_chain_tx_in_cond_t*)dap_chain_datum_tx_item_get(l_prev_tx, NULL, (byte_t*)l_out_cond + l_size, TX_ITEM_TYPE_IN_COND, NULL) )) {
+        l_hash_tmp = l_in_cond->header.tx_prev_hash;
+        if ( dap_hash_fast_is_blank(&l_hash_tmp) )
+            return l_hash_tmp;
+        l_size = 0;
+        if (( l_prev_tx = dap_ledger_tx_find_by_hash(a_ledger, &l_hash_tmp) ) && ( l_out_cond = dap_chain_datum_tx_out_cond_get(l_prev_tx, a_cond_out->header.subtype, NULL) )) {
+            l_size = dap_chain_datum_item_tx_get_size((const byte_t*)l_out_cond, (byte_t*)l_out_cond - l_prev_tx->tx_items);
+            l_hash = l_hash_tmp;
+        }
+    }
+    return l_hash;
 }
 
-dap_chain_datum_tx_t *dap_ledger_tx_unspent_find_by_hash(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash)
-{
-    return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL, true);
-}
-dap_hash_fast_t *dap_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)
+dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash)
 {
+    dap_chain_hash_fast_t l_hash = { }, l_hash_tmp;
     if (!a_ledger || !a_tx_hash || dap_hash_fast_is_blank(a_tx_hash))
-        return NULL;
-    dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
+        return l_hash;
+    
+    dap_chain_datum_tx_t *l_tx = NULL;
+    l_hash = *a_tx_hash;
+    int l_out_num = 0;
     dap_ledger_tx_item_t *l_item = NULL;
-    unsigned l_hash_value;
-    dap_chain_hash_fast_t *l_tx_hash = a_tx_hash;
-    pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
-    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) {
-            l_tx_hash = NULL;
-            break;      // Not found in ledger
-        }
-        int l_out_num = 0;
-        if (!dap_chain_datum_tx_out_cond_get(l_item->tx, a_cond_type, &l_out_num) || dap_hash_fast_is_blank(&l_item->cache_data.tx_hash_spent_fast[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
-        }
-    }
-    pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
-    return l_tx_hash;
-}
-
-dap_hash_fast_t* dap_ledger_get_first_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_t *a_cond_out)
-{
-    dap_hash_fast_t *l_ret_hash = NULL;
-
-    if (!a_ledger || !a_cond_out || !a_tx){
-        log_it(L_ERROR, "Argument is NULL in dap_ledger_get_first_chain_tx_hash()");
-        return NULL;
-    }
-
-    dap_chain_tx_out_cond_subtype_t l_type = a_cond_out->header.subtype;
-
-    int l_item_idx = 0;
-    dap_chain_datum_tx_t * l_prev_tx = a_tx;
-    byte_t *l_tx_item_temp = NULL;
-    dap_hash_fast_t l_hash = {};
-    while((l_tx_item_temp = dap_chain_datum_tx_item_get(l_prev_tx, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL)) != NULL){
-        dap_chain_tx_in_cond_t * l_in_cond_temp = (dap_chain_tx_in_cond_t *) l_tx_item_temp;
-        dap_chain_datum_tx_t *l_prev_tx_temp = dap_ledger_tx_find_by_hash(a_ledger, &l_in_cond_temp->header.tx_prev_hash);
-        dap_chain_tx_out_cond_t *l_out_cond_temp = dap_chain_datum_tx_out_cond_get(l_prev_tx_temp, l_type, NULL);
-        if (l_out_cond_temp){
-            l_item_idx = l_in_cond_temp->header.tx_out_prev_idx;
-            l_hash = l_in_cond_temp->header.tx_prev_hash;
-        }
-        l_prev_tx = l_prev_tx_temp;
-    }
-
-    if(l_prev_tx && !dap_hash_fast_is_blank(&l_hash)){
-        l_ret_hash = DAP_NEW_SIZE(dap_hash_fast_t, sizeof(dap_hash_fast_t));
-        *l_ret_hash = l_hash;
+    while (( l_tx = dap_ledger_tx_find_datum_by_hash(a_ledger, &l_hash, &l_item, false) )) {
+        l_hash_tmp = l_item->cache_data.tx_hash_spent_fast[l_out_num];
+        if ( !dap_chain_datum_tx_out_cond_get(l_tx, a_cond_type, &l_out_num)
+            || dap_hash_fast_is_blank(&l_hash_tmp) )
+            break;
+        l_hash = l_hash_tmp;
     }
-
-    return l_ret_hash;
+    return l_hash;
 }
 
-
 /**
  * Check whether used 'out' items (local function)
  */
@@ -3338,7 +3228,7 @@ static int s_callback_sign_compare(dap_list_t *a_list_elem, dap_list_t *a_sign_e
 
 bool dap_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx)
 {
-    dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
+    dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
     dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig);
     return dap_list_find(a_ledger->net->pub.keys, l_sign, s_callback_sign_compare);
 }
@@ -3457,9 +3347,8 @@ bool dap_ledger_deduct_tx_tag(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
     if (l_deductions_ok > 1)
     {
         char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-        dap_chain_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
-        dap_chain_hash_fast_to_str(l_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
-
+        dap_chain_hash_fast_t l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
+        dap_chain_hash_fast_to_str(&l_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
 
         log_it(L_WARNING, "Transaction %s identyfied by multiple services (%d):", l_tx_hash_str, l_deductions_ok);
     
@@ -3585,11 +3474,11 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
             }
             dap_hash_fast_t *l_emission_hash = &l_tx_in_ems->header.token_emission_hash;
             // 2. Check current transaction for doubles in input items list
-            for (dap_list_t *l_iter = l_list_in; l_iter; l_iter = l_iter->next) {
+            for (dap_list_t *l_iter = it->next; l_iter; l_iter = l_iter->next) {
                 dap_chain_tx_in_ems_t *l_in_ems_check = l_iter->data;
-                if (l_tx_in_ems != l_in_ems_check &&
-                        l_in_ems_check->header.type == TX_ITEM_TYPE_IN_EMS &&
-                        dap_hash_fast_compare(&l_in_ems_check->header.token_emission_hash, l_emission_hash) && !a_check_for_removing) {
+                if (l_in_ems_check->header.type == TX_ITEM_TYPE_IN_EMS &&
+                    dap_hash_fast_compare(&l_in_ems_check->header.token_emission_hash, l_emission_hash) && !a_check_for_removing)
+                {
                     debug_if(s_debug_more, L_ERROR, "Emission output already used in current tx");
                     l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX;
                     break;
@@ -3670,7 +3559,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
                 uint256_t l_stake_lock_ems_value = {};
                 int l_item_idx = 0;
                 do {
-                    l_tx_out_ext = (dap_chain_tx_out_ext_t *)dap_chain_datum_tx_item_get(a_tx, &l_item_idx, TX_ITEM_TYPE_OUT_EXT, NULL);
+                    l_tx_out_ext = (dap_chain_tx_out_ext_t *)dap_chain_datum_tx_item_get(a_tx, &l_item_idx, NULL, TX_ITEM_TYPE_OUT_EXT, NULL);
                     if (!l_tx_out_ext) {
                         if (l_girdled_ems) {
                             debug_if(s_debug_more, L_WARNING, "No OUT_EXT for girdled IN_EMS [%s]", l_tx_in_ems->header.ticker);
@@ -3681,7 +3570,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
                     l_item_idx++;
                 } while (strcmp(l_tx_out_ext->token, l_token));
                 if (!l_tx_out_ext) {
-                    dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_OUT, NULL);
+                    dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_OUT, NULL);
                     if (!l_tx_out) {
                         debug_if(true, L_WARNING, "Can't find OUT nor OUT_EXT item for base TX with IN_EMS [%s]", l_tx_in_ems->header.ticker);
                         l_err_num = DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX;
@@ -3765,7 +3654,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
                 break;
             if (!l_tx_first_sign_pkey) {
                 // Get sign item
-                dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL,
+                dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL, NULL,
                         TX_ITEM_TYPE_SIG, NULL);
                 assert(l_tx_sig);
                 // Get sign from sign item
@@ -3872,7 +3761,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
             }
             // Get previous transaction in the cache by hash
             dap_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, false);
+            l_tx_prev = dap_ledger_tx_find_datum_by_hash(a_ledger, l_tx_prev_hash, &l_item_out, false);
             char l_tx_prev_hash_str[DAP_HASH_FAST_STR_SIZE];
             dap_hash_fast_to_str(l_tx_prev_hash, l_tx_prev_hash_str, DAP_HASH_FAST_STR_SIZE);
             if (!l_tx_prev) { // Unchained transaction or previous TX was already spent and removed from ledger
@@ -3907,7 +3796,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
             }
             if (dap_hash_fast_is_blank(&l_tx_first_sign_pkey_hash)) {
                 // Get sign item
-                dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL,
+                dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL, NULL,
                         TX_ITEM_TYPE_SIG, NULL);
                 assert(l_tx_sig);
                 // Get sign from sign item
@@ -3976,15 +3865,13 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
 
                 // 5a. Check for condition owner
                 // Get owner tx
-                dap_hash_fast_t *l_owner_tx_hash = dap_ledger_get_first_chain_tx_hash(a_ledger, l_tx_prev, l_tx_prev_out_cond);
-                dap_chain_datum_tx_t *l_owner_tx = l_tx_prev;
-                if (l_owner_tx_hash){
-                    l_owner_tx = dap_ledger_tx_find_by_hash(a_ledger, l_owner_tx_hash);
-                    DAP_DEL_Z(l_owner_tx_hash);
-                }
-                dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
+                dap_hash_fast_t l_owner_tx_hash = dap_ledger_get_first_chain_tx_hash(a_ledger, l_tx_prev, l_tx_prev_out_cond);
+                dap_chain_datum_tx_t *l_owner_tx = dap_hash_fast_is_blank(&l_owner_tx_hash)
+                    ? l_tx_prev
+                    : dap_ledger_tx_find_by_hash(a_ledger, &l_owner_tx_hash);
+                dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
                 dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig);
-                dap_chain_tx_sig_t *l_owner_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_owner_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
+                dap_chain_tx_sig_t *l_owner_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_owner_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
                 dap_sign_t *l_owner_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_owner_tx_sig);
 
                 bool l_owner = false;
@@ -4056,9 +3943,8 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
         }
     }
 
-    if (l_list_in)
-        dap_list_free(l_list_in);
-    DAP_DEL_Z(l_tx_first_sign_pkey);
+    dap_list_free(l_list_in);
+    DAP_DELETE(l_tx_first_sign_pkey);
     if (l_err_num) {
         if ( l_list_bound_items )
             dap_list_free_full(l_list_bound_items, NULL);
@@ -4104,16 +3990,15 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
     bool l_tax_check = l_key_item && !dap_chain_addr_is_blank(&l_key_item->sovereign_addr) && !IS_ZERO_256(l_key_item->sovereign_tax);
 
     // find 'out' items
-    dap_list_t *l_list_out = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) a_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
     uint256_t l_value = {}, l_fee_sum = {}, l_tax_sum = {};
     bool l_fee_check = !IS_ZERO_256(a_ledger->net->pub.fee_value) && !dap_chain_addr_is_blank(&a_ledger->net->pub.fee_addr);
     int l_item_idx = 0;
-    for (dap_list_t *it = l_list_out; it; it = it->next, l_item_idx++) {
-        dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data;
-        dap_chain_addr_t l_tx_out_to={0};
-        switch (l_type) {
+    byte_t *it; size_t l_size;
+    TX_ITEM_ITER_TX(it, l_size, a_tx) {
+        dap_chain_addr_t l_tx_out_to = { };
+        switch ( *it ) {
         case TX_ITEM_TYPE_OUT_OLD: {
-            dap_chain_tx_out_old_t *l_tx_out = (dap_chain_tx_out_old_t *)it->data;
+            dap_chain_tx_out_old_t *l_tx_out = (dap_chain_tx_out_old_t*)it;
             if (l_multichannel) { // token ticker is mandatory for multichannel transactions
                 l_err_num = DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER;
                 break;
@@ -4123,7 +4008,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
             l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out);
         } break;
         case TX_ITEM_TYPE_OUT: { // 256
-            dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)it->data;
+            dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)it;
             if (l_multichannel) { // token ticker is mandatory for multichannel transactions
                 if (l_main_ticker)
                     l_token = l_main_ticker;
@@ -4137,7 +4022,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
             l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out);
         } break;
         case TX_ITEM_TYPE_OUT_EXT: { // 256
-            dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)it->data;
+            dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)it;
             if (!l_multichannel) { // token ticker is forbiden for single-channel transactions
                 l_err_num = DAP_LEDGER_TX_CHECK_UNEXPECTED_TOKENIZED_OUT;
                 break;
@@ -4148,7 +4033,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
             l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out);
         } break;
         case TX_ITEM_TYPE_OUT_COND: {
-            dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t *)it->data;
+            dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t *)it;
             if (l_multichannel) {
                 if (l_tx_out->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE)
                     l_token = (char *)a_ledger->net->pub.native_ticker;
@@ -4169,8 +4054,10 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
                 break;
             }
         } break;
-        default: {}
+        default:
+            continue;
         }
+
         if (l_err_num)
             break;
         if (l_multichannel) {
@@ -4215,9 +4102,6 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
             SUM_256_256(l_tax_sum, l_value, &l_tax_sum);
     }
 
-    if ( l_list_out )
-        dap_list_free(l_list_out);
-
     // Check for transaction consistency (sum(ins) == sum(outs))
     if (!l_err_num) {
         HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) {
@@ -4271,8 +4155,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
 
     if (!l_err_num) {
         // TODO move it to service tag deduction
-        dap_list_t *l_items_voting;
-        if ((l_items_voting = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) a_tx, TX_ITEM_TYPE_VOTING, NULL))) {
+        if ( dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_VOTING, NULL ) ) {
             if (s_voting_callbacks.voting_callback){
                 if (!s_voting_callbacks.voting_callback(a_ledger, TX_ITEM_TYPE_VOTING, a_tx, false)){
                     debug_if(s_debug_more, L_WARNING, "Verificator check error for voting.");
@@ -4282,10 +4165,9 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
                 debug_if(s_debug_more, L_WARNING, "Verificator check error for voting item");
                 l_err_num = DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET;
             }
-            dap_list_free(l_items_voting);
             if (a_tag)
                 a_tag->uint64 = DAP_CHAIN_TX_TAG_ACTION_VOTING;
-        }else if ((l_items_voting = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) a_tx, TX_ITEM_TYPE_VOTE, NULL))) {
+        } else if ( dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_VOTE, NULL) ) {
            if (s_voting_callbacks.voting_callback){
                if (!s_voting_callbacks.voting_callback(a_ledger, TX_ITEM_TYPE_VOTE, a_tx, false)){
                    debug_if(s_debug_more, L_WARNING, "Verificator check error for vote.");
@@ -4295,7 +4177,6 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
                debug_if(s_debug_more, L_WARNING, "Verificator check error for vote item");
                l_err_num = DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET;
            }
-           dap_list_free(l_items_voting);
            if (a_tag)
                a_tag->uint64 = DAP_CHAIN_TX_TAG_ACTION_VOTE;
         }
@@ -5255,7 +5136,7 @@ uint64_t dap_ledger_count_from_to(dap_ledger_t * a_ledger, dap_nanotime_t a_ts_f
 bool dap_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_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, false);
+    /*dap_chain_datum_tx_t *l_tx =*/ dap_ledger_tx_find_datum_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;
 }
 
@@ -5299,76 +5180,42 @@ uint256_t dap_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_a
     HASH_ITER(hh, l_ledger_pvt->ledger_items , l_iter_current, l_item_tmp)
     {
         dap_chain_datum_tx_t *l_cur_tx = l_iter_current->tx;
-
-        //        dap_chain_hash_fast_t *l_cur_tx_hash = &l_iter_current->tx_hash_fast;
-        //        int l_n_outs_used = l_iter_current->n_outs_used; // number of used 'out' items
-
         // Get 'out' items from transaction
-        int l_out_item_count = 0;
-        dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_cur_tx, TX_ITEM_TYPE_OUT_ALL, &l_out_item_count);
-        if(l_out_item_count >= MAX_OUT_ITEMS) {
-            if(s_debug_more)
-                log_it(L_ERROR, "Too many 'out' items=%d in transaction (max=%d)", l_out_item_count, MAX_OUT_ITEMS);
-            if (l_out_item_count >= MAX_OUT_ITEMS){
-                // uint128_t l_ret;
-                uint256_t l_ret = uint256_0;
-                memset(&l_ret,0,sizeof(l_ret));
-                return l_ret;
-            }
-        }
-        int l_out_idx_tmp = 0;
-        for (dap_list_t *it = l_list_out_items; it; it = it->next, l_out_idx_tmp++) {
-            assert(it->data);
-            dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data;
-            if (l_type == TX_ITEM_TYPE_OUT_COND)
+        int l_out_idx = 0;
+        byte_t *it; size_t l_size;
+        TX_ITEM_ITER_TX(it, l_size, l_cur_tx) {
+            if ( l_out_idx > MAX_OUT_ITEMS )
+                return log_it(L_ERROR, "Number of 'out' items exeeds max number %d", MAX_OUT_ITEMS), uint256_0;
+            uint256_t l_add = { };
+            dap_chain_addr_t l_out_addr = { };
+            switch (*it) {
+            case TX_ITEM_TYPE_OUT_OLD: {
+                dap_chain_tx_out_old_t *l_tx_out = (dap_chain_tx_out_old_t*)it;
+                l_add = dap_chain_uint256_from(l_tx_out->header.value);
+                l_out_addr = l_tx_out->addr;
+            } break;
+            case TX_ITEM_TYPE_OUT: {
+                dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t*)it;
+                l_add = l_tx_out->header.value;
+                l_out_addr = l_tx_out->addr;
+            } break;
+            case TX_ITEM_TYPE_OUT_EXT: {
+                dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t*)it;
+                l_add = l_tx_out->header.value;
+                l_out_addr = l_tx_out->addr;
+            } break;
+            case TX_ITEM_TYPE_OUT_COND:
+                ++l_out_idx;
+            default:
                 continue;
-            if (l_type == TX_ITEM_TYPE_OUT_OLD) { // 64
-                const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t*) it->data;
-                // Check for token name
-                if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_ticker))
-                {   // if transaction has the out item with requested addr
-                    if (!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) {
-                        // if 'out' item not used & transaction is valid
-                        if(!s_ledger_tx_hash_is_used_out_item(l_iter_current, l_out_idx_tmp, NULL) &&
-                                !dap_chain_datum_tx_verify_sign(l_cur_tx)) {
-                            uint256_t l_add = dap_chain_uint256_from(l_tx_out->header.value);
-                            SUM_256_256(balance, l_add, &balance);
-                        }
-                    }
-                }
-            }
-            if (l_type == TX_ITEM_TYPE_OUT) { // 256
-                const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) it->data;
-                // const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t*) it->data;
-                // Check for token name
-                if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_ticker))
-                {   // if transaction has the out item with requested addr
-                    if (!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) {
-                        // if 'out' item not used & transaction is valid
-                        if(!s_ledger_tx_hash_is_used_out_item(l_iter_current, l_out_idx_tmp, NULL) &&
-                                !dap_chain_datum_tx_verify_sign(l_cur_tx)) {
-                            SUM_256_256(balance, l_tx_out->header.value, &balance);
-                        }
-                    }
-                }
-            }
-            if (l_type == TX_ITEM_TYPE_OUT_EXT) { // 256
-                const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) it->data;
-                // const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) it->data;
-                // Check for token name
-                if (!strcmp(a_token_ticker, l_tx_out->token))
-                {   // if transaction has the out item with requested addr
-                    if (!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) {
-                        // if 'out' item not used & transaction is valid
-                        if(!s_ledger_tx_hash_is_used_out_item(l_iter_current, l_out_idx_tmp, NULL) &&
-                                !dap_chain_datum_tx_verify_sign(l_cur_tx)) {
-                            SUM_256_256(balance, l_tx_out->header.value, &balance);
-                        }
-                    }
-                }
             }
+            ++l_out_idx;
+            if (    !dap_strcmp( a_token_ticker, l_iter_current->cache_data.token_ticker )  // Tokens match
+                &&  !dap_chain_addr_compare( a_addr, &l_out_addr )                          // Addresses match
+                &&  !s_ledger_tx_hash_is_used_out_item( l_iter_current, l_out_idx, NULL )   // Output is unused
+                &&  !dap_chain_datum_tx_verify_sign(l_cur_tx)                               // Signs are valid
+                ) SUM_256_256(balance, l_add, &balance);
         }
-        dap_list_free(l_list_out_items);
     }
     pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
     return balance;
@@ -5387,9 +5234,7 @@ static dap_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const
     if(!a_addr || !a_tx_first_hash)
         return NULL;
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    bool is_tx_found = false;
-    bool is_null_hash = dap_hash_fast_is_blank(a_tx_first_hash);
-    bool is_search_enable = is_null_hash;
+    bool is_tx_found = false, is_search_started = dap_hash_fast_is_blank(a_tx_first_hash);
     dap_ledger_tx_item_t *l_iter_current, *l_item_tmp;
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
     HASH_ITER(hh, l_ledger_pvt->ledger_items , l_iter_current, l_item_tmp)
@@ -5403,60 +5248,40 @@ static dap_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const
         dap_chain_datum_tx_t *l_tx = l_iter_current->tx;
         dap_chain_hash_fast_t *l_tx_hash = &l_iter_current->tx_hash_fast;
         // start searching from the next hash after a_tx_first_hash
-        if(!is_search_enable) {
-            if(dap_hash_fast_compare(l_tx_hash, a_tx_first_hash))
-                is_search_enable = true;
+        if (!is_search_started) {
+            is_search_started = !dap_hash_fast_compare(l_tx_hash, a_tx_first_hash);
             continue;
         }
         // Get 'out' items from transaction
-        dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
-        for(dap_list_t *it = l_list_out_items; it; it = dap_list_next(it)) {
-            assert(it->data);
-            dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data;
-            if (l_type == TX_ITEM_TYPE_OUT_COND)
+        byte_t *it; size_t l_size;
+        TX_ITEM_ITER_TX(it, l_size, l_tx) {
+            dap_chain_addr_t l_addr = { };
+            switch (*it) {
+            case TX_ITEM_TYPE_OUT:
+                l_addr = ((dap_chain_tx_out_t*)it)->addr;
+                break;
+            case TX_ITEM_TYPE_OUT_OLD:
+                l_addr = ((dap_chain_tx_out_old_t*)it)->addr;
+                break;
+            case TX_ITEM_TYPE_OUT_EXT:
+                if ( a_token && dap_strcmp(a_token, ((dap_chain_tx_out_ext_t*)it)->token) )
+                    continue;
+                l_addr = ((dap_chain_tx_out_ext_t*)it)->addr;
+                break;
+            default:
                 continue;
-            if (l_type == TX_ITEM_TYPE_OUT) {
-                const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t *)it->data;
-                // if transaction has the out item with requested addr
-                if(!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) {
-                    memcpy(a_tx_first_hash, l_tx_hash, sizeof(dap_chain_hash_fast_t));
-                    is_tx_found = true;
-                    break;
-                }
-            }
-            if (l_type == TX_ITEM_TYPE_OUT_OLD) {
-                const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t *)it->data;
-                // if transaction has the out item with requested addr
-                if(!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) {
-                    memcpy(a_tx_first_hash, l_tx_hash, sizeof(dap_chain_hash_fast_t));
-                    is_tx_found = true;
-                    break;
-                }
             }
-            if (l_type == TX_ITEM_TYPE_OUT_EXT) {
-                const dap_chain_tx_out_ext_t *l_tx_out_ext = (const dap_chain_tx_out_ext_t *)it->data;
-                // If a_token is setup we check if its not our token - miss it
-                if (a_token && dap_strcmp(l_tx_out_ext->token, a_token)) {
-                    continue;
-                }                // if transaction has the out item with requested addr
-                if(!memcmp(a_addr, &l_tx_out_ext->addr, sizeof(dap_chain_addr_t))) {
-                    memcpy(a_tx_first_hash, l_tx_hash, sizeof(dap_chain_hash_fast_t));
-                    is_tx_found = true;
-                    break;
-                }
+            if ( !dap_chain_addr_compare(a_addr, &l_addr) ) {
+                *a_tx_first_hash = *l_tx_hash;
+                is_tx_found = true;
+                break;
             }
         }
-        dap_list_free(l_list_out_items);
-        // already found transaction
-        if(is_tx_found)
+        if (is_tx_found)
             break;
-
     }
     pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
-    if(is_tx_found)
-        return l_iter_current;
-    else
-        return NULL;
+    return is_tx_found ? l_iter_current : NULL;
 }
 
 /**
@@ -5474,34 +5299,29 @@ static dap_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const
 
  bool dap_ledger_tx_check_recipient(dap_ledger_t* a_ledger, dap_chain_hash_fast_t* a_tx_prev_hash, dap_chain_addr_t *a_addr)
  {
-     dap_chain_datum_tx_t *l_tx;
-     l_tx = dap_ledger_tx_find_by_hash(a_ledger,a_tx_prev_hash);
-     dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL), *l_item;
-     if(!l_list_out_items)
-         return false;
-     bool l_ret = false;
-     DL_FOREACH(l_list_out_items, l_item) {
-         dap_chain_addr_t *l_dst_addr = NULL;
-         dap_chain_tx_item_type_t l_type = *(uint8_t*)l_item->data;
-         switch (l_type) {
-         case TX_ITEM_TYPE_OUT:
-             l_dst_addr = &((dap_chain_tx_out_t*)l_item->data)->addr;
-             break;
-         case TX_ITEM_TYPE_OUT_EXT:
-             l_dst_addr = &((dap_chain_tx_out_ext_t*)l_item->data)->addr;
-             break;
-         case TX_ITEM_TYPE_OUT_OLD:
-             l_dst_addr = &((dap_chain_tx_out_old_t*)l_item->data)->addr;
-         default:
-             break;
-         }
-         if(l_dst_addr && !memcmp(l_dst_addr, a_addr, sizeof(dap_chain_addr_t))) {
-             l_ret = true;
-             break;
-         }
-     }
-     dap_list_free(l_list_out_items);
-     return l_ret;
+     dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(a_ledger, a_tx_prev_hash);
+     if ( !l_tx )
+        return false;
+    dap_chain_addr_t l_dst_addr = { };
+    byte_t *it; size_t l_size;
+    TX_ITEM_ITER_TX(it, l_size, l_tx) {
+        switch (*it) {
+        case TX_ITEM_TYPE_OUT:
+            l_dst_addr = ((dap_chain_tx_out_t*)it)->addr;
+            break;
+        case TX_ITEM_TYPE_OUT_EXT:
+            l_dst_addr = ((dap_chain_tx_out_ext_t*)it)->addr;
+            break;
+        case TX_ITEM_TYPE_OUT_OLD:
+            l_dst_addr = ((dap_chain_tx_out_old_t*)it)->addr;
+            break;
+        default:
+            continue;
+        }
+        if ( dap_chain_addr_compare(a_addr, &l_dst_addr) )
+            return true;
+    }
+    return false;
  }
 
 /**
@@ -5534,7 +5354,7 @@ const dap_chain_datum_tx_t* dap_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger,
         }
         // Get sign item from transaction
         dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(l_tx_tmp, NULL,
-                TX_ITEM_TYPE_SIG, NULL);
+                NULL, TX_ITEM_TYPE_SIG, NULL);
         // Get dap_sign_t from item
         dap_sign_t *l_sig = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig);
         if(l_sig) {
@@ -5564,12 +5384,11 @@ dap_list_t* dap_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, dap_ch
     dap_ledger_tx_item_t *l_iter_current = NULL, *l_item_tmp = NULL;
     HASH_ITER(hh, l_ledger_pvt->ledger_items, l_iter_current, l_item_tmp) {
         dap_chain_datum_tx_t *l_tx = l_iter_current->tx;
-        dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_COND, NULL), *l_out_item;
-        DL_FOREACH(l_list_out_items, l_out_item) {
-            if (((dap_chain_tx_out_cond_t*)l_out_item->data)->header.srv_uid.uint64 == a_srv_uid.uint64) // is srv uid is same as we're searching for?
+        byte_t *item; size_t l_size;
+        TX_ITEM_ITER_TX(item, l_size, l_tx) {
+            if (*item == TX_ITEM_TYPE_OUT_COND && ((dap_chain_tx_out_cond_t*)item)->header.srv_uid.uint64 == a_srv_uid.uint64)
                 l_ret = dap_list_append(l_ret, l_tx);
         }
-        dap_list_free(l_list_out_items);
     }
     return l_ret;
 }
@@ -5675,157 +5494,118 @@ dap_list_t *dap_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, const c
                                                        uint256_t a_value_need, uint256_t *a_value_transfer)
 {
     dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items
-    dap_chain_hash_fast_t l_tx_cur_hash = { 0 };
-    uint256_t l_value_transfer = {};
-    while(compare256(l_value_transfer, a_value_need) == -1)
+    dap_chain_hash_fast_t l_tx_cur_hash = { };
+    uint256_t l_value_transfer = { };
+    dap_chain_datum_tx_t *l_tx;
+    while ( compare256(l_value_transfer, a_value_need) == -1 
+            && (l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash)) )
     {
-        // Get the transaction in the cache by the addr in out item
-        dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from,
-                                                                             &l_tx_cur_hash);
-        if(!l_tx)
-            break;
         // Get all item from transaction by type
-        dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
-
-        uint32_t l_out_idx_tmp = 0; // current index of 'out' item
-        for (dap_list_t *it = l_list_out_items; it; it = dap_list_next(it), l_out_idx_tmp++) {
-            dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data;
-            uint256_t l_value = {};
+        byte_t *it; size_t l_size; int i, l_out_idx_tmp = -1;
+        dap_chain_addr_t l_out_addr = { };
+        TX_ITEM_ITER_TX_TYPE(it, TX_ITEM_TYPE_OUT_ALL, l_size, i, l_tx) {
+            ++l_out_idx_tmp;
+            dap_chain_tx_item_type_t l_type = *it;
+            uint256_t l_value = { };
             switch (l_type) {
-                case TX_ITEM_TYPE_OUT_OLD: {
-                    dap_chain_tx_out_old_t *l_out = (dap_chain_tx_out_old_t *)it->data;
-                    if (!l_out->header.value || memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t)))
-                        continue;
-                    l_value = GET_256_FROM_64(l_out->header.value);
-                } break;
-                case TX_ITEM_TYPE_OUT: {
-                    dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t *)it->data;
-                    if (memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t)) ||
-                            dap_strcmp(dap_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_cur_hash), a_token_ticker) ||
-                            IS_ZERO_256(l_out->header.value))
-                        continue;
-                    l_value = l_out->header.value;
-                } break;
-                case TX_ITEM_TYPE_OUT_EXT: {
-                    dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)it->data;
-                    if (memcmp(a_addr_from, &l_out_ext->addr, sizeof(dap_chain_addr_t)) ||
-                            strcmp((char *)a_token_ticker, l_out_ext->token) ||
-                            IS_ZERO_256(l_out_ext->header.value) ) {
-                        continue;
-                    }
-                    l_value = l_out_ext->header.value;
-                } break;
-                case TX_ITEM_TYPE_OUT_COND:
-                default:
+            case TX_ITEM_TYPE_OUT_OLD: {
+                dap_chain_tx_out_old_t *l_out = (dap_chain_tx_out_old_t*)it;
+                l_out_addr = l_out->addr;
+                if ( !l_out->header.value || !dap_chain_addr_compare(a_addr_from, &l_out_addr) )
                     continue;
+                l_value = GET_256_FROM_64(l_out->header.value);
+            } break;
+            case TX_ITEM_TYPE_OUT: {
+                dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t*)it;
+                l_out_addr = l_out->addr;
+                if ( !dap_chain_addr_compare(a_addr_from, &l_out_addr) 
+                || dap_strcmp(dap_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_cur_hash), a_token_ticker)
+                || IS_ZERO_256(l_out->header.value) )
+                    continue;
+                l_value = l_out->header.value;
+            } break;
+            case TX_ITEM_TYPE_OUT_EXT: {
+                dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t*)it;
+                l_out_addr = l_out_ext->addr;
+                if ( dap_chain_addr_compare(a_addr_from, &l_out_addr)
+                || strcmp((char *)a_token_ticker, l_out_ext->token)
+                || IS_ZERO_256(l_out_ext->header.value) )
+                    continue;
+                l_value = l_out_ext->header.value;
+            } break;
+            default:
+                continue;
             }
             // Check whether used 'out' items
-            if (!dap_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp, NULL)) {
+            if ( !dap_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp, NULL) ) {
                 dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
-                if ( !l_item ) {
-                    log_it(L_CRITICAL, "Out of memory");
-                    if (l_list_used_out)
-                        dap_list_free_full(l_list_used_out, NULL);
-                    dap_list_free(l_list_out_items);
-                    return NULL;
-                }
-                l_item->tx_hash_fast = l_tx_cur_hash;
-                l_item->num_idx_out = l_out_idx_tmp;
-                l_item->value = l_value;
+                *l_item = (dap_chain_tx_used_out_item_t) { l_tx_cur_hash, (uint32_t)l_out_idx_tmp, l_value };
                 l_list_used_out = dap_list_append(l_list_used_out, l_item);
                 SUM_256_256(l_value_transfer, l_item->value, &l_value_transfer);
                 // already accumulated the required value, finish the search for 'out' items
-                if (compare256(l_value_transfer, a_value_need) != -1) {
+                if ( compare256(l_value_transfer, a_value_need) != -1 ) {
                     break;
                 }
             }
         }
-        dap_list_free(l_list_out_items);
-    }
-
-    // nothing to tranfer (not enough funds)
-    if(!l_list_used_out || compare256(l_value_transfer, a_value_need) == -1) {
-        dap_list_free_full(l_list_used_out, NULL);
-        return NULL;
-    }
-
-    if (a_value_transfer) {
-        *a_value_transfer = l_value_transfer;
     }
-    return l_list_used_out;
+    return compare256(l_value_transfer, a_value_need) > -1 && l_list_used_out
+        ? ({ if (a_value_transfer) *a_value_transfer = l_value_transfer; l_list_used_out; })
+        : ( dap_list_free_full(l_list_used_out, NULL), NULL );
 }
 
 dap_list_t *dap_ledger_get_list_tx_outs(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from,
                                         uint256_t *a_value_transfer)
 {
     dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items
-    dap_chain_hash_fast_t l_tx_cur_hash = { 0 };
+    dap_chain_hash_fast_t l_tx_cur_hash = { };
     uint256_t l_value_transfer = {};
-    dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from,
-                                                            &l_tx_cur_hash);
-
-    while(l_tx)
-    {
-        // Get all item from transaction by type
-        dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
-
-        uint32_t l_out_idx_tmp = 0; // current index of 'out' item
-        for (dap_list_t *it = l_list_out_items; it; it = dap_list_next(it), l_out_idx_tmp++) {
-            dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data;
-            uint256_t l_value = {};
-            switch (l_type) {
+    dap_chain_datum_tx_t *l_tx;
+    while (( l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash) )) {
+        byte_t *it; size_t l_size; int i, l_out_idx_tmp = -1;
+        dap_chain_addr_t l_out_addr = { };
+        TX_ITEM_ITER_TX_TYPE(it, TX_ITEM_TYPE_OUT_ALL, l_size, i, l_tx) {
+            ++l_out_idx_tmp;
+            uint256_t l_value = { };
+            switch (*it) {
             case TX_ITEM_TYPE_OUT_OLD: {
-                dap_chain_tx_out_old_t *l_out = (dap_chain_tx_out_old_t *)it->data;
-                if (!l_out->header.value || memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t)))
+                dap_chain_tx_out_old_t *l_out = (dap_chain_tx_out_old_t*)it;
+                l_out_addr = l_out->addr;
+                if ( !l_out->header.value || !dap_chain_addr_compare(a_addr_from, &l_out_addr) )
                     continue;
                 l_value = GET_256_FROM_64(l_out->header.value);
             } break;
             case TX_ITEM_TYPE_OUT: {
-                dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t *)it->data;
-                if (memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t)) ||
-                    dap_strcmp(dap_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_cur_hash), a_token_ticker) ||
-                    IS_ZERO_256(l_out->header.value))
+                dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t*)it;
+                l_out_addr = l_out->addr;
+                if ( !dap_chain_addr_compare(a_addr_from, &l_out_addr)
+                || dap_strcmp( dap_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_cur_hash), a_token_ticker )
+                || IS_ZERO_256(l_out->header.value))
                     continue;
                 l_value = l_out->header.value;
             } break;
             case TX_ITEM_TYPE_OUT_EXT: {
-                dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)it->data;
-                if (memcmp(a_addr_from, &l_out_ext->addr, sizeof(dap_chain_addr_t)) ||
-                    strcmp((char *)a_token_ticker, l_out_ext->token) ||
-                    IS_ZERO_256(l_out_ext->header.value) ) {
+                dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)it;
+                l_out_addr = l_out_ext->addr;
+                if ( !dap_chain_addr_compare(a_addr_from, &l_out_addr)
+                || strcmp((char*)a_token_ticker, l_out_ext->token)
+                || IS_ZERO_256(l_out_ext->header.value) )
                     continue;
-                }
                 l_value = l_out_ext->header.value;
             } break;
-            case TX_ITEM_TYPE_OUT_COND:
             default:
                 continue;
             }
             // Check whether used 'out' items
-            if (!dap_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp, NULL)) {
+            if ( !dap_ledger_tx_hash_is_used_out_item(a_ledger, &l_tx_cur_hash, l_out_idx_tmp, NULL) ) {
                 dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
-                if ( !l_item ) {
-                    log_it(L_CRITICAL, "Out of memory");
-                    if (l_list_used_out)
-                        dap_list_free_full(l_list_used_out, NULL);
-                    dap_list_free(l_list_out_items);
-                    return NULL;
-                }
-                l_item->tx_hash_fast = l_tx_cur_hash;
-                l_item->num_idx_out = l_out_idx_tmp;
-                l_item->value = l_value;
+                *(l_item) = (dap_chain_tx_used_out_item_t) { l_tx_cur_hash, (uint32_t)l_out_idx_tmp, l_value };
                 l_list_used_out = dap_list_append(l_list_used_out, l_item);
                 SUM_256_256(l_value_transfer, l_item->value, &l_value_transfer);
             }
         }
-        dap_list_free(l_list_out_items);
-        l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from,
-                                          &l_tx_cur_hash);
-    }
-
-    if (a_value_transfer) {
-        *a_value_transfer = l_value_transfer;
     }
+    if (a_value_transfer) *a_value_transfer = l_value_transfer;
     return l_list_used_out;
 }
 
@@ -5981,122 +5761,55 @@ dap_list_t *dap_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledger, co
     dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items
     dap_chain_hash_fast_t l_tx_cur_hash = { 0 };
     uint256_t l_value_transfer = { };
-    while(compare256(l_value_transfer, a_value_need) == -1)
+    dap_chain_datum_tx_t *l_tx;
+    while( compare256(l_value_transfer, a_value_need) == -1 
+        && ( l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash)) )
     {
-        // Get the transaction in the cache by the addr in out item
-        dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash);
-        if(!l_tx)
-            break;
-        // Get all item from transaction by type
-        dap_list_t *l_list_out_cond_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_COND, NULL);
-
-        uint32_t l_out_idx_tmp = 0; // current index of 'out' item
-        for(dap_list_t *it = l_list_out_cond_items; it; it = dap_list_next(it), l_out_idx_tmp++) {
-            dap_chain_tx_item_type_t l_type = *(uint8_t*) it->data;
-            uint256_t l_value = { };
-            switch (l_type) {
-            case TX_ITEM_TYPE_OUT_COND: {
-                dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t*) it->data;
-                if(IS_ZERO_256(l_out_cond->header.value) || a_subtype != l_out_cond->header.subtype) {
-                    continue;
-                }
-                l_value = l_out_cond->header.value;
-            }
-                break;
-            default:
+        byte_t *it; size_t l_size; int i, l_out_idx_tmp = -1;
+        TX_ITEM_ITER_TX_TYPE(it, TX_ITEM_TYPE_OUT_COND, l_size, i, l_tx) {
+            ++l_out_idx_tmp;
+            dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t*) it;
+            if (a_subtype != l_out_cond->header.subtype || IS_ZERO_256(l_out_cond->header.value) )
                 continue;
-            }
-            if (!IS_ZERO_256(l_value)) {
-                dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
-                if ( !l_item ) {
-                    if (l_list_used_out)
-                        dap_list_free_full(l_list_used_out, NULL);
-                    dap_list_free(l_list_out_cond_items);
-                    return NULL;
-                }
-                l_item->tx_hash_fast = l_tx_cur_hash;
-                l_item->num_idx_out = l_out_idx_tmp;
-                l_item->value = l_value;
-                l_list_used_out = dap_list_append(l_list_used_out, l_item);
-                SUM_256_256(l_value_transfer, l_item->value, &l_value_transfer);
-                // already accumulated the required value, finish the search for 'out' items
-                if (compare256(l_value_transfer, a_value_need) != -1) {
-                    break;
-                }
+            dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
+            *l_item = (dap_chain_tx_used_out_item_t) { l_tx_cur_hash, (uint32_t)l_out_idx_tmp, l_out_cond->header.value };
+            l_list_used_out = dap_list_append(l_list_used_out, l_item);
+            SUM_256_256(l_value_transfer, l_item->value, &l_value_transfer);
+            // already accumulated the required value, finish the search for 'out' items
+            if ( compare256(l_value_transfer, a_value_need) != -1 ) {
+                break;
             }
         }
-        dap_list_free(l_list_out_cond_items);
     }
-
-    // nothing to tranfer (not enough funds)
-    if(!l_list_used_out || compare256(l_value_transfer, a_value_need) == -1) {
-        dap_list_free_full(l_list_used_out, NULL);
-        return NULL;
-    }
-
-    if (a_value_transfer) {
-        *a_value_transfer = l_value_transfer;
-    }
-    return l_list_used_out;
+    return compare256(l_value_transfer, a_value_need) > -1 && l_list_used_out
+        ? ({ if (a_value_transfer) *a_value_transfer = l_value_transfer; l_list_used_out; })
+        : ( dap_list_free_full(l_list_used_out, NULL), NULL );
 }
 
 dap_list_t *dap_ledger_get_list_tx_cond_outs(dap_ledger_t *a_ledger, const char *a_token_ticker,  const dap_chain_addr_t *a_addr_from,
                                              dap_chain_tx_out_cond_subtype_t a_subtype, uint256_t *a_value_transfer)
 {
     dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items
-    dap_chain_hash_fast_t l_tx_cur_hash = { 0 };
+    dap_chain_hash_fast_t l_tx_cur_hash = { };
     uint256_t l_value_transfer = { };
-    dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash);
-    while(l_tx)
-    {
-        // Get all item from transaction by type
-        dap_list_t *l_list_out_cond_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_COND, NULL);
-
-        uint32_t l_out_idx_tmp = 0; // current index of 'out' item
-        for(dap_list_t *it = l_list_out_cond_items; it; it = dap_list_next(it), l_out_idx_tmp++) {
-            dap_chain_tx_item_type_t l_type = *(uint8_t*) it->data;
-            uint256_t l_value = { };
-            switch (l_type) {
-            case TX_ITEM_TYPE_OUT_COND: {
-                dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t*) it->data;
-                if(IS_ZERO_256(l_out_cond->header.value) || a_subtype != l_out_cond->header.subtype) {
-                    continue;
-                }
-                l_value = l_out_cond->header.value;
-            }
-            break;
-            default:
+    dap_chain_datum_tx_t *l_tx;
+    while(( l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash) )) {
+        byte_t *it; size_t l_size; int i, l_out_idx_tmp = -1;
+        TX_ITEM_ITER_TX_TYPE(it, TX_ITEM_TYPE_OUT_COND, l_size, i, l_tx) {
+            ++l_out_idx_tmp;
+            dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t*)it;
+            if ( a_subtype != l_out_cond->header.subtype || IS_ZERO_256(l_out_cond->header.value) )
                 continue;
-            }
-            if (!IS_ZERO_256(l_value)) {
-                dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
-                if ( !l_item ) {
-                    if (l_list_used_out)
-                        dap_list_free_full(l_list_used_out, NULL);
-                    dap_list_free(l_list_out_cond_items);
-                    return NULL;
-                }
-                l_item->tx_hash_fast = l_tx_cur_hash;
-                l_item->num_idx_out = l_out_idx_tmp;
-                l_item->value = l_value;
-                l_list_used_out = dap_list_append(l_list_used_out, l_item);
-                SUM_256_256(l_value_transfer, l_item->value, &l_value_transfer);
-            }
+            dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
+            *l_item = (dap_chain_tx_used_out_item_t) { l_tx_cur_hash, (uint32_t)l_out_idx_tmp, l_out_cond->header.value };
+            l_list_used_out = dap_list_append(l_list_used_out, l_item);
+            SUM_256_256(l_value_transfer, l_item->value, &l_value_transfer);
         }
-        dap_list_free(l_list_out_cond_items);
-        l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash);
     }
 
-    // nothing to tranfer (not enough funds)
-    if(!l_list_used_out) {
-        dap_list_free_full(l_list_used_out, NULL);
-        return NULL;
-    }
-
-    if (a_value_transfer) {
-        *a_value_transfer = l_value_transfer;
-    }
-    return l_list_used_out;
+    return l_list_used_out
+        ? ({ if (a_value_transfer) *a_value_transfer = l_value_transfer; l_list_used_out; })
+        : ( dap_list_free_full(l_list_used_out, NULL), NULL );
 }
 
 void dap_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_ledger_tx_add_notify_t a_callback, void *a_arg) {
@@ -6145,11 +5858,10 @@ void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_c
 const char *dap_ledger_tx_calculate_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc)
 {
     static _Thread_local char s_main_ticker[DAP_CHAIN_TICKER_SIZE_MAX] = { '\0' };
-    dap_chain_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
-    int l_rc = s_tx_cache_check(a_ledger, a_tx, l_tx_hash, false, NULL, NULL, s_main_ticker, NULL, NULL, false);
+    dap_hash_fast_t l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
+    int l_rc = s_tx_cache_check(a_ledger, a_tx, &l_tx_hash, false, NULL, NULL, s_main_ticker, NULL, NULL, false);
     if (l_rc == DAP_LEDGER_CHECK_ALREADY_CACHED)
-        dap_strncpy( s_main_ticker, dap_ledger_tx_get_token_ticker_by_hash(a_ledger, l_tx_hash), DAP_CHAIN_TICKER_SIZE_MAX );
-    DAP_DEL_Z(l_tx_hash);
+        dap_strncpy( s_main_ticker, dap_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_hash), DAP_CHAIN_TICKER_SIZE_MAX );
     if (a_ledger_rc)
         *a_ledger_rc = l_rc;
     return s_main_ticker;
diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c
index f6222d67745a4e8d3f2dff15e670503ef343798e..368d9acd63ce33f6a22a2ceeca24dc148b2444b7 100644
--- a/modules/net/dap_chain_net_tx.c
+++ b/modules/net/dap_chain_net_tx.c
@@ -50,72 +50,45 @@ typedef struct cond_all_by_srv_uid_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;
-    dap_chain_datum_tx_spends_items_t * l_ret = l_arg->ret;
-
-    if(l_arg->time_from && l_tx->header.ts_created < l_arg->time_from)
-        return;
-
-    // Check for time to
-    if(l_arg->time_to && l_tx->header.ts_created > l_arg->time_to)
-        return;
-
-    // Go through all items
-    uint32_t l_tx_items_pos = 0, l_tx_items_size = l_tx->header.tx_items_size;
-    while (l_tx_items_pos < l_tx_items_size) {
-        uint8_t *l_item = l_tx->tx_items + l_tx_items_pos;
-        int l_item_size = dap_chain_datum_item_tx_get_size(l_item);
-        if(!l_item_size)
-            break;
-        // check type
-        dap_chain_tx_item_type_t l_item_type = dap_chain_datum_tx_item_get_type(l_item);
-        switch (l_item_type){
-        case TX_ITEM_TYPE_IN_COND:{
-            dap_chain_tx_in_cond_t * l_tx_in_cond = (dap_chain_tx_in_cond_t *) l_item;
-            dap_chain_datum_tx_spends_item_t  *l_tx_prev_out_item = NULL;
-            HASH_FIND(hh, l_ret->tx_outs, &l_tx_in_cond->header.tx_prev_hash,sizeof(l_tx_in_cond->header.tx_prev_hash), l_tx_prev_out_item);
-
-            if (l_tx_prev_out_item){ // we found previous out_cond with target srv_uid
-                dap_chain_datum_tx_spends_item_t *l_item_in = DAP_NEW_Z(dap_chain_datum_tx_spends_item_t);
-                if (!l_item_in) {
-                    log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    return ;
-                }
-                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);
-                l_item_in->tx_hash = *a_tx_hash;
-
-                l_item_in->tx = l_tx_dup;
-                // Calc same offset from tx duplicate
-                l_item_in->in_cond = (dap_chain_tx_in_cond_t*) (l_tx_dup->tx_items + l_tx_items_pos);
-                HASH_ADD(hh,l_ret->tx_ins, tx_hash, sizeof(dap_chain_hash_fast_t), l_item_in);
-
-                // Link previous out with current in
-                l_tx_prev_out_item->tx_next = l_tx_dup;
+    dap_chain_datum_tx_spends_items_t *l_ret = l_arg->ret;
+
+    dap_return_if_pass(( l_arg->time_from && a_tx->header.ts_created < l_arg->time_from )
+                    || ( l_arg->time_to && a_tx->header.ts_created > l_arg->time_to ));
+    byte_t *l_item; size_t l_size;
+    TX_ITEM_ITER_TX(l_item, l_size, a_tx) {
+        switch (*l_item) {
+        case TX_ITEM_TYPE_IN_COND: {
+            dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t*)l_item;
+            dap_chain_datum_tx_spends_item_t *l_spends = NULL;
+            dap_hash_fast_t l_prev_hash = l_tx_in_cond->header.tx_prev_hash;
+            HASH_FIND(hh, l_ret->tx_outs, &l_prev_hash, sizeof(l_prev_hash), l_spends);
+            if (l_spends) {
+                dap_chain_datum_tx_spends_item_t *l_in = DAP_NEW_Z(dap_chain_datum_tx_spends_item_t);
+                *l_in = (dap_chain_datum_tx_spends_item_t) { 
+                    .tx = a_tx,
+                    .tx_hash = *a_tx_hash,
+                    .in_cond = l_tx_in_cond
+                };
+                HASH_ADD(hh, l_ret->tx_ins, tx_hash, sizeof(dap_chain_hash_fast_t), l_in);
+                l_spends->tx_next = a_tx;
             }
-        }break;
-        case TX_ITEM_TYPE_OUT_COND:{
-            dap_chain_tx_out_cond_t * l_tx_out_cond = (dap_chain_tx_out_cond_t *)l_item;
-            if(l_tx_out_cond->header.srv_uid.uint64 == l_arg->srv_uid.uint64){
-                dap_chain_datum_tx_spends_item_t * l_item = DAP_NEW_Z(dap_chain_datum_tx_spends_item_t);
-                if (!l_item) {
-                    log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-                    return ;
-                }
-                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);
-                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);
-
-                HASH_ADD(hh,l_ret->tx_outs, tx_hash, sizeof(dap_chain_hash_fast_t), l_item);
-                break; // We're seaching only for one specified OUT_COND output per transaction
+        } break;
+        case TX_ITEM_TYPE_OUT_COND: {
+            dap_chain_tx_out_cond_t *l_tx_out_cond = (dap_chain_tx_out_cond_t*)l_item;
+            if (l_tx_out_cond->header.srv_uid.uint64 == l_arg->srv_uid.uint64) {
+                dap_chain_datum_tx_spends_item_t *l_out = DAP_NEW_Z(dap_chain_datum_tx_spends_item_t);
+                *l_out = (dap_chain_datum_tx_spends_item_t) {
+                    .tx = a_tx,
+                    .tx_hash = *a_tx_hash,
+                    .out_cond = l_tx_out_cond
+                };
+                HASH_ADD(hh, l_ret->tx_outs, tx_hash, sizeof(dap_chain_hash_fast_t), l_out);
+                // ??? TODO?
             }
         } break;
-        default:;
+        default:
+            break;
         }
-        l_tx_items_pos += l_item_size;
     }
 }
 
@@ -265,13 +238,12 @@ struct get_tx_cond_all_from_tx
 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 = 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){
+        while ((l_tx_item = dap_chain_datum_tx_item_get(a_tx, &l_item_idx, NULL, 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;
             if(dap_hash_fast_compare(&l_in_cond->header.tx_prev_hash, &l_args->tx_last_hash) &&
                     (uint32_t)l_args->tx_last_cond_idx == l_in_cond->header.tx_out_prev_idx ){ // Found output
@@ -360,79 +332,75 @@ static void s_get_tx_cond_all_for_addr_callback(dap_chain_net_t* a_net, dap_chai
     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;
+    
     bool l_tx_for_addr = false; // TX with output related with our address
     bool l_tx_from_addr = false; // TX with input that take assets from our address
     //const char *l_tx_from_addr_token = NULL;
     bool l_tx_collected = false;  // We already collected this TX in return list
-
+    byte_t *l_tx_item = NULL; size_t l_size = 0; int l_idx = 0;
     // Get in items to detect is in or in_cond from target address
-    while ((l_tx_item = (dap_chain_datum_tx_item_t *) dap_chain_datum_tx_item_get(a_datum_tx, &l_item_idx, TX_ITEM_TYPE_ANY , NULL)) != NULL){
-        switch (l_tx_item->type){
-            case TX_ITEM_TYPE_IN:{
-                dap_chain_tx_in_t * l_in = (dap_chain_tx_in_t *) l_tx_item;
-                if( l_tx_from_addr) // Already detected thats spends from addr
-                    break;
+    TX_ITEM_ITER_TX(l_tx_item, l_size, a_datum_tx) {
+        switch (*l_tx_item) {
+        case TX_ITEM_TYPE_IN: {
+            dap_chain_tx_in_t * l_in = (dap_chain_tx_in_t *) l_tx_item;
+            if( l_tx_from_addr) // Already detected thats spends from addr
+                break;
 //                dap_chain_tx_t * l_tx = dap_chain_tx_hh_find( l_args->tx_all_hh, &l_in->header.tx_prev_hash);
-                if( dap_chain_tx_hh_find( l_args->tx_all_hh, &l_in->header.tx_prev_hash) ){ // Its input thats closing output for target address - we note it
-                    l_tx_from_addr = true;
-                    //l_tx_from_addr_token = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx->hash);
-                }
-            }break;
-            case TX_ITEM_TYPE_IN_COND:{
-                if(l_tx_collected) // Already collected
-                    break;
-                dap_chain_tx_in_cond_t * l_in_cond = (dap_chain_tx_in_cond_t *) l_tx_item;
+            if( dap_chain_tx_hh_find( l_args->tx_all_hh, &l_in->header.tx_prev_hash) ){ // Its input thats closing output for target address - we note it
+                l_tx_from_addr = true;
+                //l_tx_from_addr_token = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx->hash);
+            }
+        } break;
+        case TX_ITEM_TYPE_IN_COND: {
+            if(l_tx_collected) // Already collected
+                break;
+            dap_chain_tx_in_cond_t * l_in_cond = (dap_chain_tx_in_cond_t *) l_tx_item;
 //                dap_chain_tx_t * l_tx = dap_chain_tx_hh_find( l_args->tx_all_hh, &l_in_cond->header.tx_prev_hash);
-                if( dap_chain_tx_hh_find( l_args->tx_all_hh, &l_in_cond->header.tx_prev_hash) ){ // Its input thats closing conditioned tx related with target address, collect it
-                    //dap_chain_tx_t *l_tx_add = dap_chain_tx_wrap_packed(a_datum_tx);
-                    l_args->ret = dap_list_append(l_args->ret, a_datum_tx);
-                    l_tx_collected = true;
-                }
-            }break;
+            if( dap_chain_tx_hh_find( l_args->tx_all_hh, &l_in_cond->header.tx_prev_hash) ){ // Its input thats closing conditioned tx related with target address, collect it
+                //dap_chain_tx_t *l_tx_add = dap_chain_tx_wrap_packed(a_datum_tx);
+                l_args->ret = dap_list_append(l_args->ret, a_datum_tx);
+                l_tx_collected = true;
+            }
+        } break;
         }
-        l_item_idx++;
     }
 //dap_chain_datum_tx_out_cond_get(a_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_out_item_idx)
     // Get out items from transaction
-    l_item_idx = 0;
-    while ((l_tx_item = (dap_chain_datum_tx_item_t *) dap_chain_datum_tx_item_get(a_datum_tx, &l_item_idx, TX_ITEM_TYPE_OUT_ALL , NULL)) != NULL){
-        switch (l_tx_item->type){
-            case TX_ITEM_TYPE_OUT:{
-                if(l_tx_for_addr) // Its already added
-                    break;
-                dap_chain_tx_out_t * l_out = (dap_chain_tx_out_t*) l_tx_item;
-                if ( memcmp(&l_out->addr, l_args->addr, sizeof(*l_args->addr)) == 0){ // Its our address tx
-                    dap_chain_tx_t * l_tx = dap_chain_tx_wrap_packed(a_datum_tx);
-                    dap_chain_tx_hh_add(&l_args->tx_all_hh, l_tx);
-                    l_tx_for_addr = true;
-                }
-            }break;
-            case TX_ITEM_TYPE_OUT_EXT:{
-                if(l_tx_for_addr) // Its already added
-                    break;
-                dap_chain_tx_out_ext_t * l_out = (dap_chain_tx_out_ext_t*) l_tx_item;
-                if ( memcmp(&l_out->addr, l_args->addr, sizeof(*l_args->addr)) == 0){ // Its our address tx
-                    dap_chain_tx_t * l_tx = dap_chain_tx_wrap_packed(a_datum_tx);
-                    dap_chain_tx_hh_add(&l_args->tx_all_hh, l_tx);
-                    l_tx_for_addr = true;
-                }
-            }break;
-            case TX_ITEM_TYPE_OUT_COND:{
-                dap_chain_tx_out_cond_t * l_out_cond = (dap_chain_tx_out_cond_t*) l_tx_item;
-                if(l_tx_collected) // Already collected for return list
-                    break;
+    TX_ITEM_ITER_TX(l_tx_item, l_size, a_datum_tx) {
+        switch (*l_tx_item) {
+        case TX_ITEM_TYPE_OUT: {
+            if(l_tx_for_addr) // Its already added
+                break;
+            dap_chain_tx_out_t * l_out = (dap_chain_tx_out_t*) l_tx_item;
+            if ( memcmp(&l_out->addr, l_args->addr, sizeof(*l_args->addr)) == 0){ // Its our address tx
+                dap_chain_tx_t * l_tx = dap_chain_tx_wrap_packed(a_datum_tx);
+                dap_chain_tx_hh_add(&l_args->tx_all_hh, l_tx);
+                l_tx_for_addr = true;
+            }
+        } break;
+        case TX_ITEM_TYPE_OUT_EXT:{
+            if(l_tx_for_addr) // Its already added
+                break;
+            dap_chain_tx_out_ext_t * l_out = (dap_chain_tx_out_ext_t*) l_tx_item;
+            if ( memcmp(&l_out->addr, l_args->addr, sizeof(*l_args->addr)) == 0){ // Its our address tx
+                dap_chain_tx_t * l_tx = dap_chain_tx_wrap_packed(a_datum_tx);
+                dap_chain_tx_hh_add(&l_args->tx_all_hh, l_tx);
+                l_tx_for_addr = true;
+            }
+        } break;
+        case TX_ITEM_TYPE_OUT_COND:{
+            dap_chain_tx_out_cond_t * l_out_cond = (dap_chain_tx_out_cond_t*) l_tx_item;
+            if(l_tx_collected) // Already collected for return list
+                break;
 
-                // If this output spends monies from our address
-                if(l_tx_from_addr && l_out_cond->header.srv_uid.uint64 == l_args->srv_uid.uint64){
-                    //dap_chain_tx_t *l_tx_add = dap_chain_tx_wrap_packed(a_datum_tx);
-                    l_args->ret = dap_list_append(l_args->ret, a_datum_tx);
-                    l_tx_collected = true;
-                }
-            } break;
-        }
-        l_item_idx++;
+            // If this output spends monies from our address
+            if(l_tx_from_addr && l_out_cond->header.srv_uid.uint64 == l_args->srv_uid.uint64){
+                //dap_chain_tx_t *l_tx_add = dap_chain_tx_wrap_packed(a_datum_tx);
+                l_args->ret = dap_list_append(l_args->ret, a_datum_tx);
+                l_tx_collected = true;
+            }
+        } break;
+    }
     }
 
 }
@@ -460,32 +428,18 @@ 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, dap_hash_fast_t *a_tx_hash, void *a_arg)
+static void s_tx_cond_all_by_srv_uid_callback(UNUSED_ARG dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, UNUSED_ARG 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;
-
-    // Check for time from
-    if(l_ret->time_from && l_tx->header.ts_created < l_ret->time_from)
-        return;
+    cond_all_by_srv_uid_arg_t *l_ret = (cond_all_by_srv_uid_arg_t*)a_arg;
 
-    // Check for time to
-    if(l_ret->time_to && l_tx->header.ts_created > l_ret->time_to)
+    if (( l_ret->time_from && a_tx->header.ts_created < l_ret->time_from )
+        || ( l_ret->time_to && a_tx->header.ts_created > l_ret->time_to ))
         return;
 
-    // Check for OUT_COND items
-    dap_list_t *l_list_out_cond_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_COND, NULL), *l_out_cond_item;
-    if(l_list_out_cond_items) {
-        DL_FOREACH(l_list_out_cond_items, l_out_cond_item) {
-                dap_chain_tx_out_cond_t *l_tx_out_cond = (dap_chain_tx_out_cond_t*)l_out_cond_item->data;
-                if (l_tx_out_cond && l_tx_out_cond->header.srv_uid.uint64 == l_ret->srv_uid.uint64) {
-                    l_ret->ret = dap_list_append(l_ret->ret, l_tx);
-                }
-        }
-        dap_list_free(l_list_out_cond_items);
+    byte_t *item; size_t l_size;
+    TX_ITEM_ITER_TX(item, l_size, a_tx) {
+        if ( *item == TX_ITEM_TYPE_OUT_COND && l_ret->srv_uid.uint64 == ((dap_chain_tx_out_cond_t*)item)->header.srv_uid.uint64 )
+            l_ret->ret = dap_list_append(l_ret->ret, a_tx);
     }
 }
 
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 09cd68230f0593ca54de0c2ecb13771885f2eb73..84d8ebe6ceb0b44e20161f269806110fcd2dd689 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -2881,10 +2881,9 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
                             json_object_object_add(l_jobj_datum, "action", json_object_new_string("UNKNOWN"));
                         }
 
-
-                        dap_list_t *l_list_sig_item = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_SIG, NULL);
                         dap_list_t *l_list_in_ems = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_EMS, NULL);
-                        if (!l_list_sig_item) {
+                        dap_chain_tx_sig_t *l_sig = (dap_chain_tx_sig_t*)dap_chain_datum_tx_item_get(l_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
+                        if (!l_sig) {
                             json_object *l_jobj_wgn = json_object_new_string(
                                     "An item with a type TX_ITEM_TYPE_SIG for the "
                                     "transaction was not found, the transaction may "
@@ -2892,13 +2891,11 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
                             json_object_object_add(l_jobj_datum, "warning", l_jobj_wgn);
                             break;
                         }
-                        dap_chain_tx_sig_t *l_sig = l_list_sig_item->data;
                         dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig(l_sig);
                         dap_chain_addr_fill_from_sign(&l_addr_from, l_sign, a_net->pub.id);
                         if (l_wallet_addr && dap_chain_addr_compare(l_wallet_addr, &l_addr_from)) {
                             datum_is_accepted_addr = true;
                         }
-                        dap_list_free(l_list_sig_item);
                         dap_list_t *l_list_in_reward = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_REWARD, NULL);
                         if (l_list_in_reward) {
                             /*json_object *l_obj_in_reward_arary = json_object_new_array();
@@ -4333,7 +4330,7 @@ static int s_parse_additional_token_decl_arg(int a_argc, char ** a_argv, void **
         l_tsd_offset += l_tsd_size;
     }
     a_params->ext.tsd_total_size = l_tsd_total_size;
-
+    dap_list_free_full(l_tsd_list, NULL);
     return 0;
 }
 
@@ -4654,6 +4651,7 @@ int com_token_decl(int a_argc, char ** a_argv, void **a_str_reply)
                 l_datum_data_offset += l_params->ext.tsd_total_size;
                 DAP_DELETE(l_params->ext.parsed_tsd);
             }
+            dap_list_free_full(l_tsd_list, NULL);
             log_it(L_DEBUG, "%s token declaration '%s' initialized", l_params->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE ?
                             "Private" : "CF20", l_datum_token->ticker);
         }break;//end
@@ -5480,15 +5478,13 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **reply)
             continue;
         }
         // Get owner tx
-        dap_hash_fast_t *l_owner_tx_hash = dap_ledger_get_first_chain_tx_hash(l_ledger, l_cond_tx, l_tx_out_cond);
-        dap_chain_datum_tx_t *l_owner_tx = l_cond_tx;
-        if (l_owner_tx_hash){
-            l_owner_tx = dap_ledger_tx_find_by_hash(l_ledger, l_owner_tx_hash);
-            DAP_DEL_Z(l_owner_tx_hash);
-        }
+        dap_hash_fast_t l_owner_tx_hash = dap_ledger_get_first_chain_tx_hash(l_ledger, l_cond_tx, l_tx_out_cond);
+        dap_chain_datum_tx_t *l_owner_tx = dap_hash_fast_is_blank(&l_owner_tx_hash)
+            ? l_cond_tx:
+            dap_ledger_tx_find_by_hash(l_ledger, &l_owner_tx_hash);
         if (!l_owner_tx)
             continue;
-        dap_chain_tx_sig_t *l_owner_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_owner_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
+        dap_chain_tx_sig_t *l_owner_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_owner_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
         dap_sign_t *l_owner_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_owner_tx_sig);
 
         if (!l_owner_sign) {
@@ -5502,9 +5498,9 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **reply)
         }
 
         // get final tx 
-        dap_hash_fast_t *l_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, l_hash);
-        dap_chain_datum_tx_t *l_final_tx = dap_ledger_tx_find_by_hash(l_ledger, l_final_hash);
-        if (!l_final_tx){
+        dap_hash_fast_t l_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, l_hash);
+        dap_chain_datum_tx_t *l_final_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_final_hash);
+        if (!l_final_tx) {
             log_it(L_WARNING, "Only get final tx hash or tx is already used out.");
             continue;
         }
@@ -5519,7 +5515,7 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **reply)
         
         // add in_cond to new tx
         // add 'in' item to buy from conditional transaction
-        dap_chain_datum_tx_add_in_cond_item(&l_tx, l_final_hash, l_final_cond_idx, 0);
+        dap_chain_datum_tx_add_in_cond_item(&l_tx, &l_final_hash, l_final_cond_idx, 0);
         SUM_256_256(l_cond_value_sum, l_final_tx_out_cond->header.value, &l_cond_value_sum);
     }
     dap_list_free_full(l_hashes_list, NULL);
@@ -5752,16 +5748,14 @@ int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **reply)
         }
 
         // Check sign
-        dap_hash_fast_t *l_owner_tx_hash = dap_ledger_get_first_chain_tx_hash(l_ledger, l_data_tx->tx, l_out_cond);
-        dap_chain_datum_tx_t *l_owner_tx = l_tx;
-        if (l_owner_tx_hash){
-            l_owner_tx = dap_ledger_tx_find_by_hash(l_ledger, l_owner_tx_hash);
-            DAP_DEL_Z(l_owner_tx_hash);
-        }
+        dap_hash_fast_t l_owner_tx_hash = dap_ledger_get_first_chain_tx_hash(l_ledger, l_data_tx->tx, l_out_cond);
+        dap_chain_datum_tx_t *l_owner_tx = dap_hash_fast_is_blank(&l_owner_tx_hash)
+            ? l_tx
+            : dap_ledger_tx_find_by_hash(l_ledger, &l_owner_tx_hash);
             
         if (!l_owner_tx)
             continue;
-        dap_chain_tx_sig_t *l_owner_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_owner_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
+        dap_chain_tx_sig_t *l_owner_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_owner_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
         dap_sign_t *l_owner_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_owner_tx_sig);
 
 
@@ -8352,7 +8346,6 @@ static int s_sign_file(const char *a_filename, dap_sign_signer_file_t a_flags, c
     l_shift = 1;
     dap_list_t *l_std_list = NULL;
 
-
     for (int i = 0; i < l_count_meta; i++) {
         if (l_shift | a_flags) {
             dap_tsd_t *l_item = s_alloc_metadata(a_filename, l_shift & a_flags);
@@ -8363,23 +8356,24 @@ static int s_sign_file(const char *a_filename, dap_sign_signer_file_t a_flags, c
         l_shift <<= 1;
     }
 
-    dap_cert_t *l_cert = dap_cert_find_by_name(a_cert_name);
-    if (!l_cert) {
-        DAP_DELETE(l_buffer);
-        return 0;
-    }
-
     if (!dap_hash_fast(l_buffer, l_file_content_size, a_hash)) {
+        dap_list_free_full(l_std_list, NULL);
         DAP_DELETE(l_buffer);
         return 0;
     }
 
     size_t l_full_size_for_sign;
     uint8_t *l_data = s_concat_hash_and_mimetypes(a_hash, l_std_list, &l_full_size_for_sign);
+    dap_list_free_full(l_std_list, NULL);
     if (!l_data) {
         DAP_DELETE(l_buffer);
         return 0;
     }
+    dap_cert_t *l_cert = dap_cert_find_by_name(a_cert_name);
+    if (!l_cert) {
+        DAP_DELETE(l_buffer);
+        return 0;
+    }
     *a_signed = dap_sign_create(l_cert->enc_key, l_data, l_full_size_for_sign, 0);
     if (*a_signed == NULL) {
         DAP_DELETE(l_buffer);
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index b28680716f06337311dc487d48782957194cb17c..ccd6b5fde52ff42cf7246287cc323393a6032aa1 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -101,34 +101,23 @@ bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
     json_object_object_add(json_obj_out, "Token_description", l_description ? json_object_new_string(l_description)
                                                                             : json_object_new_null());
     dap_chain_datum_dump_tx_json(a_datum, l_ticker, json_obj_out, a_hash_out_type, a_tx_hash, a_ledger->net->pub.id);
-
-    dap_list_t *l_out_items = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_OUT_ALL, NULL);
-    int l_out_idx = 0;
     json_object* json_arr_items = json_object_new_array();
     bool l_spent = false;
-    for (dap_list_t *l_item = l_out_items; l_item; l_item = l_item->next, ++l_out_idx) {
-        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_COND: {
-            dap_hash_fast_t l_spender = { };
-            if (dap_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' };
-                dap_hash_fast_to_str(&l_spender, l_hash_str, sizeof(l_hash_str));
-                json_object * l_json_obj_datum = json_object_new_object();
-                json_object_object_add(l_json_obj_datum, "OUT - ", json_object_new_int(l_out_idx));
-                json_object_object_add(l_json_obj_datum, "is spent by tx", json_object_new_string(l_hash_str));
-                json_object_array_add(json_arr_items, l_json_obj_datum);
-                l_spent = true;
-            }
-            break;
-        }
-        default:
-            break;
+    byte_t *l_item; size_t l_size; int i, l_out_idx = -1;
+    TX_ITEM_ITER_TX_TYPE(l_item, TX_ITEM_TYPE_OUT_ALL, l_size, i, a_datum) {
+        ++l_out_idx;
+        dap_hash_fast_t l_spender = { };
+        if ( dap_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' };
+            dap_hash_fast_to_str(&l_spender, l_hash_str, sizeof(l_hash_str));
+            json_object * l_json_obj_datum = json_object_new_object();
+            json_object_object_add(l_json_obj_datum, "OUT - ", json_object_new_int(l_out_idx));
+            json_object_object_add(l_json_obj_datum, "is spent by tx", json_object_new_string(l_hash_str));
+            json_object_array_add(json_arr_items, l_json_obj_datum);
+            l_spent = true;
         }
+        break;
     }
-    dap_list_free(l_out_items);
     json_object_object_add(json_obj_out, "Spent OUTs", json_arr_items);
     json_object_object_add(json_obj_out, "all OUTs yet unspent", l_spent ? json_object_new_string("no") : json_object_new_string("yes"));
     return true;
diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h
index b536f7572f8d4c928eec6138f2d95aef8a2fcedd..29a030219bf2c304817a05d6669746e14e1ed855 100644
--- a/modules/net/include/dap_chain_ledger.h
+++ b/modules/net/include/dap_chain_ledger.h
@@ -45,6 +45,7 @@ typedef struct dap_ledger {
     void *_internal;
 } dap_ledger_t;
 
+typedef struct dap_ledger_tx_item dap_ledger_tx_item_t;
 /**
  * @brief Error codes for accepting a transaction to the ledger.
  */
@@ -384,10 +385,15 @@ uint256_t dap_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_a
  *
  * return transaction, or NULL if transaction not found in the cache
  */
-dap_chain_datum_tx_t *dap_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash);
-dap_chain_datum_tx_t *dap_ledger_tx_unspent_find_by_hash(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash);
-dap_hash_fast_t *dap_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);
-dap_hash_fast_t *dap_ledger_get_first_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_t *a_cond_out);
+dap_chain_datum_tx_t *dap_ledger_tx_find_datum_by_hash( dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash,
+                                                        dap_ledger_tx_item_t **a_item_out, bool a_unspent_only );
+#define dap_ledger_tx_find_by_hash(a_ledger, a_tx_hash) \
+    dap_ledger_tx_find_datum_by_hash(a_ledger, a_tx_hash, NULL, false)
+#define dap_ledger_tx_unspent_find_by_hash(a_ledger, a_tx_hash) \
+    dap_ledger_tx_find_datum_by_hash(a_ledger, a_tx_hash, NULL, true)
+    
+dap_hash_fast_t dap_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);
+dap_hash_fast_t dap_ledger_get_first_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_t *a_cond_out);
 
  // Get the transaction in the cache by the addr in out item
 dap_chain_datum_tx_t* dap_ledger_tx_find_by_addr(dap_ledger_t *a_ledger, const char * a_token,
diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c
index de8618dbd6f60b4058fd820b101b887d4dcb7c83..5b8954710d8246b2c40f79ea38b6f117ba5ff563 100644
--- a/modules/net/srv/dap_chain_net_srv.c
+++ b/modules/net/srv/dap_chain_net_srv.c
@@ -52,7 +52,6 @@
 #include "dap_chain_net_tx.h"
 #include "dap_chain_net_srv_order.h"
 #include "dap_chain_net_srv_stream_session.h"
-#include "dap_chain_net_tx.h"
 #include "dap_stream_ch_chain_net_srv.h"
 #include "dap_chain_cs_blocks.h"
 #ifdef DAP_MODULES_DYNAMIC
@@ -667,7 +666,7 @@ static int s_fee_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_c
     DL_FOREACH(l_net->pub.chains, l_chain) {
         if (!l_chain->callback_block_find_by_tx_hash)
             continue;
-        dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0);
+        dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t*)dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_IN_COND, NULL);
         if (!l_tx_in_cond)
             return -1;
         if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash))
@@ -682,7 +681,7 @@ static int s_fee_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_c
             return -3;
 
         // TX sign is already verified, just compare pkeys
-        dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx_in, NULL, TX_ITEM_TYPE_SIG, NULL);
+        dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
         dap_sign_t *l_sign_tx = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig);
         return dap_sign_compare_pkeys(l_sign_block, l_sign_tx) ? 0 : -5;
     }
@@ -704,7 +703,7 @@ static int s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_
     if (a_owner)
         return 0;
     dap_chain_datum_tx_receipt_t *l_receipt = (dap_chain_datum_tx_receipt_t *)
-                                               dap_chain_datum_tx_item_get(a_tx_in, NULL, TX_ITEM_TYPE_RECEIPT, NULL);
+                                               dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_RECEIPT, NULL);
     if (!l_receipt){
         log_it(L_ERROR, "Can't find receipt.");
         return -1;
@@ -731,8 +730,8 @@ static int s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_
         return -4;
     }
 
-    int l_item_size = 0;
-    uint8_t* l_sig = dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_SIG, &l_item_size);
+    size_t l_item_size = 0;
+    uint8_t* l_sig = dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_SIG, &l_item_size);
     if(!l_sig){
         log_it(L_ERROR, "Can't get item with provider signature from tx");
         return false;
@@ -772,7 +771,7 @@ static int s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_
     }
 
     // Check price is less than maximum
-    dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0);
+    dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t*)dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_IN_COND, NULL);
     dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash(a_ledger , &l_tx_in_cond->header.tx_prev_hash);
     dap_chain_tx_out_cond_t *l_prev_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_prev, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, NULL);
 
@@ -791,42 +790,35 @@ static int s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_
 
     // check remainder on srv pay cond out is valid
     // find 'out' items
-    dap_list_t *l_list_out = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) a_tx_in, TX_ITEM_TYPE_OUT_ALL, NULL);
     uint256_t l_value = l_receipt->receipt_info.value_datoshi;
     uint256_t l_cond_out_value = {};
-    dap_chain_addr_t l_network_fee_addr = {};
+    dap_chain_addr_t l_network_fee_addr = {}, l_out_addr = {};
     dap_chain_net_tx_get_fee(a_ledger->net->pub.id, NULL, &l_network_fee_addr);
-    int l_item_idx = 0;
-    for (dap_list_t * l_list_tmp = l_list_out; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_item_idx++) {
-        dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data;
-        switch (l_type) {
+    byte_t *l_item; size_t l_size; int i, l_item_idx = -1;
+    TX_ITEM_ITER_TX_TYPE(l_item, TX_ITEM_TYPE_OUT_ALL, l_size, i, a_tx_in) {
+        ++l_item_idx;
+        switch (*l_item) {
         case TX_ITEM_TYPE_OUT: { // 256
-            dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)l_list_tmp->data;
-            if (dap_chain_addr_compare(&l_tx_out->addr, &l_network_fee_addr)){
+            dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t*)l_item;
+            l_out_addr = l_tx_out->addr;
+            if (dap_chain_addr_compare(&l_out_addr, &l_network_fee_addr)){
                 SUM_256_256(l_value, l_tx_out->header.value, &l_value);
             }
         } break;
         case TX_ITEM_TYPE_OUT_COND: {
-            dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t *)l_list_tmp->data;
+            dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t*)l_item;
             if (l_tx_out->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE){
                 SUM_256_256(l_value, l_tx_out->header.value, &l_value);
             } else if (l_tx_out->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY){
                 l_cond_out_value = l_tx_out->header.value;
             }
         } break;
-        default: {}
+        default:
+            break;
         }
     }
-
-
     SUBTRACT_256_256(l_prev_out_cond->header.value, l_value, &l_value);
-    if (compare256(l_value, l_cond_out_value)){
-        log_it(L_ERROR, "Value in tx out is invalid!");
-        dap_list_free(l_list_out);
-        return -13;
-    }
-    dap_list_free(l_list_out);
-    return 0;
+    return compare256(l_value, l_cond_out_value) ? log_it(L_ERROR, "Value in tx out is invalid!"), -13 : 0;
 }
 
 dap_chain_net_srv_price_t * dap_chain_net_srv_get_price_from_order(dap_chain_net_srv_t *a_srv, const char *a_config_section, dap_chain_hash_fast_t* a_order_hash){
diff --git a/modules/service/datum/dap_chain_net_srv_datum.c b/modules/service/datum/dap_chain_net_srv_datum.c
index 25e4862174418d897f28102f5242d24cb79eed64..be719c45455d3cece2f4751aa2700d83e4c8bdd5 100644
--- a/modules/service/datum/dap_chain_net_srv_datum.c
+++ b/modules/service/datum/dap_chain_net_srv_datum.c
@@ -254,9 +254,9 @@ void s_order_notficator(dap_store_obj_t *a_obj, void *a_arg)
         log_it(L_DEBUG, "Invalid tx cond datum hash");
         return;
     }
-    int l_tx_out_cond_size;
+    size_t l_tx_out_cond_size = 0;
     dap_chain_tx_out_cond_t *l_cond_out = (dap_chain_tx_out_cond_t *)
-            dap_chain_datum_tx_item_get(l_tx_cond, NULL, TX_ITEM_TYPE_OUT_COND, &l_tx_out_cond_size);
+            dap_chain_datum_tx_item_get(l_tx_cond, NULL, NULL, TX_ITEM_TYPE_OUT_COND, &l_tx_out_cond_size);
     if (!l_cond_out || l_cond_out->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY) {
         log_it(L_DEBUG, "Condition with required subtype SRV_PAY not found in requested tx");
     }
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 f6f15e6b0637e3cdc022d98144aab3547e3664cf..ab4ec0d346221a00c20f3694daa6c2f7c2d97f89 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_lock.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c
@@ -572,7 +572,7 @@ static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, da
     uint8_t *l_owner_pkey = dap_enc_key_serialize_pub_key(l_owner_key, &l_owner_pkey_size);
     dap_sign_t *l_owner_sign = NULL;
     dap_chain_tx_sig_t *l_tx_sign = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(
-                                                            l_cond_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
+                                                            l_cond_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
     if (l_tx_sign)
         l_owner_sign = dap_chain_datum_tx_item_sign_get_sig(l_tx_sign);
     if (!l_owner_sign || l_owner_pkey_size != l_owner_sign->header.sign_pkey_size ||
@@ -1006,7 +1006,7 @@ static int s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_t
         return -2;
 
     if (NULL == (l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(
-                                                            a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0)))
+                                                            a_tx_in, NULL, NULL, TX_ITEM_TYPE_IN_COND, NULL)))
         return -3;
     if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash))
         return false;
@@ -1028,7 +1028,7 @@ static int s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_t
                 IS_ZERO_256(l_value_delegated))
             return -6;
 
-        l_receipt = (dap_chain_datum_tx_receipt_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_RECEIPT, 0);
+        l_receipt = (dap_chain_datum_tx_receipt_t *)dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_RECEIPT, NULL);
         if (l_receipt) {
             if (!dap_chain_net_srv_uid_compare_scalar(l_receipt->receipt_info.srv_uid, DAP_CHAIN_NET_SRV_STAKE_LOCK_ID))
                 return -7;
@@ -1050,26 +1050,26 @@ static int s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_t
         } else
             l_burning_tx = a_tx_in;
 
-        dap_list_t *l_outs_list = dap_chain_datum_tx_items_get(l_burning_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
         uint256_t l_blank_out_value = {};
-        for (dap_list_t *it = l_outs_list; it; it = it->next) {
-            byte_t l_type = *(byte_t *)it->data;
-            if (l_type == TX_ITEM_TYPE_OUT) {
-                dap_chain_tx_out_t *l_out = it->data;
-                if (dap_chain_addr_is_blank(&l_out->addr)) {
+        dap_chain_addr_t l_out_addr = {};
+        byte_t *l_item; size_t l_size; int i;
+        TX_ITEM_ITER_TX_TYPE(l_item, TX_ITEM_TYPE_OUT_ALL, l_size, i, l_burning_tx) {
+            if (*l_item == TX_ITEM_TYPE_OUT) {
+                dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t*)l_item;
+                l_out_addr = l_out->addr;
+                if ( dap_chain_addr_is_blank(&l_out_addr) ) {
                     l_blank_out_value = l_out->header.value;
                     break;
                 }
-            } else if (l_type == TX_ITEM_TYPE_OUT_EXT) {
-                dap_chain_tx_out_ext_t *l_out = it->data;
-                if (dap_chain_addr_is_blank(&l_out->addr) &&
-                        !strcmp(l_out->token, l_delegated_ticker_str)) {
+            } else if (*l_item == TX_ITEM_TYPE_OUT_EXT) {
+                dap_chain_tx_out_ext_t *l_out = (dap_chain_tx_out_ext_t*)l_item;
+                l_out_addr = l_out->addr;
+                if ( dap_chain_addr_is_blank(&l_out_addr) && !strcmp(l_out->token, l_delegated_ticker_str) ) {
                     l_blank_out_value = l_out->header.value;
                     break;
                 }
             }
         }
-        dap_list_free(l_outs_list);
         if (IS_ZERO_256(l_blank_out_value)) {
             log_it(L_ERROR, "Can't find OUT with BLANK addr in burning TX");
             return -11;
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 9f8277375dbba12361105cd1ec1eaf690b142608..1c3c4131926ba1792ce7e65b2e5b5671b6d24a64 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
@@ -236,7 +236,7 @@ static int s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out
         return 0;
     }
     // It's a delegation conitional TX
-    dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0);
+    dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_IN_COND, NULL);
     if (!l_tx_in_cond) {
         log_it(L_ERROR, "Conditional in item not found in checking tx");
         return -6;
@@ -252,7 +252,7 @@ static int s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out
         return -8;
     }
     bool l_owner = false;
-    dap_chain_tx_in_cond_t *l_tx_prev_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(l_prev_tx, 0, TX_ITEM_TYPE_IN_COND, 0);
+    dap_chain_tx_in_cond_t *l_tx_prev_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(l_prev_tx, NULL, NULL, TX_ITEM_TYPE_IN_COND, NULL);
     if (!l_tx_prev_in_cond)
         l_owner = a_owner;
     else {
@@ -689,7 +689,7 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_enc_
         int l_out_num = 0;
         dap_chain_datum_tx_out_cond_get(a_prev_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, &l_out_num);
         // add 'in' item to buy from conditional transaction
-        if (dap_chain_datum_tx_add_in_cond_item(&l_tx, &l_prev_tx_hash, l_out_num, -1)) {
+        if (1 != dap_chain_datum_tx_add_in_cond_item(&l_tx, &l_prev_tx_hash, l_out_num, -1)) {
             log_it(L_ERROR, "Can't compose the transaction conditional input");
             goto tx_fail;
         }
@@ -984,7 +984,7 @@ static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_h
         log_it(L_WARNING, "Requested conditional transaction is already used out by %s", l_hash_str);
         return NULL;
     }
-    dap_chain_tx_in_cond_t *l_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(l_cond_tx, 0, TX_ITEM_TYPE_IN_COND, 0);
+    dap_chain_tx_in_cond_t *l_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(l_cond_tx, NULL, NULL, TX_ITEM_TYPE_IN_COND, NULL);
     if (l_in_cond) {
         l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_in_cond->header.tx_prev_hash);
         if (!l_cond_tx) {
@@ -993,7 +993,7 @@ static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_h
         }
     }
     // Get sign item
-    dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(l_cond_tx, NULL,
+    dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(l_cond_tx, NULL, NULL,
             TX_ITEM_TYPE_SIG, NULL);
     // Get sign from sign item
     dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig);
diff --git a/modules/service/voting/dap_chain_net_srv_voting.c b/modules/service/voting/dap_chain_net_srv_voting.c
index 0611998fd40651765a993312a25207b48a6e802a..ae204b2990c4a27e6ddb0e2b942a7db5ac069dec 100644
--- a/modules/service/voting/dap_chain_net_srv_voting.c
+++ b/modules/service/voting/dap_chain_net_srv_voting.c
@@ -271,7 +271,7 @@ bool s_datum_tx_voting_verification_callback(dap_ledger_t *a_ledger, dap_chain_t
         pthread_rwlock_unlock(&s_votings_rwlock);
         return true;
     } else if (a_type == TX_ITEM_TYPE_VOTE){
-        dap_chain_tx_vote_t *l_vote_tx_item = (dap_chain_tx_vote_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_VOTE, NULL);
+        dap_chain_tx_vote_t *l_vote_tx_item = (dap_chain_tx_vote_t*)dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_VOTE, NULL);
         if(!l_vote_tx_item){
             log_it(L_ERROR, "Can't find vote item");
             return false;
@@ -385,7 +385,7 @@ bool s_datum_tx_voting_verification_callback(dap_ledger_t *a_ledger, dap_chain_t
                     continue;
                 }
                 dap_chain_datum_tx_t *l_tx_prev_temp = dap_ledger_tx_find_by_hash(a_ledger, &l_hash);
-                dap_chain_tx_out_cond_t *l_prev_out = (dap_chain_tx_out_cond_t*)dap_chain_datum_tx_item_get(l_tx_prev_temp, &l_out_idx, TX_ITEM_TYPE_OUT_COND, NULL);
+                dap_chain_tx_out_cond_t *l_prev_out = (dap_chain_tx_out_cond_t*)dap_chain_datum_tx_item_get(l_tx_prev_temp, &l_out_idx, NULL, TX_ITEM_TYPE_OUT_COND, NULL);
                 if(!l_prev_out || l_prev_out->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK){
                     l_tsd_temp = l_tsd_temp->next;
                     continue;
@@ -532,7 +532,7 @@ static bool s_datum_tx_voting_verification_delete_callback(dap_ledger_t *a_ledge
 
         return true;
     } else if (a_type == TX_ITEM_TYPE_VOTE){
-        dap_chain_tx_vote_t *l_vote_tx_item = (dap_chain_tx_vote_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_VOTE, NULL);
+        dap_chain_tx_vote_t *l_vote_tx_item = (dap_chain_tx_vote_t *)dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_VOTE, NULL);
         if(!l_vote_tx_item){
             log_it(L_ERROR, "Can't find vote item");
             return false;
@@ -1075,7 +1075,7 @@ static int s_datum_tx_voting_coin_check_spent(dap_chain_net_t *a_net, dap_hash_f
         return 1;
     }
 
-    dap_chain_tx_vote_t *l_vote =(dap_chain_tx_vote_t *) dap_chain_datum_tx_item_get(l_tx, NULL, TX_ITEM_TYPE_VOTE, NULL);
+    dap_chain_tx_vote_t *l_vote =(dap_chain_tx_vote_t *) dap_chain_datum_tx_item_get(l_tx, NULL, NULL, TX_ITEM_TYPE_VOTE, NULL);
     if(l_vote && dap_hash_fast_compare(&l_vote->voting_hash, &a_voting_hash)){
         dap_chain_net_votings_t *l_voting = NULL;
         pthread_rwlock_wrlock(&s_votings_rwlock);
@@ -1166,7 +1166,7 @@ static int s_datum_tx_voting_coin_check_spent(dap_chain_net_t *a_net, dap_hash_f
         }
 
 
-        dap_chain_tx_vote_t *l_vote =(dap_chain_tx_vote_t *) dap_chain_datum_tx_item_get(l_tx_prev_temp, NULL, TX_ITEM_TYPE_VOTE, NULL);
+        dap_chain_tx_vote_t *l_vote =(dap_chain_tx_vote_t *) dap_chain_datum_tx_item_get(l_tx_prev_temp, NULL, NULL, TX_ITEM_TYPE_VOTE, NULL);
         if(l_vote && dap_hash_fast_compare(&l_vote->voting_hash, &a_voting_hash)){
             dap_chain_net_votings_t *l_voting = NULL;
             pthread_rwlock_wrlock(&s_votings_rwlock);
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 55b491adc60323e7a8c0781ef31e89a81b64243c..789d3ef48e721864dede29ef4f116f7878755aa7 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -249,7 +249,7 @@ static int s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_o
     if(!a_tx_in || !a_tx_out_cond)
         return -1;
 
-    dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0);
+    dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_IN_COND, NULL);
     if (!l_tx_in_cond)
         return -2;
     if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash))
@@ -261,8 +261,6 @@ static int s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_o
 
     uint256_t l_buy_val = {}, l_fee_val = {},
               l_sell_again_val = {}, l_service_fee_val = {};
-    int l_item_idx_start = 0;
-    byte_t * l_tx_item;
 
     dap_chain_addr_t l_service_fee_addr, *l_seller_addr = &a_tx_out_cond->subtype.srv_xchange.seller_addr;
     uint16_t l_service_fee_type = 0;
@@ -271,39 +269,38 @@ static int s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_o
     const char *l_native_ticker = l_net->pub.native_ticker;
     const char *l_service_ticker = (l_service_fee_type == SERVICE_FEE_OWN_FIXED || l_service_fee_type == SERVICE_FEE_OWN_PERCENT) ?
                 l_buy_ticker : l_native_ticker;
-    while ((l_tx_item = dap_chain_datum_tx_item_get(a_tx_in, &l_item_idx_start, TX_ITEM_TYPE_OUT_ALL, NULL)) != NULL)
-    {
-        dap_chain_tx_item_type_t l_tx_out_type = dap_chain_datum_tx_item_get_type(l_tx_item);
-        switch(l_tx_out_type){
-            case TX_ITEM_TYPE_OUT_EXT: {
-                dap_chain_tx_out_ext_t *l_tx_in_output = (dap_chain_tx_out_ext_t *)l_tx_item;
-                const char * l_out_token = l_tx_in_output->token;
-                const uint256_t *l_out_value = &l_tx_in_output->header.value;
-                dap_chain_addr_t * l_out_addr = &l_tx_in_output->addr;
-                // Out is with token to buy
-                if (!strcmp(l_out_token, l_buy_ticker) &&
-                        !memcmp(l_out_addr, l_seller_addr, sizeof(*l_out_addr)))
-                    SUM_256_256(l_buy_val, *l_out_value, &l_buy_val);
-                // Out is with token to fee
-                if (l_service_fee_used && !strcmp(l_out_token, l_service_ticker) &&
-                        !memcmp(l_out_addr, &l_service_fee_addr, sizeof(*l_out_addr)))
-                    SUM_256_256(l_fee_val, *l_out_value, &l_fee_val);
-            } break;
-            case TX_ITEM_TYPE_OUT_COND: {
-                dap_chain_tx_out_cond_t *l_tx_in_output = (dap_chain_tx_out_cond_t *)l_tx_item;
-                if (l_tx_in_output->header.subtype == a_tx_out_cond->header.subtype &&                             // Same subtype
-                        l_tx_in_output->header.srv_uid.uint64 == a_tx_out_cond->header.srv_uid.uint64 &&          // Same service uid
-                        l_tx_in_output->header.ts_expires == a_tx_out_cond->header.ts_expires &&                  // Same expires time
-                        l_tx_in_output->tsd_size == a_tx_out_cond->tsd_size &&                              // Same params size
-                        memcmp(l_tx_in_output->tsd, a_tx_out_cond->tsd, l_tx_in_output->tsd_size) == 0 && // Same params itself
-                        memcmp(&l_tx_in_output->subtype.srv_xchange, &a_tx_out_cond->subtype.srv_xchange,         // Same subtype header
-                           sizeof(a_tx_out_cond->subtype.srv_xchange)) == 0) {
-                    l_sell_again_val = l_tx_in_output->header.value;                                    // It is back to cond owner value
-                }
-            }break;
-            default: break;
+    byte_t *l_tx_item; size_t l_size;
+    TX_ITEM_ITER_TX(l_tx_item, l_size, a_tx_in) {
+        switch (*l_tx_item) {
+        case TX_ITEM_TYPE_OUT_EXT: {
+            dap_chain_tx_out_ext_t *l_tx_in_output = (dap_chain_tx_out_ext_t*)l_tx_item;
+            const char *l_out_token = l_tx_in_output->token;
+            const uint256_t l_out_value = l_tx_in_output->header.value;
+            dap_chain_addr_t l_out_addr = l_tx_in_output->addr;
+            // Out is with token to buy
+            if (!strcmp(l_out_token, l_buy_ticker) &&
+                    !memcmp(&l_out_addr, l_seller_addr, sizeof(l_out_addr)))
+                SUM_256_256(l_buy_val, l_out_value, &l_buy_val);
+            // Out is with token to fee
+            if (l_service_fee_used && !strcmp(l_out_token, l_service_ticker) &&
+                    !memcmp(&l_out_addr, &l_service_fee_addr, sizeof(l_out_addr)))
+                SUM_256_256(l_fee_val, l_out_value, &l_fee_val);
+        } break;
+        case TX_ITEM_TYPE_OUT_COND: {
+            dap_chain_tx_out_cond_t *l_tx_in_output = (dap_chain_tx_out_cond_t*)l_tx_item;
+            if (l_tx_in_output->header.subtype == a_tx_out_cond->header.subtype &&                             // Same subtype
+                    l_tx_in_output->header.srv_uid.uint64 == a_tx_out_cond->header.srv_uid.uint64 &&          // Same service uid
+                    l_tx_in_output->header.ts_expires == a_tx_out_cond->header.ts_expires &&                  // Same expires time
+                    l_tx_in_output->tsd_size == a_tx_out_cond->tsd_size &&                              // Same params size
+                    memcmp(l_tx_in_output->tsd, a_tx_out_cond->tsd, l_tx_in_output->tsd_size) == 0 && // Same params itself
+                    memcmp(&l_tx_in_output->subtype.srv_xchange, &a_tx_out_cond->subtype.srv_xchange,         // Same subtype header
+                        sizeof(a_tx_out_cond->subtype.srv_xchange)) == 0) {
+                l_sell_again_val = l_tx_in_output->header.value;                                    // It is back to cond owner value
+            }
+        } break;
+        default:
+            break;
         }
-        l_item_idx_start++;
     }
 
     /* Check the condition for rate verification success
@@ -679,7 +676,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
         return NULL;
     }
     const dap_chain_addr_t *l_seller_addr = &l_tx_out_cond->subtype.srv_xchange.seller_addr;
-    if (dap_chain_datum_tx_add_in_cond_item(&l_tx, &a_price->tx_hash, l_prev_cond_idx, 0)) {
+    if (1 != dap_chain_datum_tx_add_in_cond_item(&l_tx, &a_price->tx_hash, l_prev_cond_idx, 0)) {
         dap_chain_datum_tx_delete(l_tx);
         log_it(L_ERROR, "Can't add conditional input");
         return NULL;
@@ -867,14 +864,14 @@ uint64_t dap_chain_net_srv_xchange_get_order_completion_rate(dap_chain_net_t *a_
         return 0;
     }
 
-    dap_hash_fast_t * l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
-    if(!l_last_tx_hash){
+    dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
+    if ( dap_hash_fast_is_blank(&l_last_tx_hash) ){
         log_it(L_ERROR, " Can't get last tx cond hash from order");
         return 0;
     }
 
-    dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, l_last_tx_hash);
-    if(!l_last_tx_hash){
+    dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &l_last_tx_hash);
+    if(!l_last_tx){
         log_it(L_ERROR, "Can't find last tx");
         return 0;
     }
@@ -924,14 +921,14 @@ dap_chain_net_srv_xchange_order_status_t dap_chain_net_srv_xchange_get_order_sta
         return XCHANGE_ORDER_STATUS_UNKNOWN;
     }
 
-    dap_hash_fast_t * l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
-    if(!l_last_tx_hash){
+    dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
+    if ( dap_hash_fast_is_blank(&l_last_tx_hash) ) {
         log_it(L_ERROR, " Can't get last tx cond hash from order");
         return XCHANGE_ORDER_STATUS_UNKNOWN;
     }
 
-    dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, l_last_tx_hash);
-    if(!l_last_tx_hash){
+    dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &l_last_tx_hash);
+    if (!l_last_tx) {
         log_it(L_ERROR, "Can't find last tx");
         return XCHANGE_ORDER_STATUS_UNKNOWN;
     }
@@ -1149,10 +1146,10 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a
     l_price->creator_addr = l_out_cond->subtype.srv_xchange.seller_addr;
     if (!IS_ZERO_256(l_price->datoshi_buy)) {
         l_price->rate = l_out_cond->subtype.srv_xchange.rate;
-        dap_hash_fast_t *l_final_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger,
+        dap_hash_fast_t l_final_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger,
                                             DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_tx_hash);
-        if (l_final_hash) {
-            l_price->tx_hash = *l_final_hash;
+        if ( !dap_hash_fast_is_blank(&l_final_hash) ) {
+            l_price->tx_hash = l_final_hash;
             return l_price;
         } else {
             log_it(L_WARNING, "This order have no active conditional transaction");
@@ -1533,14 +1530,14 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
             dap_ledger_t * l_ledger = dap_ledger_by_net_name(l_net->pub.name);
             char *l_cp_rate;
             char* l_status_order = NULL;
-            dap_hash_fast_t * l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
-            if(!l_last_tx_hash){
+            dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
+            if( dap_hash_fast_is_blank(&l_last_tx_hash) ){
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get last tx cond hash from order");
                 return -18;
             }
 
-            dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(l_ledger, l_last_tx_hash);
-            if(!l_last_tx_hash){
+            dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_last_tx_hash);
+            if (!l_last_tx){
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find last tx");
                 return -18;
             }
@@ -1631,7 +1628,7 @@ static bool s_filter_tx_list(dap_chain_datum_t *a_datum, dap_chain_t *a_chain, v
         return true;
     // Find SRV_XCHANGE in_cond item
     int l_item_idx = 0;
-    dap_chain_tx_in_cond_t * l_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(l_datum_tx, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL);
+    dap_chain_tx_in_cond_t * l_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(l_datum_tx, &l_item_idx, NULL, TX_ITEM_TYPE_IN_COND , NULL);
     int l_prev_cond_idx = 0;
     dap_chain_datum_tx_t * l_prev_tx = l_in_cond ? dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_in_cond->header.tx_prev_hash) : NULL;
     dap_chain_tx_out_cond_t *l_out_prev_cond_item = l_prev_tx ? dap_chain_datum_tx_out_cond_get(l_prev_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE,
@@ -1651,7 +1648,7 @@ xchange_tx_type_t dap_chain_net_srv_xchange_tx_get_type (dap_ledger_t * a_ledger
                                                                                &l_cond_idx);
     // Find SRV_XCHANGE in_cond item
     int l_item_idx = 0;
-    byte_t *l_tx_item = dap_chain_datum_tx_item_get(a_tx, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL);
+    byte_t *l_tx_item = dap_chain_datum_tx_item_get(a_tx, &l_item_idx, NULL, TX_ITEM_TYPE_IN_COND , NULL);
     dap_chain_tx_in_cond_t * l_in_cond = l_tx_item ? (dap_chain_tx_in_cond_t *) l_tx_item : NULL;
     int l_prev_cond_idx = 0;
     dap_chain_datum_tx_t * l_prev_tx = l_in_cond ? dap_ledger_tx_find_by_hash(a_ledger, &l_in_cond->header.tx_prev_hash) : NULL;
@@ -1673,7 +1670,7 @@ xchange_tx_type_t dap_chain_net_srv_xchange_tx_get_type (dap_ledger_t * a_ledger
     {
         dap_chain_datum_tx_t * l_prev_tx_temp = a_tx;
         byte_t *l_tx_item_temp = NULL;
-        while((l_tx_item_temp = dap_chain_datum_tx_item_get(l_prev_tx_temp, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL)) != NULL)
+        while((l_tx_item_temp = dap_chain_datum_tx_item_get(l_prev_tx_temp, &l_item_idx, NULL, TX_ITEM_TYPE_IN_COND , NULL)) != NULL)
         {
                 dap_chain_tx_in_cond_t * l_in_cond_temp = (dap_chain_tx_in_cond_t *) l_tx_item_temp;
                 l_prev_tx_temp = dap_ledger_tx_find_by_hash(a_ledger, &l_in_cond_temp->header.tx_prev_hash);
@@ -1686,9 +1683,9 @@ xchange_tx_type_t dap_chain_net_srv_xchange_tx_get_type (dap_ledger_t * a_ledger
         if (!l_out_cond_item) {
             l_tx_type = TX_TYPE_UNDEFINED;
         } else {
-            dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_prev_tx_temp, NULL, TX_ITEM_TYPE_SIG, NULL);
+            dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_prev_tx_temp, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
             dap_sign_t *l_prev_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_prev_sig);
-            dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
+            dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
             dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig);
 
         bool l_owner = false;
@@ -1721,14 +1718,14 @@ static int s_tx_check_for_open_close(dap_chain_net_t * a_net, dap_chain_datum_tx
 
     dap_hash_fast_t l_tx_hash = {};
     dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_tx_hash);
-    dap_hash_fast_t * l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_tx_hash);
-    if(!l_last_tx_hash){
+    dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_tx_hash);
+    if ( dap_hash_fast_is_blank(&l_last_tx_hash) ) {
         log_it(L_WARNING,"Can't get last tx cond hash from order");
         return 0;
     }
 
-    dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(l_ledger, l_last_tx_hash);
-    if(!l_last_tx_hash){
+    dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_last_tx_hash);
+    if (!l_last_tx) {
         log_it(L_WARNING,"Can't find last tx");
         return 0;
     }
@@ -1806,7 +1803,7 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
         } break;
         case TX_TYPE_EXCHANGE:{
             dap_chain_tx_in_cond_t *l_in_cond 
-                = (dap_chain_tx_in_cond_t*)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_IN_COND , NULL);
+                = (dap_chain_tx_in_cond_t*)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_IN_COND , NULL);
             char l_tx_prev_cond_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
             dap_hash_fast_to_str(&l_in_cond->header.tx_prev_hash, l_tx_prev_cond_hash_str, sizeof(l_tx_prev_cond_hash_str));
 
@@ -1856,7 +1853,7 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
                 dap_string_append_printf(a_reply_str, "\n  Prev cond: %s", l_tx_prev_cond_hash_str);
         } break;
         case TX_TYPE_INVALIDATE:{
-            dap_chain_tx_in_cond_t * l_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_IN_COND , NULL);
+            dap_chain_tx_in_cond_t * l_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_IN_COND , NULL);
             char l_tx_prev_cond_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
             dap_hash_fast_to_str(&l_in_cond->header.tx_prev_hash,l_tx_prev_cond_hash_str, sizeof(l_tx_prev_cond_hash_str));
 
@@ -1870,13 +1867,10 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
                 return false;
 
             int l_out_num = l_in_cond->header.tx_out_prev_idx;
-            dap_hash_fast_t l_order_hash = l_in_cond->header.tx_prev_hash;
             dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_prev_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_out_num);
-            dap_hash_fast_t *l_order_hash_ptr = dap_ledger_get_first_chain_tx_hash(a_net->pub.ledger, a_tx, l_out_cond);
-            if (l_order_hash_ptr){
-                l_order_hash = *l_order_hash_ptr;
-                DAP_DEL_Z(l_order_hash_ptr);
-            }
+            dap_hash_fast_t l_order_hash = dap_ledger_get_first_chain_tx_hash(a_net->pub.ledger, a_tx, l_out_cond);
+            if ( dap_hash_fast_is_blank(&l_order_hash) )
+                l_order_hash = l_in_cond->header.tx_prev_hash;
 
             char *l_value_from_str = dap_chain_balance_to_coins(l_out_prev_cond_item->header.value);
             char *l_value_from_datoshi_str = dap_chain_balance_print(l_out_prev_cond_item->header.value);
@@ -1941,13 +1935,11 @@ 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, dap_hash_fast_t *a_tx_hash, void *a_arg)
+void s_tx_is_order_check(UNUSED_ARG dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, UNUSED_ARG 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))
+    if ( dap_chain_datum_tx_out_cond_get(a_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, NULL) &&
+        !dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_IN_COND, NULL))
        *l_tx_list_ptr = dap_list_append(*l_tx_list_ptr, a_tx);
 }
 
@@ -2086,14 +2078,14 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 dap_ledger_t * l_ledger = dap_ledger_by_net_name(l_net->pub.name);
                 char *l_cp_rate;
                 char* l_status_order = NULL;
-                dap_hash_fast_t * l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
-                if(!l_last_tx_hash){
+                dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
+                if ( dap_hash_fast_is_blank(&l_last_tx_hash) ) {
                     log_it(L_WARNING,"Can't get last tx cond hash from order");
                     continue;
                 }
 
-                dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(l_ledger, l_last_tx_hash);
-                if(!l_last_tx_hash){
+                dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_last_tx_hash);
+                if(!l_last_tx){
                     log_it(L_WARNING,"Can't find last tx");
                     continue;
                 }
@@ -2486,7 +2478,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                                                                                                        NULL);
                             if(!l_out_cond_item){
                                 int l_item_idx = 0;
-                                byte_t *l_tx_item = dap_chain_datum_tx_item_get(l_tx, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL);
+                                byte_t *l_tx_item = dap_chain_datum_tx_item_get(l_tx, &l_item_idx, NULL, TX_ITEM_TYPE_IN_COND , NULL);
                                 dap_chain_tx_in_cond_t * l_in_cond = l_tx_item ? (dap_chain_tx_in_cond_t *) l_tx_item : NULL;
                                 int l_prev_cond_idx = 0;
                                 dap_chain_datum_tx_t * l_prev_tx = l_in_cond ? dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_in_cond->header.tx_prev_hash) : NULL;
diff --git a/modules/wallet/dap_chain_wallet.c b/modules/wallet/dap_chain_wallet.c
index c341711cdbaed35563d8d77025643c23a801e45c..6e9a439f4f927842f43b7a495ab52c7c65eebf84 100644
--- a/modules/wallet/dap_chain_wallet.c
+++ b/modules/wallet/dap_chain_wallet.c
@@ -352,7 +352,7 @@ static char s_wallets_path[MAX_PATH];
 
 const char* dap_chain_wallet_get_path(dap_config_t * a_config)
 {
-    char *l_cp = NULL;
+    const char *l_cp = NULL;
     if (!a_config)
         a_config = g_config;
     if ( s_wallets_path[0] )                                                /* Is the path to the wallet's store has been defined ? */