diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index d620ee7c64fad6d3771446b9fecb7ac5a57ad36f..7dba00c290879a367942ba4c65a9489e6e15c137 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -37,6 +37,7 @@ static int s_callback_requested(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id,
 static int s_callback_response_success(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_t *a_srv_client, const void *a_data, size_t a_data_size);
 static int s_callback_response_error(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_t *a_srv_client, const void *a_data, size_t a_data_size);
 static int s_callback_receipt_next_success(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_t *a_srv_client, const void *a_data, size_t a_data_size);
+static dap_chain_net_srv_xchange_price_t *s_xchange_db_load(char *a_key, uint8_t *a_item);
 
 static dap_chain_net_srv_xchange_t *s_srv_xchange;
 
@@ -71,9 +72,16 @@ int dap_chain_net_srv_xchange_init()
         dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_XCHANGE_ID };
         dap_chain_net_srv_t* l_srv = dap_chain_net_srv_add(l_uid, s_callback_requested, s_callback_response_success,
                                                            s_callback_response_error, s_callback_receipt_next_success);
-        s_srv_xchange  = DAP_NEW_Z(dap_chain_net_srv_xchange_t);
+        s_srv_xchange = DAP_NEW_Z(dap_chain_net_srv_xchange_t);
         l_srv->_inhertor = s_srv_xchange;
         s_srv_xchange->enabled = false;
+        size_t l_prices_count = 0;
+        dap_global_db_obj_t *l_prices = dap_chain_global_db_gr_load(GROUP_LOCAL_XCHANGE, &l_prices_count);
+        for (size_t i = 0; i < l_prices_count; i++) {
+            dap_chain_net_srv_xchange_price_t *l_price = s_xchange_db_load(l_prices[i].key, l_prices[i].value);
+            HASH_ADD_KEYPTR(hh, s_srv_xchange->pricelist, l_price->key_ptr, strlen(l_price->key_ptr), l_price);
+        }
+        dap_chain_global_db_objs_delete(l_prices, l_prices_count);
         return 0;
 }
 
@@ -135,11 +143,12 @@ static dap_chain_datum_tx_receipt_t *s_xchage_receipt_create(dap_chain_net_srv_x
 {
     uint32_t l_ext_size = sizeof(uint64_t) + DAP_CHAIN_TICKER_SIZE_MAX;
     uint8_t *l_ext = DAP_NEW_SIZE(uint8_t, l_ext_size);
-    dap_lendian_put64(l_ext, a_price->datoshi_sell);
-    strcpy((char *)&l_ext[sizeof(uint64_t)], a_price->token_sell);
+    uint64_t l_datoshi_buy = (long double)a_price->datoshi_sell / a_price->rate;
+    dap_lendian_put64(l_ext, l_datoshi_buy);
+    strcpy((char *)&l_ext[sizeof(uint64_t)], a_price->token_buy);
     dap_chain_net_srv_price_unit_uid_t l_unit = { .uint32 = SERV_UNIT_UNDEFINED};
     dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_XCHANGE_ID };
-    dap_chain_datum_tx_receipt_t *l_receipt =  dap_chain_datum_tx_receipt_create(l_uid, l_unit, 0, a_price->datoshi_buy,
+    dap_chain_datum_tx_receipt_t *l_receipt =  dap_chain_datum_tx_receipt_create(l_uid, l_unit, 0, a_price->datoshi_sell,
                                                                                  l_ext, l_ext_size);
     return l_receipt;
 }
@@ -223,13 +232,14 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
     // create empty transaction
     dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
 
-    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_price->net_sell->pub.name);
-    dap_chain_addr_t *l_seller_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(a_wallet, a_price->net_sell->pub.id);
+    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_price->net_buy->pub.name);
+    dap_chain_addr_t *l_seller_addr = (dap_chain_addr_t *)dap_chain_wallet_get_addr(a_wallet, a_price->net_buy->pub.id);
     dap_enc_key_t *l_seller_key = dap_chain_wallet_get_key(a_wallet, 0);
-    uint64_t l_value_sell = 0; // how many coins to transfer
+    uint64_t l_value_buy = 0; // how many coins to transfer
     // list of transaction with 'out' items to sell
