diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index ccecb739db3ca02aaa5a3ab9e5e7a5dbb5ace9cc..8e5565f9fdbe9f2686bcbadd6d13adc60aa39b4a 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -112,15 +112,14 @@ typedef struct dap_chain_ledger_tx_bound {
     dap_chain_hash_fast_t tx_prev_hash_fast;
     dap_chain_datum_tx_t *tx_prev;
     union {
-        struct {
-            dap_chain_tx_in_t *tx_cur_in;
-            dap_chain_tx_out_t *tx_prev_out;
-        };
-        struct {
-            dap_chain_tx_in_cond_t *tx_cur_in_cond;
-            dap_chain_tx_out_cond_t *tx_prev_out_cond;
-        };
-    };
+        dap_chain_tx_in_t *tx_cur_in;
+        dap_chain_tx_in_cond_t *tx_cur_in_cond;
+    } in;
+    union {
+        dap_chain_tx_out_t *tx_prev_out;
+        dap_chain_tx_out_ext_t *tx_prev_out_ext;
+        dap_chain_tx_out_cond_t *tx_prev_out_cond;
+    } out;
     dap_chain_ledger_tx_item_t *item_out;
 } dap_chain_ledger_tx_bound_t;
 
@@ -731,11 +730,11 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
         if (l_cond_type == TX_ITEM_TYPE_IN) {
             l_tx_in = (dap_chain_tx_in_t *)l_list_tmp->data;
             l_tx_prev_hash = l_tx_in->header.tx_prev_hash;
-            bound_item->tx_cur_in = l_tx_in;
+            bound_item->in.tx_cur_in = l_tx_in;
         } else { // TX_ITEM_TYPE_IN_COND
             l_tx_in_cond = (dap_chain_tx_in_cond_t *)l_list_tmp->data;
             l_tx_prev_hash = l_tx_in_cond->header.tx_prev_hash;
-            bound_item->tx_cur_in_cond = l_tx_in_cond;
+            bound_item->in.tx_cur_in_cond = l_tx_in_cond;
         }
         memcpy(&bound_item->tx_prev_hash_fast, &l_tx_prev_hash, sizeof(dap_chain_hash_fast_t));
 
@@ -804,15 +803,23 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
         uint64_t l_value;
         // Get list of all 'out' items from previous transaction
         dap_list_t *l_list_prev_out = dap_chain_datum_tx_items_get(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, NULL);
