diff --git a/dap-sdk b/dap-sdk
index 026c0def2a5685885e9577586f6b5b93b042f896..1587a436ec9231ac3bb485e74cc5ec2a7534efd5 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 026c0def2a5685885e9577586f6b5b93b042f896
+Subproject commit 1587a436ec9231ac3bb485e74cc5ec2a7534efd5
diff --git a/modules/chain/dap_chain_ch.c b/modules/chain/dap_chain_ch.c
index 65b2f1e43fad588092b751e4c1845f1d017ea05f..9af3f8ad1d8a2801ef83dd69c464c34daffa1b0f 100644
--- a/modules/chain/dap_chain_ch.c
+++ b/modules/chain/dap_chain_ch.c
@@ -143,7 +143,7 @@ static uint32_t s_sync_packets_per_thread_call = 10;
 static uint32_t s_sync_ack_window_size = 512; // atoms
 
 // Legacy
-static uint_fast16_t s_update_pack_size = 100; // Number of hashes packed into the one packet
+static const uint_fast16_t s_update_pack_size = 100; // Number of hashes packed into the one packet
 
 #ifdef  DAP_SYS_DEBUG
 
@@ -653,7 +653,7 @@ static bool s_sync_in_chains_callback(void *a_arg)
         break;
     }
     if (l_ack_send && l_args->ack_req) {
-        uint64_t l_ack_num = (l_chain_pkt->hdr.num_hi << 16) | l_chain_pkt->hdr.num_lo;
+        uint64_t l_ack_num = ((uint32_t)l_chain_pkt->hdr.num_hi << 16) | l_chain_pkt->hdr.num_lo;
         dap_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id,
                                                          &l_ack_num, sizeof(uint64_t), DAP_CHAIN_CH_PKT_VERSION_CURRENT);
         dap_stream_ch_pkt_send_by_addr(&l_args->addr, DAP_CHAIN_CH_ID, DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK, l_pkt, dap_chain_ch_pkt_get_size(l_pkt));
@@ -745,7 +745,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
     } break;
 
     case DAP_CHAIN_CH_PKT_TYPE_CHAIN: {
-        if (!l_chain_pkt_data_size) {
+        if (!l_chain_pkt_data_size || l_chain_pkt_data_size > sizeof(dap_chain_ch_pkt_t) + DAP_CHAIN_ATOM_MAX_SIZE) {
             log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size,
                                                     dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type));
             dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id,
@@ -1101,7 +1101,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
 
     // Response with gdb element hashes and sizes
     case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB: {
-        if (l_chain_pkt_data_size % sizeof(dap_chain_ch_update_element_t)) {
+        if (l_chain_pkt_data_size % sizeof(dap_chain_ch_update_element_t) || l_chain_pkt_data_size > UINT16_MAX) {
             log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size,
                                                     dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type));
             dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id,
@@ -1214,7 +1214,8 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
     case DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB: {
         dap_global_db_pkt_old_t *l_pkt = (dap_global_db_pkt_old_t *)l_chain_pkt->data;
         if (l_chain_pkt_data_size < sizeof(dap_global_db_pkt_old_t) ||
-                l_chain_pkt_data_size != sizeof(*l_pkt) + l_pkt->data_size) {
+                (uint64_t)sizeof(*l_pkt) + l_pkt->data_size < l_pkt->data_size ||
+                l_chain_pkt_data_size != (uint64_t)sizeof(*l_pkt) + l_pkt->data_size) {
             log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size,
                                                     dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type));
             dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id,
@@ -1353,7 +1354,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
 
     // Response with atom hashes and sizes
     case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS: {
-        if (l_chain_pkt_data_size > sizeof(dap_chain_ch_update_element_t) * s_update_pack_size) {
+        if (l_chain_pkt_data_size % sizeof(dap_chain_ch_update_element_t) || l_chain_pkt_data_size > UINT16_MAX) {
             log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size,
                                                     dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type));
             dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id,
@@ -1470,7 +1471,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
     } break;
 
     case DAP_CHAIN_CH_PKT_TYPE_CHAIN_OLD: {
-        if (!l_chain_pkt_data_size) {
+        if (!l_chain_pkt_data_size || l_chain_pkt_data_size > sizeof(dap_chain_ch_pkt_t) + DAP_CHAIN_ATOM_MAX_SIZE) {
             log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size,
                                                     dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type));
             dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id,
diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h
index ffefac6b4a44721b8015f8014f655b42e1577e2c..869ab65076249aaa437c4bf0be095493eb286365 100644
--- a/modules/chain/include/dap_chain.h
+++ b/modules/chain/include/dap_chain.h
@@ -30,6 +30,12 @@
 #include "dap_chain_common.h"
 #include "dap_chain_datum.h"
 
+#ifdef DAP_TPS_TEST
+#define DAP_CHAIN_ATOM_MAX_SIZE (100 * 1024 * 1024)
+#else
+#define DAP_CHAIN_ATOM_MAX_SIZE (256 * 1024) // 256 KB
+#endif
+
 typedef struct dap_chain dap_chain_t;
 
 typedef struct dap_chain_cell dap_chain_cell_t;
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/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
index 75f0adec6b4031258261ed0c9d10c4c0cd1282bb..5dcf39ce43476b5d7cfbb044f9d09d58f87b382d 100644
--- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
+++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
@@ -769,7 +769,7 @@ static bool s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
         if ( !l_price ) {
             log_it( L_WARNING, "Request can't be processed because no acceptable price in pricelist for token %s in network %s",
                     l_ticker, l_net->pub.name );
-            l_err.code =DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ACCEPT_TOKEN;
+            l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ACCEPT_TOKEN;
             s_grace_error(a_grace, l_err);
             return false;
         }
@@ -1265,6 +1265,12 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
             return false;
         }
         pkt_test_t *l_request = (pkt_test_t*)l_ch_pkt->data;
+        if (l_request->data_size_recv > DAP_CHAIN_NET_SRV_CH_REQUEST_SIZE_MAX || l_request->data_size > DAP_CHAIN_NET_SRV_CH_REQUEST_SIZE_MAX) {
+            log_it(L_WARNING, "Too large payload %zu [pkt seq %"DAP_UINT64_FORMAT_U"]", l_request->data_size_recv, l_ch_pkt->hdr.seq_id);
+            l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_BIG_SIZE;
+            dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err));
+            return false;
+        }
         size_t l_request_size = l_request->data_size + sizeof(pkt_test_t);
         if (l_ch_pkt->hdr.data_size != l_request_size) {
             log_it(L_WARNING, "Wrong CHECK_REQUEST size %u, must be %zu [pkt seq %"DAP_UINT64_FORMAT_U"]", l_ch_pkt->hdr.data_size, l_request_size, l_ch_pkt->hdr.seq_id);
@@ -1272,14 +1278,8 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
             dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err));
             return false;
         }
-        if(l_request->data_size_recv > DAP_CHAIN_NET_SRV_CH_REQUEST_SIZE_MAX) {
-            log_it(L_WARNING, "Too large payload %zu [pkt seq %"DAP_UINT64_FORMAT_U"]", l_request->data_size_recv, l_ch_pkt->hdr.seq_id);
-            l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_BIG_SIZE;
-            dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err));
-            return false;
-        }
         dap_chain_hash_fast_t l_data_hash;
-        dap_hash_fast(l_request->data, l_request->data_size, &l_data_hash);
+        dap_hash_fast(l_request->data, l_request->data_size, &l_data_hash); // TODO change it to less CPU consuming algorithm
         if (l_request->data_size > 0 && !dap_hash_fast_compare(&l_data_hash, &l_request->data_hash)) {
             log_it(L_WARNING, "Wrong hash [pkt seq %"DAP_UINT64_FORMAT_U"]", l_ch_pkt->hdr.seq_id);
             l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_WRONG_HASH;
@@ -1353,6 +1353,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
             return false;
         }
         dap_chain_datum_tx_receipt_t * l_receipt = (dap_chain_datum_tx_receipt_t *) l_ch_pkt->data;
+        // TODO calculate actual receipt size and compare it with provided packet size
         size_t l_receipt_size = l_ch_pkt->hdr.data_size;
 
         bool l_is_found = false;
diff --git a/modules/channel/chain-net/dap_stream_ch_chain_net.c b/modules/channel/chain-net/dap_stream_ch_chain_net.c
index 3039ce38e7e5efb8252d38ba6af09387e3d6334f..fe4c18c8626843aee823fb25758b151e16a0159a 100644
--- a/modules/channel/chain-net/dap_stream_ch_chain_net.c
+++ b/modules/channel/chain-net/dap_stream_ch_chain_net.c
@@ -125,20 +125,24 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
             return false;
         }
         dap_stream_ch_chain_net_pkt_t *l_ch_chain_net_pkt = (dap_stream_ch_chain_net_pkt_t *)l_ch_pkt->data;
-        if (l_ch_chain_net_pkt->hdr.data_size + sizeof(dap_stream_ch_chain_net_pkt_t) > l_ch_pkt->hdr.data_size) {
+        if ((uint32_t)l_ch_chain_net_pkt->hdr.data_size + sizeof(dap_stream_ch_chain_net_pkt_t) > l_ch_pkt->hdr.data_size) {
             log_it(L_WARNING, "Too small stream channel N packet size %u (expected at least %zu)",
                                     l_ch_pkt->hdr.data_size, l_ch_chain_net_pkt->hdr.data_size + sizeof(dap_stream_ch_chain_net_pkt_t));
             return false;
         }
         dap_chain_net_t *l_net = dap_chain_net_by_id(l_ch_chain_net_pkt->hdr.net_id);
         if (!l_net) {
-            log_it(L_ERROR, "Invalid net id in packet");
+            log_it(L_ERROR, "Invalid net id 0x%016" DAP_UINT64_FORMAT_x " in stream channel N packet", l_ch_chain_net_pkt->hdr.net_id.uint64);
             char l_err_str[] = "ERROR_NET_INVALID_ID";
             dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR ,
                                               l_ch_chain_net_pkt->hdr.net_id, l_err_str, sizeof(l_err_str));
             return false;
         }
         if (l_ch_pkt->hdr.type == DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR) {
+            if (l_ch_chain_net_pkt->data[l_ch_chain_net_pkt->hdr.data_size - 1] != '\0') {
+                log_it(L_WARNING, "Invalid error string format with no trailing zero");
+                return false;
+            }
             char *l_err_str = (char *)l_ch_chain_net_pkt->data;
             log_it(L_WARNING, "Stream channel N for network communication got error on other side: %s", l_err_str);
             if (a_ch->stream->authorized) {
diff --git a/modules/channel/chain-net/dap_stream_ch_chain_net_pkt.c b/modules/channel/chain-net/dap_stream_ch_chain_net_pkt.c
index 24be3ab116c691b8d1641316cf3be559f4fe1f30..a53bb80396d6cdb37deca22c4468e84f014280f9 100644
--- a/modules/channel/chain-net/dap_stream_ch_chain_net_pkt.c
+++ b/modules/channel/chain-net/dap_stream_ch_chain_net_pkt.c
@@ -19,7 +19,6 @@
 #include <dap_stream.h>
 #include <dap_stream_pkt.h>
 #include <dap_stream_ch_pkt.h>
-#include "dap_stream_ch_chain_net.h"
 #include "dap_stream_ch_chain_net_pkt.h"
 
 #define LOG_TAG "dap_stream_ch_chain_net_pkt"
diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c
index f0ac122c4eb9da05f548cfda3839cbd4f29c9d58..8394a83ea5872759fe1a25480b7602c486bfc783 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..d0e934bb729133e49377c867473078605564fe87 100644
--- a/modules/common/dap_chain_datum_anchor.c
+++ b/modules/common/dap_chain_datum_anchor.c
@@ -30,33 +30,11 @@
 
 #define LOG_TAG "dap_chain_datum_anchor"
 
-int dap_chain_datum_anchor_get_hash_from_data(dap_chain_datum_anchor_t* a_anchor, dap_hash_fast_t * l_out_hash)
+int dap_chain_datum_anchor_get_hash_from_data(dap_chain_datum_anchor_t* a_anchor, dap_hash_fast_t *a_out_hash)
 {
-    if(!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_get_scalar(l_tsd, l_out_hash);
-            return 0;
-        }
-        l_tsd_offset += l_tsd_size;
-    }
-    return -100;
+    dap_return_val_if_fail(a_anchor && a_out_hash, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_anchor->data_n_sign, a_anchor->header.data_size, DAP_CHAIN_DATUM_ANCHOR_TSD_TYPE_DECREE_HASH);
+    return l_tsd && l_tsd->size == sizeof(dap_hash_fast_t) ? ( _dap_tsd_get_scalar(l_tsd, a_out_hash), 0 ) : 1;
 }
 
 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..5ef31fc6f91a9283bf35fcbbb5eb96abecc7b0d1 100644
--- a/modules/common/dap_chain_datum_decree.c
+++ b/modules/common/dap_chain_datum_decree.c
@@ -68,18 +68,12 @@ 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 = 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)
+        *a_owners_num = (uint16_t)dap_list_length(l_ret);
     return l_ret;
 }
 
@@ -155,210 +149,6 @@ int dap_chain_datum_decree_get_ban_addr(dap_chain_datum_decree_t *a_decree, cons
     return l_tsd ? ( *a_addr = dap_tsd_get_string_const(l_tsd), !dap_strcmp(*a_addr, DAP_TSD_CORRUPTED_STRING) ) : 1;
 }
 
-void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type)
-{
-    char *l_type_str = "";
-    switch(a_decree->header.type)
-    {
-        case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON:
-            l_type_str = "DECREE_TYPE_COMMON";
-            break;
-        case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE:
-            l_type_str = "DECREE_TYPE_SERVICE";
-            break;
-        default:
-            l_type_str = "DECREE_TYPE_UNKNOWN";
-    }
-    dap_string_append_printf(a_str_out, "type: %s\n", l_type_str);
-    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);
-        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);
-                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);
-                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));
-                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);
-                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);
-                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);
-                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));
-                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);
-                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);
-                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;
-                }
-                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,
-                                      a_decree->header.signs_size, a_hash_out_type);
-}
-
-void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type)
-{
-    dap_string_append_printf(a_str_out, "signatures: ");
-    if (!a_certs_size) {
-        dap_string_append_printf(a_str_out, "<NONE>\n");
-        return;
-    }
-
-    dap_string_append_printf(a_str_out, "\n");
-
-    size_t l_offset = 0;
-    for (int i = 1; l_offset < (a_certs_size); i++) {
-        dap_sign_t *l_sign = (dap_sign_t *) (a_signs + l_offset);
-        l_offset += dap_sign_get_size(l_sign);
-        if (l_sign->header.sign_size == 0) {
-            dap_string_append_printf(a_str_out, "<CORRUPTED - 0 size signature>\n");
-            continue;
-        }
-
-        dap_chain_hash_fast_t l_pkey_hash = {0};
-        if (dap_sign_get_pkey_hash(l_sign, &l_pkey_hash) == false) {
-            dap_string_append_printf(a_str_out, "<CORRUPTED - can't calc hash>\n");
-            continue;
-        }
-
-        const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
-                ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash)
-                : dap_chain_hash_fast_to_str_static(&l_pkey_hash);
-        dap_string_append_printf(a_str_out, "%d) %s, %s, %u bytes\n", i, l_hash_str,
-                                 dap_sign_type_to_str(l_sign->header.type), l_sign->header.sign_size);
-    }
-}
-
 void dap_chain_datum_decree_dump_json(json_object *a_json_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type)
 {
     char *l_type_str = "";
@@ -378,154 +168,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));
+        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_SIGN:
+            }
+            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_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));
-                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));
+        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_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));
-                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..8ea7e5f2905dc4a33b3e9bfeaf444198c162b5bd 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,9 @@ 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);
+    dap_return_val_if_fail(a_tx, 0);
+    return (sizeof(dap_chain_datum_tx_t) + a_tx->header.tx_items_size) > a_tx->header.tx_items_size
+            ? sizeof(dap_chain_datum_tx_t) + a_tx->header.tx_items_size : 0;
 }
 
 /**
@@ -76,35 +72,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 +129,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 +139,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 +148,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 +159,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 +195,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 +206,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 +218,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 +230,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 +243,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_receipt.c b/modules/common/dap_chain_datum_tx_receipt.c
index b4e4c836c4632987d4243461d94b071ebd510673..ef1618beebc9f92daec607b3398e528dd3af66b6 100644
--- a/modules/common/dap_chain_datum_tx_receipt.c
+++ b/modules/common/dap_chain_datum_tx_receipt.c
@@ -53,6 +53,7 @@ dap_chain_datum_tx_receipt_t * dap_chain_datum_tx_receipt_create( dap_chain_net_
     l_ret->receipt_info.srv_uid = a_srv_uid;
     l_ret->receipt_info.units = a_units;
     l_ret->receipt_info.value_datoshi = a_value_datoshi;
+    l_ret->receipt_info.version = 1;
     l_ret->size = sizeof(dap_chain_datum_tx_receipt_t) + a_ext_size;
 
     if (a_ext_size && a_ext) {
@@ -96,26 +97,24 @@ dap_chain_datum_tx_receipt_t *dap_chain_datum_tx_receipt_sign_add(dap_chain_datu
  * @param a_sign_position
  * @return
  */