-    dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_price->token_sell,
-                                                                             l_seller_addr, a_price->datoshi_sell, &l_value_sell);
+    uint64_t l_datoshi_buy = ceill(a_price->datoshi_sell / a_price->rate);
+    dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_price->token_buy,
+                                                                             l_seller_addr, l_datoshi_buy, &l_value_buy);
     if(!l_list_used_out) {
         dap_chain_datum_tx_delete(l_tx);
         log_it(L_WARNING, "Nothing to change (not enough funds)");
@@ -243,7 +253,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
     // add 'in' items to sell
     uint64_t l_value_to_items = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_used_out);
     dap_list_free_full(l_list_used_out, free);
-    if (l_value_to_items != l_value_sell) {
+    if (l_value_to_items != l_value_buy) {
         dap_chain_datum_tx_delete(l_tx);
         DAP_DELETE(l_seller_addr);
         log_it(L_ERROR, "Can't compose the transaction input");
@@ -266,16 +276,16 @@ 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;
-        if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_buyer_addr, a_price->datoshi_sell, a_price->token_sell) == -1) {
+        if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_buyer_addr, l_datoshi_buy, a_price->token_buy) == -1) {
             dap_chain_datum_tx_delete(l_tx);
             DAP_DELETE(l_seller_addr);
             log_it(L_ERROR, "Can't add selling coins output");
             return NULL;
         }
         // coin back
-        uint64_t l_value_back = l_value_sell - a_price->datoshi_sell;
+        uint64_t l_value_back = l_value_buy - l_datoshi_buy;
         if (l_value_back) {
-            if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_seller_addr, l_value_back, a_price->token_sell) == -1) {
+            if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_seller_addr, l_value_back, a_price->token_buy) == -1) {
                 dap_chain_datum_tx_delete(l_tx);
                 DAP_DELETE(l_seller_addr);
                 log_it(L_ERROR, "Can't add selling coins back output");
@@ -283,7 +293,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
             }
         }
         //transfer buying coins
-        if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_seller_addr, a_price->datoshi_buy, a_price->token_buy) == -1) {
+        if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_seller_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 buying coins output");
@@ -292,9 +302,9 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
         DAP_DELETE(l_seller_addr);
         //transfer unbuying coins (partial exchange)
         uint64_t l_buying_value = l_tx_out_cond->header.value;
-        l_value_back = l_buying_value - a_price->datoshi_buy;
+        l_value_back = l_buying_value - a_price->datoshi_sell;
         if (l_value_back) {
-            if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_buyer_addr, l_value_back, a_price->token_buy) == -1) {
+            if (dap_chain_datum_tx_add_out_ext_item(&l_tx, l_buyer_addr, l_value_back, a_price->token_sell) == -1) {
                 log_it(L_WARNING, "Can't add buying coins back output (cashback)");
                 return NULL;
             }
@@ -337,8 +347,8 @@ static bool s_xchage_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price, d
     // create empty transaction
     dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
 
-    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_price->net_sell->pub.name);
-    dap_chain_addr_t *l_seller_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(a_wallet, a_price->net_sell->pub.id);
+    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_price->net_buy->pub.name);
+    dap_chain_addr_t *l_seller_addr = (dap_chain_addr_t *)dap_chain_wallet_get_addr(a_wallet, a_price->net_buy->pub.id);
     dap_enc_key_t *l_seller_key = dap_chain_wallet_get_key(a_wallet, 0);
 
     // create and add reciept
@@ -380,7 +390,7 @@ static bool s_xchage_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price, d
         log_it( L_ERROR, "Can't add sign output");
         return false;
     }
-    if (!s_xchange_tx_put(l_tx, a_price->net_sell)) {
+    if (!s_xchange_tx_put(l_tx, a_price->net_buy)) {
         return false;
     }
     return true;
@@ -399,8 +409,9 @@ char *s_xchange_order_create(dap_chain_net_srv_xchange_price_t *a_price, dap_cha
     dap_chain_node_addr_t *l_node_addr = dap_chain_net_get_cur_addr(a_price->net_sell);
     dap_chain_net_srv_price_unit_uid_t l_unit = { .uint32 =  SERV_UNIT_UNDEFINED};
     dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_XCHANGE_ID };
+    uint64_t l_datoshi_buy = ceill(a_price->datoshi_sell / a_price->rate);
     char *l_order_hash_str = dap_chain_net_srv_order_create(a_price->net_buy, SERV_DIR_SELL, l_uid, *l_node_addr,
-                                                            l_tx_hash, a_price->datoshi_buy, l_unit, a_price->token_buy, 0,
+                                                            l_tx_hash, l_datoshi_buy, l_unit, a_price->token_buy, 0,
                                                             (uint8_t *)&l_ext, l_ext_size, NULL, 0);
     return l_order_hash_str;
 }