+        // Get one 'out' item in previous transaction bound with current 'in' item
+        void *l_tx_prev_out = dap_list_nth_data(l_list_prev_out, l_tx_in->header.tx_out_prev_idx);
+        dap_list_free(l_list_prev_out);
+        if(!l_tx_prev_out) {
+            l_err_num = -8;
+            break;
+        }
         if (l_cond_type == TX_ITEM_TYPE_IN) {
-            // Get one 'out' item in previous transaction bound with current 'in' item
-            dap_chain_tx_out_t *l_tx_prev_out = dap_list_nth_data(l_list_prev_out, l_tx_in->header.tx_out_prev_idx);
-            if(!l_tx_prev_out || *(uint8_t *)l_tx_prev_out != TX_ITEM_TYPE_OUT) {
+            dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_prev_out;
+            if (l_type == TX_ITEM_TYPE_OUT) {
+                bound_item->out.tx_prev_out = l_tx_prev_out;
+            } else if (l_type == TX_ITEM_TYPE_OUT_EXT) {
+                bound_item->out.tx_prev_out_ext = l_tx_prev_out;
+            } else {
                 l_err_num = -8;
                 break;
             }
-            dap_list_free(l_list_prev_out);
-            bound_item->tx_prev_out = l_tx_prev_out;
             // calculate hash of public key in current transaction
             dap_chain_hash_fast_t l_hash_pkey;
             {
@@ -827,22 +834,27 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                 // calculate hash from public key
                 dap_hash_fast(l_pkey_ser, l_pkey_ser_size, &l_hash_pkey);
                 // hash of public key in 'out' item of previous transaction
-                uint8_t *l_prev_out_addr_key = l_tx_prev_out->addr.data.key;
-
+                uint8_t *l_prev_out_addr_key = (l_type == TX_ITEM_TYPE_OUT) ?
+                                                bound_item->out.tx_prev_out->addr.data.key :
+                                                bound_item->out.tx_prev_out_ext->addr.data.key;
                 // 4. compare public key hashes in the signature of the current transaction and in the 'out' item of the previous transaction
                 if(memcmp(&l_hash_pkey, l_prev_out_addr_key, sizeof(dap_chain_hash_fast_t))) {
                     l_err_num = -9;
                     break;
                 }
             }
-            l_value = l_tx_prev_out->header.value;
-            l_token = l_tx_prev_out->token;
+            if (l_type == TX_ITEM_TYPE_OUT) {
+                l_value = bound_item->out.tx_prev_out->header.value;
+            } else {
+                l_value = bound_item->out.tx_prev_out_ext->header.value;
+                l_token = bound_item->out.tx_prev_out_ext->token;
+            }
         } else { // TX_ITEM_TYPE_IN_COND
-            dap_chain_tx_out_cond_t *l_tx_prev_out_cond = dap_list_nth_data(l_list_prev_out, l_tx_in_cond->header.tx_out_prev_idx);
-            if(!l_tx_prev_out_cond || *(uint8_t *)l_tx_prev_out_cond != TX_ITEM_TYPE_OUT_COND) {
+            if(*(uint8_t *)l_tx_prev_out != TX_ITEM_TYPE_OUT_COND) {
                 l_err_num = -8;
                 break;
             }
+            dap_chain_tx_out_cond_t * l_tx_prev_out_cond = (dap_chain_tx_out_cond_t *)l_tx_prev_out;
             dap_chain_ledger_verificator_t *l_verificator;
             int l_tmp = (int)l_tx_prev_out_cond->header.subtype;
             HASH_FIND_INT(s_verificators, &l_tmp, l_verificator);
@@ -856,7 +868,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                 l_err_num = -14;
                 break;
             }
-            bound_item->tx_prev_out_cond = l_tx_prev_out_cond;
+            bound_item->out.tx_prev_out_cond = l_tx_prev_out_cond;
             // calculate sum of values from previous transactions
             l_value = l_tx_prev_out_cond->header.value;
             l_token = NULL;
@@ -908,24 +920,31 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
     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);
     uint64_t l_value;
     for (l_list_tmp = l_list_out; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp)) {
-        if (*(uint8_t *)l_list_tmp->data == TX_ITEM_TYPE_OUT) {
-            dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t*) l_list_tmp->data;
+        dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data;
+        if (l_type == TX_ITEM_TYPE_OUT)
+        {
+            dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)l_list_tmp->data;
+            if (l_multichannel) { // token ticker is mandatory for multichannel transactions
+                l_err_num = -16;
+                break;
+            }
             if (emission_flag) {
                  l_value = l_tx_out->header.value;
             }
-            if (l_multichannel) {
-                l_token = l_tx_out->token;
-                if (!*l_token) { // token ticker is mandatory for multichannel transactions
-                    l_err_num = -16;
-                    break;
-                }
-            } else if (*l_tx_out->token) { // token ticker is deprecated for single-channel tx
-                l_err_num = -17;
+            l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out);
+        } else if (l_type == TX_ITEM_TYPE_OUT_EXT) {
+            dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)l_list_tmp->data;
+            if (!l_multichannel) { // token ticker is depricated for single-channel transactions
+                l_err_num = -16;
                 break;
             }
+            if (emission_flag) {
+                 l_value = l_tx_out->header.value;
+                 l_token = l_tx_out->token;
+            }
             l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out);