-dap_sign_t* dap_chain_datum_tx_receipt_sign_get(dap_chain_datum_tx_receipt_t *a_receipt, size_t a_receipt_size, uint16_t a_sign_position)
+dap_sign_t *dap_chain_datum_tx_receipt_sign_get(dap_chain_datum_tx_receipt_t *a_receipt, size_t a_receipt_size, uint16_t a_sign_position)
 {
-    dap_return_val_if_fail(a_receipt && a_receipt_size == a_receipt->size &&
-                           a_receipt_size >= sizeof(dap_chain_datum_tx_receipt_t) + a_receipt->exts_size,
-                           NULL);
-    if (a_receipt_size < sizeof(dap_chain_datum_tx_receipt_t) + a_receipt->exts_size + sizeof(dap_sign_t))
-        return NULL;    // No signs at all
-    dap_sign_t *l_sign = (dap_sign_t *)(a_receipt->exts_n_signs + a_receipt->exts_size);
-    uint16_t l_sign_position;
-    for (l_sign_position = a_sign_position;
-             l_sign_position && a_receipt_size > (size_t)((byte_t *)l_sign - (byte_t *)a_receipt) + sizeof(dap_sign_t);
-             l_sign_position--) {
-        l_sign = (dap_sign_t *)((byte_t *)l_sign + dap_sign_get_size(l_sign));
-    }
-    // not enough signs in receipt
-    if (l_sign_position > 0)
+    if (dap_chain_datum_tx_receipt_check_size(a_receipt, a_receipt_size)) {
+        log_it(L_WARNING, "Receipt size check error");
         return NULL;
-    // too big sign size
-    if (dap_sign_get_size(l_sign) + ((byte_t *)l_sign - a_receipt->exts_n_signs) + sizeof(dap_chain_datum_tx_receipt_t) > a_receipt_size)
+    }
+    size_t l_offset = a_receipt->exts_size;
+    size_t l_total_signs_size = a_receipt->size - sizeof(dap_chain_datum_tx_receipt_t) - a_receipt->exts_size;
+    if (!l_total_signs_size)
         return NULL;
+    dap_sign_t *l_sign = NULL;
+    for (uint16_t l_sign_position = a_sign_position + 1; l_sign_position; l_sign_position--) {
+        l_sign = (dap_sign_t *)(a_receipt->exts_n_signs + l_offset);
+        uint64_t l_sign_size = dap_sign_get_size(l_sign);
+        l_offset += l_sign_size;
+        if (l_offset > l_total_signs_size)
+            return NULL;
+    }
     return l_sign;
 }
 
@@ -147,17 +146,38 @@ uint256_t   dap_chain_datum_tx_receipt_value_get(dap_chain_datum_tx_receipt_t *a
  * @param a_receipt_size
  * @return
  */
-uint16_t dap_chain_datum_tx_receipt_signs_count(dap_chain_datum_tx_receipt_t * a_receipt, size_t a_receipt_size)
+uint16_t dap_chain_datum_tx_receipt_signs_count(dap_chain_datum_tx_receipt_t *a_receipt)
 {
     uint16_t l_ret = 0;
-    if(!a_receipt)
-        return 0;
+    dap_return_val_if_fail(a_receipt, 0);
     dap_sign_t *l_sign;
-    for (l_sign = (dap_sign_t *)a_receipt->exts_n_signs; a_receipt_size > (size_t) ( (byte_t *) l_sign - (byte_t *) a_receipt ) ;
+    for (l_sign = (dap_sign_t *)a_receipt->exts_n_signs; a_receipt->size > (size_t) ( (byte_t *) l_sign - (byte_t *) a_receipt ) ;
         l_sign =(dap_sign_t *) (((byte_t*) l_sign)+  dap_sign_get_size( l_sign )) ){
         l_ret++;
     }
-    if(a_receipt_size != (size_t) ((byte_t *) l_sign - (byte_t *) a_receipt) )
-        log_it(L_ERROR, "Receipt 0x%zu (size=%zu) is corrupted", (size_t)a_receipt, a_receipt_size);
     return l_ret;
 }
+
+int dap_chain_datum_tx_receipt_check_size(dap_chain_datum_tx_receipt_t *a_receipt, size_t a_control_size)
+{
+    dap_return_val_if_fail(a_receipt && a_control_size == a_receipt->size &&
+                           a_control_size >= sizeof(dap_chain_datum_tx_receipt_t) + a_receipt->exts_size,
+                           -1); // Main controls incosistentency
+    if (a_control_size == sizeof(dap_chain_datum_tx_receipt_t) + a_receipt->exts_size)
+        return 0;               // No signs at receipt, it's OK
+    if (a_control_size < sizeof(dap_chain_datum_tx_receipt_t) + a_receipt->exts_size + sizeof(dap_sign_t))
+        return -2;
+    dap_sign_t *l_sign = (dap_sign_t *)(a_receipt->exts_n_signs + a_receipt->exts_size);
+    for (uint16_t l_sign_position = 2; l_sign_position; l_sign_position--) {
+        size_t l_sign_offset = (byte_t *)l_sign - (byte_t *)a_receipt;
+        if (a_control_size < l_sign_offset + sizeof(dap_sign_t))
+            return -2;          // Left space is too samll to contain a sign
+        uint64_t l_sign_size = dap_sign_get_size(l_sign);
+        if (l_sign_size + l_sign_offset <= l_sign_offset || l_sign_size + l_sign_offset > a_control_size)
+            return -3;
+        l_sign = (dap_sign_t *)((byte_t *)l_sign + l_sign_size);
+    }
+    size_t l_sign_offset = (byte_t *)l_sign - (byte_t *)a_receipt;
+                                                // Receipt is lagrer that two signs need
+    return l_sign_offset == a_control_size ? 0 : (a_receipt->receipt_info.version ? -4 : 0);
+}
diff --git a/modules/common/dap_chain_datum_tx_voting.c b/modules/common/dap_chain_datum_tx_voting.c
index 305ed3937eb719693ef64506a8077d511d13ccea..2a161dd3a93ce110042cf4c8c30030a536e9ec28 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;
 }
 
@@ -117,16 +108,18 @@ dap_chain_tx_tsd_t* dap_chain_datum_voting_max_votes_count_tsd_create(uint64_t a
     return l_tsd;
 }
 
-dap_chain_tx_tsd_t* dap_chain_datum_voting_delegated_key_required_tsd_create(bool a_delegate_key_required)
+dap_chain_tx_tsd_t* dap_chain_datum_voting_delegated_key_required_tsd_create(bool a_delegated_key_required)
 {
-    dap_chain_tx_tsd_t* l_tsd = dap_chain_datum_tx_item_tsd_create(&a_delegate_key_required, VOTING_TSD_TYPE_DELEGATED_KEY_REQUIRED, sizeof(bool));
+    byte_t l_value = a_delegated_key_required;
+    dap_chain_tx_tsd_t* l_tsd = dap_chain_datum_tx_item_tsd_create(&l_value, VOTING_TSD_TYPE_DELEGATED_KEY_REQUIRED, sizeof(byte_t));
 
     return l_tsd;
 }
 
 dap_chain_tx_tsd_t* dap_chain_datum_voting_vote_changing_allowed_tsd_create(bool a_vote_changing_allowed)
 {
-    dap_chain_tx_tsd_t* l_tsd = dap_chain_datum_tx_item_tsd_create(&a_vote_changing_allowed, VOTING_TSD_TYPE_VOTE_CHANGING_ALLOWED, sizeof(bool));
+    byte_t l_value = a_vote_changing_allowed;
+    dap_chain_tx_tsd_t* l_tsd = dap_chain_datum_tx_item_tsd_create(&l_value, VOTING_TSD_TYPE_VOTE_CHANGING_ALLOWED, sizeof(byte_t));
 
     return l_tsd;
 }
@@ -151,29 +144,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 +162,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.h b/modules/common/include/dap_chain_datum.h
index 74f39e9ca3bff1a76be6016a9e46479d56f4e246..8227287524f67ead3b3f73a2286552bc7da333c8 100644
--- a/modules/common/include/dap_chain_datum.h
+++ b/modules/common/include/dap_chain_datum.h
@@ -134,11 +134,11 @@ typedef struct dap_chain_datum{
  * @param a_datum
  * @return
  */
-DAP_STATIC_INLINE size_t dap_chain_datum_size(const dap_chain_datum_t *a_datum)
+DAP_STATIC_INLINE uint64_t dap_chain_datum_size(const dap_chain_datum_t *a_datum)
 {
     if (!a_datum)
         return 0;
-    return sizeof(a_datum->header) + a_datum->header.data_size;
+    return (uint64_t)sizeof(a_datum->header) + a_datum->header.data_size;
 }
 
 DAP_STATIC_INLINE void dap_chain_datum_calc_hash(const dap_chain_datum_t *a_datum, dap_hash_fast_t *a_out_hash)
diff --git a/modules/common/include/dap_chain_datum_anchor.h b/modules/common/include/dap_chain_datum_anchor.h
index 16c1ab915990752fbdae51a3851f621c2981dda8..79a0c48102707bb2f9b4acd0975e0c9411f45ced 100644
--- a/modules/common/include/dap_chain_datum_anchor.h
+++ b/modules/common/include/dap_chain_datum_anchor.h
@@ -48,7 +48,7 @@ DAP_STATIC_INLINE size_t dap_chain_datum_anchor_get_size(dap_chain_datum_anchor_
     return sizeof(*a_datum_anchor) + a_datum_anchor->header.data_size + a_datum_anchor->header.signs_size;
 }
 
-int dap_chain_datum_anchor_get_hash_from_data(dap_chain_datum_anchor_t* a_anchor, dap_hash_fast_t * l_out_hash);
+int dap_chain_datum_anchor_get_hash_from_data(dap_chain_datum_anchor_t* a_anchor, dap_hash_fast_t * a_out_hash);
 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/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..2f5480e7f30b7608c66c0ae3ea0ca7416248ba98 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_nth(a_tx, TX_ITEM_TYPE_OUT_ALL, a_out_num);
 
diff --git a/modules/common/include/dap_chain_datum_tx_receipt.h b/modules/common/include/dap_chain_datum_tx_receipt.h
index cbbb246d2ac7caff59dab448d94f0506233628e7..5210c4fff5a322515ed52fcb96b6f376ecd5da0f 100644
--- a/modules/common/include/dap_chain_datum_tx_receipt.h
+++ b/modules/common/include/dap_chain_datum_tx_receipt.h
@@ -33,7 +33,8 @@ typedef struct dap_chain_receipt_info {
     uint64_t addition;
 #endif
     dap_chain_net_srv_price_unit_uid_t units_type;
-    byte_t padding[4];
+    byte_t version;
+    byte_t padding[3];
     uint64_t units; // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT
     uint256_t value_datoshi; // Receipt value
 } DAP_ALIGN_PACKED dap_chain_receipt_info_t;
@@ -67,7 +68,8 @@ uint32_t    dap_chain_datum_tx_receipt_utype_get(dap_chain_datum_tx_receipt_t *a
 uint64_t    dap_chain_datum_tx_receipt_srv_uid_get(dap_chain_datum_tx_receipt_t *a_receipt);
 uint64_t    dap_chain_datum_tx_receipt_units_get(dap_chain_datum_tx_receipt_t *a_receipt);
 uint256_t   dap_chain_datum_tx_receipt_value_get(dap_chain_datum_tx_receipt_t *a_receipt);
-uint16_t dap_chain_datum_tx_receipt_signs_count(dap_chain_datum_tx_receipt_t *a_receipt, size_t a_receipt_size);
+uint16_t dap_chain_datum_tx_receipt_signs_count(dap_chain_datum_tx_receipt_t *a_receipt);
+int dap_chain_datum_tx_receipt_check_size(dap_chain_datum_tx_receipt_t *a_receipt, size_t a_control_size);
 
 #ifdef __cplusplus
 }
diff --git a/modules/common/include/dap_chain_datum_tx_voting.h b/modules/common/include/dap_chain_datum_tx_voting.h
index 331cb806f80f929b7b33af509b38b3e8117bfafa..d9a991a839a48be78ccbe6a4de762398d6f6f372 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"
@@ -79,7 +80,7 @@ dap_chain_tx_tsd_t* dap_chain_datum_voting_question_tsd_create(const char* a_que
 dap_chain_tx_tsd_t* dap_chain_datum_voting_answer_tsd_create(const char* a_answer_str, size_t str_len);
 dap_chain_tx_tsd_t* dap_chain_datum_voting_expire_tsd_create(dap_time_t a_expire);
 dap_chain_tx_tsd_t* dap_chain_datum_voting_max_votes_count_tsd_create(uint64_t a_max_count);
-dap_chain_tx_tsd_t* dap_chain_datum_voting_delegated_key_required_tsd_create(bool a_delegate_key_required);
+dap_chain_tx_tsd_t *dap_chain_datum_voting_delegated_key_required_tsd_create(bool a_delegated_key_required);
 dap_chain_tx_tsd_t* dap_chain_datum_voting_vote_changing_allowed_tsd_create(bool a_vote_changing_allowed);
 dap_chain_tx_tsd_t* dap_chain_datum_voting_vote_tx_cond_tsd_create(dap_chain_hash_fast_t a_tx_hash, int a_out_idx);
 
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index 112e5bc495c4d63e4757b8894932712506ad290e..9b1e629107767a4294f513b3998a33875343a9ec 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -2000,7 +2000,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) {
@@ -2128,7 +2128,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
     dap_chain_esbocs_message_t *l_message = (dap_chain_esbocs_message_t *)l_ch_pkt->data;
     size_t l_message_size = l_ch_pkt->hdr.data_size;
     if (l_message_size < sizeof(dap_chain_esbocs_message_t) ||
-            l_message_size > DAP_CHAIN_CS_BLOCKS_MAX_BLOCK_SIZE + PKT_SIGN_N_HDR_OVERHEAD ||
+            l_message_size > DAP_CHAIN_ATOM_MAX_SIZE + PKT_SIGN_N_HDR_OVERHEAD ||
             l_message_size != sizeof(*l_message) + l_message->hdr.sign_size + l_message->hdr.message_size) {
         log_it(L_WARNING, "Invalid message size %zu, drop this packet", l_message_size);
         return false;
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 3c05f9fc287bfe13380529bbc41c35ec44646bc7..827e3cc46527df108467db3d33474b1640e35822 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -602,29 +602,31 @@ 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;
-    size_t l_tsd_size = 0;
+#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; })
+    uint64_t l_tsd_size = 0;
     dap_tsd_t *l_tsd = (dap_tsd_t *)a_tsd;
-    for (size_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) {
+    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) {
+        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);
         }
         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 +637,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 +648,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 +669,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 +683,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 +692,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 +700,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 +708,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 +722,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 +734,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 +751,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 +762,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 +776,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 +785,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 +793,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 +801,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 +815,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 +827,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 +844,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 +855,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 +869,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 +878,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 +886,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 +894,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 +909,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 +921,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 +938,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 +949,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 +963,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 +972,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 +982,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 +990,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 +1004,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 +1016,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 +1033,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 +1043,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 +1055,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 +1063,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 +1072,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 +1096,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 +1106,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 +1128,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 +1136,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 +1145,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 +1171,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 +1190,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 +1203,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 +1225,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;
 }
 
 /**
@@ -1459,7 +1389,8 @@ int s_token_add_check(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_si
             return DAP_LEDGER_CHECK_PARSE_ERROR;
         }
     }
-    if (l_token_size < sizeof(dap_chain_datum_token_t) + l_size_tsd_section) {
+    if (sizeof(dap_chain_datum_token_t) + l_size_tsd_section > l_token_size ||
+            sizeof(dap_chain_datum_token_t) + l_size_tsd_section < l_size_tsd_section) {
         log_it(L_WARNING, "Incorrect size %zu of datum token, expected at least %zu", l_token_size,
                                                 sizeof(dap_chain_datum_token_t) + l_size_tsd_section);
         DAP_DELETE(l_token);
@@ -1467,16 +1398,23 @@ int s_token_add_check(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_si
     }
     // Check signs
     byte_t *l_signs_ptr = l_token->tsd_n_signs + l_size_tsd_section;
-    size_t l_signs_size = 0, l_signs_offset = sizeof(dap_chain_datum_token_t) + l_size_tsd_section;
+    uint64_t l_signs_size = 0, l_signs_offset = sizeof(dap_chain_datum_token_t) + l_size_tsd_section;
     for (uint16_t l_signs_passed = 0; l_signs_passed < l_token->signs_total; l_signs_passed++) {
         dap_sign_t *l_sign = (dap_sign_t *)(l_signs_ptr + l_signs_size);
-        if (l_token_size < l_signs_offset + l_signs_size + sizeof(dap_sign_t)) {
+        if (l_signs_offset + l_signs_size + sizeof(dap_sign_t) > l_token_size ||
+                l_signs_offset + l_signs_size + sizeof(dap_sign_t) < l_signs_offset) {
             log_it(L_WARNING, "Incorrect size %zu of datum token, expected at least %zu", l_token_size,
                                                     l_signs_offset + l_signs_size + sizeof(dap_sign_t));
             DAP_DELETE(l_token);
             return DAP_LEDGER_CHECK_INVALID_SIZE;
         }
-        l_signs_size += dap_sign_get_size(l_sign);
+        uint64_t l_sign_size = dap_sign_get_size(l_sign);
+        if (!l_sign_size || l_sign_size + l_signs_size < l_signs_size) {
+            log_it(L_WARNING, "Incorrect size %zu of datum token sign", l_sign_size);
+            DAP_DELETE(l_token);
+            return DAP_LEDGER_CHECK_INVALID_SIZE;
+        }
+        l_signs_size += l_sign_size;
     }
     if (l_token_size != l_signs_offset + l_signs_size) {
         log_it(L_WARNING, "Incorrect size %zu of datum token, expected %zu", l_token_size, l_signs_offset + l_signs_size);
@@ -1825,127 +1763,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")));
@@ -1953,7 +1883,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)
@@ -2799,7 +2728,8 @@ int s_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_
     switch (l_emission->hdr.type) {
 
     case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH: {
-        size_t l_sign_data_check_size = sizeof(dap_chain_datum_token_emission_t) + l_emission->data.type_auth.tsd_total_size;
+        size_t l_sign_data_check_size = sizeof(dap_chain_datum_token_emission_t) + l_emission->data.type_auth.tsd_total_size >= sizeof(dap_chain_datum_token_emission_t)
+                                                ? sizeof(dap_chain_datum_token_emission_t) + l_emission->data.type_auth.tsd_total_size : 0;
         if (l_sign_data_check_size > l_emission_size) {
             if (!s_check_hal(a_ledger, a_emission_hash)) {
                 log_it(L_WARNING, "Incorrect size %zu of datum emission, expected at least %zu", l_emission_size, l_sign_data_check_size);
@@ -2808,7 +2738,8 @@ int s_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_
             }
             goto ret_success;
         }
-        size_t l_emission_check_size = sizeof(dap_chain_datum_token_emission_t) + l_emission->data.type_auth.tsd_n_signs_size;
+        size_t l_emission_check_size = sizeof(dap_chain_datum_token_emission_t) + l_emission->data.type_auth.tsd_n_signs_size >= sizeof(dap_chain_datum_token_emission_t)
+                                                ? sizeof(dap_chain_datum_token_emission_t) + l_emission->data.type_auth.tsd_n_signs_size : 0;
         if (l_emission_check_size != l_emission_size) {
             log_it(L_WARNING, "Incorrect size %zu of datum emission, must be %zu", l_emission_size, l_emission_check_size);
             DAP_DELETE(l_emission);
@@ -3175,14 +3106,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;
@@ -3199,84 +3127,48 @@ 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)
-{
-    return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL, false);
-}
-
-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)
-{
-    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);
-    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 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;
-
+    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 NULL;
+        return l_hash;
     }
-
-    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;
+    dap_chain_datum_tx_t *l_prev_tx = a_tx;
+    byte_t *l_iter = a_tx->tx_items;
+    while (( l_iter = dap_chain_datum_tx_item_get(l_prev_tx, NULL, l_iter, TX_ITEM_TYPE_IN_COND, NULL) )) {
+        l_hash_tmp =  ((dap_chain_tx_in_cond_t *)l_iter)->header.tx_prev_hash;
+        if ( dap_hash_fast_is_blank(&l_hash_tmp) )
+            return l_hash_tmp;
+        if (( l_prev_tx = dap_ledger_tx_find_by_hash(a_ledger, &l_hash_tmp) ) &&
+                ( dap_chain_datum_tx_out_cond_get(l_prev_tx, a_cond_out->header.subtype, NULL) )) {
+            l_hash = l_hash_tmp;
+            l_iter = l_prev_tx->tx_items;
         }
-        l_prev_tx = l_prev_tx_temp;
     }
+    return l_hash;
+}
 
-    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;
+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 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;
+    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)
  */
@@ -3328,7 +3220,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);
 }