@@ -408,14 +419,49 @@ char *s_xchange_order_create(dap_chain_net_srv_xchange_price_t *a_price, dap_cha
 dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a_net, dap_chain_net_srv_order_t *a_order)
 {
     dap_chain_net_srv_xchange_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_xchange_price_t);
-    l_price->net_sell = a_net;
-    strcpy(l_price->token_sell, a_order->price_ticker);
-    l_price->datoshi_sell = a_order->price;
     dap_srv_xchange_order_ext_t *l_ext = (dap_srv_xchange_order_ext_t *)a_order->ext;
     dap_chain_net_id_t l_net_buy_id = { .uint64 = dap_lendian_get64((uint8_t *)&l_ext->net_sell_id) };
-    l_price->net_buy = dap_chain_net_by_id(l_net_buy_id);
-    l_price->datoshi_buy = dap_lendian_get64((uint8_t *)&l_ext->datoshi_sell);
-    strcpy(l_price->token_buy, l_ext->token_sell);
+    l_price->net_sell = dap_chain_net_by_id(l_net_buy_id);
+    l_price->datoshi_sell = dap_lendian_get64((uint8_t *)&l_ext->datoshi_sell);
+    strcpy(l_price->token_sell, l_ext->token_sell);
+    l_price->net_buy = a_net;
+    strcpy(l_price->token_buy, a_order->price_ticker);
+    l_price->rate = (long double)l_price->datoshi_sell / a_order->price;
+    return l_price;
+}
+
+static bool s_xchange_db_add(dap_chain_net_srv_xchange_price_t *a_price)
+{
+    size_t l_size = sizeof(dap_chain_net_srv_xchange_db_item_t) + strlen(a_price->wallet_str) + 1;
+    dap_chain_net_srv_xchange_db_item_t *l_item = DAP_NEW_Z_SIZE(dap_chain_net_srv_xchange_db_item_t, l_size);
+    strcpy(l_item->token_sell, a_price->token_sell);
+    strcpy(l_item->token_buy, a_price->token_buy);
+    l_item->net_sell_id = a_price->net_sell->pub.id.uint64;
+    l_item->net_buy_id = a_price->net_buy->pub.id.uint64;
+    l_item->datoshi_sell = a_price->datoshi_sell;
+    l_item->rate = a_price->rate;
+    memcpy(&l_item->tx_hash, &a_price->tx_hash, sizeof(dap_chain_hash_fast_t));
+    memcpy(&l_item->order_hash, &a_price->order_hash, sizeof(dap_chain_hash_fast_t));
+    strcpy(l_item->wallet_str, a_price->wallet_str);
+    return dap_chain_global_db_gr_set(dap_strdup(a_price->key_ptr), (uint8_t *)l_item, l_size, GROUP_LOCAL_XCHANGE);
+}
+
+static dap_chain_net_srv_xchange_price_t *s_xchange_db_load(char *a_key, uint8_t *a_item)
+{
+    dap_chain_net_srv_xchange_db_item_t *l_item = (dap_chain_net_srv_xchange_db_item_t *)a_item;
+    dap_chain_net_srv_xchange_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_xchange_price_t);
+    strcpy(l_price->key_ptr, a_key);
+    strcpy(l_price->token_sell, l_item->token_sell);
+    strcpy(l_price->token_buy, l_item->token_buy);
+    dap_chain_net_id_t l_id = { .uint64 = l_item->net_sell_id};
+    l_price->net_sell = dap_chain_net_by_id(l_id);
+    l_id.uint64 = l_item->net_buy_id;
+    l_price->net_buy = dap_chain_net_by_id(l_id);
+    l_price->datoshi_sell = l_item->datoshi_sell;
+    l_price->rate = l_item->rate;
+    memcpy(&l_price->tx_hash, &l_item->tx_hash, sizeof(dap_chain_hash_fast_t));
+    memcpy(&l_price->order_hash, &l_item->order_hash, sizeof(dap_chain_hash_fast_t));
+    strcpy(l_price->wallet_str, l_item->wallet_str);
     return l_price;
 }
 
@@ -545,24 +591,30 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c
             l_price->net_buy = l_net_buy;
             l_price->key_ptr = l_strkey;
             l_price->datoshi_sell = l_datoshi_sell;