-        } else {
-            dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t*) l_list_tmp->data;
+        } else if (l_type == 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 (emission_flag) {
                 l_value = l_tx_out->header.value;
             }
@@ -1076,28 +1095,34 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx)
 //    int l_list_tmp_num = 0;
     while(l_list_tmp) {
         dap_chain_ledger_tx_bound_t *bound_item = l_list_tmp->data;
-        uint8_t l_cond = *(uint8_t *)bound_item->tx_cur_in;
+        dap_chain_tx_item_type_t l_type = *(uint8_t *)&bound_item->in;
         dap_chain_ledger_tx_item_t *l_prev_item_out = bound_item->item_out;
         if (*l_prev_item_out->token_tiker) {
             l_token_ticker = l_prev_item_out->token_tiker;
         } else { // Previous multichannel transaction
-            l_token_ticker = bound_item->tx_prev_out->token;
+            l_token_ticker = bound_item->out.tx_prev_out_ext->token;
         }
-        if (l_token_ticker_old && strcmp(l_token_ticker, l_token_ticker_old)) {
+        if (!l_multichannel && l_token_ticker_old && strcmp(l_token_ticker, l_token_ticker_old)) {
             l_multichannel = true;
         }
         l_token_ticker_old = l_token_ticker;
         dap_chain_hash_fast_t *l_tx_prev_hash;
-        if (l_cond == TX_ITEM_TYPE_IN) {
-            dap_chain_tx_in_t *l_tx_in = bound_item->tx_cur_in;
+        if (l_type == TX_ITEM_TYPE_IN) {
+            dap_chain_tx_in_t *l_tx_in = bound_item->in.tx_cur_in;
             // Update balance: deducts
             dap_ledger_wallet_balance_t *wallet_balance = NULL;
-            char *l_addr_str = dap_chain_addr_to_str(&bound_item->tx_prev_out->addr);
+            dap_chain_tx_item_type_t l_out_type = *(uint8_t *)&bound_item->out;
+            dap_chain_addr_t *l_addr = (l_out_type == TX_ITEM_TYPE_OUT) ?
+                                        &bound_item->out.tx_prev_out->addr :
+                                        &bound_item->out.tx_prev_out_ext->addr;
+            char *l_addr_str = dap_chain_addr_to_str(l_addr);
             char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_token_ticker, (char*)NULL);
             HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, wallet_balance);
             if (wallet_balance) {
                 //log_it(L_DEBUG,"SPEND %lu from addr: %s", bound_item->tx_prev_out->header.value, l_wallet_balance_key);
-                wallet_balance->balance -= bound_item->tx_prev_out->header.value;
+                wallet_balance->balance -= (l_out_type == TX_ITEM_TYPE_OUT) ?
+                                            bound_item->out.tx_prev_out->header.value :
+                                            bound_item->out.tx_prev_out_ext->header.value;
             } else {
                 log_it(L_ERROR,"!!! Attempt to SPEND from some non-existent balance !!!: %s %s", l_addr_str, l_token_ticker);
             }
@@ -1107,7 +1132,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx)
             l_tx_prev_hash = &(l_prev_item_out->tx_hash_spent_fast[l_tx_in->header.tx_out_prev_idx]);
         } else { // TX_ITEM_TYPE_IN_COND
             // all balance deducts performed with previous conditional transaction
-            dap_chain_tx_in_cond_t *l_tx_in_cond = bound_item->tx_cur_in_cond;
+            dap_chain_tx_in_cond_t *l_tx_in_cond = bound_item->in.tx_cur_in_cond;
             /// Mark 'out' item in cache because it used
             l_tx_prev_hash = &(l_prev_item_out->tx_hash_spent_fast[l_tx_in_cond->header.tx_out_prev_idx]);
         }