@@ -3447,9 +3339,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);
     
@@ -3575,11 +3466,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;
@@ -3660,7 +3551,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);
@@ -3671,7 +3562,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;
@@ -3755,7 +3646,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
@@ -3862,7 +3753,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
@@ -3897,7 +3788,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
@@ -3966,15 +3857,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;
@@ -3992,6 +3881,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
                     l_err_num = DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET;
                     break;
                 }
+
                 int l_verificator_error = l_verificator->callback(a_ledger, l_tx_prev_out_cond, a_tx, l_owner);
                 if (l_verificator_error != DAP_LEDGER_CHECK_OK) { // TODO add string representation for verificator return codes
                     debug_if(s_debug_more, L_WARNING, "Verificator check error %d for conditional output %s",
@@ -4046,9 +3936,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);
@@ -4094,16 +3983,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;
@@ -4113,7 +4001,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;
@@ -4127,7 +4015,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;
@@ -4138,7 +4026,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;
@@ -4159,8 +4047,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) {
@@ -4205,9 +4095,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) {
@@ -4261,31 +4148,28 @@ 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 (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.");
+        if ( dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_VOTING, NULL ) ) {
+            if (s_voting_callbacks.voting_callback) {
+                if ((l_err_num = s_voting_callbacks.voting_callback(a_ledger, TX_ITEM_TYPE_VOTING, a_tx, a_tx_hash, false))) {
+                    debug_if(s_debug_more, L_WARNING, "Verificator check error %d for voting", l_err_num);
                     l_err_num = DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE;
                 }
             } else {
                 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))) {
-           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.");
+        } else if ( dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_VOTE, NULL) ) {
+           if (s_voting_callbacks.voting_callback) {
+               if ((l_err_num = s_voting_callbacks.voting_callback(a_ledger, TX_ITEM_TYPE_VOTE, a_tx, a_tx_hash, false))) {
+                   debug_if(s_debug_more, L_WARNING, "Verificator check error %d for vote", l_err_num);
                    l_err_num = DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE;
                }
            } else {
                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;
         }
@@ -4680,12 +4564,14 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
             s_balance_cache_update(a_ledger, wallet_balance);
         }
     }
+    int l_err_num = 0;
     if (s_voting_callbacks.voting_callback) {
         if (l_tag.uint64 == DAP_CHAIN_TX_TAG_ACTION_VOTING)
-            s_voting_callbacks.voting_callback(a_ledger, TX_ITEM_TYPE_VOTING, a_tx, true);
+            l_err_num = s_voting_callbacks.voting_callback(a_ledger, TX_ITEM_TYPE_VOTING, a_tx, a_tx_hash, true);
         else if (l_tag.uint64 == DAP_CHAIN_TX_TAG_ACTION_VOTE)
-            s_voting_callbacks.voting_callback(a_ledger, TX_ITEM_TYPE_VOTE, a_tx, true);
+            l_err_num = s_voting_callbacks.voting_callback(a_ledger, TX_ITEM_TYPE_VOTE, a_tx, a_tx_hash, true);
     }
+    assert(!l_err_num);
 
     // add transaction to the cache list
     dap_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_ledger_tx_item_t);
@@ -5245,7 +5131,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;
 }
 
@@ -5289,76 +5175,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;
@@ -5377,7 +5229,8 @@ 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_tx_found = false, is_search_started = dap_hash_fast_is_blank(a_tx_first_hash);
     dap_ledger_tx_item_t *l_iter_start = NULL, *l_iter_current, *l_item_tmp;
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
     if (!dap_hash_fast_is_blank(a_tx_first_hash)) {
@@ -5397,55 +5250,41 @@ static dap_ledger_tx_item_t *tx_item_find_by_addr(dap_ledger_t *a_ledger, const
         // Now work with it
         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_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;
 }
 
 /**
@@ -5463,34 +5302,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;
  }
 
 /**
@@ -5516,14 +5350,13 @@ const dap_chain_datum_tx_t* dap_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger,
         dap_chain_datum_tx_t *l_tx_tmp = l_iter_current->tx;
         dap_chain_hash_fast_t *l_tx_hash_tmp = &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_tmp, a_tx_first_hash))
-                is_search_enable = true;
+        if (!is_search_enable) {
+            is_search_enable = dap_hash_fast_compare(l_tx_hash_tmp, a_tx_first_hash);
             continue;
         }
         // 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) {
@@ -5553,12 +5386,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;
 }
@@ -5586,9 +5418,8 @@ dap_chain_datum_tx_t* dap_ledger_tx_cache_find_out_cond(dap_ledger_t *a_ledger,
         dap_chain_datum_tx_t *l_tx_tmp = l_iter_current->tx;
         dap_chain_hash_fast_t *l_tx_hash_tmp = &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_tmp, a_tx_first_hash))
-                is_search_enable = true;
+        if (!is_search_enable) {
+            is_search_enable = dap_hash_fast_compare(l_tx_hash_tmp, a_tx_first_hash);
             continue;
         }
         // Get out_cond item from transaction
@@ -5664,157 +5495,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) >= 0 && 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;
 }
 
@@ -5970,122 +5762,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) {
@@ -6134,11 +5859,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 3811e7e4f4a2597cd3728000a55510018533225b..a65a28b99060eb025468d290b8f4cd27ef985c8b 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -2883,10 +2883,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 "
@@ -2894,13 +2893,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();
@@ -4335,7 +4332,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;
 }
 
@@ -4656,6 +4653,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
@@ -5482,15 +5480,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) {
@@ -5504,9 +5500,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;
         }
@@ -5521,7 +5517,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);
@@ -5754,16 +5750,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);
 
 
@@ -8354,7 +8348,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);
@@ -8365,23 +8358,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..7aafc5faef5b37b81b9f379a766583e1dec3b50c 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.
  */
@@ -203,7 +204,7 @@ typedef void (* dap_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger,
 typedef void (* dap_ledger_bridged_tx_notify_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg, dap_chan_ledger_notify_opcodes_t a_opcode);
 typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash);
 typedef struct dap_chain_net dap_chain_net_t;
-typedef bool (*dap_chain_ledger_voting_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx, bool a_apply);
+typedef int (*dap_chain_ledger_voting_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_apply);
 typedef bool (*dap_chain_ledger_voting_delete_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx);
 typedef bool (*dap_ledger_tag_check_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action);
 
@@ -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..88ca4c3c6e5f89a51e53659adb7875bd82ce1804 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;
     }
@@ -703,15 +702,16 @@ static int s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_
 {
     if (a_owner)
         return 0;
+    size_t l_receipt_size = 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, &l_receipt_size);
     if (!l_receipt){
         log_it(L_ERROR, "Can't find receipt.");
         return -1;
     }
 
     // Check provider sign
-    dap_sign_t *l_sign = dap_chain_datum_tx_receipt_sign_get(l_receipt, l_receipt->size, 0);
+    dap_sign_t *l_sign = dap_chain_datum_tx_receipt_sign_get(l_receipt, l_receipt_size, 0);
 
     if (!l_sign){
         log_it(L_ERROR, "Can't get provider sign from receipt.");
@@ -731,8 +731,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;
@@ -755,7 +755,7 @@ static int s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out_
     }
 
     // Check client sign
-    l_sign = dap_chain_datum_tx_receipt_sign_get(l_receipt, l_receipt->size, 1);
+    l_sign = dap_chain_datum_tx_receipt_sign_get(l_receipt, l_receipt_size, 1);
     if (!l_sign){
         log_it(L_ERROR, "Can't get client signature from receipt.");
         return -8;
@@ -772,16 +772,16 @@ 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);
 
     uint256_t l_unit_price = {};