-            l_price->datoshi_buy = l_datoshi_sell / l_rate;
+            l_price->rate = l_rate;
             // Create conditional transaction
             dap_chain_datum_tx_t *l_tx = s_xchange_tx_create_request(l_price, l_wallet);
             dap_chain_wallet_close(l_wallet);
             if (!l_tx) {
                 dap_chain_node_cli_set_reply_text(a_str_reply, "Can't compose the conditional transaction");
                 DAP_DELETE(l_price);
-                break;
+                return -14;
             }
             // Create the order & put it to GDB
             char *l_order_hash_str = s_xchange_order_create(l_price, l_tx);
             if (l_order_hash_str) {
                 dap_chain_str_to_hash_fast(l_order_hash_str, &l_price->order_hash);
                 if(!s_xchange_tx_put(l_tx, l_net_buy)) {
-                    dap_chain_node_cli_set_reply_text(a_str_reply, "Can't put transaction to mempool/chains");
+                    dap_chain_node_cli_set_reply_text(a_str_reply, "Can't put transaction to mempool");
+                    dap_chain_net_srv_order_delete_by_hash_str(l_net_buy, l_order_hash_str);
+                    DAP_DELETE(l_order_hash_str);
+                    return -15;
+                }
+                if (!s_xchange_db_add(l_price)) {
+                    dap_chain_node_cli_set_reply_text(a_str_reply, "Can't save price in database");
                     dap_chain_net_srv_order_delete_by_hash_str(l_net_buy, l_order_hash_str);
                     DAP_DELETE(l_order_hash_str);
-                    break;
+                    return -16;
                 }
                 dap_chain_node_cli_set_reply_text(a_str_reply, "Successfully created order %s", l_order_hash_str);
                 DAP_DELETE(l_order_hash_str);
@@ -578,121 +630,127 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c
         case CMD_UPDATE: {
             dap_chain_net_srv_xchange_price_t *l_price = NULL;
             HASH_FIND_STR(s_srv_xchange->pricelist, l_strkey, l_price);
-            if (l_price) {
-                if (l_cmd_num == CMD_REMOVE) {
-                    dap_string_t *l_str_reply = dap_string_new("");
-                    HASH_DEL(s_srv_xchange->pricelist, l_price);
-                    dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_price->wallet_str, dap_chain_wallet_get_path(g_config));
-                    bool l_ret = s_xchage_tx_invalidate(l_price, l_wallet);
-                    dap_chain_wallet_close(l_wallet);
-                    if (!l_ret) {
-                        char *l_tx_hash_str = dap_chain_hash_fast_to_str_new(&l_price->tx_hash);
-                        dap_string_append_printf(l_str_reply, "Can't invalidate transaction %s\n", l_tx_hash_str);
-                        DAP_DELETE(l_tx_hash_str);
-                    }
-                    char *l_order_hash_str = dap_chain_hash_fast_to_str_new(&l_price->order_hash);
-                    if (dap_chain_net_srv_order_delete_by_hash_str(l_price->net_buy, l_order_hash_str)) {
-                        dap_string_append_printf(l_str_reply, "Can't remove order %s\n", l_order_hash_str);
-                    }
-                    DAP_DELETE(l_order_hash_str);
-                    DAP_DELETE(l_price->key_ptr);
-                    DAP_DELETE(l_price->wallet_str);
-                    DAP_DELETE(l_price);
-                    if (!l_str_reply->len) {
-                        dap_string_append(l_str_reply, "Price successfully removed");
-                    }
-                    *a_str_reply = dap_string_free(l_str_reply, false);
-                } else {    // CMD_UPDATE
-                    const char *l_val_sell_str = NULL, *l_val_rate_str = NULL, *l_wallet_str = NULL, *l_new_wallet_str = NULL;
-                    uint64_t l_datoshi_sell = 0;
-                    long double l_rate = 0;
-                    dap_chain_wallet_t *l_wallet = NULL;
-                    dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-coins", &l_val_sell_str);
-                    if (l_val_sell_str) {
-                        l_datoshi_sell = strtoull(l_val_sell_str, NULL, 10);
-                        if (!l_datoshi_sell) {
-                            dap_chain_node_cli_set_reply_text(a_str_reply, "Format -coins <unsigned long long>");
-                            return -9;
-                        }
-                    }
-                    dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-rate", &l_val_rate_str);
-                    if (l_val_rate_str) {
-                        l_rate = strtold(l_val_rate_str, NULL);
-                        if (!l_rate) {
-                            dap_chain_node_cli_set_reply_text(a_str_reply, "Format -rate <long double> = sell / buy");
-                            return -9;
-                        }
-                    }
-                    dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-wallet", &l_new_wallet_str);
-                    l_wallet_str = l_new_wallet_str ? l_new_wallet_str : l_price->wallet_str;
-                    l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config));
-                    if (!l_wallet) {
-                        dap_chain_node_cli_set_reply_text(a_str_reply, "Specified wallet not found");
-                        return -11;
-                    }
-                    if (!l_val_sell_str && !l_val_rate_str && !l_wallet_str) {
-                        dap_chain_node_cli_set_reply_text(a_str_reply, "At least one of updating parameters is mandatory");
-                        return -13;
-                    }
-                    if (l_datoshi_sell && dap_chain_wallet_get_balance(l_wallet, l_net_sell->pub.id, l_token_sell_str) < l_datoshi_sell) {
-                            dap_chain_node_cli_set_reply_text(a_str_reply, "Not enough cash in specified wallet");
-                            dap_chain_wallet_close(l_wallet);
-                            return -12;
-                    }
-                    if (l_val_sell_str) {
-                        l_price->datoshi_sell = l_datoshi_sell;
+            if (!l_price) {
+                dap_chain_node_cli_set_reply_text(a_str_reply, "Price with provided pair of token ticker + net name is not exist");
+                return -1;
+            }
+            if (l_cmd_num == CMD_REMOVE) {
+                dap_string_t *l_str_reply = dap_string_new("");
+                HASH_DEL(s_srv_xchange->pricelist, l_price);
+                dap_chain_global_db_gr_del(l_price->key_ptr, GROUP_LOCAL_XCHANGE);
+                dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_price->wallet_str, dap_chain_wallet_get_path(g_config));
+                bool l_ret = s_xchage_tx_invalidate(l_price, l_wallet);
+                dap_chain_wallet_close(l_wallet);
+                if (!l_ret) {
+                    char *l_tx_hash_str = dap_chain_hash_fast_to_str_new(&l_price->tx_hash);
+                    dap_string_append_printf(l_str_reply, "Can't invalidate transaction %s\n", l_tx_hash_str);
+                    DAP_DELETE(l_tx_hash_str);
+                }
+                char *l_order_hash_str = dap_chain_hash_fast_to_str_new(&l_price->order_hash);
+                if (dap_chain_net_srv_order_delete_by_hash_str(l_price->net_buy, l_order_hash_str)) {
+                    dap_string_append_printf(l_str_reply, "Can't remove order %s\n", l_order_hash_str);
+                }
+                DAP_DELETE(l_order_hash_str);
+                DAP_DELETE(l_price->wallet_str);
+                DAP_DELETE(l_price);
+                if (!l_str_reply->len) {
+                    dap_string_append(l_str_reply, "Price successfully removed");
+                }
+                *a_str_reply = dap_string_free(l_str_reply, false);
+            } else {    // CMD_UPDATE
+                const char *l_val_sell_str = NULL, *l_val_rate_str = NULL, *l_wallet_str = NULL, *l_new_wallet_str = NULL;
+                uint64_t l_datoshi_sell = 0;
+                long double l_rate = 0;
+                dap_chain_wallet_t *l_wallet = NULL;
+                dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-coins", &l_val_sell_str);
+                if (l_val_sell_str) {
+                    l_datoshi_sell = strtoull(l_val_sell_str, NULL, 10);
+                    if (!l_datoshi_sell) {
+                        dap_chain_node_cli_set_reply_text(a_str_reply, "Format -coins <unsigned long long>");
+                        return -9;
                     }
-                    if (l_val_rate_str) {
-                        l_price->datoshi_buy = l_price->datoshi_sell / l_rate;
+                }
+                dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-rate", &l_val_rate_str);
+                if (l_val_rate_str) {
+                    l_rate = strtold(l_val_rate_str, NULL);
+                    if (!l_rate) {
+                        dap_chain_node_cli_set_reply_text(a_str_reply, "Format -rate <long double> = sell / buy");
+                        return -9;
                     }
-                    // Update the transaction
-                    dap_chain_datum_tx_t *l_tx = s_xchange_tx_create_request(l_price, l_wallet);
-                    if (l_new_wallet_str) {
+                }
+                dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-wallet", &l_new_wallet_str);
+                l_wallet_str = l_new_wallet_str ? l_new_wallet_str : l_price->wallet_str;
+                l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config));
+                if (!l_wallet) {
+                    dap_chain_node_cli_set_reply_text(a_str_reply, "Specified wallet not found");
+                    return -11;
+                }
+                if (!l_val_sell_str && !l_val_rate_str && !l_wallet_str) {
+                    dap_chain_node_cli_set_reply_text(a_str_reply, "At least one of updating parameters is mandatory");
+                    return -13;
+                }
+                if (l_datoshi_sell && dap_chain_wallet_get_balance(l_wallet, l_net_sell->pub.id, l_token_sell_str) < l_datoshi_sell) {
+                        dap_chain_node_cli_set_reply_text(a_str_reply, "Not enough cash in specified wallet");
                         dap_chain_wallet_close(l_wallet);
-                        l_wallet = dap_chain_wallet_open(l_price->wallet_str, dap_chain_wallet_get_path(g_config));
-                        DAP_DELETE(l_price->wallet_str);
-                        l_price->wallet_str = dap_strdup(l_new_wallet_str);
-                    }
-                    if (!l_tx) {
-                        dap_chain_node_cli_set_reply_text(a_str_reply, "Can't compose the conditional transaction");
-                        break;
-                    }
-                    HASH_DEL(s_srv_xchange->pricelist, l_price);
-                    bool l_ret = s_xchage_tx_invalidate(l_price, l_wallet); // may be changed to old price later
+                        return -12;
+                }
+                if (l_val_sell_str) {
+                    l_price->datoshi_sell = l_datoshi_sell;
+                }
+                if (l_val_rate_str) {
+                    l_price->rate = l_rate;
+                }
+                // Update the transaction
+                dap_chain_datum_tx_t *l_tx = s_xchange_tx_create_request(l_price, l_wallet);
+                if (l_new_wallet_str) {
                     dap_chain_wallet_close(l_wallet);
-                    if (!l_ret) {
-                        char *l_tx_hash_str = dap_chain_hash_fast_to_str_new(&l_price->tx_hash);
-                        dap_chain_node_cli_set_reply_text(a_str_reply, "Can't invalidate transaction %s\n", l_tx_hash_str);
-                        DAP_DELETE(l_tx_hash_str);
-                        break;
+                    l_wallet = dap_chain_wallet_open(l_price->wallet_str, dap_chain_wallet_get_path(g_config));
+                    DAP_DELETE(l_price->wallet_str);
+                    l_price->wallet_str = dap_strdup(l_new_wallet_str);
+                }
+                if (!l_tx) {
+                    dap_chain_node_cli_set_reply_text(a_str_reply, "Can't compose the conditional transaction");
+                    return -14;
+                }
+                HASH_DEL(s_srv_xchange->pricelist, l_price);
+                dap_chain_global_db_gr_del(l_price->key_ptr, GROUP_LOCAL_XCHANGE);
+                bool l_ret = s_xchage_tx_invalidate(l_price, l_wallet); // may be changed to old price later
+                dap_chain_wallet_close(l_wallet);
+                if (!l_ret) {
+                    char *l_tx_hash_str = dap_chain_hash_fast_to_str_new(&l_price->tx_hash);
+                    dap_chain_node_cli_set_reply_text(a_str_reply, "Can't invalidate transaction %s\n", l_tx_hash_str);
+                    DAP_DELETE(l_tx_hash_str);
+                    return -17;
+                }
+                // Update the order
+                char *l_order_hash_str = dap_chain_hash_fast_to_str_new(&l_price->order_hash);
+                dap_chain_net_srv_order_delete_by_hash_str(l_price->net_buy, l_order_hash_str);
+                DAP_DELETE(l_order_hash_str);
+                l_order_hash_str = s_xchange_order_create(l_price, l_tx);
+                if (l_order_hash_str) {
+                    dap_chain_str_to_hash_fast(l_order_hash_str, &l_price->order_hash);
+                    if(!s_xchange_tx_put(l_tx, l_net_buy)) {
+                        dap_chain_node_cli_set_reply_text(a_str_reply, "Can't put transaction to mempool");
+                        dap_chain_net_srv_order_delete_by_hash_str(l_net_buy, l_order_hash_str);
+                        DAP_DELETE(l_order_hash_str);
+                        return -15;
                     }
-                    // Update the order
-                    char *l_order_hash_str = dap_chain_hash_fast_to_str_new(&l_price->order_hash);
-                    dap_chain_net_srv_order_delete_by_hash_str(l_price->net_buy, l_order_hash_str);
-                    DAP_DELETE(l_order_hash_str);
-                    l_order_hash_str = s_xchange_order_create(l_price, l_tx);
-                    if (l_order_hash_str) {
-                        dap_chain_str_to_hash_fast(l_order_hash_str, &l_price->order_hash);
-                        if(!s_xchange_tx_put(l_tx, l_net_buy)) {
-                            dap_chain_node_cli_set_reply_text(a_str_reply, "Can't put transaction to mempool/chains");
-                            dap_chain_net_srv_order_delete_by_hash_str(l_net_buy, l_order_hash_str);
-                            break;
-                        } else {
-                            dap_chain_node_cli_set_reply_text(a_str_reply, "Successfully created order %s", l_order_hash_str);
-                        }
+                    if (!s_xchange_db_add(l_price)) {
+                        dap_chain_node_cli_set_reply_text(a_str_reply, "Can't save price in database");
+                        dap_chain_net_srv_order_delete_by_hash_str(l_net_buy, l_order_hash_str);
                         DAP_DELETE(l_order_hash_str);
-                    } else {
-                        dap_chain_node_cli_set_reply_text(a_str_reply, "Can't compose the order");
-                        DAP_DELETE(l_price->key_ptr);
-                        DAP_DELETE(l_price);
-                        break;
+                        return -16;
                     }
-                    // Update the pricelist
-                    HASH_ADD_KEYPTR(hh, s_srv_xchange->pricelist, l_price->key_ptr, strlen(l_price->key_ptr), l_price);
+                    dap_chain_node_cli_set_reply_text(a_str_reply, "Successfully created order %s", l_order_hash_str);
+                    DAP_DELETE(l_order_hash_str);
+                } else {
+                    dap_chain_node_cli_set_reply_text(a_str_reply, "Can't compose the order");
+                    DAP_DELETE(l_price->key_ptr);
+                    DAP_DELETE(l_price);
+                    return -18;
                 }
-            } else {
-                dap_chain_node_cli_set_reply_text(a_str_reply, "Price with provided pair of token ticker + net name is not exist");
-                return -1;
+                // Update the pricelist
+                HASH_ADD_KEYPTR(hh, s_srv_xchange->pricelist, l_price->key_ptr, strlen(l_price->key_ptr), l_price);
             }
         } break;
         case CMD_LIST: {
@@ -700,10 +758,9 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c
             dap_string_t *l_reply_str = dap_string_new("");
             HASH_ITER(hh, s_srv_xchange->pricelist, l_price, l_tmp) {
                 char *l_order_hash_str = dap_chain_hash_fast_to_str_new(&l_price->order_hash);
-                long double l_rate = (long double)l_price->datoshi_sell / l_price->datoshi_buy;
                 dap_string_append_printf(l_reply_str, "%s\t%s\t%s\t%s\t%s\t%lu\t%ld\t%s\n", l_order_hash_str, l_price->token_sell,
                                          l_price->net_sell->pub.name, l_price->token_buy, l_price->net_buy->pub.name,
-                                         l_price->datoshi_sell, l_rate, l_price->wallet_str);
+                                         l_price->datoshi_sell, l_price->rate, l_price->wallet_str);
                 DAP_DELETE(l_order_hash_str);
             }
             if (!l_reply_str->len) {
@@ -769,10 +826,9 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void *a_arg_func, char *
                     continue;
                 // TODO add filters to list (tokens, network, etc.)
                 l_price = s_xchange_price_from_order(l_net, l_order);
-                long double l_rate = (long double)l_price->datoshi_buy / l_price->datoshi_sell;
-                dap_string_append_printf(l_reply_str, "%s\t%s\t%s\t%s\t%s\t%lu\t%ld\n", l_orders[i].key, l_price->token_buy,
-                                         l_price->net_buy->pub.name, l_price->token_sell, l_price->net_sell->pub.name,
-                                         l_price->datoshi_buy, l_rate);
+                dap_string_append_printf(l_reply_str, "%s\t%s\t%s\t%s\t%s\t%lu\t%ld\n", l_orders[i].key, l_price->token_sell,
+                                         l_price->net_sell->pub.name, l_price->token_buy, l_price->net_buy->pub.name,
+                                         l_price->datoshi_sell, l_price->rate);
                 DAP_DELETE(l_price);
             }
             dap_chain_global_db_objs_delete(l_orders, l_orders_count);
@@ -783,7 +839,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void *a_arg_func, char *
             *a_str_reply = dap_string_free(l_reply_str, false);
         } break;
         case CMD_PURCHASE: {
-            const char *l_net_str = NULL, *l_wallet_str = NULL, *l_order_hash_str = NULL, *l_val_buy_str = NULL;
+            const char *l_net_str = NULL, *l_wallet_str = NULL, *l_order_hash_str = NULL, *l_val_sell_str = NULL;
             l_arg_index++;
             dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
@@ -810,28 +866,24 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void *a_arg_func, char *
                 dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'purchase' required parameter -order");
                 return -12;
             }