@@ -1164,30 +1189,41 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx)
 
     //Update balance : raise
     for (dap_list_t *l_tx_out = l_list_tx_out; l_tx_out; l_tx_out = dap_list_next(l_tx_out)) {
-        if (*(uint8_t *)l_tx_out->data == TX_ITEM_TYPE_OUT_COND) {
+        dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_out->data;
+        if (l_type == TX_ITEM_TYPE_OUT_COND) {
             continue;   // balance raise will be with next conditional transaction
         }
-        dap_chain_tx_out_t *l_out_item = l_tx_out->data;
+        dap_chain_tx_out_t *l_out_item;
+        dap_chain_tx_out_ext_t *l_out_item_ext;
+        if (l_type == TX_ITEM_TYPE_OUT) {
+            l_out_item = l_tx_out->data;
+        } else {
+            l_out_item_ext = l_tx_out->data;
+        }
         if (l_out_item && l_token_ticker) {
-            char *l_addr_str = dap_chain_addr_to_str(&l_out_item->addr);
+             dap_chain_addr_t *l_addr = (l_type == TX_ITEM_TYPE_OUT) ?
+                                        &l_out_item->addr :
+                                        &l_out_item_ext->addr;
+            char *l_addr_str = dap_chain_addr_to_str(l_addr);
             //log_it (L_DEBUG, "Check unspent %.03Lf %s for addr %s",
             //        (long double) l_out_item->header.value/ 1000000000000.0L,
             //        l_token_ticker, l_addr_str);
             dap_ledger_wallet_balance_t *wallet_balance = NULL;
             if (l_multichannel) {
-                l_token_ticker = l_out_item->token;
+                l_token_ticker = l_out_item_ext->token;
             }
             char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_token_ticker, (char*)NULL);
             //log_it (L_DEBUG,"\t\tAddr: %s token: %s", l_addr_str, l_token_ticker);
+            uint64_t l_value =  (l_type == TX_ITEM_TYPE_OUT) ? l_out_item->header.value : l_out_item_ext->header.value;
             HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, wallet_balance);
             if (wallet_balance) {
                 //log_it(L_DEBUG, "Balance item is present in cache");
-                wallet_balance->balance += l_out_item->header.value;
+                wallet_balance->balance += l_value;
                 DAP_DELETE (l_wallet_balance_key);
             } else {
                 wallet_balance = DAP_NEW_Z(dap_ledger_wallet_balance_t);
                 wallet_balance->key = l_wallet_balance_key;
-                wallet_balance->balance += l_out_item->header.value;
+                wallet_balance->balance += l_value;
                 dap_stpcpy(wallet_balance->token_ticker, l_token_ticker);
                 //log_it(L_DEBUG,"!!! Create new balance item: %s %s", l_addr_str, l_token_ticker);
                 HASH_ADD_KEYPTR(hh, PVT(a_ledger)->balance_accounts, wallet_balance->key,
@@ -1444,31 +1480,46 @@ uint64_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_ch
 
         // 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, &l_out_item_count);
+        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) {
             log_it(L_ERROR, "Too many 'out' items=%d in transaction (max=%d)", l_out_item_count, MAX_OUT_ITEMS);
             assert(l_out_item_count < MAX_OUT_ITEMS);
         }
-        dap_list_t *l_list_tmp = l_list_out_items;
         int l_out_idx_tmp = 0;
-        while(l_list_tmp) {
-            const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data;
-            assert(l_tx_out);
-            // Check for token name
-            if (!strcmp(a_token_ticker, l_iter_current->token_tiker) || !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(!dap_chain_ledger_item_is_used_out(l_iter_current, l_out_idx_tmp) &&
-                            dap_chain_datum_tx_verify_sign(l_cur_tx))
-                        balance += l_tx_out->header.value;
+        for (dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_out_idx_tmp++) {
+            assert(l_list_tmp->data);
+            dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data;
+            if (l_type == TX_ITEM_TYPE_OUT_COND) {
+                continue;
+            }
+            if (l_type == TX_ITEM_TYPE_OUT) {
+                const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data;
+                // Check for token name
+                if (!strcmp(a_token_ticker, l_iter_current->token_tiker))
+                {   // 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(!dap_chain_ledger_item_is_used_out(l_iter_current, l_out_idx_tmp) &&
+                                dap_chain_datum_tx_verify_sign(l_cur_tx))
+                            balance += l_tx_out->header.value;
+                    }
+                }
+            }
+            if (l_type == TX_ITEM_TYPE_OUT_EXT) {
+                const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) l_list_tmp->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(!dap_chain_ledger_item_is_used_out(l_iter_current, l_out_idx_tmp) &&
+                                dap_chain_datum_tx_verify_sign(l_cur_tx))
+                            balance += l_tx_out->header.value;
+                    }
                 }
             }