-    if (l_receipt->receipt_info.units != 0){
-        DIV_256(l_receipt->receipt_info.value_datoshi, GET_256_FROM_64(l_receipt->receipt_info.units), &l_unit_price);
-    } else {
+    if (!l_receipt->receipt_info.units) {
+        log_it(L_ERROR, "Receipt units can't be a zero");
         return -11;
     }
+    DIV_256(l_receipt->receipt_info.value_datoshi, GET_256_FROM_64(l_receipt->receipt_info.units), &l_unit_price);
 
     if( !IS_ZERO_256(l_prev_out_cond->subtype.srv_pay.unit_price_max_datoshi) &&
         compare256(l_unit_price, l_prev_out_cond->subtype.srv_pay.unit_price_max_datoshi) > 0){
@@ -791,42 +791,43 @@ 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)){
-                SUM_256_256(l_value, l_tx_out->header.value, &l_value);
+            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)) {
+                log_it(L_WARNING, "Integer overflow while sum of outs calculation");
+                return -14;
             }
         } 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;
-            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);
+            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) {
+                if (SUM_256_256(l_value, l_tx_out->header.value, &l_value)) {
+                    log_it(L_WARNING, "Integer overflow while sum of outs calculation");
+                    return -14;
+                }
             } 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;
+    if (SUBTRACT_256_256(l_prev_out_cond->header.value, l_value, &l_value)) {
+        log_it(L_WARNING, "Integer overflow while payback calculation");
+        return -14;
     }
-    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/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c
index f8d627ae2faad2cd910eec6d3fd163caa875df86..9dd95fdcd9a700e4a42a94a599c65311b39b5693 100644
--- a/modules/net/srv/dap_chain_net_srv_order.c
+++ b/modules/net/srv/dap_chain_net_srv_order.c
@@ -81,13 +81,14 @@ void dap_chain_net_srv_order_deinit()
 
 }
 
-size_t dap_chain_net_srv_order_get_size(const dap_chain_net_srv_order_t *a_order)
+uint64_t dap_chain_net_srv_order_get_size(const dap_chain_net_srv_order_t *a_order)
 {
     if (!a_order || a_order->version != 3)
         return 0;
     dap_sign_t *l_sign = (dap_sign_t *)(a_order->ext_n_sign + a_order->ext_size);
-    size_t l_sign_size = l_sign->header.type.type == SIG_TYPE_NULL ? sizeof(dap_sign_type_t) : dap_sign_get_size(l_sign);
-    return sizeof(dap_chain_net_srv_order_t) + a_order->ext_size + l_sign_size;
+    uint64_t l_sign_size = l_sign->header.type.type == SIG_TYPE_NULL ? sizeof(dap_sign_type_t) : dap_sign_get_size(l_sign);
+    uint64_t l_size_without_sign = (uint64_t)sizeof(dap_chain_net_srv_order_t) + a_order->ext_size;
+    return l_size_without_sign + l_sign_size < l_size_without_sign ? 0 : l_size_without_sign + l_sign_size;
 }
 
 const dap_chain_net_srv_order_t *dap_chain_net_srv_order_check(const char *a_order_hash_str, const byte_t *a_order, size_t a_order_size)
diff --git a/modules/net/srv/include/dap_chain_net_srv_order.h b/modules/net/srv/include/dap_chain_net_srv_order.h
index 0898053d89a2700892c6a825dc3596455a925851..5d20752b1e153aadc26f97ae6b63f39c5423fb29 100644
--- a/modules/net/srv/include/dap_chain_net_srv_order.h
+++ b/modules/net/srv/include/dap_chain_net_srv_order.h
@@ -55,7 +55,7 @@ typedef struct dap_chain_net_srv_order
 int dap_chain_net_srv_order_init();
 void dap_chain_net_srv_order_deinit(void);
 
-size_t dap_chain_net_srv_order_get_size(const dap_chain_net_srv_order_t *a_order);
+uint64_t dap_chain_net_srv_order_get_size(const dap_chain_net_srv_order_t *a_order);
 const dap_chain_net_srv_order_t *dap_chain_net_srv_order_check(const char *a_order_hash_str, const byte_t *a_order, size_t a_order_size);
 
 bool dap_chain_net_srv_order_set_continent_region(dap_chain_net_srv_order_t **a_order, uint8_t a_continent_num, const char *a_region);
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..53a216607537db1cbf3f2d8f92c4b1ea1852b6d6 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;
@@ -1027,12 +1027,14 @@ static int s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_t
                 MULT_256_COIN(a_cond->header.value, l_emission_rate, &l_value_delegated) ||
                 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);