-            dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-coins", &l_val_buy_str);
-            if (!l_val_buy_str) {
+            dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-coins", &l_val_sell_str);
+            if (!l_val_sell_str) {
                 dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'price create' required parameter -coins");
                 return -8;
             }
-            uint64_t l_datoshi_buy = strtoull(l_val_buy_str, NULL, 10);
-            if (!l_datoshi_buy) {
+            uint64_t l_datoshi_sell = strtoull(l_val_sell_str, NULL, 10);
+            if (!l_datoshi_sell) {
                 dap_chain_node_cli_set_reply_text(a_str_reply, "Format -coins <unsigned long long>");
                 return -9;
             }
             dap_chain_net_srv_order_t *l_order = dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_str);
             if (l_order) {
                 dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(l_net, l_order);
-                if (l_price->datoshi_buy != l_datoshi_buy) {
-                    long double l_rate = (long double)l_price->datoshi_buy / l_price->datoshi_sell;
-                    l_price->datoshi_buy = l_datoshi_buy;
-                    l_price->datoshi_sell = ceill(l_datoshi_buy * l_rate);
-                 }
+                l_price->datoshi_sell = l_datoshi_sell;
                 // Create conditional transaction
                 dap_chain_datum_tx_t *l_tx = s_xchange_tx_create_exchange(l_price, &l_order->tx_cond_hash, l_wallet);
                 if (l_tx && s_xchange_tx_put(l_tx, l_net)) {
-                    // TODO send request to seller to delete order & price
+                    // TODO send request to seller to update / delete order & price
                     dap_chain_net_srv_order_delete_by_hash_str(l_price->net_buy, l_order_hash_str);
                 }
                 DAP_DELETE(l_price);
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index 0ab6610b71c5dd5e0491d7e8021ec87045090b7d..f59791fea9c51326e5026278a59de60c0de0078a 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -28,6 +28,7 @@
 #include "dap_chain_net_srv_order.h"
 
 #define DAP_CHAIN_NET_SRV_XCHANGE_ID 0x2
+#define GROUP_LOCAL_XCHANGE "local.xchange"
 
 typedef struct dap_chain_net_srv_xchange_price {
     char *wallet_str;
@@ -36,13 +37,26 @@ typedef struct dap_chain_net_srv_xchange_price {
     uint64_t datoshi_sell;
     dap_chain_net_t *net_buy;
     char token_buy[DAP_CHAIN_TICKER_SIZE_MAX];
-    uint64_t datoshi_buy;
+    long double rate;
     dap_chain_hash_fast_t tx_hash;
     dap_chain_hash_fast_t order_hash;
     char *key_ptr;
     UT_hash_handle hh;
 } dap_chain_net_srv_xchange_price_t;
 
+typedef struct dap_chain_net_srv_xchange_db_item {
+    char token_sell[DAP_CHAIN_TICKER_SIZE_MAX];
+    char token_buy[DAP_CHAIN_TICKER_SIZE_MAX];
+    uint8_t padding[4];
+    uint64_t net_sell_id;
+    uint64_t net_buy_id;
+    uint64_t datoshi_sell;
+    long double rate;
+    dap_chain_hash_fast_t tx_hash;
+    dap_chain_hash_fast_t order_hash;
+    char wallet_str[];
+} DAP_ALIGN_PACKED dap_chain_net_srv_xchange_db_item_t;
+
 typedef struct dap_srv_xchange_order_ext {
     uint64_t net_sell_id;
     uint64_t datoshi_sell;