-            // go to the next 'out' item in l_tx_tmp transaction
-            l_out_idx_tmp++;
-            l_list_tmp = dap_list_next(l_list_tmp);
         }
-        dap_list_free(l_list_tmp);
+        dap_list_free(l_list_out_items);
     }
     pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
     return balance;
@@ -1507,20 +1558,34 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
             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, NULL);   
+        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 *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp)) {
-            const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data;
-            assert(l_tx_out);
-            // If a_token is setup we check if its not our token - miss it
-            if (a_token && !*l_iter_current->token_tiker && dap_strcmp(l_tx_out->token, a_token)) {
+            assert(l_list_tmp->data);
+            dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data;
+            if (l_type == TX_ITEM_TYPE_OUT_COND) {
                 continue;
             }
-            // 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) {
+                const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t *)l_list_tmp->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 *)l_list_tmp->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;
+                }
+            }
         }
         dap_list_free(l_list_out_items);
         // already found transaction
@@ -1699,24 +1764,36 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c
 
         uint32_t l_out_idx_tmp = 0; // current index of 'out' item
         for (dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_out_idx_tmp++) {
-            if (*(uint8_t *)l_list_tmp->data != TX_ITEM_TYPE_OUT) {
+            dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data;
+            if (l_type == TX_ITEM_TYPE_OUT_COND) {
                 continue;
             }
-            dap_chain_tx_out_t *out_item = l_list_tmp->data;
-            // if 'out' item has addr = a_addr_from
-            if(out_item && out_item->header.value && !memcmp(a_addr_from, &out_item->addr, sizeof(dap_chain_addr_t))) {
-                // Check whether used 'out' items
-                if(!dap_chain_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp)) {
-                    list_used_item_t *item = DAP_NEW(list_used_item_t);
-                    memcpy(&item->tx_hash_fast, &l_tx_cur_hash, sizeof(dap_chain_hash_fast_t));
-                    item->num_idx_out = l_out_idx_tmp;
-                    item->value = out_item->header.value;
-                    l_list_used_out = dap_list_append(l_list_used_out, item);
-                    l_value_transfer += item->value;
-                    // already accumulated the required value, finish the search for 'out' items
-                    if(l_value_transfer >= a_value_need) {
-                        break;
-                    }
+            uint64_t l_value;
+            if (l_type == TX_ITEM_TYPE_OUT) {
+                dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t *)l_list_tmp->data;
+                if (!l_out->header.value || memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t))) {
+                    continue;
+                }
+                l_value =  l_out->header.value;
+            } else { // TX_ITEM_TYPE_OUT_EXT
+                dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)l_list_tmp->data;
+                if (!l_out_ext->header.value || memcmp(a_addr_from, &l_out_ext->addr, sizeof(dap_chain_addr_t)) ||
+                        strcpy((char *)a_token_ticker, l_out_ext->token)) {
+                    continue;
+                }
+                l_value =  l_out_ext->header.value;
+            }
+            // Check whether used 'out' items
+            if (!dap_chain_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp)) {
+                list_used_item_t *item = DAP_NEW(list_used_item_t);
+                memcpy(&item->tx_hash_fast, &l_tx_cur_hash, sizeof(dap_chain_hash_fast_t));
+                item->num_idx_out = l_out_idx_tmp;
+                item->value = l_value;
+                l_list_used_out = dap_list_append(l_list_used_out, item);
+                l_value_transfer += item->value;
+                // already accumulated the required value, finish the search for 'out' items
+                if(l_value_transfer >= a_value_need) {
+                    break;
                 }
             }
         }