+        size_t l_receipt_size = 0;
+        l_receipt = (dap_chain_datum_tx_receipt_t *)dap_chain_datum_tx_item_get(a_tx_in, NULL, NULL, TX_ITEM_TYPE_RECEIPT, &l_receipt_size);
         if (l_receipt) {
+            if (dap_chain_datum_tx_receipt_check_size(l_receipt, l_receipt_size))
+                return -13;
             if (!dap_chain_net_srv_uid_compare_scalar(l_receipt->receipt_info.srv_uid, DAP_CHAIN_NET_SRV_STAKE_LOCK_ID))
                 return -7;
-            if (!l_receipt->exts_size)
+            if (l_receipt->exts_size < sizeof(dap_hash_fast_t))
                 return -8;
             l_burning_tx_hash = *(dap_hash_fast_t*)l_receipt->exts_n_signs;
             if (dap_hash_fast_is_blank(&l_burning_tx_hash))
@@ -1050,45 +1052,43 @@ 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;
         }
 
         if (s_debug_more) {
-            char *str1 = dap_chain_balance_print(a_cond->header.value);
-            char *str2 = dap_chain_balance_print(l_value_delegated);
-            char *str3 = dap_chain_balance_print(l_blank_out_value);
-            log_it(L_INFO, "hold/take_value: %s",	str1);
-            log_it(L_INFO, "delegated_value: %s",	str2);
-            log_it(L_INFO, "burning_value:   %s",	str3);
+            char *str1 = dap_chain_balance_to_coins(a_cond->header.value);
+            char *str2 = dap_chain_balance_to_coins(l_value_delegated);
+            char *str3 = dap_chain_balance_to_coins(l_blank_out_value);
+            log_it(L_INFO, "hold/take_value: %s, delegated_value: %s, burning_value: %s", str1,	str2, str3);
             DAP_DEL_MULTY(str1, str2, str3);
         }
 
         if (!EQUAL_256(l_blank_out_value, l_value_delegated)) {
             // !!! A terrible legacy crutch, TODO !!!
-            SUM_256_256(l_value_delegated, GET_256_FROM_64(10), &l_value_delegated);
-            if (!EQUAL_256(l_blank_out_value, l_value_delegated)) {
+            if (SUM_256_256(l_value_delegated, GET_256_FROM_64(10), &l_value_delegated) ||
+                    !EQUAL_256(l_blank_out_value, l_value_delegated)) {
                 log_it(L_ERROR, "Burning and delegated value mismatch");
                 return -12;
             }
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 e62cbb57759d3fc73cafe101dc5bc9ebaf547b03..494ae6cd9eab56720468c56ea16bdb808b801a69 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,41 +236,18 @@ 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;
     }
+    // ATTENTION: It's correct only with single IN_COND TX item
     dap_hash_fast_t *l_prev_hash = &l_tx_in_cond->header.tx_prev_hash;
     if (dap_hash_fast_is_blank(l_prev_hash)) {
         log_it(L_ERROR, "Blank hash of prev tx in tx_in_cond");
         return -7;
     }
-    dap_chain_datum_tx_t *l_prev_tx = dap_ledger_tx_find_by_hash(a_ledger, l_prev_hash);
-    if (!l_prev_tx) {
-        log_it(L_ERROR, "Previous tx not found for now but is found in ledger before");
-        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);
-    if (!l_tx_prev_in_cond)
-        l_owner = a_owner;
-    else {
-        dap_hash_fast_t *l_owner_tx_hash = &l_tx_prev_in_cond->header.tx_prev_hash;
-        dap_chain_datum_tx_t *l_owner_tx = dap_ledger_tx_find_by_hash(a_ledger, l_owner_tx_hash);
-        dap_sign_t *l_owner_sign = dap_chain_datum_tx_get_sign(l_owner_tx, 0);
-        if (!l_owner_sign) {
-            log_it(L_ERROR, "Can't get owner sign");
-            return -9;
-        }
-        dap_sign_t *l_taker_sign = dap_chain_datum_tx_get_sign(a_tx_in, 0);
-        if (!l_taker_sign) {
-            log_it(L_ERROR, "Can't get taker sign");
-            return -10;
-        }
-        l_owner = dap_sign_compare_pkeys(l_taker_sign, l_owner_sign);
-    }
-    if (!l_owner) {
+    if (!a_owner) {
         log_it(L_WARNING, "Trying to spend conditional tx not by owner");
         return -11;
     }
@@ -689,7 +666,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 +961,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 +970,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 f4805ddea2990db7754c5cc1559c165cf35396fb..84b2689868d76f591cbbc8a314f57e4d8f11ce93 100644
--- a/modules/service/voting/dap_chain_net_srv_voting.c
+++ b/modules/service/voting/dap_chain_net_srv_voting.c
@@ -44,19 +44,13 @@ typedef struct dap_chain_net_voting_params_offsets{
     dap_chain_datum_tx_t* voting_tx;
     size_t voting_question_offset;
     size_t voting_question_length;
-    dap_list_t* option_offsets_list;
-    size_t voting_expire_offset;
-    size_t votes_max_count_offset;
-    size_t delegate_key_required_offset;
-    size_t vote_changing_allowed_offset;
+    dap_list_t *option_offsets_list;
+    dap_time_t voting_expire;
+    uint64_t votes_max_count;
+    bool delegate_key_required;
+    bool vote_changing_allowed;
 } dap_chain_net_voting_params_offsets_t;
 
-
-typedef struct dap_chain_net_voting{
-    dap_hash_fast_t hash_vote;
-    dap_chain_net_id_t net_id;
-}dap_chain_net_voting_t;
-
 typedef struct dap_chain_net_vote_option {
     size_t vote_option_offset;
     size_t vote_option_length;
@@ -93,8 +87,8 @@ static pthread_rwlock_t s_votings_rwlock;
 
 static int s_datum_tx_voting_coin_check_cond_out(dap_chain_net_t *a_net, dap_hash_fast_t a_voting_hash, dap_hash_fast_t a_tx_cond_hash, int a_cond_out_idx);
 /// -1 error, 0 - unspent, 1 - spent
-static int s_datum_tx_voting_coin_check_spent(dap_chain_net_t *a_net, dap_hash_fast_t a_voting_hash, dap_hash_fast_t a_tx_prev_hash, int a_out_idx);
-static bool s_datum_tx_voting_verification_callback(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx_in, bool a_apply);
+static int s_datum_tx_voting_coin_check_spent(dap_chain_net_t *a_net, dap_hash_fast_t a_voting_hash, dap_hash_fast_t a_tx_prev_hash, int a_out_idx, dap_hash_fast_t *a_pkey_hash);
+static int s_datum_tx_voting_verification_callback(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx_in, dap_hash_fast_t *a_tx_hash, bool a_apply);
 static bool s_datum_tx_voting_verification_delete_callback(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx_in);
 static int s_cli_voting(int argc, char **argv, void **a_str_reply);
 
@@ -178,319 +172,298 @@ uint64_t* dap_chain_net_voting_get_result(dap_ledger_t* a_ledger, dap_chain_hash
 }
 
 
-
-bool s_datum_tx_voting_verification_callback(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx_in, bool a_apply)
+static int s_voting_verificator(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx_in, dap_hash_fast_t *a_tx_hash, bool a_apply)
 {
-
-    dap_hash_fast_t l_hash = {};
-    dap_hash_fast(a_tx_in, dap_chain_datum_tx_get_size(a_tx_in), &l_hash);
-
-    if (a_type == TX_ITEM_TYPE_VOTING){
-        if (!a_apply){
-            dap_chain_net_votings_t * l_voting = NULL;
-            pthread_rwlock_rdlock(&s_votings_rwlock);
-            HASH_FIND(hh, s_votings, &l_hash, sizeof(dap_hash_fast_t), l_voting);
-            pthread_rwlock_unlock(&s_votings_rwlock);
-            if(l_voting && l_voting->net_id.uint64 == a_ledger->net->pub.id.uint64){
-                char* l_hash_str = dap_hash_fast_to_str_new(&l_hash);
-                log_it(L_ERROR, "Voting with hash %s is already presents in net %s", l_hash_str, a_ledger->net->pub.name);
-                DAP_DEL_Z(l_hash_str);
-                return false;
-            }
-
-            dap_list_t* l_tsd_list = dap_chain_datum_tx_items_get(a_tx_in, TX_ITEM_TYPE_TSD, NULL);
-            dap_list_t* l_temp = l_tsd_list;
-            size_t l_question_len = 0;
-            size_t l_options_count = 0;
-            while (l_temp){
-                dap_tsd_t* l_tsd = (dap_tsd_t*)((dap_chain_tx_tsd_t*)l_temp->data)->tsd;
-                dap_chain_net_vote_option_t *l_vote_option = NULL;
-                switch(l_tsd->type){
-                case VOTING_TSD_TYPE_QUESTION:
-                    l_question_len = l_tsd->size;
-                    break;
-                case VOTING_TSD_TYPE_ANSWER:
-                    l_options_count++;
-                    break;
-                default:
-                    break;
-                }
-                l_temp = l_temp->next;
-            }
-            dap_list_free(l_tsd_list);
-
-            if (!l_question_len || !l_options_count)
-                return false;
-
-            return true;
+    if (!a_apply) {
+        dap_chain_net_votings_t * l_voting = NULL;
+        pthread_rwlock_rdlock(&s_votings_rwlock);
+        HASH_FIND(hh, s_votings, a_tx_hash, sizeof(dap_hash_fast_t), l_voting);
+        pthread_rwlock_unlock(&s_votings_rwlock);
+        if (l_voting && l_voting->net_id.uint64 == a_ledger->net->pub.id.uint64) {
+            log_it(L_DEBUG, "Voting with hash %s is already presents in net %s",  dap_hash_fast_to_str_static(a_tx_hash), a_ledger->net->pub.name);
+            return -1;
         }
 
-        dap_chain_net_votings_t *l_item = DAP_NEW_Z_SIZE(dap_chain_net_votings_t, sizeof(dap_chain_net_votings_t));
-        l_item->voting_hash = l_hash;
-        l_item->voting_params.voting_tx = a_tx_in;
-        l_item->net_id = a_ledger->net->pub.id;
-        pthread_rwlock_init(&l_item->s_tx_outs_rwlock, NULL);
-
         dap_list_t* l_tsd_list = dap_chain_datum_tx_items_get(a_tx_in, 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;
-            dap_chain_net_vote_option_t *l_vote_option = NULL;
-            switch(l_tsd->type){
+        size_t l_question_len = 0, l_options_count = 0;
+        for (dap_list_t *it = l_tsd_list; it; it = it->next) {
+            dap_tsd_t *l_tsd = (dap_tsd_t *)((dap_chain_tx_tsd_t *)it->data)->tsd;
+            switch (l_tsd->type) {
             case VOTING_TSD_TYPE_QUESTION:
-                l_item->voting_params.voting_question_offset = (size_t)(l_tsd->data - (byte_t*)l_item->voting_params.voting_tx);
-                l_item->voting_params.voting_question_length = l_tsd->size;
+                l_question_len = l_tsd->size;
                 break;
             case VOTING_TSD_TYPE_ANSWER:
-                l_vote_option = DAP_NEW_Z(dap_chain_net_vote_option_t);
-                l_vote_option->vote_option_offset = (size_t)(l_tsd->data - (byte_t*)l_item->voting_params.voting_tx);
-                l_vote_option->vote_option_length = l_tsd->size;
-                l_item->voting_params.option_offsets_list = dap_list_append(l_item->voting_params.option_offsets_list, l_vote_option);
-                break;
-            case VOTING_TSD_TYPE_EXPIRE:
-                l_item->voting_params.voting_expire_offset = (size_t)(l_tsd->data - (byte_t*)l_item->voting_params.voting_tx);
-                break;
-            case VOTING_TSD_TYPE_MAX_VOTES_COUNT:
-                l_item->voting_params.votes_max_count_offset = (size_t)(l_tsd->data - (byte_t*)l_item->voting_params.voting_tx);
-                break;
-            case VOTING_TSD_TYPE_DELEGATED_KEY_REQUIRED:
-                l_item->voting_params.delegate_key_required_offset = (size_t)(l_tsd->data - (byte_t*)l_item->voting_params.voting_tx);
-                break;
-            case VOTING_TSD_TYPE_VOTE_CHANGING_ALLOWED:
-                l_item->voting_params.vote_changing_allowed_offset = (size_t)(l_tsd->data - (byte_t*)l_item->voting_params.voting_tx);
+                l_options_count++;
                 break;
             default:
                 break;
             }
-            l_temp = l_temp->next;
         }
         dap_list_free(l_tsd_list);
 
-        pthread_rwlock_wrlock(&s_votings_rwlock);
-        HASH_ADD(hh, s_votings, voting_hash, sizeof(dap_hash_fast_t), l_item);
-        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);
-        if(!l_vote_tx_item){
-            log_it(L_ERROR, "Can't find vote item");
-            return false;
+        if (!l_question_len || !l_options_count) {
+            log_it(L_WARNING, "Voting with hash %s contain no question or answer options", dap_hash_fast_to_str_static(a_tx_hash));
+            return -2;
         }
 
-        dap_chain_net_votings_t * l_voting = NULL;
-        pthread_rwlock_wrlock(&s_votings_rwlock);
-        HASH_FIND(hh, s_votings, &l_vote_tx_item->voting_hash, sizeof(dap_hash_fast_t), l_voting);
-        pthread_rwlock_unlock(&s_votings_rwlock);
-        if(!l_voting || l_voting->net_id.uint64 != a_ledger->net->pub.id.uint64) {
-            log_it(L_ERROR, "Can't find voting with hash %s in net %s",
-                   dap_chain_hash_fast_to_str_static(&l_hash), a_ledger->net->pub.name);
-            return false;
-        }
+        return DAP_LEDGER_CHECK_OK;
+    }
 
-        if (!a_apply){
-            if (l_vote_tx_item->answer_idx > dap_list_length(l_voting->voting_params.option_offsets_list)){
-                log_it(L_ERROR, "Invalid vote option index.");
-                return false;
+    dap_chain_net_votings_t *l_item;
+    DAP_NEW_Z_SIZE_RET_VAL(l_item, dap_chain_net_votings_t, sizeof(dap_chain_net_votings_t), -DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY, NULL);
+    l_item->voting_hash = *a_tx_hash;
+    l_item->voting_params.voting_tx = a_tx_in;
+    l_item->net_id = a_ledger->net->pub.id;
+    pthread_rwlock_init(&l_item->s_tx_outs_rwlock, NULL);
+
+    dap_list_t* l_tsd_list = dap_chain_datum_tx_items_get(a_tx_in, TX_ITEM_TYPE_TSD, NULL);
+    for (dap_list_t *it = l_tsd_list; it; it = it->next) {
+        dap_tsd_t* l_tsd = (dap_tsd_t *)((dap_chain_tx_tsd_t*)it->data)->tsd;
+        dap_chain_net_vote_option_t *l_vote_option = NULL;
+        switch(l_tsd->type){
+        case VOTING_TSD_TYPE_QUESTION:
+            l_item->voting_params.voting_question_offset = (size_t)(l_tsd->data - (byte_t*)l_item->voting_params.voting_tx);
+            l_item->voting_params.voting_question_length = l_tsd->size;
+            break;
+        case VOTING_TSD_TYPE_ANSWER:
+            l_vote_option = DAP_NEW_Z(dap_chain_net_vote_option_t);
+            l_vote_option->vote_option_offset = (size_t)(l_tsd->data - (byte_t*)l_item->voting_params.voting_tx);
+            l_vote_option->vote_option_length = l_tsd->size;
+            l_item->voting_params.option_offsets_list = dap_list_append(l_item->voting_params.option_offsets_list, l_vote_option);
+            break;
+        case VOTING_TSD_TYPE_EXPIRE:
+            if (l_tsd->size != sizeof(dap_time_t)) {
+                log_it(L_WARNING, "Incorrect size %u of TSD section EXPIRE vot voting %s", l_tsd->size, dap_hash_fast_to_str_static(a_tx_hash));
+                return -DAP_LEDGER_CHECK_INVALID_SIZE;
             }
-
-            if(l_voting->voting_params.votes_max_count_offset){
-                uint64_t l_votes_max_count = *(uint64_t*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.votes_max_count_offset);
-                if (l_votes_max_count && dap_list_length(l_voting->votes) >= l_votes_max_count){
-                    log_it(L_ERROR, "The required number of votes has been collected.");
-                    return false;
-                }
+            l_item->voting_params.voting_expire = *(dap_time_t *)l_tsd->data;
+            break;
+        case VOTING_TSD_TYPE_MAX_VOTES_COUNT:
+            if (l_tsd->size != sizeof(uint64_t)) {
+                log_it(L_WARNING, "Incorrect size %u of TSD section MAX_VOTES_COUNT vot voting %s", l_tsd->size, dap_hash_fast_to_str_static(a_tx_hash));
+                return -DAP_LEDGER_CHECK_INVALID_SIZE;
             }
-
-            if(l_voting->voting_params.voting_expire_offset){
-                dap_time_t l_expire = *(dap_time_t*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.voting_expire_offset);
-                if( l_expire && l_expire <= a_tx_in->header.ts_created){
-                    log_it(L_ERROR, "The voting has been expired.");
-                    return false;
-                }
+            l_item->voting_params.votes_max_count = *(uint64_t *)l_tsd->data;
+            break;
+        case VOTING_TSD_TYPE_DELEGATED_KEY_REQUIRED:
+            if (l_tsd->size != sizeof(byte_t)) {
+                log_it(L_WARNING, "Incorrect size %u of TSD section DELEGATED_KEY_REQUIRED vot voting %s", l_tsd->size, dap_hash_fast_to_str_static(a_tx_hash));
+                return -DAP_LEDGER_CHECK_INVALID_SIZE;
+            }
+            l_item->voting_params.delegate_key_required = *(byte_t *)l_tsd->data;
+            break;
+        case VOTING_TSD_TYPE_VOTE_CHANGING_ALLOWED:
+            if (l_tsd->size != sizeof(byte_t)) {
+                log_it(L_WARNING, "Incorrect size %u of TSD section VOTE_CHANGING_ALLOWED vot voting %s", l_tsd->size, dap_hash_fast_to_str_static(a_tx_hash));
+                return -DAP_LEDGER_CHECK_INVALID_SIZE;
             }
+            l_item->voting_params.vote_changing_allowed = *(byte_t *)l_tsd->data;
+            break;
+        default:
+            break;
+        }
+    }
+    dap_list_free(l_tsd_list);
 
-            dap_hash_fast_t pkey_hash = {};
-            dap_chain_tx_sig_t *l_vote_sig = NULL;
-            int l_item_cnt = 0;
-            dap_list_t* l_signs_list = NULL;
-            l_signs_list = dap_chain_datum_tx_items_get(a_tx_in, TX_ITEM_TYPE_SIG, &l_item_cnt);
+    pthread_rwlock_wrlock(&s_votings_rwlock);
+    HASH_ADD(hh, s_votings, voting_hash, sizeof(dap_hash_fast_t), l_item);
+    pthread_rwlock_unlock(&s_votings_rwlock);
+    return DAP_LEDGER_CHECK_OK;
+}
 
-            if(!l_signs_list){
-                log_it(L_ERROR, "Can't get sign.");
-                return false;
-            }
-            l_vote_sig = (dap_chain_tx_sig_t *)(dap_list_last(l_signs_list)->data);
-            dap_sign_get_pkey_hash((dap_sign_t*)l_vote_sig->sig, &pkey_hash);
-            if (l_voting->voting_params.delegate_key_required_offset &&
-                *(bool*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.delegate_key_required_offset)){
-                if (!dap_chain_net_srv_stake_check_pkey_hash(a_ledger->net->pub.id, &pkey_hash)){
-                    log_it(L_ERROR, "The voting required a delegated key.");
-                    dap_list_free(l_signs_list);
-                    return false;
-                }
-            }
+static int s_vote_verificator(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx_in, dap_hash_fast_t *a_tx_hash, bool a_apply)
+{
+    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 for tx %s", dap_chain_hash_fast_to_str_static(a_tx_hash));
+        return -4;
+    }
 
-            dap_list_t *l_temp = l_voting->votes;
-            while(l_temp){
-                if (dap_hash_fast_compare(&((dap_chain_net_vote_t *)l_temp->data)->pkey_hash, &pkey_hash)){
-                    if(l_voting->voting_params.vote_changing_allowed_offset &&
-                        *(bool*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.vote_changing_allowed_offset)){
-                        //delete conditional outputs
-                        dap_chain_datum_tx_t *l_old_tx = dap_ledger_tx_find_by_hash(a_ledger, &((dap_chain_net_vote_t *)l_temp->data)->vote_hash);
-
-                        dap_list_t* l_tsd_list = dap_chain_datum_tx_items_get(l_old_tx, TX_ITEM_TYPE_TSD, NULL);
-                        dap_list_t* l_tsd_temp = l_tsd_list;
-                        while (l_tsd_temp){
-                            dap_tsd_t* l_tsd = (dap_tsd_t*)((dap_chain_tx_tsd_t*)l_tsd_temp->data)->tsd;
-                            dap_hash_fast_t l_hash = ((dap_chain_tx_voting_tx_cond_t*)l_tsd->data)->tx_hash;
-                            if(l_tsd->type == VOTING_TSD_TYPE_VOTE_TX_COND){
-                                dap_chain_net_voting_cond_outs_t *l_tx_outs = NULL;
-                                pthread_rwlock_wrlock(&l_voting->s_tx_outs_rwlock);
-                                HASH_FIND(hh, l_voting->voting_spent_cond_outs, &l_hash, sizeof(dap_hash_fast_t), l_tx_outs);
-                                if(l_tx_outs)
-                                    HASH_DELETE(hh, l_voting->voting_spent_cond_outs, l_tx_outs);
-                                pthread_rwlock_unlock(&l_voting->s_tx_outs_rwlock);
-                            }
-                            l_tsd_temp = l_tsd_temp->next;
-                        }
-                        dap_list_free(l_tsd_list);
-
-
-                        //delete vote
-                        l_voting->votes = dap_list_remove(l_voting->votes, l_temp->data);
-                        break;
-                    } else {
-                        log_it(L_ERROR, "The voting don't allow change your vote.");
-                        return false;
-                    }
-                }
-                l_temp = l_temp->next;
-            }
-            dap_list_free(l_signs_list);
-        }
+    dap_chain_net_votings_t *l_voting = NULL;
+    pthread_rwlock_wrlock(&s_votings_rwlock);
+    HASH_FIND(hh, s_votings, &l_vote_tx_item->voting_hash, sizeof(dap_hash_fast_t), l_voting);
+    pthread_rwlock_unlock(&s_votings_rwlock);
+    if (!l_voting || l_voting->net_id.uint64 != a_ledger->net->pub.id.uint64) {
+        log_it(L_ERROR, "Can't find voting with hash %s in net %s",
+               dap_chain_hash_fast_to_str_static(&l_vote_tx_item->voting_hash), a_ledger->net->pub.name);
+        return -5;
+    }
 
-        uint256_t l_weight = {};
+    dap_hash_fast_t pkey_hash = {};
+    int l_item_cnt = 0;
+    dap_list_t *l_signs_list = dap_chain_datum_tx_items_get(a_tx_in, TX_ITEM_TYPE_SIG, &l_item_cnt);
 
-        // check out conds
-        dap_list_t* l_tsd_list = dap_chain_datum_tx_items_get(a_tx_in, TX_ITEM_TYPE_TSD, NULL);
-        dap_list_t* l_tsd_temp = l_tsd_list;
-        while (l_tsd_temp){
-            dap_tsd_t* l_tsd = (dap_tsd_t*)((dap_chain_tx_tsd_t*)l_tsd_temp->data)->tsd;
-            dap_hash_fast_t l_hash = ((dap_chain_tx_voting_tx_cond_t*)l_tsd->data)->tx_hash;
-            int l_out_idx = ((dap_chain_tx_voting_tx_cond_t*)l_tsd->data)->out_idx;
-            if(l_tsd->type == VOTING_TSD_TYPE_VOTE_TX_COND){
-                if (s_datum_tx_voting_coin_check_cond_out(a_ledger->net, l_vote_tx_item->voting_hash,
-                                                          l_hash, l_out_idx) != 0){
-                    l_tsd_temp = l_tsd_temp->next;
-                    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);
-                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;
+    if (!l_signs_list) {
+        log_it(L_WARNING, "Can't get signs from tx %s", dap_chain_hash_fast_to_str_static(a_tx_hash));
+        return -9;
+    }
+    dap_chain_tx_sig_t *l_vote_sig = (dap_chain_tx_sig_t *)(dap_list_last(l_signs_list)->data);
+    dap_sign_get_pkey_hash((dap_sign_t*)l_vote_sig->sig, &pkey_hash);
+    dap_list_free(l_signs_list);
+
+    if (!a_apply) {
+        if (l_vote_tx_item->answer_idx > dap_list_length(l_voting->voting_params.option_offsets_list)) {
+            log_it(L_WARNING, "Invalid vote option index %" DAP_UINT64_FORMAT_U " for vote tx %s",
+                                                    l_vote_tx_item->answer_idx, dap_chain_hash_fast_to_str_static(a_tx_hash));
+            return -6;
+        }
+        if (l_voting->voting_params.votes_max_count && dap_list_length(l_voting->votes) >= l_voting->voting_params.votes_max_count){
+            log_it(L_WARNING, "The required number of votes has been collected for voting %s", dap_chain_hash_fast_to_str_static(&l_voting->voting_hash));
+            return -7;
+        }
+        if (l_voting->voting_params.voting_expire && l_voting->voting_params.voting_expire <= a_tx_in->header.ts_created) {
+            log_it(L_WARNING, "The voting %s has been expired", dap_chain_hash_fast_to_str_static(&l_voting->voting_hash));
+            return -8;
+        }
+
+        if (l_voting->voting_params.delegate_key_required &&
+                !dap_chain_net_srv_stake_check_pkey_hash(a_ledger->net->pub.id, &pkey_hash)){
+            log_it(L_WARNING, "Voting %s required a delegated key", dap_chain_hash_fast_to_str_static(&l_voting->voting_hash));
+            return -10;
+        }
+
+        for (dap_list_t *it = l_voting->votes; it; it = it->next) {
+            if (dap_hash_fast_compare(&((dap_chain_net_vote_t *)it->data)->pkey_hash, &pkey_hash)) {
+                dap_hash_fast_t *l_vote_hash = &((dap_chain_net_vote_t *)it->data)->vote_hash;
+                if (!l_voting->voting_params.vote_changing_allowed) {
+                    char l_vote_hash_str[DAP_HASH_FAST_STR_SIZE];
+                    dap_hash_fast_to_str(l_vote_hash, l_vote_hash_str, DAP_HASH_FAST_STR_SIZE);
+                    log_it(L_WARNING, "The voting %s don't allow change your vote %s",
+                           dap_hash_fast_to_str_static(&l_voting->voting_hash), l_vote_hash_str);
+                    return -11;
                 }
-                SUM_256_256(l_weight, l_prev_out->header.value, &l_weight);
-
-                dap_chain_net_voting_cond_outs_t *l_item = DAP_NEW_Z_SIZE(dap_chain_net_voting_cond_outs_t, sizeof(dap_chain_net_voting_cond_outs_t));
-                l_item->tx_hash = l_hash;
-                l_item->out_idx = l_out_idx;
-                pthread_rwlock_wrlock(&l_voting->s_tx_outs_rwlock);
-                HASH_ADD(hh, l_voting->voting_spent_cond_outs, tx_hash, sizeof(dap_hash_fast_t), l_item);
-                pthread_rwlock_unlock(&l_voting->s_tx_outs_rwlock);
+                break;
             }
-            l_tsd_temp = l_tsd_temp->next;
         }
-        dap_list_free(l_tsd_list);
-        // check inputs
-        dap_list_t *l_ins_list = dap_chain_datum_tx_items_get(a_tx_in, TX_ITEM_TYPE_IN, NULL);
-        if (!l_ins_list){
-            log_it(L_ERROR, "Can't get inputs from tx");
-            return -1;
-        }
-        dap_list_t *l_in_temp = l_ins_list;
-        while(l_in_temp){
-            dap_chain_tx_in_t *l_tx_in = (dap_chain_tx_in_t *)l_in_temp->data;
-            if (s_datum_tx_voting_coin_check_spent(a_ledger->net, l_vote_tx_item->voting_hash, l_tx_in->header.tx_prev_hash, l_tx_in->header.tx_out_prev_idx) == 0){
-                dap_chain_datum_tx_t *l_tx_prev_temp = dap_ledger_tx_find_by_hash(a_ledger, &l_tx_in->header.tx_prev_hash);
-                int l_out_prev_idx = (int)l_tx_in->header.tx_out_prev_idx;
-                dap_chain_tx_out_t *l_prev_out_union = (dap_chain_tx_out_t *)dap_chain_datum_tx_out_get_by_out_idx(l_tx_prev_temp, l_out_prev_idx);
-                if (!l_prev_out_union){
-                    l_in_temp = l_in_temp->next;
-                    continue;
-                }
+    }
 
-                switch (l_prev_out_union->header.type) {
-                case TX_ITEM_TYPE_OUT:
-                case TX_ITEM_TYPE_OUT_EXT:
-                    SUM_256_256(l_weight, l_prev_out_union->header.value, &l_weight);
-                }
+    uint256_t l_weight = {};
+
+    // check out conds
+    dap_list_t *l_tsd_list = dap_chain_datum_tx_items_get(a_tx_in, TX_ITEM_TYPE_TSD, NULL);
+    for (dap_list_t *it = l_tsd_list; it; it = it->next) {
+        dap_tsd_t *l_tsd = (dap_tsd_t *)((dap_chain_tx_tsd_t*)it->data)->tsd;
+        dap_hash_fast_t l_hash = ((dap_chain_tx_voting_tx_cond_t*)l_tsd->data)->tx_hash;
+        int l_out_idx = ((dap_chain_tx_voting_tx_cond_t*)l_tsd->data)->out_idx;
+        if (l_tsd->type == VOTING_TSD_TYPE_VOTE_TX_COND) {
+            if (s_datum_tx_voting_coin_check_cond_out(a_ledger->net, l_vote_tx_item->voting_hash, l_hash, l_out_idx))
+                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, 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)
+                continue;
+            if (SUM_256_256(l_weight, l_prev_out->header.value, &l_weight)) {
+                log_it(L_WARNING, "Integer overflow while parsing vote tx %s", dap_chain_hash_fast_to_str_static(a_tx_hash));
+                return -DAP_LEDGER_CHECK_INTEGER_OVERFLOW;
             }
-            l_in_temp = l_in_temp->next;
-        }
-        dap_list_free(l_ins_list);
 
-        if (IS_ZERO_256(l_weight)){
-            log_it(L_ERROR, "No unspent coins");
-            return false;
+            dap_chain_net_voting_cond_outs_t *l_item;
+            DAP_NEW_Z_SIZE_RET_VAL(l_item, dap_chain_net_voting_cond_outs_t, sizeof(dap_chain_net_voting_cond_outs_t), -DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY, NULL);
+            l_item->tx_hash = l_hash;
+            l_item->out_idx = l_out_idx;
+            pthread_rwlock_wrlock(&l_voting->s_tx_outs_rwlock);
+            HASH_ADD(hh, l_voting->voting_spent_cond_outs, tx_hash, sizeof(dap_hash_fast_t), l_item);
+            pthread_rwlock_unlock(&l_voting->s_tx_outs_rwlock);
         }
+    }
+    dap_list_free(l_tsd_list);
+    // check inputs
+    dap_list_t *l_ins_list = dap_chain_datum_tx_items_get(a_tx_in, TX_ITEM_TYPE_IN, NULL);
+    if (!l_ins_list) {
+        log_it(L_WARNING, "Can't get inputs from vote tx %s", dap_chain_hash_fast_to_str_static(a_tx_hash));
+        return -12;
+    }
+    for (dap_list_t *it = l_ins_list; it; it = it->next) {
+        dap_chain_tx_in_t *l_tx_in = (dap_chain_tx_in_t *)it->data;
+        if (!s_datum_tx_voting_coin_check_spent(a_ledger->net, l_vote_tx_item->voting_hash,
+                                                l_tx_in->header.tx_prev_hash, l_tx_in->header.tx_out_prev_idx, &pkey_hash)) {
+            dap_chain_datum_tx_t *l_tx_prev_temp = dap_ledger_tx_find_by_hash(a_ledger, &l_tx_in->header.tx_prev_hash);
+            dap_chain_tx_out_t *l_prev_out_union = (dap_chain_tx_out_t *)dap_chain_datum_tx_out_get_by_out_idx(l_tx_prev_temp, l_tx_in->header.tx_out_prev_idx);
+            if (!l_prev_out_union)
+                continue;
+            if ((l_prev_out_union->header.type == TX_ITEM_TYPE_OUT || l_prev_out_union->header.type == TX_ITEM_TYPE_OUT_EXT) &&
+                    SUM_256_256(l_weight, l_prev_out_union->header.value, &l_weight)) {
+                log_it(L_WARNING, "Integer overflow while parsing vote tx %s", dap_chain_hash_fast_to_str_static(a_tx_hash));
+                return -DAP_LEDGER_CHECK_INTEGER_OVERFLOW;
+            }
+        }
+    }
+    dap_list_free(l_ins_list);
 
+    if (IS_ZERO_256(l_weight)) {
+        log_it(L_ERROR, "No unspent coins found in vote tx %s", dap_chain_hash_fast_to_str_static(a_tx_hash));
+        return -13;
+    }
 
-        if (a_apply){
-            dap_hash_fast_t pkey_hash = {};
-            dap_chain_tx_sig_t *l_vote_sig = NULL;
-            int l_item_cnt = 0;
-            dap_list_t* l_signs_list = NULL;
-            l_signs_list = dap_chain_datum_tx_items_get(a_tx_in, TX_ITEM_TYPE_SIG, &l_item_cnt);
-
-            if(!l_signs_list){
-                log_it(L_ERROR, "Can't get sign.");
-                return false;
-            }
-            l_vote_sig = (dap_chain_tx_sig_t *)(dap_list_last(l_signs_list)->data);
-            dap_sign_get_pkey_hash((dap_sign_t*)l_vote_sig->sig, &pkey_hash);
-
-            dap_chain_net_vote_t *l_vote_item = DAP_NEW_Z(dap_chain_net_vote_t);
-            if (!l_vote_item){
-                log_it(L_CRITICAL, "Memory allocate_error!");
-                dap_list_free(l_signs_list);
-                return false;
-            }
-            l_vote_item->vote_hash = l_hash;
-            l_vote_item->pkey_hash = pkey_hash;
-            l_vote_item->answer_idx = l_vote_tx_item->answer_idx;
-            l_vote_item->weight = l_weight;
-
-            dap_list_t *l_temp = l_voting->votes;
-            while(l_temp){
-                if (dap_hash_fast_compare(&((dap_chain_net_vote_t *)l_temp->data)->pkey_hash, &pkey_hash)){
-                    if(l_voting->voting_params.vote_changing_allowed_offset &&
-                        *(bool*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.vote_changing_allowed_offset)){
-
-                        l_voting->votes = dap_list_append(l_voting->votes, l_vote_item);
-
-                        log_it(L_ERROR, "Vote is changed.");
-                        dap_list_free(l_signs_list);
-                        return true;
-                    } else {
-                        log_it(L_ERROR, "The voting don't allow change your vote.");
-                        dap_list_free(l_signs_list);
-                        DAP_DELETE(l_vote_item);
-                        return false;
+    if (a_apply) {
+
+        dap_chain_net_vote_t *l_vote_item;
+        DAP_NEW_Z_RET_VAL(l_vote_item, dap_chain_net_vote_t, -DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY, NULL);
+        l_vote_item->vote_hash = *a_tx_hash;
+        l_vote_item->pkey_hash = pkey_hash;
+        l_vote_item->answer_idx = l_vote_tx_item->answer_idx;
+        l_vote_item->weight = l_weight;
+
+        // cycle is safe cause return after link deletion
+        for (dap_list_t *it = l_voting->votes; it; it = it->next) {
+            if (dap_hash_fast_compare(&((dap_chain_net_vote_t *)it->data)->pkey_hash, &pkey_hash)){
+                if (!l_voting->voting_params.vote_changing_allowed) {
+                    char l_vote_hash_str[DAP_HASH_FAST_STR_SIZE];
+                    dap_hash_fast_to_str(a_tx_hash, l_vote_hash_str, DAP_HASH_FAST_STR_SIZE);
+                    log_it(L_WARNING, "The voting %s don't allow change your vote %s",
+                           dap_hash_fast_to_str_static(&l_voting->voting_hash), l_vote_hash_str);
+                    DAP_DELETE(l_vote_item);
+                    return -11;
+                }
+                dap_hash_fast_t *l_vote_hash = &((dap_chain_net_vote_t *)it->data)->vote_hash;
+                //delete conditional outputs
+                dap_chain_datum_tx_t *l_old_tx = dap_ledger_tx_find_by_hash(a_ledger, l_vote_hash);
+                if (!l_old_tx) {
+                    char l_vote_hash_str[DAP_HASH_FAST_STR_SIZE];
+                    dap_hash_fast_to_str(l_vote_hash, l_vote_hash_str, DAP_HASH_FAST_STR_SIZE);
+                    log_it(L_ERROR, "Can't find old vote %s of voting %s in ledger",
+                           l_vote_hash_str, dap_hash_fast_to_str_static(&l_voting->voting_hash));
+                }
+                dap_list_t* l_tsd_list = dap_chain_datum_tx_items_get(l_old_tx, TX_ITEM_TYPE_TSD, NULL);
+                for (dap_list_t *it_tsd = l_tsd_list; it_tsd; it_tsd = it_tsd->next) {
+                    dap_tsd_t* l_tsd = (dap_tsd_t*)((dap_chain_tx_tsd_t*)it_tsd->data)->tsd;
+                    dap_hash_fast_t *l_hash = &((dap_chain_tx_voting_tx_cond_t*)l_tsd->data)->tx_hash;
+                    if (l_tsd->type == VOTING_TSD_TYPE_VOTE_TX_COND) {
+                        dap_chain_net_voting_cond_outs_t *l_tx_outs = NULL;
+                        pthread_rwlock_wrlock(&l_voting->s_tx_outs_rwlock);
+                        HASH_FIND(hh, l_voting->voting_spent_cond_outs, l_hash, sizeof(dap_hash_fast_t), l_tx_outs);
+                        if(l_tx_outs)
+                            HASH_DELETE(hh, l_voting->voting_spent_cond_outs, l_tx_outs);
+                        pthread_rwlock_unlock(&l_voting->s_tx_outs_rwlock);
                     }
                 }
-                l_temp = l_temp->next;
+                dap_list_free(l_tsd_list);
+                // change vote & move it to the end of list
+                l_voting->votes = dap_list_remove_link(l_voting->votes, it);
+                DAP_DELETE(it->data);
+                l_voting->votes = dap_list_append(l_voting->votes, l_vote_item);
+                char l_vote_hash_str[DAP_HASH_FAST_STR_SIZE];
+                dap_hash_fast_to_str(&((dap_chain_net_vote_t *)it->data)->vote_hash, l_vote_hash_str, DAP_HASH_FAST_STR_SIZE);
+                log_it(L_INFO, "Vote %s of voting %s has been changed", l_vote_hash_str, dap_hash_fast_to_str_static(&l_voting->voting_hash));
+                return DAP_LEDGER_CHECK_OK;
             }
-            dap_list_free(l_signs_list);
-            log_it(L_INFO, "Vote is accepted.");
-            l_voting->votes = dap_list_append(l_voting->votes, l_vote_item);
         }
-        return true;
-    } else {
-        log_it(L_ERROR, "Item is not supported in votings.");
+        l_voting->votes = dap_list_append(l_voting->votes, l_vote_item);
+        char l_vote_hash_str[DAP_HASH_FAST_STR_SIZE];
+        dap_hash_fast_to_str(a_tx_hash, l_vote_hash_str, DAP_HASH_FAST_STR_SIZE);
+        log_it(L_INFO, "Vote %s of voting %s has been accepted", l_vote_hash_str, dap_hash_fast_to_str_static(&l_voting->voting_hash));
     }
+    return DAP_LEDGER_CHECK_OK;
+}
 
-    return false;
+int s_datum_tx_voting_verification_callback(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx_in, dap_hash_fast_t *a_tx_hash, bool a_apply)
+{
+    if (a_type == TX_ITEM_TYPE_VOTING)
+        return s_voting_verificator(a_ledger, a_type, a_tx_in, a_tx_hash, a_apply);
+    if (a_type == TX_ITEM_TYPE_VOTE)
+        return s_vote_verificator(a_ledger, a_type, a_tx_in, a_tx_hash, a_apply);
+    log_it(L_ERROR, "Item %d is not supported in votings", a_type);
+    return -3;
 }
 
 static bool s_datum_tx_voting_verification_delete_callback(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx_in)
@@ -532,7 +505,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;
@@ -549,14 +522,13 @@ static bool s_datum_tx_voting_verification_delete_callback(dap_ledger_t *a_ledge
             return false;
         }
 
-        dap_list_t *l_vote = l_voting->votes;
-        while(l_vote){
+        for (dap_list_t *l_vote = l_voting->votes; l_vote; l_vote = l_vote->next) {
             if (dap_hash_fast_compare(&((dap_chain_net_vote_t *)l_vote->data)->vote_hash, &l_hash)){
                 // Delete vote
+                DAP_DELETE(l_vote->data);
                 l_voting->votes = dap_list_remove(l_voting->votes, l_vote->data);
                 break;
             }
-            l_vote = l_vote->next;
         }
     }
 
@@ -1006,20 +978,18 @@ static int s_cli_voting(int a_argc, char **a_argv, void **a_str_reply)
                               l_voting->voting_params.voting_question_length);
         dap_string_append(l_str_out, "\n\n");
 
-        if(l_voting->voting_params.voting_expire_offset){
+        if (l_voting->voting_params.voting_expire) {
             char l_tmp_buf[DAP_TIME_STR_SIZE];
-            dap_time_t l_expire = *(dap_time_t*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.voting_expire_offset);
-            dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_expire);
-            dap_string_append_printf(l_str_out, "\t Voting expire: %s \n", l_tmp_buf);
+            dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_voting->voting_params.voting_expire);
+            dap_string_append_printf(l_str_out, "\t Voting expire: %s\n", l_tmp_buf);
             dap_string_truncate(l_str_out, l_str_out->len - 1);
-            dap_string_append_printf(l_str_out, " (%s)\n", l_expire > dap_time_now() ? "active" : "expired");
+            dap_string_append_printf(l_str_out, " (%s)\n", l_voting->voting_params.voting_expire > dap_time_now() ? "active" : "expired");
         }
-        if (l_voting->voting_params.votes_max_count_offset){
-            uint64_t l_max_count = *(uint64_t*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.votes_max_count_offset);
-            dap_string_append_printf(l_str_out, "\t Votes max count: %"DAP_UINT64_FORMAT_U" (%s)\n", l_max_count, l_max_count <= l_votes_count ? "closed" : "active");
-        }
-        dap_string_append_printf(l_str_out, "\t Changing vote is %s available.\n", l_voting->voting_params.vote_changing_allowed_offset ? "" : "not");
-        dap_string_append_printf(l_str_out, "\t A delegated key is%s required to participate in voting. \n", l_voting->voting_params.delegate_key_required_offset ? "" : " not");
+        if (l_voting->voting_params.votes_max_count)
+            dap_string_append_printf(l_str_out, "\t Votes max count: %"DAP_UINT64_FORMAT_U" (%s)\n", l_voting->voting_params.votes_max_count,
+                                     l_voting->voting_params.votes_max_count <= l_votes_count ? "closed" : "active");
+        dap_string_append_printf(l_str_out, "\t Changing vote is %s available.\n", l_voting->voting_params.vote_changing_allowed ? "" : "not");
+        dap_string_append_printf(l_str_out, "\t A delegated key is%s required to participate in voting. \n", l_voting->voting_params.delegate_key_required ? "" : " not");
         dap_string_append_printf(l_str_out, "\n\nResults:\n\n");
         for (uint64_t i = 0; i < dap_list_length(l_voting->voting_params.option_offsets_list); i++){
             dap_string_append_printf(l_str_out, "%"DAP_UINT64_FORMAT_U")  ", i);
@@ -1053,7 +1023,7 @@ static int s_cli_voting(int a_argc, char **a_argv, void **a_str_reply)
     return 0;
 }
 
-static int s_datum_tx_voting_coin_check_spent(dap_chain_net_t *a_net, dap_hash_fast_t a_voting_hash, dap_hash_fast_t a_tx_prev_hash, int a_out_idx)
+static int s_datum_tx_voting_coin_check_spent(dap_chain_net_t *a_net, dap_hash_fast_t a_voting_hash, dap_hash_fast_t a_tx_prev_hash, int a_out_idx, dap_hash_fast_t *a_pkey_hash)
 {
     int l_coin_is_spent = 0;
 
@@ -1082,22 +1052,22 @@ 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);
-    if(l_vote && dap_hash_fast_compare(&l_vote->voting_hash, &a_voting_hash)){
+    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);
         HASH_FIND(hh, s_votings, &a_voting_hash, sizeof(dap_hash_fast_t), l_voting);
         pthread_rwlock_unlock(&s_votings_rwlock);
-        if (l_voting)
-        {
-            dap_list_t *l_temp = l_voting->votes;
-            while (l_temp){
-                dap_chain_net_vote_t *l_vote = (dap_chain_net_vote_t *)l_temp->data;
-                if (dap_hash_fast_compare(&l_vote->vote_hash, &a_tx_prev_hash)){
-                    l_coin_is_spent = 1;
+        if (l_voting) {
+            for (dap_list_t *it = l_voting->votes; it; it = it->next) {
+                dap_chain_net_vote_t *l_vote = (dap_chain_net_vote_t *)it->data;
+                if (dap_hash_fast_compare(&l_vote->vote_hash, &a_tx_prev_hash)) {
+                    if (l_voting->voting_params.vote_changing_allowed &&
+                            !dap_hash_fast_is_blank(a_pkey_hash) &&
+                            dap_hash_fast_compare(&l_vote->pkey_hash, a_pkey_hash))
+                        break;  // it's vote changing, allow it
                     return 1;
                 }
-                l_temp = l_temp->next;
             }
         }
     }
@@ -1126,10 +1096,9 @@ static int s_datum_tx_voting_coin_check_spent(dap_chain_net_t *a_net, dap_hash_f
         dap_list_t *l_ins_list = (dap_list_t*)l_tx_temp->data;
         dap_chain_tx_in_t* l_temp_in = (dap_chain_tx_in_t*)l_ins_list->data;
         dap_chain_datum_tx_t *l_tx_prev_temp = dap_ledger_tx_find_by_hash(l_ledger, &l_temp_in->header.tx_prev_hash);
-        int l_out_prev_idx = (int)l_temp_in->header.tx_out_prev_idx;
 
         const char* l_tx_token = NULL;
-        dap_chain_tx_out_t *l_prev_out_union = (dap_chain_tx_out_t*)dap_chain_datum_tx_out_get_by_out_idx(l_tx_prev_temp, l_out_prev_idx);
+        dap_chain_tx_out_t *l_prev_out_union = (dap_chain_tx_out_t*)dap_chain_datum_tx_out_get_by_out_idx(l_tx_prev_temp, l_temp_in->header.tx_out_prev_idx);
         if (!l_prev_out_union){
             l_tx_temp->data = dap_list_remove(l_tx_temp->data, l_temp_in);
             if (l_tx_temp->data == NULL){
@@ -1173,7 +1142,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);
@@ -1420,58 +1389,36 @@ int dap_chain_net_vote_voting(dap_cert_t *a_cert, uint256_t a_fee, dap_chain_wal
     pthread_rwlock_rdlock(&s_votings_rwlock);
     HASH_FIND(hh, s_votings, &a_hash, sizeof(dap_hash_fast_t),l_voting);
     pthread_rwlock_unlock(&s_votings_rwlock);
-    if(!l_voting || l_voting->net_id.uint64 != a_net->pub.id.uint64){
+    if (!l_voting || l_voting->net_id.uint64 != a_net->pub.id.uint64)
         return DAP_CHAIN_NET_VOTE_VOTING_CAN_NOT_FIND_VOTE;
-    }
 
-    if(l_voting->voting_params.votes_max_count_offset){
-        uint64_t l_max_count = *(uint64_t*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.votes_max_count_offset);
-        if (l_max_count && dap_list_length(l_voting->votes) >= l_max_count){
-            return DAP_CHAIN_NET_VOTE_VOTING_THIS_VOTING_HAVE_MAX_VALUE_VOTES;
-        }
-    }
-
-    if(l_voting->voting_params.voting_expire_offset){
-        dap_time_t l_expire = *(dap_time_t*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.voting_expire_offset);
-        dap_time_t l_time_now = dap_time_now();
-        if (l_expire && l_time_now > l_expire){
-            return DAP_CHAIN_NET_VOTE_VOTING_ALREADY_EXPIRED;
-        }
-    }
+    if (l_voting->voting_params.votes_max_count && dap_list_length(l_voting->votes) >= l_voting->voting_params.votes_max_count)
+        return DAP_CHAIN_NET_VOTE_VOTING_THIS_VOTING_HAVE_MAX_VALUE_VOTES;
 
-    if(l_voting->voting_params.delegate_key_required_offset &&
-       *(bool*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.delegate_key_required_offset) ){
-        if (!a_cert) {
-            return DAP_CHAIN_NET_VOTE_VOTING_CERT_REQUIRED;
-        } else {
-            if (a_cert->enc_key == NULL) {
-                return DAP_CHAIN_NET_VOTE_VOTING_NO_KEY_FOUND_IN_CERT;
-            }
-            // Get publivc key hash
-            size_t l_pub_key_size = 0;
-            uint8_t *l_pub_key = dap_enc_key_serialize_pub_key(a_cert->enc_key, &l_pub_key_size);;
-            if (l_pub_key == NULL) {
-                return DAP_CHAIN_NET_VOTE_VOTING_NO_PUBLIC_KEY_IN_CERT;
-            }
+    if (l_voting->voting_params.voting_expire && dap_time_now() > l_voting->voting_params.voting_expire)
+        return DAP_CHAIN_NET_VOTE_VOTING_ALREADY_EXPIRED;
 
-            dap_hash_fast_t l_pkey_hash = {0};
+    dap_hash_fast_t l_pkey_hash = {0};
 
-            dap_hash_fast(l_pub_key, l_pub_key_size, &l_pkey_hash);
-            DAP_DELETE(l_pub_key);
-            if (!dap_chain_net_srv_stake_check_pkey_hash(a_net->pub.id, &l_pkey_hash)) {
-                return DAP_CHAIN_NET_VOTE_VOTING_KEY_IS_NOT_DELEGATED;
-            }
-            dap_list_t *l_temp = l_voting->votes;
-            while(l_temp){
-                if (dap_hash_fast_compare(&((dap_chain_net_vote_t *)l_temp->data)->pkey_hash, &l_pkey_hash)){
-                    if(!l_voting->voting_params.vote_changing_allowed_offset ||
-                       !*(bool*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.vote_changing_allowed_offset)){
-                        return DAP_CHAIN_NET_VOTE_VOTING_DOES_NOT_ALLOW_CHANGE_YOUR_VOTE;
-                    }
-                }
-                l_temp = l_temp->next;
-            }
-        }
+    if (l_voting->voting_params.delegate_key_required) {
+        if (!a_cert)
+            return DAP_CHAIN_NET_VOTE_VOTING_CERT_REQUIRED;
+        if (!a_cert->enc_key)
+            return DAP_CHAIN_NET_VOTE_VOTING_NO_KEY_FOUND_IN_CERT;
+        // Get publivc key hash
+        size_t l_pub_key_size = 0;
+        uint8_t *l_pub_key = dap_enc_key_serialize_pub_key(a_cert->enc_key, &l_pub_key_size);;
+        if (l_pub_key == NULL)
+            return DAP_CHAIN_NET_VOTE_VOTING_NO_PUBLIC_KEY_IN_CERT;
+
+        dap_hash_fast(l_pub_key, l_pub_key_size, &l_pkey_hash);
+        DAP_DELETE(l_pub_key);
+        if (!dap_chain_net_srv_stake_check_pkey_hash(a_net->pub.id, &l_pkey_hash))
+            return DAP_CHAIN_NET_VOTE_VOTING_KEY_IS_NOT_DELEGATED;
+        for (dap_list_t *it = l_voting->votes; it; it = it->next)
+            if (dap_hash_fast_compare(&((dap_chain_net_vote_t *)it->data)->pkey_hash, &l_pkey_hash) &&
+                    !l_voting->voting_params.vote_changing_allowed)
+                return DAP_CHAIN_NET_VOTE_VOTING_DOES_NOT_ALLOW_CHANGE_YOUR_VOTE;
     }
 
     dap_enc_key_t *l_priv_key = NULL;
@@ -1480,9 +1427,8 @@ int dap_chain_net_vote_voting(dap_cert_t *a_cert, uint256_t a_fee, dap_chain_wal
 
     const dap_chain_addr_t *l_addr_from = (const dap_chain_addr_t *) dap_chain_wallet_get_addr(a_wallet, a_net->pub.id);
 
-    if(!l_addr_from) {
+    if (!l_addr_from)
         return DAP_CHAIN_NET_VOTE_VOTING_SOURCE_ADDRESS_INVALID;
-    }
 
     const char *l_native_ticker = a_net->pub.native_ticker;
     uint256_t l_net_fee = {}, l_total_fee = {}, l_value_transfer;
@@ -1496,22 +1442,18 @@ int dap_chain_net_vote_voting(dap_cert_t *a_cert, uint256_t a_fee, dap_chain_wal
         return DAP_CHAIN_NET_VOTE_VOTING_NOT_ENOUGH_FUNDS_TO_TRANSFER;
     }
 
-
     // check outputs UTXOs
-    dap_list_t *l_utxo_temp = l_list_used_out;
     uint256_t l_value_transfer_new = {};
-    while(l_utxo_temp){
-        dap_chain_tx_used_out_item_t *l_out = (dap_chain_tx_used_out_item_t *)l_utxo_temp->data;
-        if (s_datum_tx_voting_coin_check_spent(a_net, a_hash, l_out->tx_hash_fast, l_out->num_idx_out) != 0 &&
-            (!l_voting->voting_params.vote_changing_allowed_offset ||
-             !*(bool*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.vote_changing_allowed_offset))){
-            dap_list_t *l_temp = l_utxo_temp;
-            l_utxo_temp = l_utxo_temp->next;
-            dap_list_delete_link(l_list_used_out, l_temp);
+    dap_list_t *it, *tmp;
+    DL_FOREACH_SAFE(l_list_used_out, it, tmp) {
+        dap_chain_tx_used_out_item_t *l_out = (dap_chain_tx_used_out_item_t *)it->data;
+        if (s_datum_tx_voting_coin_check_spent(a_net, a_hash, l_out->tx_hash_fast, l_out->num_idx_out, &l_pkey_hash) &&
+                !l_voting->voting_params.vote_changing_allowed) {
+            dap_list_delete_link(l_list_used_out, it);
             continue;
         }
-        SUM_256_256(l_value_transfer_new, l_out->value, &l_value_transfer_new);
-        l_utxo_temp = l_utxo_temp->next;
+        if (SUM_256_256(l_value_transfer_new, l_out->value, &l_value_transfer_new))
+            return DAP_CHAIN_NET_VOTE_VOTING_INTEGER_OVERFLOW;
     }
 
     if (IS_ZERO_256(l_value_transfer_new) || compare256(l_value_transfer_new, l_total_fee) <= 0){
@@ -1633,17 +1575,10 @@ dap_chain_net_vote_info_t *s_dap_chain_net_vote_extract_info(dap_chain_net_votin
     l_info->question.question_size = a_voting->voting_params.voting_question_length;
     l_info->question.question_str = (char*)((byte_t*)a_voting->voting_params.voting_tx + a_voting->voting_params.voting_question_offset);
     l_info->hash = a_voting->voting_hash;
-
-    l_info->is_expired = a_voting->voting_params.voting_expire_offset;
-    if(a_voting->voting_params.voting_expire_offset){
-        l_info->expired = *(dap_time_t*)((byte_t*)a_voting->voting_params.voting_tx + a_voting->voting_params.voting_expire_offset);
-    }
-    l_info->is_max_count_votes = a_voting->voting_params.votes_max_count_offset;
-    if (a_voting->voting_params.votes_max_count_offset){
-        l_info->max_count_votes = *(uint64_t*)((byte_t*)a_voting->voting_params.voting_tx + a_voting->voting_params.votes_max_count_offset);
-    }
-    l_info->is_changing_allowed = a_voting->voting_params.vote_changing_allowed_offset;
-    l_info->is_delegate_key_required = a_voting->voting_params.delegate_key_required_offset;
+    l_info->is_expired = (l_info->expired = a_voting->voting_params.voting_expire);
+    l_info->is_max_count_votes = (l_info->max_count_votes = a_voting->voting_params.votes_max_count);
+    l_info->is_changing_allowed = a_voting->voting_params.vote_changing_allowed;
+    l_info->is_delegate_key_required = a_voting->voting_params.delegate_key_required;
     l_info->options.count_option = dap_list_length(a_voting->voting_params.option_offsets_list);
     dap_chain_net_vote_info_option_t **l_options = DAP_NEW_Z_COUNT(dap_chain_net_vote_info_option_t*, l_info->options.count_option);
     for (uint64_t i = 0; i < l_info->options.count_option; i++){
diff --git a/modules/service/voting/include/dap_chain_net_srv_voting.h b/modules/service/voting/include/dap_chain_net_srv_voting.h
index 6fcf2f9a45bb1d02cf2bf3b2d53b4beb2799dac0..f21c10d291c7ade08ae4ec1ddb21592fec321955 100644
--- a/modules/service/voting/include/dap_chain_net_srv_voting.h
+++ b/modules/service/voting/include/dap_chain_net_srv_voting.h
@@ -110,7 +110,8 @@ enum DAP_CHAIN_NET_VOTE_VOTING_ERROR{
     DAP_CHAIN_NET_VOTE_VOTING_CAN_NOT_ADD_NET_FEE_OUT,
     DAP_CHAIN_NET_VOTE_VOTING_CAN_NOT_ADD_OUT_WITH_VALUE_BACK,
     DAP_CHAIN_NET_VOTE_VOTING_CAN_NOT_SIGN_TX,
-    DAP_CHAIN_NET_VOTE_VOTING_CAN_NOT_POOL_IN_MEMPOOL
+    DAP_CHAIN_NET_VOTE_VOTING_CAN_NOT_POOL_IN_MEMPOOL,
+    DAP_CHAIN_NET_VOTE_VOTING_INTEGER_OVERFLOW
 };
 int dap_chain_net_vote_voting(dap_cert_t *a_cert, uint256_t a_fee, dap_chain_wallet_t *a_wallet, dap_hash_fast_t a_hash,
                               uint64_t a_option_idx, dap_chain_net_t *a_net, const char *a_hash_out_type,
diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c
index 9ba8db186f44b867cb924aa7c20c6ad6c3310fc5..e64992b108c503592d5911a7a484f9c75e80f383 100644
--- a/modules/service/vpn/dap_chain_net_srv_vpn.c
+++ b/modules/service/vpn/dap_chain_net_srv_vpn.c
@@ -1065,8 +1065,6 @@ static int s_callback_receipt_next_success(dap_chain_net_srv_t * a_srv, uint32_t
     const dap_chain_datum_tx_receipt_t * l_receipt_next = (const dap_chain_datum_tx_receipt_t *) a_receipt_next;
     size_t l_receipt_next_size = a_receipt_next_size;
 
-
-
     log_it(L_INFO, "Next receipt successfuly accepted");
     // usage is present, we've accepted packets
     dap_stream_ch_set_ready_to_read_unsafe( l_srv_ch_vpn->ch , true );
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 87efb2f7871551493bc7f18ef8d1d3d9e29b89c3..42cea326359093a8f25eeb79c879444c329ebb39 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -34,7 +34,6 @@
 #include "dap_time.h"
 #include "dap_chain_net_srv.h"
 #include "dap_chain_ledger.h"
-#include "dap_chain_net_srv_order.h"
 #include "dap_common.h"
 #include "dap_hash.h"
 #include "dap_math_ops.h"
@@ -75,7 +74,7 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_
 dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a_net, dap_chain_datum_tx_t *a_order, uint256_t *a_fee, bool a_ret_is_invalid);
 
 static dap_chain_net_srv_xchange_t *s_srv_xchange;
-static bool s_debug_more = true;
+static bool s_debug_more = false;
 
 
 static bool s_tag_check_xchange(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
@@ -249,7 +248,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 +260,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 +268,44 @@ 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)) {
+                log_it(L_WARNING, "Integer overflow for buyer value of exchange tx");
+                return -5;
+            }
+            // 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)) {
+                log_it(L_WARNING, "Integer overflow for fee value of exchange tx");
+                return -5;
+            }
+        } 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
@@ -316,11 +318,28 @@ static int s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_o
      * a_cond->subtype.srv_xchange.buy_value * (a_cond->header.value - new_cond->header.value)
      */
 
+
     uint256_t l_sell_val, l_buyer_val_expected;
-    if (compare256(l_sell_again_val, a_tx_out_cond->header.value) >= 0)
+    if (SUBTRACT_256_256(a_tx_out_cond->header.value, l_sell_again_val, &l_sell_val)) {
+        log_it(L_WARNING, "Integer overflow for resell value of exchange tx");
         return -5;
-    SUBTRACT_256_256(a_tx_out_cond->header.value, l_sell_again_val, &l_sell_val);
+    }
     MULT_256_COIN(l_sell_val, a_tx_out_cond->subtype.srv_xchange.rate, &l_buyer_val_expected);
+    if (s_debug_more) {
+        const char *l_value_str;
+        dap_uint256_to_char(a_tx_out_cond->header.value, &l_value_str);
+        log_it(L_NOTICE, "Total sell %s %s from %s", l_value_str, l_sell_ticker, dap_hash_fast_to_str_static(&l_tx_in_cond->header.tx_prev_hash));
+        dap_uint256_to_char(a_tx_out_cond->subtype.srv_xchange.rate, &l_value_str);
+        log_it(L_NOTICE, "Rate is %s", l_value_str);
+        dap_uint256_to_char(l_sell_again_val, &l_value_str);
+        log_it(L_NOTICE, "Resell %s %s", l_value_str, l_sell_ticker);
+        dap_uint256_to_char(l_buyer_val_expected, &l_value_str);
+        log_it(L_NOTICE, "Expect to buy %s %s", l_value_str, l_buy_ticker);
+        dap_uint256_to_char(l_buy_val, &l_value_str);
+        log_it(L_NOTICE, "Buy %s %s", l_value_str, l_buy_ticker);
+        dap_uint256_to_char(l_fee_val, &l_value_str);
+        log_it(L_NOTICE, "Service fee is %s %s", l_value_str, l_service_ticker);
+    }
     if (compare256(l_buyer_val_expected, l_buy_val) > 0)
         return -6;
 
@@ -679,7 +698,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 +886,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 +943,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 +1168,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 +1552,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 +1650,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 +1670,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 +1692,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 +1705,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 +1740,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 +1825,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 +1875,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 +1889,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 +1957,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 +2100,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 +2500,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/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index ae29fe56a99637fb09d8defdd4bef8525bb3bb3f..17180d9a64676e2a41ebf7f06e577663ec8951b0 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -1155,7 +1155,10 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                                         "Certificate \"%s\" doesn't contains private key", l_cert_name);
                 return DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR;
             }
-
+            if (!l_fee_value_str) {
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block %s collect' requires parameter '-fee'", l_subcmd_str);
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
+            }
             l_fee_value = dap_chain_balance_scan(l_fee_value_str);
             if (!l_fee_value_str || IS_ZERO_256(l_fee_value)) {
                 dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block %s collect' requires parameter '-fee' to be valid uint256", l_subcmd_str);
@@ -2310,8 +2313,8 @@ static size_t s_callback_add_datums(dap_chain_t *a_chain, dap_chain_datum_t **a_
             log_it(L_WARNING, "Empty datum"); /* How might it be? */
             continue;
         }
-        if (l_blocks->block_new_size + l_datum_size > DAP_CHAIN_CS_BLOCKS_MAX_BLOCK_SIZE) {
-            log_it(L_DEBUG, "Maximum size exeeded, %zu > %d", l_blocks->block_new_size + l_datum_size, DAP_CHAIN_CS_BLOCKS_MAX_BLOCK_SIZE);
+        if (l_blocks->block_new_size + l_datum_size > DAP_CHAIN_ATOM_MAX_SIZE) {
+            log_it(L_DEBUG, "Maximum size exeeded, %zu > %d", l_blocks->block_new_size + l_datum_size, DAP_CHAIN_ATOM_MAX_SIZE);
             break;
         }
         if (!l_blocks->block_new) {
diff --git a/modules/type/blocks/include/dap_chain_cs_blocks.h b/modules/type/blocks/include/dap_chain_cs_blocks.h
index 69a25180ca834f2d526d4c402d0445f58b0d1f42..dd538ac6bcb08f874b82cd549d9cd93818ce7711 100644
--- a/modules/type/blocks/include/dap_chain_cs_blocks.h
+++ b/modules/type/blocks/include/dap_chain_cs_blocks.h
@@ -26,12 +26,6 @@
 #include "dap_chain_block.h"
 #include "dap_chain_block_cache.h"
 
-#ifdef DAP_TPS_TEST
-#define DAP_CHAIN_CS_BLOCKS_MAX_BLOCK_SIZE (100 * 1024 * 1024)
-#else
-#define DAP_CHAIN_CS_BLOCKS_MAX_BLOCK_SIZE (256 * 1024) // 256 KB
-#endif
-
 #define DAP_FORK_MAX_DEPTH 100
 
 #define DAP_REWARD_INIT_TIMESTAMP 1700870400UL // 25 Nov 2023 00:00:00 GMT
diff --git a/modules/type/dag/dap_chain_cs_dag_event.c b/modules/type/dag/dap_chain_cs_dag_event.c
index 8bce113cf5cc3f468f2f972d1f0875ba0929585c..8e4fc060129010fbf0010edf8a07953441c6aec9 100644
--- a/modules/type/dag/dap_chain_cs_dag_event.c
+++ b/modules/type/dag/dap_chain_cs_dag_event.c
@@ -100,16 +100,16 @@ dap_chain_cs_dag_event_t *dap_chain_cs_dag_event_new(dap_chain_id_t a_chain_id,
  * @param a_event
  * @return
  */
-size_t dap_chain_cs_dag_event_calc_size_excl_signs(dap_chain_cs_dag_event_t *a_event, size_t a_limit_size)
+uint64_t dap_chain_cs_dag_event_calc_size_excl_signs(dap_chain_cs_dag_event_t *a_event, uint64_t a_limit_size)
 {
     dap_return_val_if_fail(a_event, 0);
     if (a_limit_size && a_limit_size < sizeof(a_event->header))
         return 0;
-    size_t l_hashes_size = a_event->header.hash_count * sizeof(dap_chain_hash_fast_t);
+    uint32_t l_hashes_size = a_event->header.hash_count * sizeof(dap_chain_hash_fast_t);
     if (a_limit_size && a_limit_size < l_hashes_size + sizeof(a_event->header) + sizeof(dap_chain_datum_t))
         return 0;
-    dap_chain_datum_t *l_datum = (dap_chain_datum_t*) (a_event->hashes_n_datum_n_signs + l_hashes_size);
-    size_t l_ret = dap_chain_datum_size(l_datum) + l_hashes_size + sizeof(a_event->header);
+    dap_chain_datum_t *l_datum = (dap_chain_datum_t *)(a_event->hashes_n_datum_n_signs + l_hashes_size);
+    uint64_t l_ret = dap_chain_datum_size(l_datum) + l_hashes_size + sizeof(a_event->header);
     if (a_limit_size && a_limit_size < l_ret)
         return 0;
     return l_ret;
@@ -120,21 +120,28 @@ size_t dap_chain_cs_dag_event_calc_size_excl_signs(dap_chain_cs_dag_event_t *a_e
  * @param a_event
  * @return
  */
-size_t dap_chain_cs_dag_event_calc_size(dap_chain_cs_dag_event_t *a_event, size_t a_limit_size)
+uint64_t dap_chain_cs_dag_event_calc_size(dap_chain_cs_dag_event_t *a_event, uint64_t a_limit_size)
 {
     dap_return_val_if_fail(a_event, 0);
-    size_t l_signs_offset = dap_chain_cs_dag_event_calc_size_excl_signs(a_event, a_limit_size);
+    uint64_t l_signs_offset = dap_chain_cs_dag_event_calc_size_excl_signs(a_event, a_limit_size);
     if (!l_signs_offset)
         return 0;
     byte_t *l_signs = (byte_t *)a_event + l_signs_offset;
     size_t l_signs_size = 0;
     for (uint16_t l_signs_passed = 0; l_signs_passed < a_event->header.signs_count; l_signs_passed++) {
         dap_sign_t *l_sign = (dap_sign_t *)(l_signs + l_signs_size);
+        if (l_signs_offset + l_signs_size + sizeof(dap_sign_t) <= l_signs_offset)
+            return 0;
         if (a_limit_size && a_limit_size < l_signs_offset + l_signs_size + sizeof(dap_sign_t))
             return 0;
-        l_signs_size += dap_sign_get_size(l_sign);
+        uint64_t l_sign_size = dap_sign_get_size(l_sign);
+        if (!l_sign_size)
+            break;
+        if (l_signs_size + l_sign_size <= l_signs_size)
+            return 0;
+        l_signs_size += l_sign_size;
     }
-    size_t l_total_size = l_signs_offset + l_signs_size;
+    size_t l_total_size = l_signs_offset + l_signs_size <= l_signs_offset ? 0 : l_signs_offset + l_signs_size;
     return a_limit_size && l_total_size > a_limit_size ? 0 : l_total_size;
 }
 
diff --git a/modules/type/dag/include/dap_chain_cs_dag_event.h b/modules/type/dag/include/dap_chain_cs_dag_event.h
index 5f4d6a1c94255515bb77d0487764860e1457c3cb..4de1d9055b8eca61d05ca961d6fd6cfcd5a003cc 100644
--- a/modules/type/dag/include/dap_chain_cs_dag_event.h
+++ b/modules/type/dag/include/dap_chain_cs_dag_event.h
@@ -90,8 +90,8 @@ bool dap_chain_cs_dag_event_sign_exists(dap_chain_cs_dag_event_t *a_event, size_
 bool dap_chain_cs_dag_event_round_sign_exists(dap_chain_cs_dag_event_round_item_t *a_round_item, dap_enc_key_t * a_key);
 dap_sign_t * dap_chain_cs_dag_event_get_sign( dap_chain_cs_dag_event_t * a_event, size_t a_event_size, uint16_t a_sign_number);
 
-size_t dap_chain_cs_dag_event_calc_size_excl_signs(dap_chain_cs_dag_event_t *a_event, size_t a_limit_size);
-size_t dap_chain_cs_dag_event_calc_size(dap_chain_cs_dag_event_t *a_event, size_t a_limit_size);
+uint64_t dap_chain_cs_dag_event_calc_size_excl_signs(dap_chain_cs_dag_event_t *a_event, uint64_t a_limit_size);
+uint64_t dap_chain_cs_dag_event_calc_size(dap_chain_cs_dag_event_t *a_event, uint64_t a_limit_size);
 
 
 /**
diff --git a/modules/wallet/dap_chain_wallet.c b/modules/wallet/dap_chain_wallet.c
index 25892281a3fab2a8418557a4eb05290c2a0c4b53..38986922299ee3aa5c5bd9cd36dcbe8da9f6e7f3 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 ? */