diff --git a/modules/common/dap_chain_datum_tx.c b/modules/common/dap_chain_datum_tx.c
index 350bf57843cb3c5b44b47e86104b773337abe1a6..0bdb9260550bdd590f66badd8d3f5076660aa29e 100644
--- a/modules/common/dap_chain_datum_tx.c
+++ b/modules/common/dap_chain_datum_tx.c
@@ -141,6 +141,7 @@ int dap_chain_datum_tx_add_in_cond_item(dap_chain_datum_tx_t **a_tx, dap_chain_h
     return -1;
 
 }
+
 /**
  * Create 'out' item and insert to transaction
  *
@@ -148,7 +149,23 @@ int dap_chain_datum_tx_add_in_cond_item(dap_chain_datum_tx_t **a_tx, dap_chain_h
  */
 int dap_chain_datum_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint64_t a_value)
 {
-    dap_chain_tx_out_t *l_tx_out = dap_chain_datum_tx_item_out_create(a_addr, a_value, NULL);
+    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;
+}
+
+/**
+ * Create 'out_ext' item and insert to transaction
+ *
+ * return 1 Ok, -1 Error
+ */
+int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint64_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);
diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c
index 438e774512fb648b19322cde7768456a9d451541..6c44465b08399af133461ab20a4e36ea8c868ebf 100644
--- a/modules/common/dap_chain_datum_tx_items.c
+++ b/modules/common/dap_chain_datum_tx_items.c
@@ -58,6 +58,13 @@ static size_t dap_chain_tx_out_get_size(const dap_chain_tx_out_t *a_item)
     return size;
 }
 
+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)
 {
     return sizeof(dap_chain_tx_out_cond_t) + a_item->params_size;
@@ -110,6 +117,9 @@ size_t dap_chain_datum_item_tx_get_size(const uint8_t *a_item)
     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:
+        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);
     case TX_ITEM_TYPE_IN_COND: // Transaction inputs with condition
@@ -194,7 +204,7 @@ dap_chain_tx_in_cond_t* dap_chain_datum_tx_item_in_cond_create(dap_chain_hash_fa
  *
  * return item, NULL Error
  */
-dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a_addr, uint64_t a_value, const char *a_token)
+dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a_addr, uint64_t a_value)
 {
     if(!a_addr)
         return NULL;
@@ -202,9 +212,18 @@ dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a
     l_item->header.type = TX_ITEM_TYPE_OUT;
     l_item->header.value = a_value;
     memcpy(&l_item->addr, a_addr, sizeof(dap_chain_addr_t));
-    if (a_token) {
-        strcpy(l_item->token, a_token);
-    }
+    return l_item;
+}
+
+dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_addr_t *a_addr, uint64_t a_value, const char *a_token)
+{
+    if (!a_addr || !a_token)
+        return NULL;
+    dap_chain_tx_out_ext_t *l_item = DAP_NEW_Z(dap_chain_tx_out_ext_t);
+    l_item->header.type = TX_ITEM_TYPE_OUT_EXT;
+    l_item->header.value = a_value;
+    memcpy(&l_item->addr, a_addr, sizeof(dap_chain_addr_t));
+    strcpy(l_item->token, a_token);
     return l_item;
 }
 
@@ -320,7 +339,8 @@ uint8_t* dap_chain_datum_tx_item_get( dap_chain_datum_tx_t *a_tx, int *a_item_id
             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_COND)) {
+                    (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)) {
                 if(a_item_idx_start)
                     *a_item_idx_start = l_item_idx;
                 if(a_item_out_size)
diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h
index 19cc29e9e542b1208520bb13ca5c709c6f0c2b76..a4a11b7d27703246ffc778bfcb9940b75f291938 100644
--- a/modules/common/include/dap_chain_common.h
+++ b/modules/common/include/dap_chain_common.h
@@ -173,6 +173,7 @@ typedef union {
 typedef enum dap_chain_tx_item_type {
     TX_ITEM_TYPE_IN = 0x00, /// @brief  Transaction: inputs
     TX_ITEM_TYPE_OUT = 0x10, /// @brief  Transaction: outputs
+    TX_ITEM_TYPE_OUT_EXT = 0x11,
     TX_ITEM_TYPE_PKEY = 0x20,
     TX_ITEM_TYPE_SIG = 0x30,
     TX_ITEM_TYPE_TOKEN = 0x40,
diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h
index 189222a4097f1f0a41a20af87c6a1aa674be5cfa..54885c4863ecfe326112fc46141c54141ac66043 100644
--- a/modules/common/include/dap_chain_datum_tx.h
+++ b/modules/common/include/dap_chain_datum_tx.h
@@ -106,6 +106,14 @@ int dap_chain_datum_tx_add_in_cond_item(dap_chain_datum_tx_t **a_tx, dap_chain_h
  */
 int dap_chain_datum_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint64_t a_value);
 
+/**
+ * Create 'out'_ext item and insert to transaction
+ *
+ * return 1 Ok, -1 Error
+ */
+int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr,
+                                        uint64_t a_value, const char *a_token);
+
 /**
  * Create 'out_cond' item and insert to transaction
  *
diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h
index bea1bf9fd272abe470cfbcdccd61651724eb613c..7ef0ab207c26e21ea3c702865a6c4c59815528cb 100644
--- a/modules/common/include/dap_chain_datum_tx_items.h
+++ b/modules/common/include/dap_chain_datum_tx_items.h
@@ -34,6 +34,7 @@
 #include "dap_chain_datum_tx.h"
 #include "dap_chain_datum_tx_in.h"
 #include "dap_chain_datum_tx_out.h"
+#include "dap_chain_datum_tx_out_ext.h"
 #include "dap_chain_datum_tx_in_cond.h"
 #include "dap_chain_datum_tx_out_cond.h"
 #include "dap_chain_datum_tx_sig.h"
@@ -77,7 +78,14 @@ dap_chain_tx_in_cond_t* dap_chain_datum_tx_item_in_cond_create(dap_chain_hash_fa
  *
  * return item, NULL Error
  */
-dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a_addr, uint64_t a_value, const char *a_token);
+dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a_addr, uint64_t a_value);
+
+/**
+ * Create item dap_chain_tx_out_ext_t
+ *
+ * return item, NULL Error
+ */
+dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_addr_t *a_addr, uint64_t a_value, const char *a_token);
 
 /**
  * Create item dap_chain_tx_out_cond_t
diff --git a/modules/common/include/dap_chain_datum_tx_out.h b/modules/common/include/dap_chain_datum_tx_out.h
index 77dfd998dbb0c9e45a6cf9f5b97f62b8e28eea44..24f8240a6fc37aaf163783b7700dc7d71323e00f 100644
--- a/modules/common/include/dap_chain_datum_tx_out.h
+++ b/modules/common/include/dap_chain_datum_tx_out.h
@@ -38,5 +38,4 @@ typedef struct dap_chain_tx_out{
         uint64_t value; ///                       @param    value           @brief  Number of Datoshis ( DAP/10^9 ) to be transfered
     } header; /// Only header's hash is used for verification
     dap_chain_addr_t addr; ////
-    char token[DAP_CHAIN_TICKER_SIZE_MAX];
 } DAP_ALIGN_PACKED dap_chain_tx_out_t;
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 7d1ad6ca0910e362ad92b9f2754c953c5982c232..809d073a559952b4be4e489f37c794be47a9a4f5 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -3095,7 +3095,7 @@ int com_token_emit(int argc, char ** argv, void *arg_func, char ** str_reply)
     // create items
     dap_chain_tx_token_t *l_tx_token = dap_chain_datum_tx_item_token_create(&l_token_emission_hash, l_ticker);
     dap_chain_tx_in_t *l_in = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, 0);
-    dap_chain_tx_out_t *l_out = dap_chain_datum_tx_item_out_create(l_addr, l_emission_value, NULL);
+    dap_chain_tx_out_t *l_out = dap_chain_datum_tx_item_out_create(l_addr, l_emission_value);
 
     // pack items to transaction
     dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_tx_token);
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 00645c770ac735c7a1524634c60093ee62ef67e3..75b4c2b48d5fd000e6582fbb8640319d375656a4 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -101,11 +101,11 @@ bool dap_chain_net_srv_xchange_verificator(dap_chain_tx_out_cond_t *a_cond, dap_
         // it's the condition owner, let the transaction to be performed
         return true;
     } else {
-        dap_list_t *l_list_out = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT, NULL);
+        dap_list_t *l_list_out = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_EXT, NULL);
 
         uint64_t l_out_val = 0;
         for (dap_list_t *l_list_tmp = l_list_out;l_list_tmp;  l_list_tmp = l_list_tmp->next) {
-            dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)l_list_tmp->data;
+            dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)l_list_tmp->data;
             if (memcmp(&l_tx_out->addr, &a_cond->params, sizeof(dap_chain_addr_t)) ||
                     strcmp(l_tx_out->token, a_cond->subtype.srv_xchange.token)) {
                 continue;
@@ -250,11 +250,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
     {
         // transfer selling coins
         const dap_chain_addr_t *l_buyer_addr = (dap_chain_addr_t *)l_tx_out_cond->params;
-        dap_chain_tx_out_t *l_tx_out = dap_chain_datum_tx_item_out_create(l_buyer_addr, a_price->datoshi_sell, a_price->token_sell);
-        if (l_tx_out) {
-            dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_tx_out);
-            DAP_DELETE(l_tx_out);
-        } else {
+        if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_buyer_addr, a_price->datoshi_sell, a_price->token_sell) == -1) {
             dap_chain_datum_tx_delete(l_tx);
             DAP_DELETE(l_seller_addr);
             log_it(L_ERROR, "Can't add selling coins output");
@@ -263,11 +259,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
         // coin back
         uint64_t l_value_back = l_value_sell - a_price->datoshi_sell;
         if (l_value_back) {
-            l_tx_out = dap_chain_datum_tx_item_out_create(l_seller_addr, l_value_back, a_price->token_sell);
-            if (l_tx_out) {
-                dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_tx_out);
-                DAP_DELETE(l_tx_out);
-            } else {
+            if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_seller_addr, l_value_back, a_price->token_sell) == -1) {
                 dap_chain_datum_tx_delete(l_tx);
                 DAP_DELETE(l_seller_addr);
                 log_it(L_ERROR, "Can't add selling coins back output");
@@ -275,11 +267,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
             }
         }
         //transfer buying coins
-        l_tx_out = dap_chain_datum_tx_item_out_create(l_seller_addr, a_price->datoshi_buy, a_price->token_buy);
-        if (l_tx_out) {
-            dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_tx_out);
-            DAP_DELETE(l_tx_out);
-        } else {
+        if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_seller_addr, a_price->datoshi_buy, a_price->token_buy) == -1) {
             dap_chain_datum_tx_delete(l_tx);
             DAP_DELETE(l_seller_addr);
             log_it(L_ERROR, "Cant add buying coins output");
@@ -290,12 +278,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
         uint64_t l_buying_value = l_tx_out_cond->header.value;
         l_value_back = l_buying_value - a_price->datoshi_buy;
         if (l_value_back) {
-            /*l_tx_out = dap_chain_datum_tx_item_out_create(l_buyer_addr, l_value_back, a_price->token_buy);
-            if (l_tx_out) {
-                dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_tx_out);
-                DAP_DELETE(l_tx_out);
-            } else {
-                dap_chain_datum_tx_delete(l_tx);*/
+            //if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_buyer_addr, l_value_back, a_price->token_buy) == -1) {
                 log_it(L_WARNING, "Partial exchange not allowed");
                 return NULL;
             //}