diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c
index cc62a48ac565f3d1d57b1321c1dd7d1cc237edce..64dd868c72117a9284d00d79badfd41853404ec6 100644
--- a/modules/chain/dap_chain.c
+++ b/modules/chain/dap_chain.c
@@ -542,6 +542,21 @@ bool dap_chain_has_file_store(dap_chain_t * a_chain)
 }
 
 
+/**
+ * @brief get type of chain
+ *
+ * @param l_chain
+ * @return char*
+ */
+const char *dap_chain_get_cs_type(dap_chain_t *l_chain)
+{
+    if (!l_chain){
+        log_it(L_DEBUG, "dap_get_chain_type. Chain object is 0");
+        return NULL;
+    }
+    return (const char *)DAP_CHAIN_PVT(l_chain)->cs_name;
+}
+
 /**
  * @brief dap_chain_save_all
  * @param l_chain
diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h
index 420891e4d07c07328bd160decab0b38d71772fad..9e9fb28cd6db8939bc608305ad91b1e089d64f00 100644
--- a/modules/chain/include/dap_chain.h
+++ b/modules/chain/include/dap_chain.h
@@ -29,9 +29,6 @@
 #include "dap_config.h"
 #include "dap_chain_common.h"
 #include "dap_chain_datum.h"
-#include "dap_chain_datum_tx.h"
-#include "dap_cert.h"
-#include "dap_global_db_cluster.h"
 
 typedef struct dap_chain dap_chain_t;
 
@@ -118,10 +115,6 @@ typedef void (*dap_chain_callback_notify_t)(void *a_arg, dap_chain_t *a_chain, d
 typedef uint64_t (*dap_chain_callback_get_count)(dap_chain_t *a_chain);
 typedef dap_list_t *(*dap_chain_callback_get_list)(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse);
 typedef dap_list_t *(*dap_chain_callback_get_poa_certs)(dap_chain_t *a_chain, size_t *a_auth_certs_count, uint16_t *count_verify);
-typedef void (*dap_chain_callback_set_min_validators_count)(dap_chain_t *a_chain,  uint16_t a_new_value);
-typedef uint256_t (*dap_chain_callback_get_minimum_fee)(dap_chain_t *a_chain);
-typedef uint256_t (*dap_chain_callback_get_collectiong_level)(dap_chain_t *a_chain);
-typedef dap_enc_key_t* (*dap_chain_callback_get_signing_certificate)(dap_chain_t *a_chain);
 typedef void (*dap_chain_callback_load_from_gdb)(dap_chain_t *a_chain);
 typedef uint256_t (*dap_chain_callback_calc_reward)(dap_chain_t *a_chain, dap_hash_fast_t *a_block_hash, dap_pkey_t *a_block_sign_pkey);
 
@@ -198,10 +191,6 @@ typedef struct dap_chain {
 
     // Consensus specific callbacks
     dap_chain_callback_get_poa_certs callback_get_poa_certs;
-    dap_chain_callback_set_min_validators_count callback_set_min_validators_count;
-    dap_chain_callback_get_minimum_fee callback_get_minimum_fee;
-    dap_chain_callback_get_collectiong_level callback_get_collectiong_level;
-    dap_chain_callback_get_signing_certificate callback_get_signing_certificate;
     dap_chain_callback_calc_reward callback_calc_reward;
     dap_chain_callback_load_from_gdb callback_load_from_gdb;
 
@@ -269,5 +258,5 @@ DAP_STATIC_INLINE bool dap_chain_get_atom_last_hash(dap_chain_t *a_chain, dap_ch
 }
 ssize_t dap_chain_atom_save(dap_chain_cell_t *a_chain_cell, const uint8_t *a_atom, size_t a_atom_size, dap_hash_fast_t *a_new_atom_hash);
 int dap_cert_chain_file_save(dap_chain_datum_t *datum, char *net_name);
-const char* dap_chain_get_path(dap_chain_t *a_chain);
-
+const char *dap_chain_get_path(dap_chain_t *a_chain);
+const char *dap_chain_get_cs_type(dap_chain_t *l_chain);
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 23d3aaac5a2808a68dec9aac455be73aba851857..448a1e0a8dec601490c9089bd47243de23228037 100644
--- a/modules/channel/chain-net/dap_stream_ch_chain_net.c
+++ b/modules/channel/chain-net/dap_stream_ch_chain_net.c
@@ -43,10 +43,8 @@
 
 #include "dap_common.h"
 #include "dap_strfuncs.h"
-#include "dap_cert.h"
-#include "uthash.h"
-#include "dap_http_client.h"
-#include "dap_global_db.h"
+#include "dap_chain_cs_esbocs.h"
+#include "dap_chain_net_srv_order.h"
 #include "dap_stream.h"
 #include "dap_stream_ch_pkt.h"
 #include "dap_stream_ch_proc.h"
@@ -207,12 +205,12 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
                 log_it(L_ERROR, "Invalid net id in packet");
             } else {
                 dap_list_t * l_orders = NULL;
-                dap_enc_key_t * enc_key_pvt = NULL;
+                dap_enc_key_t *l_enc_key_pvt = NULL;
                 dap_chain_t *l_chain = NULL;
                 DL_FOREACH(l_net->pub.chains, l_chain)
-                    if(l_chain->callback_get_signing_certificate != NULL){
-                        enc_key_pvt = l_chain->callback_get_signing_certificate(l_chain);
-                        if(enc_key_pvt)
+                    if (!dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) {
+                        l_enc_key_pvt = dap_chain_esbocs_get_sign_key(l_chain);
+                        if (l_enc_key_pvt)
                             break;
                     }
                 dap_sign_t *l_sign = NULL;
@@ -228,10 +226,9 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
                     .uint64 = dap_chain_net_get_cur_addr_int(l_net)
                 };
 
-                if(enc_key_pvt)
-                {
+                if (l_enc_key_pvt) {
                     flags = flags | F_CERT;//faund sert
-                    l_sign = dap_sign_create(enc_key_pvt, (uint8_t*)l_ch_chain_net_pkt->data,
+                    l_sign = dap_sign_create(l_enc_key_pvt, (uint8_t*)l_ch_chain_net_pkt->data,
                                            l_ch_chain_net_pkt->hdr.data_size, 0);
                     if(l_sign)
                     {
diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c
index 92343bb29cd12f60b7915b90cfae9f7d4d2cbb40..fe7747c57905df34bb39529dc193e66e7448a91c 100644
--- a/modules/common/dap_chain_common.c
+++ b/modules/common/dap_chain_common.c
@@ -71,7 +71,7 @@ size_t dap_chain_hash_slow_to_str( dap_chain_hash_slow_t *a_hash, char *a_str, s
  * @param a_addr
  * @return
  */
-char *dap_chain_addr_to_str(const dap_chain_addr_t *a_addr)
+const char *dap_chain_addr_to_str(const dap_chain_addr_t *a_addr)
 {
     dap_return_val_if_pass(!a_addr, NULL);
     if (dap_chain_addr_is_blank(a_addr))
diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c
index b1f7aec824abdaf6728ddc5366cafa4c64ce961d..b9911519508ef19a80130dbf663add20ad907bdd 100644
--- a/modules/common/dap_chain_datum.c
+++ b/modules/common/dap_chain_datum.c
@@ -161,7 +161,7 @@ void dap_chain_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_tok
             continue;
             case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK: {
                 dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_tsd_section = _dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t);
-                char *l_balance, *l_tmp = dap_uint256_to_char(l_tsd_section->emission_rate, &l_balance);
+                const char *l_balance, *l_tmp = dap_uint256_to_char(l_tsd_section->emission_rate, &l_balance);
                 dap_string_append_printf(a_str_out, "ticker_token_from: %s\nemission_rate: %s\n",
                                          l_tsd_section->ticker_token_from, l_balance);
             }continue;
@@ -429,7 +429,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                                         ((dap_chain_tx_in_t*)item)->header.tx_out_prev_idx);
             break;
         case TX_ITEM_TYPE_OUT_OLD: {
-            char *l_value_str = dap_uint256_to_char(
+            const char *l_value_str = dap_uint256_to_char(
                 dap_chain_uint256_from(((dap_chain_tx_out_old_t*)item)->header.value), NULL );
             dap_string_append_printf(a_str_out, "\t OUT OLD (64):\n"
                                                 "\t\t Value: %s (%"DAP_UINT64_FORMAT_U")\n"
@@ -439,7 +439,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                                         dap_chain_addr_to_str(&((dap_chain_tx_out_old_t*)item)->addr));
         } break;
         case TX_ITEM_TYPE_OUT: { // 256
-            char    *l_coins_str,
+            const char *l_coins_str,
                     *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_t*)item)->header.value, &l_coins_str),
                     *l_addr_str = dap_chain_addr_to_str(&((dap_chain_tx_out_t*)item)->addr);
             dap_string_append_printf(a_str_out, "\t OUT:\n"
@@ -502,7 +502,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
             dap_string_append_printf(a_str_out, "\tSender addr: %s\n", dap_chain_addr_to_str(&l_sender_addr));
         } break;
         case TX_ITEM_TYPE_RECEIPT: {
-            char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi, &l_coins_str);
+            const char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi, &l_coins_str);
             dap_string_append_printf(a_str_out, "\t Receipt:\n"
                                                 "\t\t size: %"DAP_UINT64_FORMAT_U"\n"
                                                 "\t\t ext size: %"DAP_UINT64_FORMAT_U"\n"
@@ -575,7 +575,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                                      ((dap_chain_tx_in_cond_t*)item)->header.tx_out_prev_idx);
             break;
         case TX_ITEM_TYPE_OUT_COND: {
-            char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_coins_str);
+            const char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_coins_str);
             dap_time_t l_ts_exp = ((dap_chain_tx_out_cond_t*)item)->header.ts_expires;
             dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_exp);
             dap_string_append_printf(a_str_out, "\t OUT COND:\n"
@@ -589,7 +589,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                                      ((dap_chain_tx_out_cond_t*)item)->header.srv_uid.uint64);
             switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) {
                 case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: {
-                    char *l_coins_str, *l_value_str =
+                    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_str = dap_strcmp(a_hash_out_type, "hex")
@@ -618,7 +618,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                                                         NODE_ADDR_FP_ARGS(l_signer_node_addr));
                 } break;
                 case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: {
-                    char *l_rate_str, *l_tmp_str =
+                    const char *l_rate_str, *l_tmp_str =
                         dap_uint256_to_char( (((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.rate), &l_rate_str );
                     dap_string_append_printf(a_str_out, "\t\t\t net id: 0x%016"DAP_UINT64_FORMAT_x"\n"
                                                         "\t\t\t buy_token: %s\n"
@@ -636,7 +636,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
             }
         } break;
         case TX_ITEM_TYPE_OUT_EXT: {
-            char *l_coins_str, *l_value_str = dap_uint256_to_char( ((dap_chain_tx_out_ext_t*)item)->header.value, &l_coins_str );
+            const char *l_coins_str, *l_value_str = dap_uint256_to_char( ((dap_chain_tx_out_ext_t*)item)->header.value, &l_coins_str);
             dap_string_append_printf(a_str_out, "\t OUT EXT:\n"
                                                 "\t\t Addr: %s\n"
                                                 "\t\t Token: %s\n"
@@ -819,7 +819,7 @@ void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, c
         case DAP_CHAIN_DATUM_TOKEN_EMISSION: {
             size_t l_emission_size = a_datum->header.data_size;
             dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_datum->data, &l_emission_size);
-            char *l_coins_str, *l_value_str = dap_uint256_to_char(l_emission->hdr.value, &l_coins_str);
+            const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_emission->hdr.value, &l_coins_str);
             dap_string_append_printf(a_str_out, "emission: hash %s\n\t%s(%s) %s, type: %s, version: %d\n",
                                     l_hash_str,
                                     l_coins_str,
diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c
index 6920023a493e992d1188653a5ccb0a2d7affe229..d3c060befb1979d4b2000ffe260d107b9a04c7de 100644
--- a/modules/common/dap_chain_datum_decree.c
+++ b/modules/common/dap_chain_datum_decree.c
@@ -41,11 +41,7 @@
 
 dap_sign_t *dap_chain_datum_decree_get_signs(dap_chain_datum_decree_t *a_decree, size_t* a_signs_size)
 {
-    if (!a_decree || !a_signs_size) {
-        log_it(L_CRITICAL, "Invalid arguments");
-        return NULL;
-    }
-
+    dap_return_val_if_fail(a_decree && a_signs_size, NULL);
     dap_sign_t *l_signs_section = (dap_sign_t*)(a_decree->data_n_signs + a_decree->header.data_size);
     *a_signs_size = a_decree->header.signs_size;
     return l_signs_section;
@@ -53,29 +49,23 @@ dap_sign_t *dap_chain_datum_decree_get_signs(dap_chain_datum_decree_t *a_decree,
 
 int dap_chain_datum_decree_get_fee(dap_chain_datum_decree_t *a_decree, uint256_t *a_fee_value)
 {
-    if(!a_decree || !a_fee_value) {
-        log_it(L_CRITICAL, "Invalid arguments");
-        return -1;
-    }
-    dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE);
-    return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_fee_value); 0; }) : 1;
+    dap_return_val_if_fail(a_decree && a_fee_value, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE);
+    return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_fee_value); 0; }) : 1;
 }
 
 int dap_chain_datum_decree_get_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_value)
 {
     dap_return_val_if_fail(a_decree && a_value, -1);
     dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE);
-    return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_value); 0; }) : 1;
+    return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_value); 0; }) : 1;
 }
 
 int dap_chain_datum_decree_get_fee_addr(dap_chain_datum_decree_t *a_decree, dap_chain_addr_t *a_fee_wallet)
 {
-    if(!a_decree || !a_fee_wallet) {
-        log_it(L_CRITICAL, "Invalid arguments");
-        return -1;
-    }
-    dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET);
-    return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_fee_wallet); 0; }) : 1;
+    dap_return_val_if_fail(a_decree && a_fee_wallet, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET);
+    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) {
@@ -84,10 +74,7 @@ static void *s_cb_copy_pkeys(const void *a_pkey, UNUSED_ARG void *a_data) {
 
 dap_list_t *dap_chain_datum_decree_get_owners(dap_chain_datum_decree_t *a_decree, uint16_t *a_owners_num)
 {
-    if(!a_decree || !a_owners_num){
-        log_it(L_CRITICAL, "Invalid arguments");
-        return NULL;
-    }
+    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);
     *a_owners_num = (uint16_t)dap_list_length(l_tsd_list);
     dap_list_t *l_ret = dap_list_copy_deep(l_tsd_list, s_cb_copy_pkeys, NULL);
@@ -95,77 +82,80 @@ dap_list_t *dap_chain_datum_decree_get_owners(dap_chain_datum_decree_t *a_decree
     return l_ret;
 }
 
-int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, uint16_t *a_min_owners_num)
+int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_owners_num)
 {
-    if(!a_decree || !a_min_owners_num){
-        log_it(L_CRITICAL, "Invalid arguments");
-        return -1;
-    }
-    dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER);
-    return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_min_owners_num); 0; }) : 1;
+    dap_return_val_if_fail(a_decree && a_min_owners_num, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER);
+    return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_min_owners_num); 0; }) : 1;
 }
 
-int dap_chain_datum_decree_get_stake_tx_hash(dap_chain_datum_decree_t *a_decree, dap_hash_fast_t *a_tx_hash)
+int dap_chain_datum_decree_get_hash(dap_chain_datum_decree_t *a_decree, dap_hash_fast_t *a_tx_hash)
 {
-    if(!a_decree || !a_tx_hash){
-        log_it(L_CRITICAL, "Invalid arguments");
-        return -1;
-    }
-    dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH);
-    return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_tx_hash); 0; }) : 1;
+    dap_return_val_if_fail(a_decree && a_tx_hash, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH);
+    return l_tsd && l_tsd->size == sizeof(dap_hash_fast_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_tx_hash); 0; }) : 1;
 }
 
 int dap_chain_datum_decree_get_stake_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_stake_value)
 {
-    if(!a_decree || !a_stake_value){
-        log_it(L_CRITICAL, "Invalid arguments");
-        return -1;
-    }
-    dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE);
-    return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_stake_value); 0; }) : 1;
+    dap_return_val_if_fail(a_decree && a_stake_value, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE);
+    return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_stake_value); 0; }) : 1;
 }
 
 int dap_chain_datum_decree_get_stake_signing_addr(dap_chain_datum_decree_t *a_decree, dap_chain_addr_t *a_signing_addr)
 {
-    if(!a_decree || !a_signing_addr){
-        log_it(L_CRITICAL, "Invalid arguments");
-        return -1;
-    }
-    dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR);
-    return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_signing_addr); 0; }) : 1;
+    dap_return_val_if_fail(a_decree && a_signing_addr, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR);
+    return l_tsd && l_tsd->size == sizeof(dap_chain_addr_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_signing_addr); 0; }) : 1;
 }
 
 int dap_chain_datum_decree_get_stake_signer_node_addr(dap_chain_datum_decree_t *a_decree, dap_chain_node_addr_t *a_node_addr)
 {
-    if(!a_decree || !a_node_addr){
-        log_it(L_CRITICAL, "Invalid arguments");
-        return -1;
-    }
-    dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR);
-    return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_node_addr); 0; }) : 1;
+    dap_return_val_if_fail(a_decree && a_node_addr, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR);
+    return l_tsd && l_tsd->size == sizeof(dap_chain_node_addr_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_node_addr); 0; }) : 1;
 }
 
 int dap_chain_datum_decree_get_stake_min_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_value)
 {
-    if(!a_decree || !a_min_value){
-        log_it(L_CRITICAL, "Invalid arguments");
-        return -1;
-    }
-    dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE);
-    return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_min_value); 0; }) : 1;
+    dap_return_val_if_fail(a_decree && a_min_value, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE);
+    return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_min_value); 0; }) : 1;
 }
 
 int dap_chain_datum_decree_get_stake_min_signers_count(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_signers_count)
 {
-    if(!a_decree || !a_min_signers_count){
-        log_it(L_CRITICAL, "Invalid arguments");
-        return -1;
-    }
-    dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT);
-    return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_min_signers_count); 0; }) : 1;
+    dap_return_val_if_fail(a_decree && a_min_signers_count, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT);
+    return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_min_signers_count); 0; }) : 1;
+}
+
+int dap_chain_datum_decree_get_action(dap_chain_datum_decree_t *a_decree, uint8_t *a_action)
+{
+    dap_return_val_if_fail(a_decree && a_action, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION);
+    return l_tsd && l_tsd->size == sizeof(uint8_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_action); 0; }) : 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) {
+int dap_chain_datum_decree_get_signature_type(dap_chain_datum_decree_t *a_decree, uint32_t *a_signature_type)
+{
+    dap_return_val_if_fail(a_decree && a_signature_type, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE);
+    return l_tsd && l_tsd->size == sizeof(uint32_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_signature_type); 0; }) : 1;
+}
+
+int dap_chain_datum_decree_get_ban_addr(dap_chain_datum_decree_t *a_decree, const char **a_addr)
+{
+    dap_return_val_if_fail(a_decree && a_addr, -1);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST);
+    if (!l_tsd)
+        l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR);
+    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)
     {
@@ -193,7 +183,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 }
                 uint256_t l_value = uint256_0;
                 _dap_tsd_get_scalar(l_tsd, &l_value);
-                char *l_value_str = dap_uint256_to_char(l_value, NULL);
+                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:
@@ -205,7 +195,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 }
                 uint256_t l_fee_value = uint256_0;
                 _dap_tsd_get_scalar(l_tsd, &l_fee_value);
-                char *l_fee_value_str = dap_uint256_to_char(l_fee_value, NULL);
+                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:
@@ -220,13 +210,13 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 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)){
+                if (l_tsd->size != sizeof(uint32_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);
-                char *l_owner_min_str = dap_uint256_to_char(l_owner_min, NULL);
+                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:
@@ -238,9 +228,9 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 _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(l_addr_fee_wallet));
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH:
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH:
                 if (l_tsd->size > sizeof(dap_hash_fast_t)) {
-                    dap_string_append_printf(a_str_out, "\tStake tx: <WRONG SIZE>\n");
+                    dap_string_append_printf(a_str_out, "\tHash: <WRONG SIZE>\n");
                     break;
                 }
                 dap_hash_fast_t *l_stake_tx = /*{ };
@@ -248,7 +238,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 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, "\tStake tx: %s\n", l_stake_tx_hash);
+                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)){
@@ -257,7 +247,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 }
                 uint256_t l_stake_value = uint256_0;
                 _dap_tsd_get_scalar(l_tsd, &l_stake_value);
-                char *l_stake_value_str = dap_uint256_to_char(l_stake_value, NULL);
+                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:
@@ -275,6 +265,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 dap_string_append_printf(a_str_out, "\tSigning pkey fingerprint: %s\n", l_pkey_signing_str);
                 break;
             case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR:
+            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;
@@ -290,7 +281,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 }
                 uint256_t l_min_value = uint256_0;
                 _dap_tsd_get_scalar(l_tsd, &l_min_value);
-                char *l_min_value_str = dap_uint256_to_char(l_min_value, NULL);
+                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:
@@ -300,13 +291,31 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 }
                 uint256_t l_min_signers_count = uint256_0;
                 _dap_tsd_get_scalar(l_tsd, &l_min_signers_count);
-                char *l_min_signers_count_str = dap_uint256_to_char(l_min_signers_count, NULL);
+                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_NODE_ADDR: {
-                dap_string_append_printf(a_str_out, "\tNode address: %s\n", dap_tsd_get_string(l_tsd));
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST: {
+                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;
@@ -349,30 +358,52 @@ void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_sign
     }
 }
 
-dap_chain_datum_decree_t* dap_chain_datum_decree_sign_in_cycle(dap_cert_t ** a_certs, dap_chain_datum_decree_t *a_datum_decree,
+dap_chain_datum_decree_t *dap_chain_datum_decree_new(dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id,
+                                                     dap_chain_cell_id_t a_cell_id, size_t a_total_tsd_size)
+{
+    dap_chain_datum_decree_t *l_decree = NULL;
+    DAP_NEW_Z_SIZE_RET_VAL(l_decree, dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + a_total_tsd_size, NULL, NULL);
+
+    l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION;
+    l_decree->header.ts_created = dap_time_now();
+    l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON;
+    l_decree->header.common_decree_params.net_id = a_net_id;
+    l_decree->header.common_decree_params.chain_id = a_chain_id;
+    l_decree->header.common_decree_params.cell_id = a_cell_id;
+    l_decree->header.data_size = a_total_tsd_size;
+    return l_decree;
+}
+
+dap_chain_datum_decree_t *dap_chain_datum_decree_sign_in_cycle(dap_cert_t **a_certs, dap_chain_datum_decree_t *a_datum_decree,
                                                   size_t a_certs_count, size_t *a_total_sign_count)
 {
     size_t l_cur_sign_offset = a_datum_decree->header.data_size + a_datum_decree->header.signs_size;
     size_t l_total_signs_size = a_datum_decree->header.signs_size, l_total_sign_count = 0;
 
-    for(size_t i = 0; i < a_certs_count; i++)
-    {
-        dap_sign_t * l_sign = dap_cert_sign(a_certs[i],  a_datum_decree,
+    for(size_t i = 0; i < a_certs_count; i++) {
+        dap_sign_t * l_sign = dap_cert_sign(a_certs[i], a_datum_decree,
                                             sizeof(dap_chain_datum_decree_t) + a_datum_decree->header.data_size, 0);
-
-        if (l_sign) {
-            size_t l_sign_size = dap_sign_get_size(l_sign);
-            a_datum_decree = DAP_REALLOC(a_datum_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size);
-            memcpy((byte_t*)a_datum_decree->data_n_signs + l_cur_sign_offset, l_sign, l_sign_size);
-            l_total_signs_size += l_sign_size;
-            l_cur_sign_offset += l_sign_size;
-            a_datum_decree->header.signs_size = l_total_signs_size;
+        if (!l_sign) {
+            log_it(L_ERROR, "Decree signing failed");
+            DAP_DELETE(a_datum_decree);
+            return NULL;
+        }
+        size_t l_sign_size = dap_sign_get_size(l_sign);
+        a_datum_decree = DAP_REALLOC(a_datum_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size);
+        if (!a_datum_decree) {
+            log_it(L_CRITICAL, "%s", g_error_memory_alloc);
             DAP_DELETE(l_sign);
-            log_it(L_DEBUG,"<-- Signed with '%s'", a_certs[i]->name);
-            l_total_sign_count++;
+            return NULL;
         }
+        memcpy(a_datum_decree->data_n_signs + l_cur_sign_offset, l_sign, l_sign_size);
+        DAP_DELETE(l_sign);
+        l_total_signs_size += l_sign_size;
+        l_cur_sign_offset += l_sign_size;
+        a_datum_decree->header.signs_size = l_total_signs_size;
+        log_it(L_DEBUG,"<-- Signed with '%s'", a_certs[i]->name);
+        l_total_sign_count++;
     }
-
-    *a_total_sign_count = l_total_sign_count;
+    if (a_total_sign_count)
+        *a_total_sign_count = l_total_sign_count;
     return a_datum_decree;
 }
diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h
index fe9cebf3cc00646789cb6f1b5ecf23ba3e1d967c..a6e9143468133b9c46045e0af2ee24082f0f2550 100644
--- a/modules/common/include/dap_chain_common.h
+++ b/modules/common/include/dap_chain_common.h
@@ -30,10 +30,8 @@
 #include "dap_math_ops.h"
 #include "dap_math_convert.h"
 #include "dap_enc_key.h"
-#include "dap_pkey.h"
 #include "dap_sign.h"
 #include "dap_hash.h"
-#include "json.h"
 #include "dap_strfuncs.h"
 
 #define DAP_CHAIN_ADDR_VERSION_CURRENT 1
@@ -200,7 +198,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);
 
-char* dap_chain_addr_to_str(const dap_chain_addr_t *a_addr);
+const char *dap_chain_addr_to_str(const dap_chain_addr_t *a_addr);
 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 c3be81a88aeea7a52b0a01a1d98a3ccd6aabb8da..f7fc580471492ed2bc6d841ebceae598492552ed 100644
--- a/modules/common/include/dap_chain_datum.h
+++ b/modules/common/include/dap_chain_datum.h
@@ -25,11 +25,9 @@
 #pragma once
 #include <stdint.h>
 #include "dap_common.h"
-#include "dap_math_ops.h"
 #include "dap_chain_common.h"
 #include "dap_chain_datum_tx.h"
 #include "dap_chain_datum_token.h"
-#include "json.h"
 
 #define DAP_CHAIN_DATUM_VERSION 0x00
 
diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h
index 42964d99c508c3717876134c261584b57ca79b77..5c854559f72cbff9923db824f10552da10f147ad 100644
--- a/modules/common/include/dap_chain_datum_decree.h
+++ b/modules/common/include/dap_chain_datum_decree.h
@@ -26,7 +26,6 @@
 #include "dap_math_ops.h"
 #include "dap_time.h"
 #include "dap_list.h"
-#include "dap_tsd.h"
 #include "dap_cert.h"
 #include <stdint.h>
 
@@ -73,6 +72,9 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_
 #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN                           0x0009
 #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN                         0x000A
 #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD                        0x000B
+#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT                    0x000C
+#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS          0x000D
+#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE         0x000E
 
 // DECREE TSD types
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE                               0x0100
@@ -81,7 +83,7 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER                               0x0103
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER                           0x0104
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET                          0x0106
-#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH                       0x0107
+#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH                                0x0107
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE                         0x0108
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR                  0x0109
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR              0x0110
@@ -89,6 +91,8 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT             0x0112
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST                                0x0113
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR                           0x0115
+#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION                              0x010A
+#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE                      0x010B
 
 DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_decree_subtype)
 {
@@ -113,6 +117,12 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_d
         return "DECREE_COMMON_SUBTYPE_UNBAN";
     case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD:
         return "DECREE_COMMON_SUBTYPE_REWARD";
+    case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT:
+        return "DECREE_COMMON_SUBTYPE_VALIDATOR_MAX_WEIGHT";
+    case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS:
+        return "DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS";
+    case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE:
+        return "DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE";
     default:
         return "DECREE_SUBTYPE_UNKNOWN";
     }
@@ -120,39 +130,45 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_d
 
 DAP_STATIC_INLINE const char *dap_chain_datum_decree_tsd_type_to_str(uint16_t a_decree_tsd_type) {
     switch (a_decree_tsd_type) {
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST";
-        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
-            return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR";
-        default:
-            return "DECREE_TSD_TYPE_UNKNOWN";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION:
+         return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE:
+         return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE";
+    default:
+        return "DECREE_TSD_TYPE_UNKNOWN";
     }
 }
 
+dap_chain_datum_decree_t *dap_chain_datum_decree_new(dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id,
+                                                     dap_chain_cell_id_t a_cell_id, size_t a_total_tsd_size);
 /**
  * @brief dap_chain_datum_decree_get_signs
  * @param decree pointer to decree
@@ -192,7 +208,7 @@ dap_list_t *dap_chain_datum_decree_get_owners(dap_chain_datum_decree_t *a_decree
  * @param a_owners_num pointer to minimum number of owners buffer
  * @return result code. 0 - success
  */
-int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, uint16_t *a_min_owners_num);
+int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_owners_num);
 
 /**
  * @brief dap_chain_datum_decree_get_tx_hash get stake tx hash
@@ -200,7 +216,7 @@ int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, ui
  * @param a_tx_hash pointer to tx hash buffer
  * @return result code. 0 - success
  */
-int dap_chain_datum_decree_get_stake_tx_hash(dap_chain_datum_decree_t *a_decree, dap_hash_fast_t *a_tx_hash);
+int dap_chain_datum_decree_get_hash(dap_chain_datum_decree_t *a_decree, dap_hash_fast_t *a_tx_hash);
 
 /**
  * @brief dap_chain_datum_decree_get_stake_value get stake value
@@ -250,6 +266,9 @@ int dap_chain_datum_decree_get_stake_min_value(dap_chain_datum_decree_t *a_decre
  * @return result code. 0 - success
  */
 int dap_chain_datum_decree_get_stake_min_signers_count(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_signers_count);
+int dap_chain_datum_decree_get_action(dap_chain_datum_decree_t *a_decree, uint8_t *a_action);
+int dap_chain_datum_decree_get_signature_type(dap_chain_datum_decree_t *a_decree, uint32_t *a_signature_type);
+int dap_chain_datum_decree_get_ban_addr(dap_chain_datum_decree_t *a_decree, const char **a_addr);
 
 /**
  * @breif dap_chain_datum_decree_dump Dump information about decree
diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h
index 87776da8f6d5d02eda7f1b7206ea8799a39848c6..396fa43dfb9320f2d62c9a7d31b5b47471b340b3 100644
--- a/modules/common/include/dap_chain_datum_tx.h
+++ b/modules/common/include/dap_chain_datum_tx.h
@@ -27,7 +27,7 @@
 #include "dap_enc_key.h"
 #include "dap_chain_common.h"
 #include "dap_time.h"
-#include "json.h"
+#include "dap_pkey.h"
 
 /**
   * @struct dap_chain_datum_tx
diff --git a/modules/common/include/dap_chain_datum_tx_out_cond.h b/modules/common/include/dap_chain_datum_tx_out_cond.h
index 85414a2fabea9b3328bdd20e69617c86b0d6ca45..f8dd739dd37c84b8e468d0ddb64b269bbda41cb2 100644
--- a/modules/common/include/dap_chain_datum_tx_out_cond.h
+++ b/modules/common/include/dap_chain_datum_tx_out_cond.h
@@ -28,7 +28,6 @@
 #include "dap_common.h"
 #include "dap_time.h"
 #include "dap_chain_common.h"
-#include "dap_chain_datum_tx.h"
 
 enum dap_chain_tx_out_cond_subtype {
     DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED = 0x0,
diff --git a/modules/consensus/block-poa/dap_chain_cs_block_poa.c b/modules/consensus/block-poa/dap_chain_cs_block_poa.c
index 6498631906238d2b6540062ecd5d9e2e8519b1ae..46a6586ad7a31166ec56e69835ed28dc571dfc85 100644
--- a/modules/consensus/block-poa/dap_chain_cs_block_poa.c
+++ b/modules/consensus/block-poa/dap_chain_cs_block_poa.c
@@ -116,7 +116,7 @@ static int s_cli_block_poa(int argc, char ** argv, void **a_str_reply)
         return -3;
     }
 
-    const char *l_chain_type = dap_chain_net_get_type(l_chain);
+    const char *l_chain_type = dap_chain_get_cs_type(l_chain);
     if (strcmp(l_chain_type, "block_poa")){
             dap_cli_server_cmd_set_reply_text(a_str_reply,
                         "Type of chain %s is not block_poa. This chain with type %s is not supported by this command",
diff --git a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
index b4ed565db5542156be5c1b400e17857d64f6b08a..412e3813d3d1c5deaf6fd334edc9415e4f66a041 100644
--- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
+++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
@@ -194,7 +194,7 @@ static int s_cli_dag_poa(int argc, char ** argv, void **a_str_reply)
         return -3;
     }
 
-    const char *l_chain_type = dap_chain_net_get_type(l_chain);
+    const char *l_chain_type = dap_chain_get_cs_type(l_chain);
 
     if (strcmp(l_chain_type, "dag_poa")){
             dap_cli_server_cmd_set_reply_text(a_str_reply,
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index c21788121248dbed68ece4e08c73d33a39fe3263..db6cd9cb2ce2923c42ae1963151b8b2a8fa7fe1c 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -28,6 +28,7 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "rand/dap_rand.h"
 #include "dap_stream_ch_proc.h"
 #include "dap_chain_net.h"
+#include "dap_chain_net_srv_order.h"
 #include "dap_chain_common.h"
 #include "dap_chain_mempool.h"
 #include "dap_chain_cell.h"
@@ -36,7 +37,6 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_chain_cs_esbocs.h"
 #include "dap_chain_net_srv_stake_pos_delegate.h"
 #include "dap_chain_ledger.h"
-#include "dap_chain_node_cli.h"
 #include "dap_chain_node_cli_cmd.h"
 
 #define LOG_TAG "dap_chain_cs_esbocs"
@@ -79,12 +79,8 @@ static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks);
 static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cfg);
 static size_t s_callback_block_sign(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t **a_block_ptr, size_t a_block_size);
 static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t *a_block, size_t a_block_size);
-static uint256_t s_callback_get_minimum_fee(dap_chain_t *a_chain);
-static uint256_t s_callback_get_collectiong_level(dap_chain_t *a_chain);
-static dap_enc_key_t *s_callback_get_sign_key(dap_chain_t *a_chain);
-static void s_callback_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value);
 static void s_db_change_notifier(dap_store_obj_t *a_obj, void * a_arg);
-
+static dap_list_t *s_check_emergency_rights(dap_chain_esbocs_t *a_esbocs, dap_chain_addr_t *a_signing_addr);
 static int s_cli_esbocs(int a_argc, char **a_argv, void **a_str_reply);
 
 DAP_STATIC_INLINE const char *s_voting_msg_type_to_str(uint8_t a_type)
@@ -134,12 +130,12 @@ typedef struct dap_chain_esbocs_pvt {
     dap_hash_fast_t candidate_hash;
     // Validators section
     bool poa_mode;
-    uint16_t min_validators_count;
     uint16_t start_validators_min;
     // Debug flag
     bool debug;
     // Emergancy mode with signing by current online validators only
     bool emergency_mode;
+    dap_list_t *emergency_validator_addrs;
     // Round params
     uint16_t new_round_delay;
     uint16_t round_start_sync_timeout;
@@ -152,6 +148,9 @@ typedef struct dap_chain_esbocs_pvt {
     uint256_t minimum_fee;
     uint256_t collecting_level;
     dap_pkey_t *block_sign_pkey;
+    // Decree controoled params
+    uint16_t min_validators_count;
+    bool check_signs_structure;
 } dap_chain_esbocs_pvt_t;
 
 #define PVT(a) ((dap_chain_esbocs_pvt_t *)a->_pvt)
@@ -175,10 +174,18 @@ int dap_chain_cs_esbocs_init()
                            s_stream_ch_packet_in,
                            NULL);
     dap_cli_server_cmd_add ("esbocs", s_cli_esbocs, "ESBOCS commands",
-        "esbocs min_validators_count set -net <net_name> -chain <chain_name> -cert <poa_cert_name> -val_count <value>"
+        "esbocs min_validators_count set -net <net_name> -chain <chain_name> -cert <poa_cert_name> -val_count <value>\n"
             "\tSets minimum validators count for ESBOCS consensus\n"
-        "esbocs min_validators_count print -net <net_name> -chain <chain_name>"
-            "\tShow minimum validators count for ESBOCS consensus\n\n");
+        "esbocs min_validators_count show -net <net_name> -chain <chain_name>\n"
+            "\tShow minimum validators count for ESBOCS consensus\n"
+        "esbocs check_signs_structure {enable|disable} -net <net_name> -chain <chain_name> -cert <poa_cert_name>\n"
+            "\tEnables or disables checks for blocks signs structure validity\n"
+        "esbocs check_signs_structure show -net <net_name> -chain <chain_name>\n"
+            "\tShow status of checks for blocks signs structure validity\n"
+        "esbocs emergency_validator {add|remove} -net <net_name> -chain <chain_name> -cert <poa_cert_name> -pkey_hash <validator_pkey_hash>\n"
+            "\tAdd or remove validator by its signature public key hash to list of validators allowed to work in emergency mode\n"
+        "esbocs emergency_validator show -net <net_name> -chain <chain_name>\n"
+            "\tShow list of validators public key hashes allowed to work in emergency mode\n");
     return 0;
 }
 
@@ -202,11 +209,6 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg)
     l_blocks->callback_block_sign = s_callback_block_sign;
 
     l_esbocs->chain = a_chain;
-    a_chain->callback_set_min_validators_count = s_callback_set_min_validators_count;
-    a_chain->callback_get_minimum_fee = s_callback_get_minimum_fee;
-    a_chain->callback_get_collectiong_level = s_callback_get_collectiong_level;
-    a_chain->callback_get_signing_certificate = s_callback_get_sign_key;
-
     l_esbocs->_pvt = DAP_NEW_Z(dap_chain_esbocs_pvt_t);
     dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs);
     if (!l_esbocs_pvt) {
@@ -215,7 +217,6 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg)
         goto lb_err;
     }
     l_esbocs_pvt->debug = dap_config_get_item_bool_default(a_chain_cfg, "esbocs", "consensus_debug", false);
-    l_esbocs_pvt->emergency_mode = dap_config_get_item_bool_default(a_chain_cfg, "esbocs", "emergency_mode", false);
     l_esbocs_pvt->poa_mode = dap_config_get_item_bool_default(a_chain_cfg, "esbocs", "poa_mode", false);
     l_esbocs_pvt->round_start_sync_timeout = dap_config_get_item_uint16_default(a_chain_cfg, "esbocs", "round_start_sync_timeout", 15);
     l_esbocs_pvt->new_round_delay = dap_config_get_item_uint16_default(a_chain_cfg, "esbocs", "new_round_delay", 10);
@@ -232,15 +233,16 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg)
     const char *l_auth_certs_prefix = dap_config_get_item_str(a_chain_cfg, "esbocs", "auth_certs_prefix");
     uint16_t l_node_addrs_count;
     char **l_addrs = dap_config_get_array_str(a_chain_cfg, "esbocs", "validators_addrs", &l_node_addrs_count);
-    uint16_t l_auth_certs_count = l_node_addrs_count;
-    if (l_auth_certs_count < l_esbocs_pvt->min_validators_count) {
+    if (l_node_addrs_count < l_esbocs_pvt->min_validators_count) {
         l_ret = -2;
         goto lb_err;
     }
-    char l_cert_name[512];
-    dap_cert_t *l_cert_cur;
+    dap_chain_net_srv_stake_net_add(a_chain->net_id);
+    uint16_t l_auth_certs_count = dap_config_get_item_uint16_default(a_chain_cfg, "esbocs", "auth_certs_count", l_node_addrs_count);
     dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id);
     for (size_t i = 0; i < l_auth_certs_count; i++) {
+        char l_cert_name[512];
+        dap_cert_t *l_cert_cur;
         snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu", l_auth_certs_prefix, i);
         if ((l_cert_cur = dap_cert_find_by_name(l_cert_name)) == NULL) {
             snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu.pub", l_auth_certs_prefix, i);
@@ -253,13 +255,18 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg)
         dap_chain_addr_t l_signing_addr;
         log_it(L_NOTICE, "Initialized auth cert \"%s\"", l_cert_name);
         dap_chain_addr_fill_from_key(&l_signing_addr, l_cert_cur->enc_key, a_chain->net_id);
+
+        l_esbocs_pvt->emergency_validator_addrs = dap_list_append(l_esbocs_pvt->emergency_validator_addrs,
+                                                                  DAP_DUP(&l_signing_addr));
+        if (i >= l_node_addrs_count)
+            continue;
+
         dap_chain_node_addr_t l_signer_node_addr;
         if (dap_chain_node_addr_from_str(&l_signer_node_addr, l_addrs[i])) {
             log_it(L_ERROR, "Wrong address format, should be like 0123::4567::89AB::CDEF");
             l_ret = -4;
             goto lb_err;
         }
-
         dap_chain_esbocs_validator_t *l_validator = DAP_NEW_Z(dap_chain_esbocs_validator_t);
         if (!l_validator) {
         log_it(L_CRITICAL, "%s", g_error_memory_alloc);
@@ -275,7 +282,7 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg)
 
         if (!l_esbocs_pvt->poa_mode) { // auth certs in PoA mode will be first PoS validators keys
             dap_hash_fast_t l_stake_tx_hash = {};
-            uint256_t l_weight = dap_chain_net_srv_stake_get_allowed_min_value();
+            uint256_t l_weight = dap_chain_net_srv_stake_get_allowed_min_value(a_chain->net_id);
             dap_chain_net_srv_stake_key_delegate(l_net, &l_signing_addr, &l_stake_tx_hash,
                                                  l_weight, &l_signer_node_addr);
         }
@@ -461,7 +468,7 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf
     l_esbocs_pvt->collecting_addr = dap_chain_addr_from_str(dap_config_get_item_str(a_chain_net_cfg, "esbocs", "fee_addr"));
     l_esbocs_pvt->collecting_level = dap_chain_coins_to_balance(dap_config_get_item_str_default(a_chain_net_cfg, "esbocs", "set_collect_fee", "10.0"));
 
-    dap_list_t *l_validators = dap_chain_net_srv_stake_get_validators(a_chain->net_id, false);
+    dap_list_t *l_validators = dap_chain_net_srv_stake_get_validators(a_chain->net_id, false, NULL);
     for (dap_list_t *it = l_validators; it; it = it->next) {
         dap_stream_node_addr_t *l_addr = &((dap_chain_net_srv_stake_item_t *)it->data)->node_addr;
         dap_chain_net_add_validator_to_clusters(a_chain, l_addr);
@@ -519,8 +526,7 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf
 
     l_session->my_addr.uint64 = dap_chain_net_get_cur_addr_int(l_net);
     l_session->my_signing_addr = l_my_signing_addr;
-// TODO make correct link management w/o global DB cluster
-#ifdef DAP_CHAIN_CS_ESBOCS_DIRECTIVE_SUPPORT
+
     char *l_sync_group = s_get_penalty_group(l_net->pub.id);
     l_session->db_cluster = dap_global_db_cluster_add(dap_global_db_instance_get_default(), NULL,
                                                       dap_guuid_compose(l_net->pub.id.uint64, DAP_CHAIN_CLUSTER_ID_ESBOCS),
@@ -528,12 +534,16 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf
                                                       DAP_GDB_MEMBER_ROLE_NOBODY, DAP_CLUSTER_TYPE_AUTONOMIC);
     DAP_DELETE(l_sync_group);
     dap_global_db_cluster_add_notify_callback(l_session->db_cluster, s_db_change_notifier, l_session);
-#endif
     dap_link_manager_add_net_associate(l_net->pub.id.uint64, l_session->db_cluster->links_cluster);
 
+#ifdef DAP_CHAIN_CS_ESBOCS_DIRECTIVE_SUPPORT
+    dap_global_db_role_t l_directives_cluster_role_default = DAP_GDB_MEMBER_ROLE_ROOT;
+#else
+    dap_global_db_role_t l_directives_cluster_role_default = DAP_GDB_MEMBER_ROLE_GUEST;
+#endif
     for (dap_list_t *it = l_validators; it; it = it->next) {
         dap_stream_node_addr_t *l_addr = &((dap_chain_net_srv_stake_item_t *)it->data)->node_addr;
-        dap_global_db_cluster_member_add(l_session->db_cluster, l_addr, DAP_GDB_MEMBER_ROLE_ROOT);
+        dap_global_db_cluster_member_add(l_session->db_cluster, l_addr, l_directives_cluster_role_default);
     }
     dap_list_free_full(l_validators, NULL);
 
@@ -568,6 +578,11 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf
         log_it(L_ERROR, "No valid order found was signed by this validator deledgated key. Switch off validator mode.");
         return -4;
     }
+    l_esbocs_pvt->emergency_mode = dap_config_get_item_bool_default(a_chain_net_cfg, "esbocs", "emergency_mode", false);
+    if (l_esbocs_pvt->emergency_mode && !s_check_emergency_rights(l_esbocs, &l_my_signing_addr)) {
+        log_it(L_ERROR, "This validator is not allowed to work in emergency mode. Use special decree to supply it");
+        return -5;
+    }
     pthread_mutex_init(&l_session->mutex, NULL);
     dap_chain_add_callback_notify(a_chain, s_new_atom_notifier, l_session);
     s_session_round_new(l_session);
@@ -663,31 +678,86 @@ bool dap_chain_esbocs_remove_validator_from_clusters(dap_chain_net_id_t a_net_id
     return NULL;
 }
 
-static uint256_t s_callback_get_minimum_fee(dap_chain_t *a_chain)
+uint256_t dap_chain_esbocs_get_collecting_level(dap_chain_t *a_chain)
 {
+    dap_return_val_if_fail(a_chain && !strcmp(dap_chain_get_cs_type(a_chain), "esbocs"), uint256_0);
     dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
     dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks);
     dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs);
 
-    return l_esbocs_pvt->minimum_fee;
+    return l_esbocs_pvt->collecting_level;
 }
 
-static uint256_t s_callback_get_collectiong_level(dap_chain_t *a_chain)
+dap_enc_key_t *dap_chain_esbocs_get_sign_key(dap_chain_t *a_chain)
 {
+    dap_return_val_if_fail(a_chain && !strcmp(dap_chain_get_cs_type(a_chain), "esbocs"), NULL);
     dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
     dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks);
     dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs);
 
-    return l_esbocs_pvt->collecting_level;
+    return l_esbocs_pvt->blocks_sign_key;
 }
 
-static dap_enc_key_t *s_callback_get_sign_key(dap_chain_t *a_chain)
+int dap_chain_esbocs_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value)
 {
+    dap_return_val_if_fail(a_chain && !strcmp(dap_chain_get_cs_type(a_chain), "esbocs"), -1);
     dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
     dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks);
     dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs);
+    if (a_new_value)
+        l_esbocs_pvt->min_validators_count = a_new_value;
+    else {
+        dap_hash_fast_t l_stake_tx_hash = {};
+        dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id);
+        uint256_t l_weight = dap_chain_net_srv_stake_get_allowed_min_value(a_chain->net_id);
+        for (dap_list_t *it = l_esbocs_pvt->poa_validators; it; it = it->next) {
+            dap_chain_esbocs_validator_t *l_validator = it->data;
+            dap_chain_net_srv_stake_key_delegate(l_net, &l_validator->signing_addr, &l_stake_tx_hash,
+                                                 l_weight, &l_validator->node_addr);
+        }
+        l_esbocs_pvt->min_validators_count = l_esbocs_pvt->start_validators_min;
+    }
+    return 0;
+}
 
-    return l_esbocs_pvt->blocks_sign_key;
+int dap_chain_esbocs_set_signs_struct_check(dap_chain_t *a_chain, bool a_enable)
+{
+    dap_return_val_if_fail(a_chain && !strcmp(dap_chain_get_cs_type(a_chain), "esbocs"), -1);
+    dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
+    dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks);
+    dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs);
+    l_esbocs_pvt->check_signs_structure = a_enable;
+    return 0;
+}
+
+int dap_chain_esbocs_set_emergency_validator(dap_chain_t *a_chain, bool a_add, uint32_t a_sign_type, dap_hash_fast_t *a_validator_hash)
+{
+    dap_return_val_if_fail(a_chain && !strcmp(dap_chain_get_cs_type(a_chain), "esbocs"), -1);
+    dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
+    dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks);
+    dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs);
+    dap_chain_addr_t l_signing_addr;
+    dap_sign_type_t l_type = { .type = a_sign_type };
+    dap_chain_addr_fill(&l_signing_addr, l_type , a_validator_hash, a_chain->net_id);
+    if (a_add) {
+        if (s_check_emergency_rights(l_esbocs, &l_signing_addr))
+            return -2;
+        dap_chain_addr_t *l_addr_new = DAP_DUP(&l_signing_addr);
+        if (!l_addr_new) {
+            log_it(L_CRITICAL, "%s", g_error_memory_alloc);
+            return -4;
+        }
+        l_esbocs_pvt->emergency_validator_addrs = dap_list_append(
+                                    l_esbocs_pvt->emergency_validator_addrs, l_addr_new);
+    } else {
+        dap_list_t *l_to_remove = s_check_emergency_rights(l_esbocs, &l_signing_addr);
+        if (!l_to_remove)
+            return -3;
+        DAP_DELETE(l_to_remove->data);
+        l_esbocs_pvt->emergency_validator_addrs = dap_list_delete_link(
+                                    l_esbocs_pvt->emergency_validator_addrs, l_to_remove);
+    }
+    return 0;
 }
 
 static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks)
@@ -738,33 +808,30 @@ static void *s_callback_list_form(const void *a_srv_validator, UNUSED_ARG void *
     return l_validator;
 }
 
-static void s_callback_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value)
+static dap_list_t *s_get_validators_list(dap_chain_esbocs_t *a_esbocs, dap_hash_fast_t *a_last_hash, uint64_t a_skip_count,
+                                         uint16_t *a_excluded_list, uint16_t a_excluded_list_size)
 {
-    dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
-    dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks);
-    dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs);
-    if (a_new_value)
-        l_esbocs_pvt->min_validators_count = a_new_value;
-    else {
-        dap_hash_fast_t l_stake_tx_hash = {};
-        dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id);
-        uint256_t l_weight = dap_chain_net_srv_stake_get_allowed_min_value();
-        for (dap_list_t *it = l_esbocs_pvt->poa_validators; it; it = it->next) {
-            dap_chain_esbocs_validator_t *l_validator = it->data;
-            dap_chain_net_srv_stake_key_delegate(l_net, &l_validator->signing_addr, &l_stake_tx_hash,
-                                                 l_weight, &l_validator->node_addr);
-        }
-        l_esbocs_pvt->min_validators_count = l_esbocs_pvt->start_validators_min;
-    }
-}
-
-static dap_list_t *s_get_validators_list(dap_chain_esbocs_session_t *a_session, uint64_t a_skip_count)
-{
-    dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(a_session->esbocs);
+    dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(a_esbocs);
     dap_list_t *l_ret = NULL;
-
+    dap_list_t *l_validators = NULL;
     if (!l_esbocs_pvt->poa_mode) {
-        dap_list_t *l_validators = dap_chain_net_srv_stake_get_validators(a_session->chain->net_id, true);
+        if (a_excluded_list_size) {
+            l_validators =  dap_chain_net_srv_stake_get_validators(a_esbocs->chain->net_id, false, NULL);
+            uint16_t l_excluded_num = *a_excluded_list;
+            uint16_t l_excluded_list_idx = 0, l_validator_idx = 0;
+            dap_list_t *it, *tmp;
+            DL_FOREACH_SAFE(l_validators, it, tmp) {
+                if (l_validator_idx++ == l_excluded_num) {
+                    DAP_DELETE(it->data);
+                    l_validators = dap_list_delete_link(l_validators, it);
+                    if (l_excluded_list_idx == a_excluded_list_size - 1)
+                        break;
+                    l_excluded_num = a_excluded_list[++l_excluded_list_idx];
+                }
+            }
+        } else
+            l_validators = dap_chain_net_srv_stake_get_validators(a_esbocs->chain->net_id, true,
+                                                                  &a_esbocs->session->cur_round.excluded_list);
         uint16_t l_total_validators_count = dap_list_length(l_validators);
         if (l_total_validators_count < l_esbocs_pvt->min_validators_count) {
             log_it(L_MSG, "Can't start new round. Totally active validators count %hu is below minimum count %hu",
@@ -787,7 +854,7 @@ static dap_list_t *s_get_validators_list(dap_chain_esbocs_session_t *a_session,
         size_t l_consensus_optimum = (size_t)l_esbocs_pvt->min_validators_count * 2 - 1;
         size_t l_need_vld_cnt = dap_min(l_total_validators_count, l_consensus_optimum);
 
-        dap_pseudo_random_seed(*(uint256_t *)&a_session->cur_round.last_block_hash);
+        dap_pseudo_random_seed(*(uint256_t *)a_last_hash);
         for (uint64_t i = 0; i < a_skip_count * l_need_vld_cnt; i++)
             dap_pseudo_random_get(uint256_0, NULL);
         for (size_t l_current_vld_cnt = 0; l_current_vld_cnt < l_need_vld_cnt; l_current_vld_cnt++) {
@@ -795,11 +862,12 @@ static dap_list_t *s_get_validators_list(dap_chain_esbocs_session_t *a_session,
             uint256_t l_chosen_weight = dap_pseudo_random_get(l_total_weight, &l_raw_result);
             if (false) { //PVT(a_session->esbocs)->debug) {
                 unsigned l_strlen = 1024, l_off = 0;
-                char *l_chosen_weight_str, *l_total_weight_str, *l_raw_result_str, l_str[l_strlen];
+                const char *l_chosen_weight_str, *l_total_weight_str, *l_raw_result_str;
+                char l_str[l_strlen];
                 dap_uint256_to_char(l_chosen_weight, &l_chosen_weight_str);
                 l_off = dap_snprintf(l_str, l_strlen,
                                      "Round seed %s, sync attempt %"DAP_UINT64_FORMAT_U", chosen weight %s ",
-                                     dap_hash_fast_to_str_static(&a_session->cur_round.last_block_hash),
+                                     dap_hash_fast_to_str_static(a_last_hash),
                                      a_skip_count + 1, l_chosen_weight_str);
                 dap_uint256_to_char(l_total_weight, &l_total_weight_str);
                 l_off += dap_snprintf(l_str + l_off, l_strlen - l_off, "from %s, ", l_total_weight_str);
@@ -939,6 +1007,7 @@ static void s_session_round_clear(dap_chain_esbocs_session_t *a_session)
     dap_chain_esbocs_store_t *l_store_item, *l_store_tmp;
     HASH_ITER(hh, a_session->cur_round.store_items, l_store_item, l_store_tmp) {
         HASH_DEL(a_session->cur_round.store_items, l_store_item);
+        DAP_DEL_Z(l_store_item->candidate);
         dap_list_free_full(l_store_item->candidate_signs, NULL);
         DAP_DELETE(l_store_item);
     }
@@ -982,7 +1051,10 @@ static bool s_session_round_new(void *a_arg)
             a_session->cur_round.sync_attempt = 1;
     }
     if (!PVT(a_session->esbocs)->emergency_mode) {
-        a_session->cur_round.validators_list = s_get_validators_list(a_session, a_session->cur_round.sync_attempt - 1);
+        a_session->cur_round.validators_list = s_get_validators_list(a_session->esbocs,
+                                                                     &a_session->cur_round.last_block_hash,
+                                                                     a_session->cur_round.sync_attempt - 1,
+                                                                     NULL, 0);
         if (!a_session->cur_round.validators_list) {
             log_it(L_WARNING, "Minimum active validators not found");
             a_session->ts_round_sync_start = dap_time_now();
@@ -990,7 +1062,7 @@ static bool s_session_round_new(void *a_arg)
             return false;
         }
     }
-    dap_list_t *l_validators = dap_chain_net_srv_stake_get_validators(a_session->chain->net_id, false);
+    dap_list_t *l_validators = dap_chain_net_srv_stake_get_validators(a_session->chain->net_id, false, NULL);
     a_session->cur_round.all_validators = dap_list_copy_deep(l_validators, s_callback_list_form, NULL);
     dap_list_free_full(l_validators, NULL);
     bool l_round_already_started = a_session->round_fast_forward;
@@ -1459,20 +1531,34 @@ static void s_session_candidate_submit(dap_chain_esbocs_session_t *a_session)
 {
     dap_chain_t *l_chain = a_session->chain;
     dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain);
-    dap_chain_block_t *l_candidate;
     size_t l_candidate_size = 0;
     dap_hash_fast_t l_candidate_hash = {0};
     dap_chain_node_mempool_process_all(a_session->chain, false);
-    l_candidate = l_blocks->callback_new_block_move(l_blocks, &l_candidate_size);
-    if (l_candidate_size) {
-        dap_hash_fast(l_candidate, l_candidate_size, &l_candidate_hash);
-        if (PVT(a_session->esbocs)->debug) {
-            const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_candidate_hash);
-            log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu. Submit my candidate %s",
-                    a_session->chain->net_name, a_session->chain->name,
-                        a_session->cur_round.id, a_session->cur_round.attempt_num, l_candidate_hash_str);
+    dap_chain_block_t *l_candidate = l_blocks->callback_new_block_move(l_blocks, &l_candidate_size);
+    if (l_candidate && l_candidate_size) {
+        if (PVT(a_session->esbocs)->emergency_mode)
+            l_candidate_size = dap_chain_block_meta_add(&l_candidate, l_candidate_size, DAP_CHAIN_BLOCK_META_EMERGENCY, NULL, 0);
+        if (PVT(a_session->esbocs)->check_signs_structure && l_candidate_size) {
+            l_candidate_size = dap_chain_block_meta_add(&l_candidate, l_candidate_size, DAP_CHAIN_BLOCK_META_SYNC_ATTEMPT,
+                                                        &a_session->cur_round.sync_attempt, sizeof(uint64_t));
+            if (l_candidate_size)
+                l_candidate_size = dap_chain_block_meta_add(&l_candidate, l_candidate_size, DAP_CHAIN_BLOCK_META_ROUND_ATTEMPT,
+                                                            &a_session->cur_round.attempt_num, sizeof(uint8_t));
+            if (l_candidate_size)
+                 l_candidate_size = dap_chain_block_meta_add(&l_candidate, l_candidate_size, DAP_CHAIN_BLOCK_META_EXCLUDED_KEYS,
+                                                            a_session->cur_round.excluded_list, *a_session->cur_round.excluded_list * sizeof(uint16_t));
+        }
+        if (l_candidate_size) {
+            dap_hash_fast(l_candidate, l_candidate_size, &l_candidate_hash);
+            if (PVT(a_session->esbocs)->debug) {
+                const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_candidate_hash);
+                log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu. Submit my candidate %s",
+                        a_session->chain->net_name, a_session->chain->name,
+                            a_session->cur_round.id, a_session->cur_round.attempt_num, l_candidate_hash_str);
+            }
         }
-    } else { // there is no my candidate, send null hash
+    }
+    if (!l_candidate || !l_candidate_size) { // there is no my candidate, send null hash
         if (PVT(a_session->esbocs)->debug)
             log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
                           " I don't have a candidate. I submit a null candidate.",
@@ -1906,6 +1992,70 @@ static int s_session_directive_apply(dap_chain_esbocs_directive_t *a_directive,
     return 0;
 }
 
+DAP_STATIC_INLINE bool s_block_is_emergency(dap_chain_block_t *a_block, size_t a_block_size)
+{
+    return dap_chain_block_meta_get(a_block, a_block_size, DAP_CHAIN_BLOCK_META_EMERGENCY);
+}
+
+static dap_list_t *s_check_emergency_rights(dap_chain_esbocs_t *a_esbocs, dap_chain_addr_t *a_signing_addr)
+{
+    for (dap_list_t *it = PVT(a_esbocs)->emergency_validator_addrs; it; it = it->next) {
+        dap_chain_addr_t *l_authorized_pkey = it->data;
+        if (dap_chain_addr_compare(l_authorized_pkey, a_signing_addr))
+            return it;
+    }
+    return NULL;
+}
+
+static bool s_check_signing_rights(dap_chain_esbocs_t *a_esbocs, dap_chain_block_t *a_block, size_t a_block_size,
+                                   dap_chain_addr_t *a_signing_addr, bool a_first_sign)
+{
+    uint8_t *l_sync_attempt_ptr = dap_chain_block_meta_get(a_block, a_block_size, DAP_CHAIN_BLOCK_META_SYNC_ATTEMPT);
+    if (!l_sync_attempt_ptr) {
+        log_it(L_ERROR, "Can't get block metadata for SYNC_ATTEMPT");
+        return false;
+    }
+    uint64_t l_sync_attempt = *(uint64_t *)l_sync_attempt_ptr;
+    uint8_t l_round_attempt = 0;
+    if (a_first_sign) {
+        uint8_t *l_round_attempt_ptr = dap_chain_block_meta_get(a_block, a_block_size, DAP_CHAIN_BLOCK_META_ROUND_ATTEMPT);
+        if (!l_round_attempt_ptr) {
+            log_it(L_ERROR, "Can't get block metadata for ROUND_ATTEMPT");
+            return false;
+        }
+        l_round_attempt = *l_round_attempt_ptr;
+    }
+    dap_hash_fast_t *l_prev_hash_ptr = (dap_hash_fast_t *)dap_chain_block_meta_get(a_block, a_block_size, DAP_CHAIN_BLOCK_META_PREV);
+    if (!l_prev_hash_ptr) {
+        log_it(L_ERROR, "Can't get block metadata for PREV_HASH");
+        return false;
+    }
+    uint16_t *l_excluded_list = (uint16_t *)dap_chain_block_meta_get(a_block, a_block_size, DAP_CHAIN_BLOCK_META_EXCLUDED_KEYS);
+    if (!l_excluded_list) {
+        log_it(L_ERROR, "Can't get block metadata for EXCLUDED_KEYS");
+        return false;
+    }
+    dap_list_t *l_allowed_validators_list = s_get_validators_list(a_esbocs, l_prev_hash_ptr, l_sync_attempt - 1,
+                                                                  l_excluded_list + 1, *l_excluded_list);
+    if (!l_allowed_validators_list) {
+        log_it(L_ERROR, "Can't get block allowed validators list");
+        return false;
+    }
+    if (a_first_sign) {
+        size_t l_list_len = dap_list_length(l_allowed_validators_list);
+        if (l_list_len < l_round_attempt) {
+            log_it(L_ERROR, "Round attempt %hhu is greater than length of allowed validators list %zu",
+                                                l_round_attempt, l_list_len);
+            return false;
+        }
+        dap_chain_esbocs_validator_t *l_chosen_validator = dap_list_nth(l_allowed_validators_list, l_round_attempt)->data;
+        if (dap_chain_addr_compare(&l_chosen_validator->signing_addr, a_signing_addr))
+            return true;
+        return false;
+    }
+    return s_validator_check(a_signing_addr, l_allowed_validators_list);
+}
+
 struct esbocs_msg_args {
     dap_stream_node_addr_t addr_from;
     dap_chain_esbocs_session_t *session;
@@ -2111,7 +2261,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
     }
     if (l_not_in_list) {
         debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
-                                    " Message rejected: validator addr:%s not in the current validators list or not synced yet",
+                                    " Message rejected: validator key:%s not in the current validators list or not synced yet",
                                         l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id,
                                             l_message->hdr.attempt_num, l_validator_addr_str);
         goto session_unlock;
@@ -2198,13 +2348,25 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
     case DAP_CHAIN_ESBOCS_MSG_TYPE_SUBMIT: {
         uint8_t *l_candidate = l_message_data;
         size_t l_candidate_size = l_message_data_size;
+        // check submission rights
+        if (s_block_is_emergency((dap_chain_block_t *)l_candidate, l_candidate_size)) {
+            if (!s_check_emergency_rights(l_session->esbocs, &l_signing_addr)) {
+                debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
+                                            " Decline emergency SUBMIT candidate from not authorized validator %s",
+                                                l_session->chain->net_name, l_session->chain->name,
+                                                    l_session->cur_round.id, l_message->hdr.attempt_num,
+                                                        l_validator_addr_str);
+                break;
+            }
+            l_session->cur_round.attempt_submit_validator = l_signing_addr;
+        }
+        // check for NULL candidate
         if (!l_candidate_size || dap_hash_fast_is_blank(&l_message->hdr.candidate_hash)) {
             debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
                                         " Receive SUBMIT candidate NULL",
                                             l_session->chain->net_name, l_session->chain->name,
                                                 l_session->cur_round.id, l_message->hdr.attempt_num);
-            if (dap_chain_addr_compare(&l_session->cur_round.attempt_submit_validator, &l_signing_addr))
-                s_session_attempt_new(l_session);
+            s_session_attempt_new(l_session);
             break;
         }
         // check candidate hash
@@ -2212,12 +2374,11 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
         dap_hash_fast(l_candidate, l_candidate_size, &l_check_hash);
         if (!dap_hash_fast_compare(&l_check_hash, l_candidate_hash)) {
             debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
-                                        " Receive SUBMIT candidate hash broken",
+                                        " Decline SUBMIT candidate with broken hash",
                                             l_session->chain->net_name, l_session->chain->name,
                                                 l_session->cur_round.id, l_message->hdr.attempt_num);
             break;
         }
-
         if (l_cs_debug) {
             const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
             log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
@@ -2329,13 +2490,21 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
         if (!l_store) {
             l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
             log_it(L_WARNING, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
-                                " Receive COMMIT_SIGN message for unknown candidate %s",
+                                " Decline COMMIT_SIGN message for unknown candidate %s",
                                     l_session->chain->net_name, l_session->chain->name,
                                         l_session->cur_round.id, l_message->hdr.attempt_num,
                                             l_candidate_hash_str);
             break;
         }
-
+        dap_list_t *l_list = s_validator_check(&l_signing_addr, l_session->cur_round.validators_list);
+        if (!l_list) {
+            log_it(L_WARNING, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
+                                " Decline COMMIT_SIGN message for validator %s not present in current validator's list",
+                                    l_session->chain->net_name, l_session->chain->name,
+                                        l_session->cur_round.id, l_message->hdr.attempt_num,
+                                            l_validator_addr_str);
+            break;
+        }
         if (l_cs_debug) {
             l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
             log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
@@ -2343,26 +2512,25 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
                                 l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id,
                                     l_message->hdr.attempt_num, l_candidate_hash_str);
         }
-
+        // check candidate's sign
         size_t l_offset = dap_chain_block_get_sign_offset(l_store->candidate, l_store->candidate_size);
         int l_sign_verified = dap_sign_verify(l_candidate_sign, l_store->candidate,
                                                 l_offset + sizeof(l_store->candidate->hdr));
-        // check candidate's sign
-        if (!l_sign_verified) {
-            l_store->candidate_signs = dap_list_append(l_store->candidate_signs,
-                                                       DAP_DUP_SIZE(l_candidate_sign, l_candidate_sign_size));
-            if (dap_list_length(l_store->candidate_signs) == l_round->validators_synced_count) {
-                if (PVT(l_session->esbocs)->debug)
-                    log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
-                                  " Candidate %s collected signs of all synced validators",
-                                        l_session->chain->net_name, l_session->chain->name, l_round->id,
-                                            l_message->hdr.attempt_num, l_candidate_hash_str);
-                s_session_state_change(l_session, DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_FINISH, dap_time_now());
-            }
-        } else {
+        if (l_sign_verified != 0) {
             if (!l_candidate_hash_str)
                 l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
             log_it(L_WARNING, "Candidate: %s sign is incorrect: code %d", l_candidate_hash_str, l_sign_verified);
+            break;
+        }
+        l_store->candidate_signs = dap_list_append(l_store->candidate_signs,
+                                                   DAP_DUP_SIZE(l_candidate_sign, l_candidate_sign_size));
+        if (dap_list_length(l_store->candidate_signs) == l_round->validators_synced_count) {
+            if (PVT(l_session->esbocs)->debug)
+                log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
+                              " Candidate %s collected signs of all synced validators",
+                                    l_session->chain->net_name, l_session->chain->name, l_round->id,
+                                        l_message->hdr.attempt_num, l_candidate_hash_str);
+            s_session_state_change(l_session, DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_FINISH, dap_time_now());
         }
     } break;
 
@@ -2548,10 +2716,11 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl
         return  -7;
     }
 
-    /*if (a_block->hdr.meta_n_datum_n_signs_size != a_block_size - sizeof(a_block->hdr)) {
+    if (a_block->hdr.meta_n_datum_n_signs_size &&
+            a_block->hdr.meta_n_datum_n_signs_size != a_block_size - sizeof(a_block->hdr)) {
         log_it(L_WARNING, "Incorrect size with block %p on chain %s", a_block, a_blocks->chain->name);
         return -8;
-    }*/ // TODO Retun it after hard-fork with correct block sizes
+    }
 
     if (l_esbocs->session && l_esbocs->session->processing_candidate == a_block)
         // It's a block candidate, don't check signs
@@ -2581,17 +2750,17 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl
     int l_ret = 0;
     uint16_t l_signs_verified_count = 0;
     size_t l_block_excl_sign_size = dap_chain_block_get_sign_offset(a_block, a_block_size) + sizeof(a_block->hdr);
+    bool l_block_is_emergency = s_block_is_emergency(a_block, a_block_size);
     // Get the header on signing operation time
     size_t l_block_original = a_block->hdr.meta_n_datum_n_signs_size;
     a_block->hdr.meta_n_datum_n_signs_size = l_block_excl_sign_size - sizeof(a_block->hdr);
-    for (size_t i=0; i< l_signs_count; i++) {
-        dap_sign_t *l_sign = (dap_sign_t *)l_signs[i];
+    for (size_t i = 0; i < l_signs_count; i++) {
+        dap_sign_t *l_sign = l_signs[i];
         if (!dap_sign_verify_size(l_sign, a_block_size - l_block_excl_sign_size + sizeof(a_block->hdr))) {
             log_it(L_ERROR, "Corrupted block: sign size is bigger than block size");
             l_ret = -3;
             break;
         }
-
         dap_chain_addr_t l_signing_addr;
         dap_chain_addr_fill_from_sign(&l_signing_addr, l_sign, a_blocks->chain->net_id);
         if (!l_esbocs_pvt->poa_mode) {
@@ -2609,6 +2778,35 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl
                 continue;
             }
         }
+        if (i == 0) {
+            if (l_block_is_emergency && !s_check_emergency_rights(l_esbocs, &l_signing_addr)) {
+                log_it(L_ATT, "Restricted emergency block submitter %s",
+                                dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast));
+                l_ret = -5;
+                break;
+            } else if (l_esbocs_pvt->check_signs_structure &&
+                       !s_check_signing_rights(l_esbocs, a_block, a_block_size, &l_signing_addr, true)) {
+                log_it(L_ATT, "Restricted block submitter %s",
+                                dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast));
+                l_ret = -5;
+                break;
+            }
+        } else {
+            if (l_block_is_emergency && !s_check_emergency_rights(l_esbocs, &l_signing_addr) &&
+                    l_esbocs_pvt->check_signs_structure &&
+                    !s_check_signing_rights(l_esbocs, a_block, a_block_size, &l_signing_addr, false)) {
+                log_it(L_ATT, "Restricted emergency block signer %s",
+                                dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast));
+                l_ret = -5;
+                break;
+            } else if (l_esbocs_pvt->check_signs_structure &&
+                    !s_check_signing_rights(l_esbocs, a_block, a_block_size, &l_signing_addr, false)) {
+                log_it(L_ATT, "Restricted block signer %s",
+                                dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast));
+                l_ret = -5;
+                break;
+            }
+        }
         if (!dap_sign_verify(l_sign, a_block, l_block_excl_sign_size))
             l_signs_verified_count++;
     }
@@ -2647,73 +2845,56 @@ static dap_chain_datum_decree_t *s_esbocs_decree_set_min_validators_count(dap_ch
                                                                           uint256_t a_value, dap_cert_t *a_cert)
 {
     size_t l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint256_t);
-    dap_chain_datum_decree_t *l_decree = NULL;
-    dap_list_t *l_tsd_list = NULL;
-    dap_tsd_t *l_tsd = NULL;
-// memory alloc
-    DAP_NEW_Z_SIZE_RET_VAL(l_tsd, dap_tsd_t, l_total_tsd_size, NULL, NULL);
-    DAP_NEW_Z_SIZE_RET_VAL(l_decree, dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size, NULL, l_tsd);
-
-    l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT;
-    l_tsd->size = sizeof(uint256_t);
-    *(uint256_t*)(l_tsd->data) = a_value;
-    l_tsd_list = dap_list_append(l_tsd_list, l_tsd);
-
-    l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION;
-    l_decree->header.ts_created = dap_time_now();
-    l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON;
-    l_decree->header.common_decree_params.net_id = a_net->pub.id;
-    dap_chain_t *l_chain = a_chain;
-    if (!a_chain)
-        l_chain = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR);
-    if(!l_chain){
-        log_it(L_ERROR, "Can't find chain with anchor support.");
-        dap_list_free_full(l_tsd_list, NULL);
-        DAP_DELETE(l_decree);
+    dap_chain_datum_decree_t *l_decree = dap_chain_datum_decree_new(a_net->pub.id, a_chain->id,
+                                                                    *dap_chain_net_get_cur_cell(a_net), l_total_tsd_size);
+    if (!l_decree)
         return NULL;
-    }
-    l_decree->header.common_decree_params.chain_id = l_chain->id;
-    l_decree->header.common_decree_params.cell_id = *dap_chain_net_get_cur_cell(a_net);
     l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT;
-    l_decree->header.data_size = l_total_tsd_size;
-    l_decree->header.signs_size = 0;
-
-    size_t l_data_tsd_offset = 0;
-    for ( dap_list_t* l_iter=dap_list_first(l_tsd_list); l_iter; l_iter=l_iter->next){
-        dap_tsd_t * l_b_tsd = (dap_tsd_t *) l_iter->data;
-        size_t l_tsd_size = dap_tsd_size(l_b_tsd);
-        memcpy((byte_t*)l_decree->data_n_signs + l_data_tsd_offset, l_b_tsd, l_tsd_size);
-        l_data_tsd_offset += l_tsd_size;
-    }
-    dap_list_free_full(l_tsd_list, NULL);
-
-    size_t l_cur_sign_offset = l_decree->header.data_size + l_decree->header.signs_size;
-    size_t l_total_signs_size = l_decree->header.signs_size;
+    dap_tsd_write(l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT, &a_value, sizeof(uint256_t));
+    return dap_chain_datum_decree_sign_in_cycle(&a_cert, l_decree, 1, NULL);
+}
 
-    dap_sign_t * l_sign = dap_cert_sign(a_cert,  l_decree,
-       sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size, 0);
+static dap_chain_datum_decree_t *s_esbocs_decree_set_signs_check(dap_chain_net_t *a_net, dap_chain_t *a_chain,
+                                                                 bool a_enable, dap_cert_t *a_cert)
+{
+    size_t l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint8_t);
+    dap_chain_datum_decree_t *l_decree = dap_chain_datum_decree_new(a_net->pub.id, a_chain->id,
+                                                                    *dap_chain_net_get_cur_cell(a_net), l_total_tsd_size);
+    if (!l_decree)
+        return NULL;
+    l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE;
+    uint8_t l_data = a_enable ? 1 : 0;
+    dap_tsd_write(l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION, &l_data, sizeof(uint8_t));
+    return dap_chain_datum_decree_sign_in_cycle(&a_cert, l_decree, 1, NULL);
+}
 
-    if (l_sign) {
-        size_t l_sign_size = dap_sign_get_size(l_sign);
-        l_decree = DAP_REALLOC(l_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size);
-        if (!l_decree) {
-            log_it(L_CRITICAL, "%s", g_error_memory_alloc);
-            DAP_DELETE(l_sign);
-            return NULL;
-        }
-        memcpy((byte_t*)l_decree->data_n_signs + l_cur_sign_offset, l_sign, l_sign_size);
-        l_total_signs_size += l_sign_size;
-        l_cur_sign_offset += l_sign_size;
-        l_decree->header.signs_size = l_total_signs_size;
-        DAP_DELETE(l_sign);
-        log_it(L_DEBUG,"<-- Signed with '%s'", a_cert->name);
-    }else{
-        log_it(L_ERROR, "Decree signing failed");
-        DAP_DELETE(l_decree);
+static dap_chain_datum_decree_t *s_esbocs_decree_set_emergency_validator(dap_chain_net_t *a_net, dap_chain_t *a_chain,
+                                                                         dap_hash_fast_t *a_pkey_hash, dap_sign_type_t a_sign_type,
+                                                                         bool a_add, dap_cert_t *a_cert)
+{
+    size_t l_total_tsd_size = sizeof(dap_tsd_t) * 3 + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(dap_hash_fast_t);
+    dap_chain_datum_decree_t *l_decree = dap_chain_datum_decree_new(a_net->pub.id, a_chain->id,
+                                                                    *dap_chain_net_get_cur_cell(a_net), l_total_tsd_size);
+    if (!l_decree)
         return NULL;
-    }
+    l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS;
+    uint8_t l_data = a_add ? 1 : 0;
+    byte_t *l_ptr = dap_tsd_write(l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION, &l_data, sizeof(uint8_t));
+    uint32_t l_type_numeric = a_sign_type.type;
+    l_ptr = dap_tsd_write(l_ptr, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE, &l_type_numeric, sizeof(uint32_t));
+    dap_tsd_write(l_ptr, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH, a_pkey_hash, sizeof(dap_hash_fast_t));
+    return dap_chain_datum_decree_sign_in_cycle(&a_cert, l_decree, 1, NULL);
+}
 
-    return l_decree;
+static void s_print_emergency_validators(char **a_str_reply, dap_list_t *a_validator_addrs)
+{
+    dap_string_t *l_str_out = dap_string_new("Current emergency validators list:\n");
+    for (dap_list_t *it = a_validator_addrs; it; it = it->next) {
+        dap_chain_addr_t *l_addr = it->data;
+        dap_string_append_printf(l_str_out, "%s\n", dap_chain_hash_fast_to_str_static(&l_addr->data.hash_fast));
+    }
+    *a_str_reply = l_str_out->str;
+    dap_string_free(l_str_out, false);
 }
 
 /**
@@ -2727,65 +2908,166 @@ static dap_chain_datum_decree_t *s_esbocs_decree_set_min_validators_count(dap_ch
  */
 static int s_cli_esbocs(int a_argc, char **a_argv, void **a_str_reply)
 {
-    int ret = -666;
-    int l_arg_index = 2;
-    dap_chain_net_t * l_chain_net = NULL;
-    dap_chain_t * l_chain = NULL;
-    const char *l_cert_str = NULL,
-               *l_value_str = NULL;
+    int l_arg_index = 1;
+    dap_chain_net_t *l_chain_net = NULL;
+    dap_chain_t *l_chain = NULL;
 
+    // TODO make parse_net_chain working with default chain by dap_chain_net_get_default_chain_by_chain_type(l_chain_net, CHAIN_TYPE_ANCHOR)
     if (dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_chain_net))
         return -3;
-    const char *l_chain_type = dap_chain_net_get_type(l_chain);
+    const char *l_chain_type = dap_chain_get_cs_type(l_chain);
     if (strcmp(l_chain_type, "esbocs")) {
             dap_cli_server_cmd_set_reply_text(a_str_reply,
                         "Type of chain \"%s\" is not block. Chain with current consensus \"%s\" is not supported by this command",
                         l_chain->name, l_chain_type);
-            return ret;
+            return -2;
     }
+    dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain);
+    dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks);
+    dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs);
 
-    if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, l_arg_index + 1, "set", NULL)) {
-        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str);
-        if (!l_cert_str) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_validators_count' requires parameter -cert");
-            return -3;
-        }
-        dap_cert_t *l_poa_cert = dap_cert_find_by_name(l_cert_str);
-        if (!l_poa_cert) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found");
-            return -25;
-        }
+    enum {
+        SUBCMD_UNDEFINED = 0,
+        SUBCMD_MIN_VALIDATORS_COUNT,
+        SUBCMD_CHECK_SIGNS_STRUCTURE,
+        SUBCMD_EMERGENCY_VALIDATOR
+    } l_subcmd = SUBCMD_UNDEFINED;
+    const char *l_subcmd_strs[] = {
+        [SUBCMD_UNDEFINED] = NULL,
+        [SUBCMD_MIN_VALIDATORS_COUNT] = "min_validators_count",
+        [SUBCMD_CHECK_SIGNS_STRUCTURE] = "check_signs_structure",
+        [SUBCMD_EMERGENCY_VALIDATOR] = "emergency_validator",
+    };
 
-        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-val_count", &l_value_str);
-        if (!l_value_str) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_validators_count' requires parameter -val_count");
-            return -9;
-        }
-        uint256_t l_value = dap_chain_balance_scan(l_value_str);
-        if (IS_ZERO_256(l_value)) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-val_count' param");
-            return -10;
+    const size_t l_subcmd_str_count = sizeof(l_subcmd_strs) / sizeof(char *);
+    const char *l_subcmd_str_arg = NULL;
+    // Parse commands
+    for (size_t i = 1; i < l_subcmd_str_count; i++) {
+        if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, l_arg_index + 1, l_subcmd_strs[i], &l_subcmd_str_arg)) {
+            l_subcmd = i;
+            break;
         }
+    }
+    dap_cert_t *l_poa_cert = NULL;
+    l_arg_index++;
+    bool l_subcommand_show = false, l_subcommand_add = false;
+    if (l_subcmd) {
+        if ((dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "set") > 0 && l_subcmd == SUBCMD_MIN_VALIDATORS_COUNT) ||
+                (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "enable") > 0 && l_subcmd == SUBCMD_CHECK_SIGNS_STRUCTURE) ||
+                (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "disable") > 0 && l_subcmd == SUBCMD_CHECK_SIGNS_STRUCTURE) ||
+                (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "add") > 0 && l_subcmd == SUBCMD_EMERGENCY_VALIDATOR) ||
+                (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "remove") > 0 && l_subcmd == SUBCMD_EMERGENCY_VALIDATOR))
+        {
+            if (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "enable") ||
+                    dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "add"))
+                l_subcommand_add = true;
+            const char *l_cert_str = NULL;
+            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str);
+            if (!l_cert_str) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_validators_count' requires parameter -cert");
+                return -3;
+            }
+            dap_cert_t *l_poa_cert = dap_cert_find_by_name(l_cert_str);
+            if (!l_poa_cert) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found");
+                return -25;
+            }
+            if (!l_poa_cert->enc_key || !l_poa_cert->enc_key->priv_key_data) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate doesn't contain a private key");
+                return -26;
+            }
+        } else if (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "show") > 0)
+            l_subcommand_show = true;
+        else
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized subcommand '%s'", a_argv[l_arg_index]);
+    }
 
-        dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_min_validators_count(
-                                                l_chain_net, l_chain, l_value, l_poa_cert);
-        char *l_decree_hash_str = NULL;
-        if (l_decree && (l_decree_hash_str = s_esbocs_decree_put(l_decree, l_chain_net))) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count has been set."
-                                                           " Decree hash %s", l_decree_hash_str);
-            DAP_DEL_MULTY(l_decree, l_decree_hash_str);
-        } else {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count setting failed");
-            DAP_DEL_Z(l_decree);
-            return -21;
-        }
-    } else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, l_arg_index + 1, "print", NULL)) {
-        dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain);
-        dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks);
-        dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs);
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count is %d",
-                                          l_esbocs_pvt->min_validators_count);
-    } else
+    int ret = 0;
+    // Do subcommand action
+    switch (l_subcmd) {
+
+    case SUBCMD_MIN_VALIDATORS_COUNT: {
+        if (!l_subcommand_show) {
+            const char *l_value_str = NULL;
+            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-val_count", &l_value_str);
+            if (!l_value_str) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command '%s' requires parameter -val_count", l_subcmd_strs[l_subcmd]);
+                return -9;
+            }
+            uint256_t l_value = dap_chain_balance_scan(l_value_str);
+            if (IS_ZERO_256(l_value)) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-val_count' param");
+                return -10;
+            }
+            dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_min_validators_count(
+                                                    l_chain_net, l_chain, l_value, l_poa_cert);
+            char *l_decree_hash_str = NULL;
+            if (l_decree && (l_decree_hash_str = s_esbocs_decree_put(l_decree, l_chain_net))) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count has been set."
+                                                               " Decree hash %s", l_decree_hash_str);
+                DAP_DEL_MULTY(l_decree, l_decree_hash_str);
+            } else {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count setting failed");
+                DAP_DEL_Z(l_decree);
+                return -21;
+            }
+        } else
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count is %d", l_esbocs_pvt->min_validators_count);
+    } break;
+
+    case SUBCMD_CHECK_SIGNS_STRUCTURE: {
+        if (!l_subcommand_show) {
+            dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_signs_check(l_chain_net, l_chain, l_subcommand_add, l_poa_cert);
+            char *l_decree_hash_str = NULL;
+            if (l_decree && (l_decree_hash_str = s_esbocs_decree_put(l_decree, l_chain_net))) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Checking signs structure has been %s. Decree hash %s",
+                                                                l_subcommand_add ? "enabled" : "disabled", l_decree_hash_str);
+                DAP_DEL_MULTY(l_decree, l_decree_hash_str);
+            } else {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Checking signs structure setting failed");
+                DAP_DEL_Z(l_decree);
+                return -21;
+            }
+        } else
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Checking signs structure is %s", l_esbocs_pvt->check_signs_structure ?
+                                                                                "enabled" : "disabled");
+    } break;
+
+    case SUBCMD_EMERGENCY_VALIDATOR: {
+        if (!l_subcommand_show) {
+            const char *l_hash_str = NULL, *l_type_str = NULL;
+            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-pkey_hash", &l_hash_str);
+            if (!l_hash_str) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command '%s' requires parameter -pkey_hash", l_subcmd_strs[l_subcmd]);
+                return -9;
+            }
+            dap_hash_fast_t l_pkey_hash;
+            if (dap_chain_hash_fast_from_str(l_hash_str, &l_pkey_hash)) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid hash format in 'pkey_hash' param");
+                return -10;
+            }
+            dap_sign_type_t l_sig_type = { .type = SIG_TYPE_DILITHIUM };
+            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-sig_type", &l_type_str);
+            if (l_type_str)
+                l_sig_type = dap_sign_type_from_str(l_type_str);
+            dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_emergency_validator(l_chain_net, l_chain, &l_pkey_hash, l_sig_type, l_subcommand_add, l_poa_cert);
+            char *l_decree_hash_str = NULL;
+            if (l_decree && (l_decree_hash_str = s_esbocs_decree_put(l_decree, l_chain_net))) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Emergency validator %s has been %s. Decree hash %s",
+                                                        dap_chain_hash_fast_to_str_static(&l_pkey_hash),
+                                                        l_subcommand_add ? "added" : "deleted", l_decree_hash_str);
+                DAP_DEL_MULTY(l_decree, l_decree_hash_str);
+            } else {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Emergency validator %s failed", l_subcommand_add ? "adding" : "deleting");
+                DAP_DEL_Z(l_decree);
+                return -21;
+            }
+        } else
+            s_print_emergency_validators((char **)a_str_reply, l_esbocs_pvt->emergency_validator_addrs);
+    } break;
+
+    default:
         dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized subcommand '%s'", a_argv[l_arg_index]);
+    }
     return ret;
 }
diff --git a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
index 15d7578f4956c74464aa9fd9ee7b9e97444816e7..2374f776de2211e74b7ab2b3895aa7eb2f2ec639 100644
--- a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
+++ b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
@@ -27,7 +27,6 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_chain.h"
 #include "dap_chain_block.h"
 #include "dap_chain_cs_blocks.h"
-#include "dap_cert.h"
 #include "dap_global_db_driver.h"
 
 #define DAP_STREAM_CH_ESBOCS_ID                     'E'
@@ -156,6 +155,7 @@ typedef struct dap_chain_esbocs_round {
     // Validators section
     dap_list_t *validators_list;
     uint16_t validators_synced_count;
+    uint16_t *excluded_list;
     // Synchronization params
     uint64_t sync_attempt;
     bool sync_sent;
@@ -225,10 +225,11 @@ typedef struct dap_chain_esbocs_block_collect{
 
 int dap_chain_cs_esbocs_init();
 void dap_chain_cs_esbocs_deinit(void);
-bool dap_chain_esbocs_started();
 
+bool dap_chain_esbocs_started(dap_chain_net_id_t a_net_id);
 void dap_chain_esbocs_stop_timer(dap_chain_net_id_t a_net_id);
 void dap_chain_esbocs_start_timer(dap_chain_net_id_t a_net_id);
+
 dap_pkey_t *dap_chain_esbocs_get_sign_pkey(dap_chain_net_id_t a_net_id);
 uint256_t dap_chain_esbocs_get_fee(dap_chain_net_id_t a_net_id);
 bool dap_chain_esbocs_get_autocollect_status(dap_chain_net_id_t a_net_id);
@@ -236,3 +237,9 @@ void dap_chain_esbocs_add_block_collect(dap_chain_block_t *a_block_ptr, size_t a
                                         dap_chain_esbocs_block_collect_t *a_block_collect_params,int a_type);
 bool dap_chain_esbocs_add_validator_to_clusters(dap_chain_net_id_t a_net_id, dap_stream_node_addr_t *a_validator_addr);
 bool dap_chain_esbocs_remove_validator_from_clusters(dap_chain_net_id_t a_net_id, dap_stream_node_addr_t *a_validator_addr);
+
+uint256_t dap_chain_esbocs_get_collecting_level(dap_chain_t *a_chain);
+dap_enc_key_t *dap_chain_esbocs_get_sign_key(dap_chain_t *a_chain);
+int dap_chain_esbocs_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value);
+int dap_chain_esbocs_set_emergency_validator(dap_chain_t *a_chain, bool a_add, uint32_t a_sign_type, dap_hash_fast_t *a_validator_hash);
+int dap_chain_esbocs_set_signs_struct_check(dap_chain_t *a_chain, bool a_enable);
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum.c b/modules/json_rpc/common/dap_json_rpc_chain_datum.c
index 30b19b0af7dab4ab3b555de1e39a53279a3334b7..58ee1ab7cc083be08055885c0293e66d841ccf1e 100644
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum.c
+++ b/modules/json_rpc/common/dap_json_rpc_chain_datum.c
@@ -347,7 +347,7 @@ json_object *s_dap_chain_datum_token_tsd_to_json(dap_chain_datum_token_t *a_toke
                     return NULL;
                 }
                 json_object_object_add(l_jobj_tsd, "ticker_token_from", l_jobj_ticker_token_from);
-                char *balance; dap_uint256_to_char(l_tsd_section->emission_rate, &balance);
+                const char *balance; dap_uint256_to_char(l_tsd_section->emission_rate, &balance);
                 json_object *l_jobj_emission_rate = json_object_new_string(balance);
                 if (!l_jobj_emission_rate) {
                     json_object_put(l_jobj_tsd);
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c
index 829801e43b64b147355186576629f90c5b85554a..ed4722d2775125340600143af182a26a8c25da0c 100644
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c
+++ b/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c
@@ -1,8 +1,7 @@
 
 #include "dap_json_rpc_chain_datum_decree.h"
 #include "dap_json_rpc_chain_common.h"
-#include "json.h"
-
+#include "dap_tsd.h"
 
 #define LOG_TAG "dap_json_rpc_chain_datum_decree"
 
@@ -320,7 +319,7 @@ json_object *dap_chain_datum_decree_to_json(dap_chain_datum_decree_t *a_decree){
                 }
                 json_object_object_add(l_jobj_tsd, "addr", l_jobj_addr_fee_wallet);
             } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH: {
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH: {
                 json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH");
                 json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
                 if (l_tsd->size > sizeof(dap_hash_fast_t)) {
@@ -517,7 +516,7 @@ json_object *dap_chain_datum_decree_to_json(dap_chain_datum_decree_t *a_decree){
             } break;
             case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR: {
                 json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR");
-                json_object *l_jobj_node_addr = json_object_new_string(l_tsd->data);
+                json_object *l_jobj_node_addr = json_object_new_string((char *)l_tsd->data);
                 if (!l_jobj_tsd_type && !l_jobj_node_addr) {
                     json_object_put(l_jobj_tsd_type);
                     json_object_put(l_jobj_node_addr);
@@ -534,7 +533,7 @@ json_object *dap_chain_datum_decree_to_json(dap_chain_datum_decree_t *a_decree){
             } break;
             case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST: {
                 json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST");
-                json_object *l_jobj_host = json_object_new_string(l_tsd->data);
+                json_object *l_jobj_host = json_object_new_string((char *)l_tsd->data);
                 if (!l_jobj_tsd_type && !l_jobj_host) {
                     json_object_put(l_jobj_tsd_type);
                     json_object_put(l_jobj_host);
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c
index 5df5fdb51304e87c431a9a3c84c274fbc718ff7f..46997d59d1b827eaece4e434b7621c7278cad1ad 100644
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c
+++ b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c
@@ -95,7 +95,7 @@ json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx, dap_chain_ne
                 }
                 json_object_object_add(l_obj_item_data, "ts_expires", json_object_new_string(l_time_str));
                 json_object_object_add(l_obj_item_data, "subtype", json_object_new_string(dap_chain_tx_out_cond_subtype_to_str(((dap_chain_tx_out_cond_t*)item)->header.subtype)));
-                char *l_val_str, *l_val_datoshi_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_val_str);
+                const char *l_val_str, *l_val_datoshi_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_val_str);
                 json_object_object_add(l_obj_item_data, "value", json_object_new_string(l_val_str));
                 json_object_object_add(l_obj_item_data, "value_datoshi", json_object_new_string(l_val_datoshi_str));
                 char uid_str[32];
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_items.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_items.c
index 3e0c0cd28474cbaf6884ba71c76d4f13f45a9234..56a7f873893a9c26879167928625bd5c24f49f05 100644
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_items.c
+++ b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_items.c
@@ -2,11 +2,9 @@
 #include <string.h>
 
 #include "dap_common.h"
-#include "dap_enc_key.h"
 #include "dap_chain_common.h"
 #include "dap_sign.h"
 #include "dap_hash.h"
-#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_in_cond.h"
@@ -17,12 +15,11 @@
 #include "dap_json_rpc_chain_datum_tx_items.h"
 #include "dap_json_rpc_chain_common.h"
 #include "dap_json_rpc_sign.h"
-#include "json.h"
 
 #define LOG_TAG "dap_json_rpc_chain_datum_tx_items"
 
 json_object *dap_chain_datum_tx_item_out_cond_srv_pay_to_json(dap_chain_tx_out_cond_t *item) {
-        char *l_coins_str,
+        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);
         char *l_hash_str = dap_enc_base58_encode_hash_to_str_static(&((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash);
         json_object *l_obj = json_object_new_object();
@@ -40,7 +37,7 @@ json_object* dap_chain_datum_tx_item_out_cond_srv_xchange_to_json(dap_chain_tx_o
         json_object *l_object = json_object_new_object();
         json_object_object_add(l_object, "value", json_object_new_string(dap_uint256_to_char(a_srv_xchange->header.value, NULL)));
         json_object_object_add(l_object, "rate", ( { 
-            char *l_rate; dap_uint256_to_char(a_srv_xchange->subtype.srv_xchange.rate, &l_rate);
+            const char *l_rate; dap_uint256_to_char(a_srv_xchange->subtype.srv_xchange.rate, &l_rate);
             json_object_new_string(l_rate); } ));
         json_object_object_add(l_object, "srv_uid", json_object_new_uint64(a_srv_xchange->header.srv_uid.uint64));
         json_object_object_add(l_object, "buy_net_id", dap_chain_net_id_to_json(a_srv_xchange->subtype.srv_xchange.buy_net_id));
@@ -92,7 +89,7 @@ json_object *dap_chain_net_srv_stake_lock_cond_out_to_json(dap_chain_tx_out_cond
 
 json_object* dap_chain_datum_tx_item_out_to_json(const dap_chain_tx_out_t *a_out) {
     json_object *l_object = json_object_new_object();
-    char *l_val_coins, *l_val_datoshi = dap_uint256_to_char(a_out->header.value, &l_val_coins);
+    const char *l_val_coins, *l_val_datoshi = dap_uint256_to_char(a_out->header.value, &l_val_coins);
     json_object_object_add(l_object, "value", json_object_new_string(l_val_coins));
     json_object_object_add(l_object, "value_datoshi", json_object_new_string(l_val_datoshi));
     json_object_object_add(l_object, "address", dap_chain_addr_to_json(&a_out->addr));
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_receipt.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_receipt.c
index 9e24faf6a2f7434bb39d4eec7a140310521d86a9..439a03ff349efc15c5e1990a3ce9fbf7ee3af7a5 100644
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_receipt.c
+++ b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_receipt.c
@@ -1,11 +1,9 @@
 #include "dap_common.h"
-#include "dap_enc_key.h"
 #include "dap_sign.h"
 #include "dap_chain_datum_tx_receipt.h"
 
 #include "dap_json_rpc_sign.h"
 #include "dap_json_rpc_chain_datum_tx_receipt.h"
-#include "json.h"
 
 #define LOG_TAG "dap_json_rpc_chain_datum_tx_receipt"
 
@@ -23,7 +21,7 @@ json_object* dap_chain_receipt_info_to_json(dap_chain_receipt_info_t *a_info){
     json_object_object_add(l_obj, "units", json_object_new_uint64(a_info->units));
     json_object_object_add(l_obj, "units_type", json_object_new_string(dap_chain_srv_unit_enum_to_str(a_info->units_type.enm)));
 
-    char *l_value, *l_datoshi_value = dap_uint256_to_char(a_info->value_datoshi, &l_value);
+    const char *l_value, *l_datoshi_value = dap_uint256_to_char(a_info->value_datoshi, &l_value);
     json_object_object_add(l_obj, "value", json_object_new_string(l_value));
     json_object_object_add(l_obj, "value_datoshi", json_object_new_string(l_datoshi_value));
     return l_obj;
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index bd12e6e28c993c3233003b1ce694531ba9462f95..3d3e862c76b6c49f1679d6cea7ec247ca1359e81 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -383,7 +383,7 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_chain_cs_blocks_t *a_blocks, dap_
 
     // Check and apply sovereign tax for this key
     uint256_t l_value_tax = {};
-    dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_sign_pkey_hash);
+    dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(l_chain->net_id, &l_sign_pkey_hash);
     if (l_key_item && !IS_ZERO_256(l_key_item->sovereign_tax) &&
                 !dap_chain_addr_is_blank(&l_key_item->sovereign_addr)) {
         MULT_256_COIN(l_value_out, l_key_item->sovereign_tax, &l_value_tax);
@@ -512,7 +512,7 @@ char *dap_chain_mempool_tx_reward_create(dap_chain_cs_blocks_t *a_blocks, dap_en
     }
     // Check and apply sovereign tax for this key
     uint256_t l_value_tax = {};
-    dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_sign_pkey_hash);
+    dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(l_chain->net_id, &l_sign_pkey_hash);
     if (l_key_item && !IS_ZERO_256(l_key_item->sovereign_tax) &&
                 !dap_chain_addr_is_blank(&l_key_item->sovereign_addr)) {
         MULT_256_COIN(l_value_out, l_key_item->sovereign_tax, &l_value_tax);
@@ -584,7 +584,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
     uint256_t l_value_need = {};
     MULT_256_256(dap_chain_uint256_from(a_tx_num), l_single_val, &l_value_need);
     uint256_t l_value_transfer = {}; // how many coins to transfer
-    char *l_balance; dap_uint256_to_char(l_value_need, &l_balance);
+    const char *l_balance; dap_uint256_to_char(l_value_need, &l_balance);
     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,
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index d12edc92b13ecc6837720e679f69a6f6dfaed24a..4f88bd46d84ce9dc1d96970d332b5224dc3f82d5 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -456,7 +456,7 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_
     }
     struct json_object *l_token = json_object_new_object();
     json_object_object_add(l_token, "name", json_object_new_string(a_bal->token_ticker));
-    char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(a_bal->balance, &l_balance_coins);
+    const char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(a_bal->balance, &l_balance_coins);
     json_object_object_add(l_token, "full_balance", json_object_new_string(l_balance_coins));
     json_object_object_add(l_token, "datoshi", json_object_new_string(l_balance_datoshi));
     json_object_object_add(l_network, "tokens", l_token);
@@ -1041,7 +1041,7 @@ static bool s_ledger_token_supply_check_update(dap_ledger_t *a_ledger, dap_ledge
         return false;
     int l_overflow = SUBTRACT_256_256(a_token_item->current_supply, a_value, &a_token_item->current_supply);
     assert(!l_overflow);
-    char *l_balance; dap_uint256_to_char(a_token_item->current_supply, &l_balance);
+    const char *l_balance; dap_uint256_to_char(a_token_item->current_supply, &l_balance);
     log_it(L_NOTICE, "New current supply %s for token %s", l_balance, a_token_item->ticker);
     s_ledger_token_cache_update(a_ledger, a_token_item);
     return true;
@@ -1218,7 +1218,7 @@ int dap_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_toke
     }
     int l_res_token_tsd_parse = 0;
 
-    char *l_balance_dbg = NULL;
+    const char *l_balance_dbg = NULL;
     if (s_debug_more)
         dap_uint256_to_char(l_token->total_supply, &l_balance_dbg);
 
@@ -2902,7 +2902,7 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi
             // Add it to cache
             s_ledger_emission_cache_update(a_ledger, l_token_emission_item);
             if (s_debug_more) {
-                char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance);
+                const char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance);
                 log_it(L_NOTICE, "Added token emission datum to emissions cache: type=%s value=%s token=%s to_addr=%s ",
                                c_dap_chain_datum_token_emission_type_str[l_token_emission_item->datum_token_emission->hdr.type],
                                l_balance, c_token_ticker,
@@ -2922,7 +2922,7 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi
             pthread_rwlock_unlock(&l_ledger_pvt->threshold_emissions_rwlock);
             l_ret = -5;
             if (s_debug_more) {
-                char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance);
+                const char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance);
                 log_it(L_NOTICE, "Added token emission datum to emissions threshold: type=%s value=%s token=%s to_addr=%s ",
                                c_dap_chain_datum_token_emission_type_str[l_token_emission_item->datum_token_emission->hdr.type],
                                l_balance, c_token_ticker,
@@ -3211,7 +3211,7 @@ void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr
                 return;
             }
             l_count = 0;
-            char *l_addr = dap_chain_addr_to_str(a_addr);
+            const char *l_addr = dap_chain_addr_to_str(a_addr);
             pthread_rwlock_rdlock(&PVT(a_ledger)->balance_accounts_rwlock);
             HASH_ITER(hh, PVT(a_ledger)->balance_accounts, wallet_balance, tmp) {
                 char **l_keys = dap_strsplit(wallet_balance->key, " ", -1);
@@ -3997,7 +3997,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
                     if (!dap_chain_addr_is_blank(l_addr_from) && s_ledger_permissions_check(l_token_item,
                                                    DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD, l_addr_from,
                                                   sizeof(*l_addr_from)) != 0 ){
-                        char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from);
+                        const char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from);
                         debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)");
                         l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED;
                         break;
@@ -4007,7 +4007,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
                     (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN ) ){ // in black list
                     if (s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD, l_addr_from,
                                                   sizeof(*l_addr_from)) == 0 ){
-                        char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from);
+                        const char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from);
                         debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)");
                         l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED;
                         break;
@@ -4149,7 +4149,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
         HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur);
     }
 
-    dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_tx_first_sign_pkey_hash);
+    dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(a_ledger->net->pub.id, &l_tx_first_sign_pkey_hash);
     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
@@ -4255,7 +4255,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
              (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN) ){ //  check if we're in white list
             if(!dap_chain_addr_is_blank(&l_tx_out_to) && s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD,&l_tx_out_to ,
                                           sizeof (l_tx_out_to)) != 0 ){
-                char * l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to);
+                const char *l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to);
                 debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_out_to?l_tmp_tx_out_to:"(null)");
                 l_err_num = -20;
                 break;
@@ -4266,7 +4266,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
              ){ // If all is allowed - check if we're in black list
             if(s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD ,&l_tx_out_to,
                                           sizeof (l_tx_out_to)) == 0 ){
-                char * l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to);
+                const char *l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to);
                 debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_out_to?l_tmp_tx_out_to:"(null)");
                 l_err_num = -22;
                 break;
@@ -4609,7 +4609,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
         case TX_ITEM_TYPE_IN: {
             dap_ledger_wallet_balance_t *wallet_balance = NULL;
             l_cur_token_ticker = l_bound_item->in.token_ticker;
-            char *l_addr_str = dap_chain_addr_to_str(&l_bound_item->in.addr_from);
+            const char *l_addr_str = dap_chain_addr_to_str(&l_bound_item->in.addr_from);
             char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_cur_token_ticker, (char*)NULL);
             pthread_rwlock_rdlock(&PVT(a_ledger)->balance_accounts_rwlock);
             HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, wallet_balance);
@@ -4722,7 +4722,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
         else if (l_addr->net_id.uint64 != a_ledger->net->pub.id.uint64 &&
                  !dap_chain_addr_is_blank(l_addr))
             l_cross_network = true;
-        char *l_addr_str = dap_chain_addr_to_str(l_addr);
+        const char *l_addr_str = dap_chain_addr_to_str(l_addr);
         dap_ledger_wallet_balance_t *wallet_balance = NULL;
         char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_cur_token_ticker, (char*)NULL);
         debug_if(s_debug_more, L_DEBUG, "GOT %s to addr: %s",
@@ -4864,7 +4864,7 @@ int dap_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_c
 {
     if (dap_chain_net_get_load_mode(a_ledger->net)) {
         if (PVT(a_ledger)->cache_tx_check_callback)
-            PVT(a_ledger)->cache_tx_check_callback(a_tx_hash);
+            PVT(a_ledger)->cache_tx_check_callback(a_ledger, a_tx_hash);
         dap_ledger_tx_item_t *l_tx_item;
         unsigned l_hash_value;
         HASH_VALUE(a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value);
@@ -5088,7 +5088,7 @@ uint256_t dap_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t
     uint256_t l_ret = uint256_0;
 
     dap_ledger_wallet_balance_t *l_balance_item = NULL;// ,* l_balance_item_tmp = NULL;
-    char *l_addr = dap_chain_addr_to_str(a_addr);
+    const char *l_addr = dap_chain_addr_to_str(a_addr);
     char *l_wallet_balance_key = dap_strjoin(" ", l_addr, a_token_ticker, (char*)NULL);
     pthread_rwlock_rdlock(&PVT(a_ledger)->balance_accounts_rwlock);
     HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, l_balance_item);
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 3aac9da563e7e6c6252629a6bdd5a49cbf983588..1432327e53922a856a8a196bd7baf2908013300d 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -71,14 +71,7 @@
 #include "dap_config.h"
 #include "dap_hash.h"
 #include "dap_cert.h"
-#include "dap_cert_file.h"
 #include "dap_chain_datum_tx.h"
-#include "dap_chain_datum_tx_in_cond.h"
-#include "dap_chain_datum_tx_items.h"
-#include "dap_chain_datum_tx_out.h"
-#include "dap_chain_datum_tx_out_cond.h"
-#include "dap_timerfd.h"
-#include "dap_stream_worker.h"
 #include "dap_worker.h"
 #include "dap_proc_thread.h"
 #include "dap_enc_http.h"
@@ -86,21 +79,16 @@
 #include "dap_chain_cell.h"
 #include "dap_chain_datum_decree.h"
 #include "dap_chain_datum_anchor.h"
-#include "dap_chain_tx.h"
 #include "dap_chain_net.h"
 #include "dap_chain_net_node_list.h"
 #include "dap_chain_net_tx.h"
 #include "dap_chain_net_anchor.h"
 #include "dap_chain_net_decree.h"
-#include "dap_chain_net_srv.h"
 #include "dap_chain_net_balancer.h"
 #include "dap_chain_node_client.h"
-#include "dap_chain_node_cli.h"
 #include "dap_chain_node_cli_cmd.h"
 #include "dap_notify_srv.h"
 #include "dap_chain_ledger.h"
-#include "dap_chain_cs_none.h"
-#include "dap_client_http.h"
 #include "dap_global_db.h"
 #include "dap_stream_ch_chain_net_pkt.h"
 #include "dap_stream_ch_chain_net.h"
@@ -108,10 +96,7 @@
 #include "dap_stream_ch.h"
 #include "dap_stream.h"
 #include "dap_stream_ch_pkt.h"
-#include "dap_chain_node_dns_client.h"
-#include "dap_module.h"
 #include "rand/dap_rand.h"
-#include "json.h"
 #include "json_object.h"
 #include "dap_chain_net_srv_stake_pos_delegate.h"
 #include "dap_chain_net_srv_xchange.h"
@@ -121,6 +106,7 @@
 #include "dap_link_manager.h"
 #include "dap_stream_cluster.h"
 #include "dap_http_ban_list_client.h"
+#include "dap_net.h"
 
 #include <stdio.h>
 #include <sys/types.h>
@@ -856,22 +842,6 @@ void s_set_reply_text_node_status(void **a_str_reply, dap_chain_net_t * a_net){
     DAP_DELETE(l_sync_current_link_text_block);
     DAP_DELETE(l_node_address_text_block);
 }
-
-/**
- * @brief get type of chain
- *
- * @param l_chain
- * @return char*
- */
-const char* dap_chain_net_get_type(dap_chain_t *l_chain)
-{
-    if (!l_chain){
-        log_it(L_DEBUG, "dap_get_chain_type. Chain object is 0");
-        return NULL;
-    }
-    return (const char*)DAP_CHAIN_PVT(l_chain)->cs_name;
-}
-
 /**
  * @brief reload ledger
  * command cellframe-node-cli net -net <network_name> ledger reload
@@ -879,7 +849,7 @@ const char* dap_chain_net_get_type(dap_chain_t *l_chain)
  * @return true
  * @return false
  */
-static void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net)
+void dap_chain_net_purge(dap_chain_net_t *l_net)
 {
     dap_ledger_purge(l_net->pub.ledger, false);
     dap_chain_net_srv_stake_purge(l_net);
@@ -888,8 +858,8 @@ static void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net)
     DL_FOREACH(l_net->pub.chains, l_chain) {
         if (l_chain->callback_purge)
             l_chain->callback_purge(l_chain);
-        if (l_chain->callback_set_min_validators_count)
-            l_chain->callback_set_min_validators_count(l_chain, 0);
+        if (!dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs"))
+            dap_chain_esbocs_set_min_validators_count(l_chain, 0);
         l_net->pub.fee_value = uint256_0;
         l_net->pub.fee_addr = c_dap_chain_addr_blank;
         dap_chain_load_all(l_chain);
@@ -1381,7 +1351,7 @@ static int s_cli_net(int argc, char **argv, void **reply)
                 uint256_t l_network_fee = {};
                 dap_chain_addr_t l_network_fee_addr = {};
                 dap_chain_net_tx_get_fee(l_net->pub.id, &l_network_fee, &l_network_fee_addr);
-                char *l_network_fee_coins_str, *l_network_fee_balance_str =
+                const char *l_network_fee_coins_str, *l_network_fee_balance_str =
                     dap_uint256_to_char(l_network_fee, &l_network_fee_coins_str);
                 json_object *l_jobj_network =  json_object_new_object();
                 json_object *l_jobj_fee_coins = json_object_new_string(l_network_fee_coins_str);
@@ -1679,7 +1649,7 @@ static int s_cli_net(int argc, char **argv, void **reply)
         } else if (l_ledger_str && !strcmp(l_ledger_str, "reload")) {
             int l_return_state = dap_chain_net_stop(l_net);
             sleep(1);   // wait to net going offline
-            s_chain_net_ledger_cache_reload(l_net);
+            dap_chain_net_purge(l_net);
             if (l_return_state)
                 dap_chain_net_start(l_net);
         } else if (l_list_str && !strcmp(l_list_str, "list")) {
diff --git a/modules/net/dap_chain_net_anchor.c b/modules/net/dap_chain_net_anchor.c
index 65673541cd3701db3f50855d13e7df862fad0cd7..38997a921cd60dafb89020754ed9354704774da0 100644
--- a/modules/net/dap_chain_net_anchor.c
+++ b/modules/net/dap_chain_net_anchor.c
@@ -25,12 +25,13 @@
 #include <assert.h>
 #include "dap_common.h"
 #include "dap_sign.h"
-#include "dap_cert.h"
 #include "dap_pkey.h"
 #include "dap_chain_common.h"
 #include "dap_chain_ledger.h"
 #include "dap_chain_net.h"
+#include "dap_chain_net_decree.h"
 #include "dap_chain_datum_decree.h"
+#include "dap_chain_datum_anchor.h"
 
 #define LOG_TAG "chain_net_anchor"
 
diff --git a/modules/net/dap_chain_net_balancer.c b/modules/net/dap_chain_net_balancer.c
index 591778a033598775ac23700b6b1ed2aad8bbad78..fb04985c3356382604fd630a0e587a70f26a6743 100644
--- a/modules/net/dap_chain_net_balancer.c
+++ b/modules/net/dap_chain_net_balancer.c
@@ -29,7 +29,9 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "http_status_code.h"
 #include "dap_chain_node_client.h"
 #include "dap_chain_node_dns_client.h"
-#include "rand/dap_rand.h"
+#include "dap_net.h"
+#include "dap_client_http.h"
+#include "dap_enc_base64.h"
 #include "dap_notify_srv.h"
 
 #define LOG_TAG "dap_chain_net_balancer"
@@ -511,4 +513,4 @@ dap_string_t *dap_chain_net_balancer_get_node_str(dap_chain_net_t *a_net)
     dap_string_append(l_ret, "-----------------------------------------------------------------\n");
     DAP_DEL_Z(l_links_info_list);
     return l_ret;
-}
\ No newline at end of file
+}
diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c
index 973aab6f5477206fb85b11b3d079edaa3b139ef3..fd5e25bb4373a79c302d24130f2d10685cd1aafb 100644
--- a/modules/net/dap_chain_net_decree.c
+++ b/modules/net/dap_chain_net_decree.c
@@ -25,12 +25,11 @@
 #include <assert.h>
 #include "dap_common.h"
 #include "dap_sign.h"
-#include "dap_cert.h"
 #include "dap_pkey.h"
 #include "dap_chain_common.h"
 #include "dap_chain_net.h"
 #include "dap_chain_net_decree.h"
-#include "dap_chain_net_srv.h"
+#include "dap_chain_cs_esbocs.h"
 #include "dap_chain_net_tx.h"
 #include "dap_chain_net_srv_stake_pos_delegate.h"
 #include "dap_http_ban_list_client.h"
@@ -198,7 +197,7 @@ static int s_decree_verify(dap_chain_net_t *a_net, dap_chain_datum_decree_t *a_d
     DAP_DELETE(l_unique_signs);
 
     if (l_signs_verify_counter < l_min_signs) {
-        log_it(L_WARNING,"Not enough valid signatures, get %hu from %hu", l_signs_verify_counter, l_min_signs);
+        log_it(L_WARNING, "Not enough valid signatures, get %hu from %hu", l_signs_verify_counter, l_min_signs);
         return -107;
     }
 
@@ -353,12 +352,15 @@ static bool s_verify_pkey (dap_sign_t *a_sign, dap_chain_net_t *a_net)
 
 static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net, bool a_apply, bool a_load_mode)
 {
-    uint256_t l_uint256_buffer;
-    uint16_t l_uint16_buffer;
-    dap_chain_addr_t l_addr = {}; //????????
+    uint256_t l_value;
+    uint32_t l_sign_type;
+    uint16_t l_owners_num;
+    uint8_t l_action;
+    dap_chain_addr_t l_addr = {};
     dap_hash_fast_t l_hash = {};
     dap_chain_node_addr_t l_node_addr = {};
     dap_list_t *l_owners_list = NULL;
+    const char *l_ban_addr;
 
     dap_return_val_if_fail(a_decree && a_net, -112);
 
@@ -372,17 +374,17 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
                     } else
                         l_addr = a_net->pub.fee_addr;
                 }
-                if (dap_chain_datum_decree_get_fee(a_decree, &l_uint256_buffer)) {
+                if (dap_chain_datum_decree_get_fee(a_decree, &l_value)) {
                     log_it(L_WARNING,"Can't get fee value from decree.");
                     return -103;
                 }
                 if (!a_apply)
                     break;
-                if (!dap_chain_net_tx_set_fee(a_net->pub.id, l_uint256_buffer, l_addr))
+                if (!dap_chain_net_tx_set_fee(a_net->pub.id, l_value, l_addr))
                     log_it(L_ERROR, "Can't set fee value for network %s", a_net->pub.name);
             break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS:
-            l_owners_list = dap_chain_datum_decree_get_owners(a_decree, &l_uint16_buffer);
+            l_owners_list = dap_chain_datum_decree_get_owners(a_decree, &l_owners_num);
             if (!l_owners_list){
                 log_it(L_WARNING,"Can't get ownners from decree.");
                 return -104;
@@ -391,26 +393,30 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
             if (!a_apply)
                 break;
 
-            a_net->pub.decree->num_of_owners = l_uint16_buffer;
+            a_net->pub.decree->num_of_owners = l_owners_num;
             dap_list_free_full(a_net->pub.decree->pkeys, NULL);
 
             a_net->pub.decree->pkeys = l_owners_list;
             break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS_MIN:
-            if (dap_chain_datum_decree_get_min_owners(a_decree, &l_uint16_buffer)){
+            if (dap_chain_datum_decree_get_min_owners(a_decree, &l_value)) {
                 log_it(L_WARNING,"Can't get min number of ownners from decree.");
                 return -105;
             }
+            if (!IS_ZERO_256(l_value) || compare256(l_value, GET_256_FROM_64(UINT16_MAX)) == 1) {
+                log_it(L_WARNING,"Illegal min number of ownners %s", dap_uint256_to_char(l_value, NULL));
+                return -116;
+            }
             if (!a_apply)
                 break;
-            a_net->pub.decree->min_num_of_owners = l_uint16_buffer;
+            a_net->pub.decree->min_num_of_owners = dap_uint256_to_uint64(l_value);
             break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE:
-            if (dap_chain_datum_decree_get_stake_tx_hash(a_decree, &l_hash)){
+            if (dap_chain_datum_decree_get_hash(a_decree, &l_hash)){
                 log_it(L_WARNING,"Can't get tx hash from decree.");
                 return -105;
             }
-            if (dap_chain_datum_decree_get_stake_value(a_decree, &l_uint256_buffer)){
+            if (dap_chain_datum_decree_get_stake_value(a_decree, &l_value)){
                 log_it(L_WARNING,"Can't get stake value from decree.");
                 return -106;
             }
@@ -432,7 +438,7 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
             }
             if (!a_apply)
                 break;
-            dap_chain_net_srv_stake_key_delegate(a_net, &l_addr, &l_hash, l_uint256_buffer, &l_node_addr);
+            dap_chain_net_srv_stake_key_delegate(a_net, &l_addr, &l_hash, l_value, &l_node_addr);
             break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE:
             if (dap_chain_datum_decree_get_stake_signing_addr(a_decree, &l_addr)){
@@ -444,16 +450,16 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
             dap_chain_net_srv_stake_key_invalidate(&l_addr);
             break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE:
-            if (dap_chain_datum_decree_get_stake_min_value(a_decree, &l_uint256_buffer)){
+            if (dap_chain_datum_decree_get_stake_min_value(a_decree, &l_value)){
                 log_it(L_WARNING,"Can't get min stake value from decree.");
                 return -105;
             }
             if (!a_apply)
                 break;
-            dap_chain_net_srv_stake_set_allowed_min_value(l_uint256_buffer);
+            dap_chain_net_srv_stake_set_allowed_min_value(a_net->pub.id, l_value);
             break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT:
-            if (dap_chain_datum_decree_get_stake_min_signers_count(a_decree, &l_uint256_buffer)){
+            if (dap_chain_datum_decree_get_stake_min_signers_count(a_decree, &l_value)){
                 log_it(L_WARNING,"Can't get min stake value from decree.");
                 return -105;
             }
@@ -462,72 +468,44 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
                 log_it(L_WARNING, "Specified chain not found");
                 return -106;
             }
-            if (!l_chain->callback_set_min_validators_count) {
+            if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) {
                 log_it(L_WARNING, "Can't apply this decree to specified chain");
                 return -115;
             }
             if (!a_apply)
                 break;
-            l_chain->callback_set_min_validators_count(l_chain, (uint16_t)dap_chain_uint256_to(l_uint256_buffer));
+            dap_chain_esbocs_set_min_validators_count(l_chain, (uint16_t)dap_chain_uint256_to(l_value));
             break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN: {
+            if (dap_chain_datum_decree_get_ban_addr(a_decree, &l_ban_addr)) {
+                log_it(L_WARNING, "Can't get ban address from decree.");
+                return -114;
+            }
+            if (dap_http_ban_list_client_check(l_ban_addr, NULL, NULL)) {
+                log_it(L_ERROR, "Can't ban addr %s: already banlisted", l_ban_addr);
+                return -112;
+            }
             if (!a_apply)
                 break;
-            size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size;
-            while(l_tsd_offset < tsd_data_size){
-                dap_tsd_t *l_tsd = (dap_tsd_t *)(a_decree->data_n_signs + l_tsd_offset);
-                size_t l_tsd_size = dap_tsd_size(l_tsd);
-                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 -2;
-                }
-                dap_hash_fast_t l_decree_hash = {0};
-                dap_hash_fast(a_decree, dap_chain_datum_decree_get_size(a_decree), &l_decree_hash);
-                char *l_addr = dap_tsd_get_string(l_tsd);
-                switch (l_tsd->type) {
-                case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
-                case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
-                    if ( dap_http_ban_list_client_add(l_addr, l_decree_hash, a_decree->header.ts_created) ) {
-                        log_it(L_ERROR, "Can't ban addr %s: already banlisted", l_addr);
-                        return -4;
-                    } break;
-                default:
-                    log_it(L_WARNING, "Invalid section TSD type for sub-decree datum of type "
-                                      "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN.");
-                    return  -3;
-                }
-                l_tsd_offset += l_tsd_size;
-            }
+            dap_hash_fast_t l_decree_hash = {0};
+            dap_hash_fast(a_decree, dap_chain_datum_decree_get_size(a_decree), &l_decree_hash);
+            dap_http_ban_list_client_add(l_ban_addr, l_decree_hash, a_decree->header.ts_created);
         } break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN: {
+            if (dap_chain_datum_decree_get_ban_addr(a_decree, &l_ban_addr)) {
+                log_it(L_WARNING, "Can't get ban address from decree.");
+                return -114;
+            }
+            if (!dap_http_ban_list_client_check(l_ban_addr, NULL, NULL)) {
+                log_it(L_ERROR, "Can't ban addr %s: already banlisted", l_ban_addr);
+                return -112;
+            }
             if (!a_apply)
                 break;
-            size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size;
-            while(l_tsd_offset < tsd_data_size){
-                dap_tsd_t *l_tsd = (dap_tsd_t *)(a_decree->data_n_signs + l_tsd_offset);
-                size_t l_tsd_size = dap_tsd_size(l_tsd);
-                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 -2;
-                }
-                char *l_addr = dap_tsd_get_string(l_tsd);
-                switch (l_tsd->type) {
-                case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
-                case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
-                    if ( dap_http_ban_list_client_remove(l_addr) ) {
-                        log_it(L_ERROR, "Can't unban addr %s: not banlisted", l_addr);
-                        return -4;
-                    } break;
-                default:
-                    log_it(L_WARNING, "Invalid section TSD type for sub-decree datum of type "
-                                      "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN.");
-                    return  -3;
-                }
-                l_tsd_offset += l_tsd_size;
-            }
+            dap_http_ban_list_client_remove(l_ban_addr);
         } break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD: {
-            if (dap_chain_datum_decree_get_value(a_decree, &l_uint256_buffer)) {
+            if (dap_chain_datum_decree_get_value(a_decree, &l_value)) {
                 log_it(L_WARNING,"Can't get value from decree.");
                 return -103;
             }
@@ -536,10 +514,80 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
                 log_it(L_WARNING, "Specified chain not found");
                 return -106;
             }
+            if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) {
+                log_it(L_WARNING, "Can't apply this decree to specified chain");
+                return -115;
+            }
             if (!a_apply)
                 break;
             uint64_t l_cur_block_num = l_chain->callback_count_atom(l_chain);
-            dap_chain_net_add_reward(a_net, l_uint256_buffer, l_cur_block_num);
+            dap_chain_net_add_reward(a_net, l_value, l_cur_block_num);
+        } break;
+        case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT: {
+            if (dap_chain_datum_decree_get_value(a_decree, &l_value)) {
+                log_it(L_WARNING,"Can't get value from decree.");
+                return -103;
+            }
+            dap_chain_t *l_chain = dap_chain_find_by_id(a_net->pub.id, a_decree->header.common_decree_params.chain_id);
+            if (!l_chain) {
+                log_it(L_WARNING, "Specified chain not found");
+                return -106;
+            }
+            if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) {
+                log_it(L_WARNING, "Can't apply this decree to specified chain");
+                return -115;
+            }
+            if (compare256(l_value, dap_chain_coins_to_balance("1.0")) >= 0) {
+                log_it(L_WARNING, "Percent must be lower than 100%%");
+                return -116;
+            }
+            if (!a_apply)
+                break;
+            dap_chain_net_srv_stake_set_percent_max(a_net->pub.id, l_value);
+        } break;
+        case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE: {
+            if (dap_chain_datum_decree_get_action(a_decree, &l_action)) {
+                log_it(L_WARNING,"Can't get action from decree.");
+                return -103;
+            }
+            dap_chain_t *l_chain = dap_chain_find_by_id(a_net->pub.id, a_decree->header.common_decree_params.chain_id);
+            if (!l_chain) {
+                log_it(L_WARNING, "Specified chain not found");
+                return -106;
+            }
+            if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) {
+                log_it(L_WARNING, "Can't apply this decree to specified chain");
+                return -115;
+            }
+            if (!a_apply)
+                break;
+            dap_chain_esbocs_set_signs_struct_check(l_chain, l_action);
+        } break;
+        case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS: {
+            if (dap_chain_datum_decree_get_action(a_decree, &l_action)) {
+                log_it(L_WARNING,"Can't get action from decree.");
+                return -103;
+            }
+            if (dap_chain_datum_decree_get_signature_type(a_decree, &l_sign_type)) {
+                log_it(L_WARNING,"Can't get signature type from decree.");
+                return -113;
+            }
+            if (dap_chain_datum_decree_get_hash(a_decree, &l_hash)){
+                log_it(L_WARNING,"Can't get validator hash from decree.");
+                return -105;
+            }
+            dap_chain_t *l_chain = dap_chain_find_by_id(a_net->pub.id, a_decree->header.common_decree_params.chain_id);
+            if (!l_chain) {
+                log_it(L_WARNING, "Specified chain not found");
+                return -106;
+            }
+            if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) {
+                log_it(L_WARNING, "Can't apply this decree to specified chain");
+                return -115;
+            }
+            if (!a_apply)
+                break;
+            dap_chain_esbocs_set_emergency_validator(l_chain, l_action, l_sign_type, &l_hash);
         } break;
         default:
             return -1;
diff --git a/modules/net/dap_chain_net_node_list.c b/modules/net/dap_chain_net_node_list.c
index 45a95c880653240d85e7f1e6f5b7bc26dc24a0fb..205a5bf2193ce6215302ad42108e1230eeedc2e3 100644
--- a/modules/net/dap_chain_net_node_list.c
+++ b/modules/net/dap_chain_net_node_list.c
@@ -105,7 +105,7 @@ void dap_chain_net_node_check_http_issue_link(dap_http_simple_t *a_http_simple,
         *l_return_code = Http_Status_MethodNotAllowed;
         return;
     }
-    char *l_key = dap_stream_node_addr_to_str_static( (dap_chain_node_addr_t){.uint64 = addr} );
+    const char *l_key = dap_stream_node_addr_to_str_static( (dap_chain_node_addr_t){.uint64 = addr} );
     if (!l_key) {
         log_it(L_ERROR, "Bad node address %zu", addr);
         *l_return_code = Http_Status_BadRequest;
diff --git a/modules/net/dap_chain_net_voting.c b/modules/net/dap_chain_net_voting.c
index 715e2a782271441b48d00a0e0ca7a116fcfa764f..9511e4c208af99b0b9c2d5880a364d95d295a6a8 100644
--- a/modules/net/dap_chain_net_voting.c
+++ b/modules/net/dap_chain_net_voting.c
@@ -32,10 +32,11 @@
 
 #include "dap_chain_net_voting.h"
 #include "dap_chain_net_srv_stake_pos_delegate.h"
-#include "dap_chain_node_cli.h"
+#include "dap_chain_net_tx.h"
 #include "dap_chain_mempool.h"
 #include "uthash.h"
 #include "utlist.h"
+#include "dap_cli_server.h"
 
 #define LOG_TAG "chain_net_voting"
 
@@ -294,7 +295,7 @@ bool s_datum_tx_voting_verification_callback(dap_ledger_t *a_ledger, dap_chain_t
             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(&pkey_hash)){
+                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;
@@ -927,14 +928,14 @@ static int s_cli_voting(int a_argc, char **a_argv, void **a_str_reply)
 
             DIV_256_COIN(l_results[i].weights, l_total_weight, &l_weight_percentage);
             MULT_256_COIN(l_weight_percentage, dap_chain_coins_to_balance("100.0"), &l_weight_percentage);
-            char *l_weight_percentage_str = dap_uint256_decimal_to_round_char(l_weight_percentage, 2, true);
-            char *l_w_coins, *l_w_datoshi = dap_uint256_to_char(l_results[i].weights, &l_w_coins);
+            const char *l_weight_percentage_str = dap_uint256_decimal_to_round_char(l_weight_percentage, 2, true);
+            const char *l_w_coins, *l_w_datoshi = dap_uint256_to_char(l_results[i].weights, &l_w_coins);
             dap_string_append_printf(l_str_out, "\nVotes: %"DAP_UINT64_FORMAT_U" (%.2f%%)\nWeight: %s (%s) %s (%s%%)\n",
                                      l_results[i].num_of_votes, l_percentage, l_w_coins, l_w_datoshi, l_net->pub.native_ticker, l_weight_percentage_str);
         }
         DAP_DELETE(l_results);
         dap_string_append_printf(l_str_out, "\nTotal number of votes: %"DAP_UINT64_FORMAT_U, l_votes_count);
-        char *l_tw_coins, *l_tw_datoshi = dap_uint256_to_char(l_total_weight, &l_tw_coins);
+        const char *l_tw_coins, *l_tw_datoshi = dap_uint256_to_char(l_total_weight, &l_tw_coins);
         dap_string_append_printf(l_str_out, "\nTotal weight: %s (%s) %s\n\n", l_tw_coins, l_tw_datoshi, l_net->pub.native_ticker);
         dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_out->str);
         dap_string_free(l_str_out, true);
@@ -1349,7 +1350,7 @@ int dap_chain_net_vote_voting(dap_cert_t *a_cert, uint256_t a_fee, dap_chain_wal
             dap_hash_fast_t l_pkey_hash = {0};
 
             dap_hash_fast(l_pub_key, l_pub_key_size, &l_pkey_hash);
-            if (!dap_chain_net_srv_stake_check_pkey_hash(&l_pkey_hash)) {
+            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;
diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c
index fdfae11a181d1ecaedf5c6db630ae1342201614e..1500729a435cf319413ba9fd8102926d90135957 100644
--- a/modules/net/dap_chain_node.c
+++ b/modules/net/dap_chain_node.c
@@ -39,13 +39,11 @@
 #include <netinet/in.h>
 #endif
 
-#include "utlist.h"
 #include "dap_hash.h"
-#include "rand/dap_rand.h"
 #include "dap_chain_net.h"
 #include "dap_global_db.h"
 #include "dap_chain_node.h"
-#include "dap_chain_cell.h"
+#include "dap_chain_cs_esbocs.h"
 #include "dap_chain_ledger.h"
 
 #define LOG_TAG "dap_chain_node"
@@ -89,14 +87,14 @@ static void s_update_node_states_info(UNUSED_ARG void *a_arg)
             memcpy(l_info->links_addrs, l_linked_node_addrs, (l_info->uplinks_count + l_info->downlinks_count) * sizeof(dap_chain_node_addr_t));
             // DB write
             char *l_gdb_group = dap_strdup_printf("%s.nodes.states", l_net->pub.gdb_groups_prefix);
-            char *l_node_addr_str = dap_stream_node_addr_to_str_static(l_info->address);
+            const char *l_node_addr_str = dap_stream_node_addr_to_str_static(l_info->address);
             dap_global_db_set_sync(l_gdb_group, l_node_addr_str, l_info, l_info_size, false);
             DAP_DEL_MULTY(l_linked_node_addrs, l_info, l_gdb_group);
         }
     }
 }
 
-static void s_states_info_to_str(dap_chain_net_t *a_net, char *a_node_addr_str, dap_string_t *l_info_str)
+static void s_states_info_to_str(dap_chain_net_t *a_net, const char *a_node_addr_str, dap_string_t *l_info_str)
 {
 // sanity check
     dap_return_if_pass(!a_net || !a_node_addr_str || !l_info_str);
@@ -137,7 +135,7 @@ static void s_states_info_to_str(dap_chain_net_t *a_net, char *a_node_addr_str,
 dap_string_t *dap_chain_node_states_info_read(dap_chain_net_t *a_net, dap_stream_node_addr_t a_addr)
 {
     dap_string_t *l_ret = dap_string_new("");
-    char *l_node_addr_str = dap_stream_node_addr_to_str_static(a_addr.uint64 ? a_addr : g_node_addr);
+    const char *l_node_addr_str = dap_stream_node_addr_to_str_static(a_addr.uint64 ? a_addr : g_node_addr);
     if(!a_net) {
         for (dap_chain_net_t *l_net = dap_chain_net_iter_start(); l_net; l_net = dap_chain_net_iter_next(l_net)) {
             s_states_info_to_str(l_net, l_node_addr_str, l_ret);
@@ -227,7 +225,7 @@ int dap_chain_node_info_del(dap_chain_net_t *a_net, dap_chain_node_info_t *a_nod
  */
 dap_chain_node_info_t* dap_chain_node_info_read(dap_chain_net_t *a_net, dap_chain_node_addr_t *a_address)
 {
-    char *l_key = dap_stream_node_addr_to_str_static(*a_address);
+    const char *l_key = dap_stream_node_addr_to_str_static(*a_address);
     size_t l_node_info_size = 0;
     dap_chain_node_info_t *l_node_info
         = (dap_chain_node_info_t*)dap_global_db_get_sync(a_net->pub.gdb_nodes, l_key, &l_node_info_size, NULL, NULL);
@@ -302,7 +300,7 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force)
             if (dap_chain_node_mempool_need_process(a_chain, l_datum)) {
 
                 if (l_datum->header.type_id == DAP_CHAIN_DATUM_TX &&
-                        a_chain->callback_get_minimum_fee){
+                        !dap_strcmp(dap_chain_get_cs_type(a_chain), "esbocs")) {
                     uint256_t l_tx_fee = {};
                     dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data;
                     if (dap_chain_datum_tx_get_fee_value (l_tx, &l_tx_fee) ||
@@ -313,7 +311,7 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force)
                         } else
                             log_it(L_DEBUG, "Process service tx without fee");
                     } else {
-                        uint256_t l_min_fee = a_chain->callback_get_minimum_fee(a_chain);
+                        uint256_t l_min_fee = dap_chain_esbocs_get_fee(a_chain->net_id);
                         if (compare256(l_tx_fee, l_min_fee) < 0) {
                             char *l_tx_fee_str = dap_chain_balance_to_coins(l_tx_fee);
                             char *l_min_fee_str = dap_chain_balance_to_coins(l_min_fee);
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 6e99d9415169af1640c059de5a28544b118845ee..f7e2b73be352ec49209b8f2f808f393fcf7f1810 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -68,6 +68,7 @@
 #include "dap_cert_file.h"
 #include "dap_file_utils.h"
 #include "dap_enc_base58.h"
+#include "dap_enc_ks.h"
 #include "dap_chain_wallet.h"
 #include "dap_chain_wallet_internal.h"
 #include "dap_chain_node.h"
@@ -76,17 +77,13 @@
 #include "dap_chain_node_client.h"
 #include "dap_chain_node_cli_cmd.h"
 #include "dap_chain_node_cli_cmd_tx.h"
-#include "dap_chain_node_ping.h"
+#include "dap_net.h"
 #include "dap_chain_net_srv.h"
 #include "dap_chain_net_tx.h"
 #include "dap_chain_net_balancer.h"
-#include "dap_chain_block.h"
-#include "dap_chain_cs_blocks.h"
-
 #include "dap_chain_cell.h"
-
 #include "dap_enc_base64.h"
-#include "json.h"
+
 #ifdef DAP_OS_UNIX
 #include <dirent.h>
 #endif
@@ -98,14 +95,9 @@
 #include "dap_chain_ledger.h"
 #include "dap_chain_mempool.h"
 #include "dap_global_db.h"
-#include "dap_global_db_cluster.h"
 #include "dap_global_db_pkt.h"
-
-#include "dap_stream_ch_chain_net.h"
 #include "dap_chain_ch.h"
-#include "dap_stream_ch_chain_net_pkt.h"
 #include "dap_enc_base64.h"
-#include "dap_chain_net_srv_stake_pos_delegate.h"
 #include "dap_chain_net_node_list.h"
 
 #include "dap_json_rpc_errors.h"
@@ -116,7 +108,6 @@
 
 #define LOG_TAG "chain_node_cli_cmd"
 
-static void s_dap_chain_net_purge(dap_chain_net_t *a_net);
 int _cmd_mempool_add_ca(dap_chain_net_t *a_net, dap_chain_t *a_chain, dap_cert_t *a_cert, void **a_str_reply);
 
 /**
@@ -382,31 +373,6 @@ static int s_node_info_list_with_reply(dap_chain_net_t *a_net, dap_chain_node_ad
     return l_ret;
 }
 
-/**
- * @brief purge ledger, stake, decree, all chains and remove chain files
- * @param a_net
- */
-void s_dap_chain_net_purge(dap_chain_net_t * a_net)
-{
-    if (!a_net)
-        return;
-    dap_chain_t *l_chain = NULL;
-    dap_ledger_purge(a_net->pub.ledger, false);
-    dap_chain_net_srv_stake_purge(a_net);
-    dap_chain_net_decree_purge(a_net);
-    DL_FOREACH(a_net->pub.chains, l_chain) {
-        if (l_chain->callback_purge)
-            l_chain->callback_purge(l_chain);
-        if (l_chain->callback_set_min_validators_count)
-            l_chain->callback_set_min_validators_count(l_chain, 0);
-        const char *l_chains_rm_path = dap_chain_get_path(l_chain);
-        dap_rm_rf(l_chains_rm_path);
-        a_net->pub.fee_value = uint256_0;
-        a_net->pub.fee_addr = c_dap_chain_addr_blank;
-        dap_chain_load_all(l_chain);
-    }
-}
-
 /**
  * @brief com_global_db
  * global_db command
@@ -1849,7 +1815,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
 
                         if (l_wallet) {
                             l_addr = l_net ? dap_chain_wallet_get_addr(l_wallet, l_net->pub.id) : NULL;
-                            char *l_addr_str = dap_chain_addr_to_str(l_addr);
+                            const char *l_addr_str = dap_chain_addr_to_str(l_addr);
                             json_object_object_add(json_obj_wall, "Wallet", json_object_new_string(l_file_name));
                             if(l_wallet->flags & DAP_WALLET$M_FL_ACTIVE)
                                 json_object_object_add(json_obj_wall, "status", json_object_new_string("Active"));
@@ -1921,7 +1887,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
                 }
             }
             json_object * json_obj_wall = json_object_new_object();
-            char *l_l_addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) l_addr);
+            const char *l_l_addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) l_addr);
             if(l_wallet)
             {
                 json_object_object_add(json_obj_wall, "sign", json_object_new_string(
@@ -1942,7 +1908,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
                 if(l_l_addr_tokens[i]) {
                     json_object * j_balance_data = json_object_new_object();
                     uint256_t l_balance = dap_ledger_calc_balance(l_ledger, l_addr, l_l_addr_tokens[i]);
-                    char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(l_balance, &l_balance_coins);
+                    const char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(l_balance, &l_balance_coins);
                     json_object_object_add(j_balance_data, "balance", json_object_new_string(""));
                     json_object_object_add(j_balance_data, "coins", json_object_new_string(l_balance_coins));
                     json_object_object_add(j_balance_data, "datoshi", json_object_new_string(l_balance_datoshi));
@@ -2167,7 +2133,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
 
                     l_addr = l_net ? dap_chain_wallet_get_addr(l_wallet,l_net->pub.id ) : NULL;
 
-                    char *l_addr_str = dap_chain_addr_to_str(l_addr);
+                    const char *l_addr_str = dap_chain_addr_to_str(l_addr);
                     json_object * json_obj_wall = json_object_new_object();
                     json_object_object_add(json_obj_wall, "Wallet name", json_object_new_string(l_wallet->name));
                     json_object_object_add(json_obj_wall, "Sign type", json_object_new_string(l_sign_type_str));
@@ -2935,7 +2901,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
                                 dap_json_rpc_allocation_error;
                                 return;
                             }
-                            char *l_value_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_value_coins_str);
+                            const char *l_value_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_value_coins_str);
                             json_object_object_add(l_jobj_money, "value", json_object_new_string(l_value_str));
                             json_object_object_add(l_jobj_money, "coins", json_object_new_string(l_value_coins_str));
                             if (l_dist_token) {
@@ -6099,7 +6065,6 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
     }
     l_tx->header.ts_created = time(NULL);
     size_t l_items_ready = 0;
-    size_t l_receipt_count = 0;
     dap_list_t *l_sign_list = NULL;// list 'sing' items
     dap_list_t *l_in_list = NULL;// list 'in' items
     dap_list_t *l_tsd_list = NULL;// list tsd sections
@@ -6397,9 +6362,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
             size_t l_params_size = dap_strlen(l_params_str);
             dap_chain_datum_tx_receipt_t *l_receipt = dap_chain_datum_tx_receipt_create(l_srv_uid, l_price_unit, l_units, l_value, l_params_str, l_params_size);
             l_item = (const uint8_t*) l_receipt;
-            if(l_item)
-                l_receipt_count++;
-            else {
+            if (!l_item) {
                 char *l_str_err = dap_strdup_printf("Unable to create receipt out for transaction "
                                                     "described by item %zu.", i);
                 json_object *l_jobj_err = json_object_new_string(l_str_err);
@@ -7708,7 +7671,7 @@ int cmd_remove(int a_argc, char **a_argv, void **a_str_reply)
             if (NULL == l_gdb_path)
                 l_net_returns = s_go_all_nets_offline();
             for (dap_chain_net_t *it = dap_chain_net_iter_start(); it; it = dap_chain_net_iter_next(it)) {
-                s_dap_chain_net_purge(it);
+                dap_chain_net_purge(it);
             }
             if (!error)
                 successful |= REMOVED_CHAINS;
@@ -7719,7 +7682,7 @@ int cmd_remove(int a_argc, char **a_argv, void **a_str_reply)
             } else {
                 error |= NET_NOT_VALID;
             }
-            s_dap_chain_net_purge(l_net);
+            dap_chain_net_purge(l_net);
             if (!error)
                 successful |= REMOVED_CHAINS;
 
@@ -8165,7 +8128,6 @@ static int s_sign_file(const char *a_filename, dap_sign_signer_file_t a_flags, c
 {
     uint32_t l_shift = 1;
     int l_count_meta = 0;
-    int l_index_meta = 0;
     char *l_buffer = NULL;
 
     if (a_flags == SIGNER_ALL_FLAGS) {
@@ -8194,7 +8156,6 @@ static int s_sign_file(const char *a_filename, dap_sign_signer_file_t a_flags, c
             dap_tsd_t *l_item = s_alloc_metadata(a_filename, l_shift & a_flags);
             if (l_item) {
                 l_std_list = dap_list_append(l_std_list, l_item);
-                l_index_meta++;
             }
         }
         l_shift <<= 1;
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index 7ae6cef70e64263953e9b01d7e72203be6a04839..f7cfd20b00791b7a9846ead6c7a30ba00e1b460a 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -26,7 +26,7 @@
 #include <stddef.h>
 #include <pthread.h>
 
-#include "dap_chain_wallet.h"
+#include "dap_cli_server.h"
 #include "dap_common.h"
 #include "dap_enc_base58.h"
 #include "dap_strfuncs.h"
@@ -40,9 +40,10 @@
 #include "dap_chain_datum_token.h"
 #include "dap_chain_datum_decree.h"
 #include "dap_chain_datum_tx_items.h"
-#include "dap_chain_node_cli.h"
+#include "dap_chain_datum_anchor.h"
 #include "dap_chain_node_cli_cmd_tx.h"
 #include "dap_chain_net_tx.h"
+#include "dap_chain_net_decree.h"
 #include "dap_chain_mempool.h"
 #include "dap_math_convert.h"
 
@@ -528,20 +529,20 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
                                       a_hash_out_type, l_ledger, &l_tx_hash, l_datum_iter->ret_code);
                     l_header_printed = true;
                 }
-                char *l_src_str = NULL;
+                const char *l_src_str = NULL;
                 if (l_base_tx)
                     l_src_str = l_reward_collect ? "reward collecting" : "emission";
                 else if (l_src_addr && dap_strcmp(l_dst_token, l_noaddr_token))
                     l_src_str = dap_chain_addr_to_str(l_src_addr);
                 else
-                    l_src_str = (char*)dap_chain_tx_out_cond_subtype_to_str(l_src_subtype);
+                    l_src_str = dap_chain_tx_out_cond_subtype_to_str(l_src_subtype);
                 if (l_is_unstake)
                     l_value = l_unstake_value;
                 else if (!dap_strcmp(l_native_ticker, l_noaddr_token)) {
                     l_is_need_correction = true;
                     l_corr_value = l_value;
                 }
-                char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str);
+                const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str);
                 if (i_tmp > l_arr_start && i_tmp <= l_arr_end) {
                     json_object *j_obj_data = json_object_new_object();
                     if (!j_obj_data) {
@@ -576,7 +577,7 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
                 const char *l_dst_addr_str = l_dst_addr ? dap_chain_addr_to_str(l_dst_addr)
                                                         : dap_chain_tx_out_cond_subtype_to_str(
                                                               ((dap_chain_tx_out_cond_t *)it->data)->header.subtype);
-                char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str);
+                const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str);
                 if (i_tmp > l_arr_start && i_tmp <= l_arr_end) {
                     json_object * j_obj_data = json_object_new_object();
                     if (!j_obj_data) {
@@ -603,7 +604,7 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
         dap_list_free(l_list_out_items);
         if (l_is_need_correction && l_corr_object) {
             SUM_256_256(l_corr_value, l_fee_sum, &l_corr_value);
-            char *l_coins_str, *l_value_str = dap_uint256_to_char(l_corr_value, &l_coins_str);
+            const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_corr_value, &l_coins_str);
             json_object_object_add(l_corr_object, "recv_coins", json_object_new_string(l_coins_str));
             json_object_object_add(l_corr_object, "recv_datoshi", json_object_new_string(l_value_str));
             if (!j_arr_data) {
diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h
index 4d3db2f9060f27a7dad04c0a2c43587dfb5763aa..db8546e97de4a0e3c94b728cfe1cc79142e3b2e5 100644
--- a/modules/net/include/dap_chain_ledger.h
+++ b/modules/net/include/dap_chain_ledger.h
@@ -127,7 +127,7 @@ typedef bool (*dap_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_ch
 typedef void (*dap_ledger_updater_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_cond);
 typedef void (* dap_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx);
 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);
-typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_hash_fast_t *a_tx_hash);
+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);
 
diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h
index d22d7e5250295573e09e03f2dce82cb89e86d1f5..5090be3fc674decfaf4585d301cad42fd7ece3e4 100644
--- a/modules/net/include/dap_chain_net.h
+++ b/modules/net/include/dap_chain_net.h
@@ -27,32 +27,24 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 
 #include <stdint.h>
 #include <string.h>
-#include "dap_net.h"
-#include "dap_time.h"
 #include "dap_math_ops.h"
-#include "dap_stream_ch.h"
 #include "dap_strfuncs.h"
 #include "dap_string.h"
 #include "dap_list.h"
 #include "dap_chain_common.h"
 #include "dap_chain.h"
 #include "dap_chain_node.h"
-#include "dap_chain_net_decree.h"
-#include "dap_chain_net_tx.h"
-#include "dap_chain_datum_decree.h"
-#include "dap_chain_datum_anchor.h"
-#include "dap_chain_datum_tx.h"
-#include "uthash.h"
-#include "dap_json_rpc.h"
+#include "dap_global_db_cluster.h"
+#include "dap_json_rpc_errors.h"
 
 #define DAP_CHAIN_NET_NAME_MAX 32
 #define DAP_CHAIN_NET_MEMPOOL_TTL 48 // Hours
 
-struct dap_chain_node_info;
 typedef struct dap_chain_node_client dap_chain_node_client_t;
 typedef struct dap_ledger dap_ledger_t;
+typedef struct dap_chain_net_decree dap_chain_net_decree_t;
 
-typedef enum dap_chain_net_state{
+typedef enum dap_chain_net_state {
     NET_STATE_OFFLINE = 0,
     NET_STATE_LINKS_PREPARE,
     NET_STATE_LINKS_CONNECTING,
@@ -140,7 +132,6 @@ dap_chain_t *dap_chain_net_get_chain_by_id(dap_chain_net_t *l_net, dap_chain_id_
 
 uint64_t dap_chain_net_get_cur_addr_int(dap_chain_net_t * l_net);
 dap_chain_cell_id_t * dap_chain_net_get_cur_cell( dap_chain_net_t * l_net);
-const char* dap_chain_net_get_type(dap_chain_t *l_chain);
 
 // Get inintial authorized nodes pointed by config
 dap_chain_node_role_t dap_chain_net_get_role(dap_chain_net_t * a_net);
@@ -157,6 +148,8 @@ int dap_chain_net_add_reward(dap_chain_net_t *a_net, uint256_t a_reward, uint64_
 uint256_t dap_chain_net_get_reward(dap_chain_net_t *a_net, uint64_t a_block_num);
 int dap_chain_net_link_add(dap_chain_net_t *a_net, dap_stream_node_addr_t *a_addr, const char *a_host, uint16_t a_port);
 
+void dap_chain_net_purge(dap_chain_net_t *l_net);
+
 /**
  * @brief dap_chain_net_get_gdb_group_mempool
  * @param l_chain
diff --git a/modules/net/include/dap_chain_net_decree.h b/modules/net/include/dap_chain_net_decree.h
index 3d25ffba6208520de5128eb523dd665b0461a6d5..c8dc68956cb65e7b7f58f711bea6744ee4901eb2 100644
--- a/modules/net/include/dap_chain_net_decree.h
+++ b/modules/net/include/dap_chain_net_decree.h
@@ -25,7 +25,7 @@
 #include "dap_list.h"
 #include "dap_chain_net.h"
 
-typedef struct decree_params {
+typedef struct dap_chain_net_decree {
     dap_list_t *pkeys;
     uint16_t num_of_owners;
     uint16_t min_num_of_owners;
diff --git a/modules/net/include/dap_chain_node.h b/modules/net/include/dap_chain_node.h
index 2ee68992d839a99a6e19553f689722505feafa11..6426048417ebf5ea4846130fd009f5b48f9eaea9 100644
--- a/modules/net/include/dap_chain_node.h
+++ b/modules/net/include/dap_chain_node.h
@@ -24,11 +24,7 @@
 #include <limits.h>
 #include "dap_common.h"
 #include "dap_list.h"
-#include "dap_worker.h"
-#include "dap_events_socket.h"
-#include "dap_stream.h"
 #include "dap_chain_common.h"
-#include "dap_global_db.h"
 #include "dap_chain.h"
 #include "dap_client.h"
 
@@ -92,4 +88,4 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force);
 bool dap_chain_node_mempool_autoproc_init();
 inline static void dap_chain_node_mempool_autoproc_deinit() {}
 dap_list_t *dap_chain_node_get_states_list_sort(dap_chain_net_t *a_net, dap_chain_node_addr_t *a_ignored, size_t a_ignored_count);
-dap_string_t *dap_chain_node_states_info_read(dap_chain_net_t *a_net, dap_stream_node_addr_t a_addr);
\ No newline at end of file
+dap_string_t *dap_chain_node_states_info_read(dap_chain_net_t *a_net, dap_stream_node_addr_t a_addr);
diff --git a/modules/net/include/dap_chain_node_cli_cmd_tx.h b/modules/net/include/dap_chain_node_cli_cmd_tx.h
index d7e4a356c913937b90d4ce44cd415cc3acb456a7..619ef18662c966d5718f70e152f302fddaabeb70 100644
--- a/modules/net/include/dap_chain_node_cli_cmd_tx.h
+++ b/modules/net/include/dap_chain_node_cli_cmd_tx.h
@@ -26,7 +26,7 @@
 
 #include "dap_chain.h"
 #include "dap_chain_common.h"
-#include "json.h"
+#include "dap_chain_net.h"
 
 typedef struct dap_chain_tx_hash_processed_ht{
     dap_chain_hash_fast_t hash;
diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c
index bd072bd1cac5dfbeea1589ddade6bbf2dc77b077..e81bda4bd2797581d256366b80df284d4adbac97 100644
--- a/modules/net/srv/dap_chain_net_srv_order.c
+++ b/modules/net/srv/dap_chain_net_srv_order.c
@@ -558,7 +558,7 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d
         dap_string_append_printf(a_str_out, "  created:          %s\n", buf_time);
         dap_string_append_printf(a_str_out, "  srv_uid:          0x%016"DAP_UINT64_FORMAT_X"\n", a_order->srv_uid.uint64 );
         
-        char *l_balance_coins, *l_balance = dap_uint256_to_char(a_order->price, &l_balance_coins);
+        const char *l_balance_coins, *l_balance = dap_uint256_to_char(a_order->price, &l_balance_coins);
         dap_string_append_printf(a_str_out, "  price:            %s (%s)\n", l_balance_coins, l_balance);
         dap_string_append_printf(a_str_out, "  price_token:      %s\n",  (*a_order->price_ticker) ? a_order->price_ticker: a_native_ticker);
         dap_string_append_printf(a_str_out, "  units:            %zu\n", a_order->units);
diff --git a/modules/net/srv/include/dap_chain_net_srv.h b/modules/net/srv/include/dap_chain_net_srv.h
index 938efa969a2a03a43213839dff6d53dbc8685ded..c524cb3a91872d44780ed1e4f799d845fe01f0a1 100755
--- a/modules/net/srv/include/dap_chain_net_srv.h
+++ b/modules/net/srv/include/dap_chain_net_srv.h
@@ -27,9 +27,8 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_chain_net.h"
 #include "dap_chain_common.h"
 #include "dap_chain_datum_decree.h"
-#include "dap_chain_wallet.h"
+#include "dap_chain_datum_tx_receipt.h"
 #include "dap_common.h"
-#include "dap_config.h"
 #include "dap_stream_ch.h"
 #include "dap_time.h"
 
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 29906fce088c362056f327d459453de63cbaae6b..fe1c8031d5193d47fac54fdb987c87466813debd 100644
--- a/modules/net/srv/include/dap_chain_net_srv_order.h
+++ b/modules/net/srv/include/dap_chain_net_srv_order.h
@@ -106,7 +106,7 @@ int dap_chain_net_srv_order_find_all_by(
     dap_list_t** a_output_orders,
     size_t* a_output_orders_count);
 
-int dap_chain_net_srv_order_delete_by_hash_str_sync( dap_chain_net_t * a_net,const char * a_hash_str );
+int dap_chain_net_srv_order_delete_by_hash_str_sync(dap_chain_net_t *a_net, const char *a_hash_str);
 
 /**
  * @brief dap_chain_net_srv_order_delete_by_hash
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 0c29eaacc5694cd0a2b4b37ce5c703d0b1eb1b7a..e779348930d66e3508a66f7272b28b4c349782df 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_lock.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c
@@ -27,10 +27,11 @@
 #include "dap_time.h"
 #include "dap_chain_ledger.h"
 #include "dap_chain_net_srv_stake_lock.h"
-#include "dap_chain_node_cli.h"
+#include "dap_chain_net_tx.h"
 #include "dap_chain_wallet.h"
 #include "dap_chain_mempool.h"
 #include "dap_chain_net_srv.h"
+#include "dap_cli_server.h"
 
 static bool s_debug_more = false;
 
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 ee10d1760401f954b4d23c44fc2b6721f889c359..b464c68a9abcb46c66143db58621b0ddfb6cbbac 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
@@ -23,13 +23,14 @@
 */
 
 #include <math.h>
-#include "dap_chain_node_cli.h"
+#include "dap_chain_wallet.h"
 #include "dap_config.h"
 #include "dap_string.h"
 #include "dap_list.h"
 #include "dap_enc_base58.h"
 #include "dap_chain_common.h"
 #include "dap_chain_mempool.h"
+#include "dap_chain_net_decree.h"
 #include "dap_chain_net_tx.h"
 #include "dap_chain_net_srv.h"
 #include "dap_chain_net_srv_stake_pos_delegate.h"
@@ -37,8 +38,9 @@
 #include "rand/dap_rand.h"
 #include "dap_chain_node_client.h"
 #include "dap_stream_ch_chain_net_pkt.h"
-#include "dap_chain_node_cli_cmd.h"
 #include "json_object.h"
+#include "dap_cli_server.h"
+#include "dap_chain_net_srv_order.h"
 
 #define LOG_TAG "dap_chain_net_srv_stake_pos_delegate"
 
@@ -52,11 +54,7 @@ static void s_stake_updater_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_
 
 static void s_cache_data(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_addr_t *a_signing_addr);
 
-static void s_stake_clear();
-
-static void s_stake_net_clear(dap_chain_net_t *a_net);
-
-static dap_chain_net_srv_stake_t *s_srv_stake = NULL;
+static dap_list_t *s_srv_stake_list = NULL;
 
 /**
  * @brief dap_stream_ch_vpn_init Init actions for VPN stream channel
@@ -97,70 +95,82 @@ int dap_chain_net_srv_stake_pos_delegate_init()
          "\tShow the list of active stake keys (optional delegated with specified cert).\n"
     "srv_stake list tx -net <net_name> \n"
          "\tShow the list of key delegation transactions.\n"
-    "srv_stake min_value -net <net_name> -cert <cert_name> -value <value>"
+    "srv_stake min_value -net <net_name> [-chain <chain_name>] -poa_cert <poa_cert_name> -value <value>\n"
          "\tSets the minimum stake value\n"
+    "srv_stake max_weight -net <net_name> [-chain <chain_name>] -poa_cert <poa_cert_name> -percent <value>\n"
+        "\tSets maximum validator related weight (in percent)\n"
     "srv_stake check -net <net_name> -tx <tx_hash>"
          "\tCheck remote validator"
     );
 
-    s_srv_stake = DAP_NEW_Z(dap_chain_net_srv_stake_t);
-    if (!s_srv_stake) {
-        log_it(L_CRITICAL, "%s", g_error_memory_alloc);
-        return -1;
+    return 0;
+}
+
+static dap_chain_net_srv_stake_t *s_srv_stake_by_net_id(dap_chain_net_id_t a_net_id)
+{
+    for (dap_list_t *it = s_srv_stake_list; it; it = it->next) {
+        dap_chain_net_srv_stake_t *l_srv_stake = it->data;
+        if (l_srv_stake->net_id.uint64 == a_net_id.uint64)
+            return l_srv_stake;
     }
-    s_srv_stake->delegate_allowed_min = dap_chain_coins_to_balance("1.0");
+    return NULL;
+}
 
+int dap_chain_net_srv_stake_net_add(dap_chain_net_id_t a_net_id)
+{
+    dap_chain_net_srv_stake_t *l_srv_stake;
+    DAP_NEW_Z_RET_VAL(l_srv_stake, dap_chain_net_srv_stake_t, -1, NULL);
+    l_srv_stake->net_id = a_net_id;
+    l_srv_stake->delegate_allowed_min = dap_chain_coins_to_balance("1.0");
+    dap_list_t *l_list_new = dap_list_append(s_srv_stake_list, l_srv_stake);
+    if (dap_list_last(l_list_new) == dap_list_last(s_srv_stake_list)) {
+        log_it(L_ERROR, "Can't add net %" DAP_UINT64_FORMAT_x "to stake service net list", a_net_id.uint64);
+        DAP_DELETE(l_srv_stake);
+        return -2;
+    }
+    s_srv_stake_list = l_list_new;
+    log_it(L_NOTICE, "Successfully added net ID 0x%016" DAP_UINT64_FORMAT_x, a_net_id.uint64);
     return 0;
 }
 
 /**
  * @brief delete ht and hh concretic net from s_srv_stake 
  */
-void s_stake_net_clear(dap_chain_net_t *a_net)
+static void s_stake_net_clear(dap_chain_net_t *a_net)
 {
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net->pub.id);
+    dap_return_if_fail(l_srv_stake);
     dap_chain_net_srv_stake_item_t *l_stake = NULL, *l_tmp = NULL;
-    HASH_ITER(ht, s_srv_stake->tx_itemlist, l_stake, l_tmp) {
+    HASH_ITER(ht, l_srv_stake->tx_itemlist, l_stake, l_tmp) {
         // Clang bug at this, l_stake should change at every loop cycle
-        if (l_stake->net->pub.id.uint64 == a_net->pub.id.uint64)
-            HASH_DELETE(ht, s_srv_stake->tx_itemlist, l_stake);
+        HASH_DELETE(ht, l_srv_stake->tx_itemlist, l_stake);
     }
-    HASH_ITER(hh, s_srv_stake->itemlist, l_stake, l_tmp) {
+    HASH_ITER(hh, l_srv_stake->itemlist, l_stake, l_tmp) {
         // Clang bug at this, l_stake should change at every loop cycle
-        if (l_stake->net->pub.id.uint64 == a_net->pub.id.uint64) {
-            HASH_DEL(s_srv_stake->itemlist, l_stake);
-            DAP_DELETE(l_stake);
-        }
+        HASH_DEL(l_srv_stake->itemlist, l_stake);
+        DAP_DELETE(l_stake);
     }
     dap_chain_net_srv_stake_cache_item_t *l_cache_item = NULL, *l_cache_tmp = NULL;
-    HASH_ITER(hh, s_srv_stake->cache, l_cache_item, l_cache_tmp) {
+    HASH_ITER(hh, l_srv_stake->cache, l_cache_item, l_cache_tmp) {
         // Clang bug at this, l_stake should change at every loop cycle
-        if (l_cache_item->signing_addr.net_id.uint64 == a_net->pub.id.uint64) {
-            HASH_DEL(s_srv_stake->cache, l_cache_item);
-            DAP_DELETE(l_cache_item);
-        }
-    }
-}
-
-/**
- * @brief delete all nets ht and hh from s_srv_stake 
- */
-void s_stake_clear()
-{
-    for (dap_chain_net_t *it = dap_chain_net_iter_start(); it; it = dap_chain_net_iter_next(it)) {
-        s_stake_net_clear(it);
+        HASH_DEL(l_srv_stake->cache, l_cache_item);
+        DAP_DELETE(l_cache_item);
     }
 }
 
 void dap_chain_net_srv_stake_pos_delegate_deinit()
 {
-    s_stake_clear();
-    DAP_DEL_Z(s_srv_stake);
+    for (dap_chain_net_t *it = dap_chain_net_iter_start(); it; it = dap_chain_net_iter_next(it))
+        s_stake_net_clear(it);
+    dap_list_free_full(s_srv_stake_list, NULL);
+    s_srv_stake_list = NULL;
 }
 
-static bool s_stake_verificator_callback(dap_ledger_t UNUSED_ARG *a_ledger, dap_chain_tx_out_cond_t *a_cond,
+static bool s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond,
                                          dap_chain_datum_tx_t *a_tx_in, bool a_owner)
 {
-    assert(s_srv_stake);
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_ledger->net->pub.id);
+    dap_return_val_if_fail(l_srv_stake, false);
     // It's a order conditional TX
     if (dap_chain_addr_is_blank(&a_cond->subtype.srv_stake_pos_delegate.signing_addr) ||
             a_cond->subtype.srv_stake_pos_delegate.signer_node_addr.uint64 == 0) {
@@ -175,7 +185,7 @@ static bool s_stake_verificator_callback(dap_ledger_t UNUSED_ARG *a_ledger, dap_
         if (compare256(l_tx_out_cond->header.value, a_cond->header.value)) {
             char *l_in_value = dap_chain_balance_to_coins(l_tx_out_cond->header.value);
             char *l_out_value = dap_chain_balance_to_coins(a_cond->header.value);
-            log_it(L_WARNING, "In value %s is not eqal to out value %s", l_in_value, l_out_value);
+            log_it(L_WARNING, "In value %s is not equal to out value %s", l_in_value, l_out_value);
             DAP_DELETE(l_in_value);
             DAP_DELETE(l_out_value);
             return false;
@@ -234,7 +244,7 @@ static bool s_stake_verificator_callback(dap_ledger_t UNUSED_ARG *a_ledger, dap_
     if (a_tx_in->header.ts_created < 1706227200) // Jan 26 2024 00:00:00 GMT, old policy rules
         return true;
     dap_chain_net_srv_stake_item_t *l_stake;
-    HASH_FIND(ht, s_srv_stake->tx_itemlist, l_prev_hash, sizeof(dap_hash_t), l_stake);
+    HASH_FIND(ht, l_srv_stake->tx_itemlist, l_prev_hash, sizeof(dap_hash_t), l_stake);
     if (l_stake) {
         log_it(L_WARNING, "Key is active with delegation decree, need to revoke it first");
         return false;
@@ -244,7 +254,8 @@ static bool s_stake_verificator_callback(dap_ledger_t UNUSED_ARG *a_ledger, dap_
 
 static void s_stake_updater_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_cond)
 {
-    assert(s_srv_stake);
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_ledger->net->pub.id);
+    dap_return_if_fail(l_srv_stake);
     if (!a_cond)
         return;
     dap_chain_addr_t *l_signing_addr = &a_cond->subtype.srv_stake_pos_delegate.signing_addr;
@@ -265,31 +276,80 @@ static bool s_srv_stake_is_poa_cert(dap_chain_net_t *a_net, dap_enc_key_t *a_key
     return l_is_poa_cert;
 }
 
+#define LIMIT_DELTA UINT64_C(1000000000000) // 1.0e-6
+static bool s_weights_truncate(dap_chain_net_srv_stake_t *l_srv_stake, const uint256_t a_limit)
+{
+    uint256_t l_sum = uint256_0;
+    for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next)
+        SUM_256_256(l_sum, it->value, &l_sum);
+    uint256_t l_weight_max;
+    MULT_256_COIN(l_sum, a_limit, &l_weight_max);
+    size_t l_exceeds_count = 0;
+    uint256_t l_sum_others = l_sum;
+    for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next) {
+        uint256_t l_weight_with_delta;
+        SUBTRACT_256_256(it->value, GET_256_FROM_64(LIMIT_DELTA), &l_weight_with_delta);
+        if (compare256(l_weight_with_delta, l_weight_max) == 1) {
+            SUBTRACT_256_256(l_sum_others, it->value, &l_sum_others);
+            it->value = uint256_0;
+            l_exceeds_count++;
+        }
+    }
+    if (l_exceeds_count) {
+        uint256_t delta = dap_uint256_decimal_from_uint64(l_exceeds_count);
+        uint256_t kappa;
+        DIV_256_COIN(dap_uint256_decimal_from_uint64(1), a_limit, &kappa);
+        SUBTRACT_256_256(kappa, delta, &kappa);
+        DIV_256_COIN(l_sum_others, kappa, &kappa);
+        for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next)
+            if (IS_ZERO_256(it->value))
+                it->value = kappa;
+    }
+    return l_exceeds_count;
+}
+
+static void s_stake_recalculate_weights(dap_chain_net_id_t a_net_id)
+{
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id);
+    dap_return_if_fail(l_srv_stake);
+    if (IS_ZERO_256(l_srv_stake->delegate_percent_max))
+        return;
+    size_t l_validators_count = HASH_COUNT(l_srv_stake->itemlist);
+    uint256_t l_limit_min;
+    DIV_256(dap_uint256_decimal_from_uint64(1), GET_256_FROM_64(l_validators_count), &l_limit_min);
+    if (compare256(l_srv_stake->delegate_percent_max, l_limit_min) == 1)
+        l_limit_min = l_srv_stake->delegate_percent_max;
+    for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next)
+        it->value = it->locked_value;       // restore original locked values
+    while (s_weights_truncate(l_srv_stake, l_limit_min));
+}
+
 void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr_t *a_signing_addr, dap_hash_fast_t *a_stake_tx_hash,
                                           uint256_t a_value, dap_chain_node_addr_t *a_node_addr)
 {
-    assert(s_srv_stake);
     dap_return_if_fail(a_net && a_signing_addr && a_node_addr && a_stake_tx_hash);
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net->pub.id);
+    dap_return_if_fail(l_srv_stake);
 
     dap_chain_net_srv_stake_item_t *l_stake = NULL;
     bool l_found = false;
-    HASH_FIND(hh, s_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake);
+    HASH_FIND(hh, l_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake);
     if (!l_stake)
         l_stake = DAP_NEW_Z(dap_chain_net_srv_stake_item_t);
     else {
         l_found = true;
-        HASH_DELETE(ht, s_srv_stake->tx_itemlist, l_stake);
+        HASH_DELETE(ht, l_srv_stake->tx_itemlist, l_stake);
     }
     l_stake->net = a_net;
     l_stake->node_addr = *a_node_addr;
     l_stake->signing_addr = *a_signing_addr;
-    l_stake->value = a_value;
+    l_stake->value = l_stake->locked_value = a_value;
     l_stake->tx_hash = *a_stake_tx_hash;
     l_stake->is_active = true;
     if (!l_found)
-        HASH_ADD(hh, s_srv_stake->itemlist, signing_addr, sizeof(dap_chain_addr_t), l_stake);
+        HASH_ADD(hh, l_srv_stake->itemlist, signing_addr, sizeof(dap_chain_addr_t), l_stake);
     if (!dap_hash_fast_is_blank(a_stake_tx_hash)) {
-        HASH_ADD(ht, s_srv_stake->tx_itemlist, tx_hash, sizeof(dap_chain_hash_fast_t), l_stake);
+        HASH_ADD(ht, l_srv_stake->tx_itemlist, tx_hash, sizeof(dap_chain_hash_fast_t), l_stake);
         dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, a_stake_tx_hash);
         if (l_tx) {
             dap_chain_tx_out_cond_t *l_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, NULL);
@@ -307,80 +367,126 @@ void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr
     char l_key_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
     dap_chain_hash_fast_to_str(&a_signing_addr->data.hash_fast,
                                l_key_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
-    char *l_value_str; dap_uint256_to_char(a_value, &l_value_str);
-    log_it(L_NOTICE, "Added key with fingerprint %s and value %s for node "NODE_ADDR_FP_STR,
+    const char *l_value_str; dap_uint256_to_char(a_value, &l_value_str);
+    log_it(L_NOTICE, "Added key with fingerprint %s and locked value %s for node "NODE_ADDR_FP_STR,
                         l_key_hash_str, l_value_str, NODE_ADDR_FP_ARGS(a_node_addr));
+    s_stake_recalculate_weights(a_signing_addr->net_id);
 }
 
 void dap_chain_net_srv_stake_key_invalidate(dap_chain_addr_t *a_signing_addr)
 {
-    assert(s_srv_stake);
     if (!a_signing_addr)
         return;
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_signing_addr->net_id);
+    dap_return_if_fail(l_srv_stake);
     dap_chain_net_srv_stake_item_t *l_stake = NULL;
-    HASH_FIND(hh, s_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake);
+    HASH_FIND(hh, l_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake);
     if (l_stake) {
         dap_chain_esbocs_remove_validator_from_clusters(l_stake->signing_addr.net_id, &l_stake->node_addr);
-        HASH_DEL(s_srv_stake->itemlist, l_stake);
-        HASH_DELETE(ht, s_srv_stake->tx_itemlist, l_stake);
+        HASH_DEL(l_srv_stake->itemlist, l_stake);
+        HASH_DELETE(ht, l_srv_stake->tx_itemlist, l_stake);
         char l_key_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
         dap_chain_hash_fast_to_str(&a_signing_addr->data.hash_fast,
                                    l_key_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
-        char *l_value_str; dap_uint256_to_char(l_stake->value, &l_value_str);
-        log_it(L_NOTICE, "Removed key with fingerprint %s and value %s for node "NODE_ADDR_FP_STR,
+        const char *l_value_str; dap_uint256_to_char(l_stake->locked_value, &l_value_str);
+        log_it(L_NOTICE, "Removed key with fingerprint %s and locked value %s for node "NODE_ADDR_FP_STR,
                             l_key_hash_str, l_value_str, NODE_ADDR_FP_ARGS_S(l_stake->node_addr));
         DAP_DELETE(l_stake);
     }
+    s_stake_recalculate_weights(a_signing_addr->net_id);
 }
 
-void dap_chain_net_srv_stake_set_allowed_min_value(uint256_t a_value)
+void dap_chain_net_srv_stake_set_allowed_min_value(dap_chain_net_id_t a_net_id, uint256_t a_value)
 {
-    assert(s_srv_stake);
-    s_srv_stake->delegate_allowed_min = a_value;
-    for (dap_chain_net_srv_stake_item_t *it = s_srv_stake->itemlist; it; it = it->hh.next)
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id);
+    dap_return_if_fail(l_srv_stake);
+    l_srv_stake->delegate_allowed_min = a_value;
+    for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next)
         if (dap_hash_fast_is_blank(&it->tx_hash))
             it->value = a_value;
 }
 
-uint256_t dap_chain_net_srv_stake_get_allowed_min_value()
+void dap_chain_net_srv_stake_set_percent_max(dap_chain_net_id_t a_net_id, uint256_t a_value)
 {
-    assert(s_srv_stake);
-    return s_srv_stake->delegate_allowed_min;
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id);
+    dap_return_if_fail(l_srv_stake);
+    l_srv_stake->delegate_percent_max = a_value;
+    s_stake_recalculate_weights(a_net_id);
 }
 
-int dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_signing_addr)
+uint256_t dap_chain_net_srv_stake_get_allowed_min_value(dap_chain_net_id_t a_net_id)
 {
-    assert(s_srv_stake);
-    if (!a_signing_addr)
-        return 0;
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id);
+    dap_return_val_if_fail(l_srv_stake, uint256_0);
+    return l_srv_stake->delegate_allowed_min;
+}
+
+uint256_t dap_chain_net_srv_stake_get_percent_max(dap_chain_net_id_t a_net_id)
+{
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id);
+    dap_return_val_if_fail(l_srv_stake, uint256_0);
+    return l_srv_stake->delegate_percent_max;
+}
 
+int dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_signing_addr)
+{
+    dap_return_val_if_fail(a_signing_addr, 0);
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_signing_addr->net_id);
+    dap_return_val_if_fail(l_srv_stake, 0);
     dap_chain_net_srv_stake_item_t *l_stake = NULL;
-    HASH_FIND(hh, s_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake);
+    HASH_FIND(hh, l_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake);
     if (l_stake) // public key delegated for this network
         return l_stake->is_active ? 1 : -1;
     return 0;
 }
 
-dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id, bool a_only_active)
+dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id, bool a_only_active, uint16_t **a_excluded_list)
 {
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id);
+    dap_return_val_if_fail(l_srv_stake, NULL);
+    if (!l_srv_stake->itemlist)
+        return NULL;
     dap_list_t *l_ret = NULL;
-    if (!s_srv_stake || !s_srv_stake->itemlist)
-        return l_ret;
-    for (dap_chain_net_srv_stake_item_t *l_stake = s_srv_stake->itemlist; l_stake; l_stake = l_stake->hh.next)
-        if (a_net_id.uint64 == l_stake->signing_addr.net_id.uint64 &&
-                a_only_active ? l_stake->is_active : true)
-            l_ret = dap_list_append(l_ret, DAP_DUP(l_stake));
+    const uint16_t l_arr_resize_step = 64;
+    size_t l_arr_size = l_arr_resize_step, l_arr_idx = 1, l_list_idx = 0;
+    if (a_excluded_list)
+        DAP_NEW_Z_COUNT_RET_VAL(*a_excluded_list, uint16_t, l_arr_size, NULL, NULL);
+    for (dap_chain_net_srv_stake_item_t *l_stake = l_srv_stake->itemlist; l_stake; l_stake = l_stake->hh.next) {
+        if (l_stake->is_active || !a_only_active) {
+            void *l_data = DAP_DUP(l_stake);
+            if (!l_data)
+                goto fail_ret;
+            l_ret = dap_list_append(l_ret, l_data);
+        }
+        if (!l_stake->is_active && a_excluded_list) {
+            *a_excluded_list[l_arr_idx++] = l_list_idx;
+            if (l_arr_idx == l_arr_size) {
+                l_arr_size += l_arr_resize_step;
+                void *l_new_arr = DAP_REALLOC(*a_excluded_list, l_arr_size * sizeof(uint16_t));
+                if (l_new_arr)
+                    goto fail_ret;
+                else
+                    *a_excluded_list = l_new_arr;
+            }
+        }
+        l_list_idx++;
+    }
     return l_ret;
+fail_ret:
+    log_it(L_CRITICAL, "%s", g_error_memory_alloc);
+    dap_list_free_full(l_ret, NULL);
+    if (a_excluded_list)
+        DAP_DELETE(*a_excluded_list);
+    return NULL;
 }
 
 int dap_chain_net_srv_stake_mark_validator_active(dap_chain_addr_t *a_signing_addr, bool a_on_off)
 {
-    assert(s_srv_stake);
-    if (!a_signing_addr)
-        return -1;
-
+    dap_return_val_if_fail(a_signing_addr, -1);
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_signing_addr->net_id);
+    dap_return_val_if_fail(l_srv_stake, -3);
     dap_chain_net_srv_stake_item_t *l_stake = NULL;
-    HASH_FIND(hh, s_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake);
+    HASH_FIND(hh, l_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake);
     if (l_stake) { // public key delegated for this network
         l_stake->is_active = a_on_off;
         return 0;
@@ -390,11 +496,9 @@ int dap_chain_net_srv_stake_mark_validator_active(dap_chain_addr_t *a_signing_ad
 
 int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_node_addr)
 {
-    assert(s_srv_stake);
-    if (!a_signing_addr || !a_node_addr){
-        log_it(L_WARNING, "Bad srv_stake_verify arguments");
-        return -100;
-    }
+    dap_return_val_if_fail(a_signing_addr && a_node_addr, -100);
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_signing_addr->net_id);
+    dap_return_val_if_fail(l_srv_stake, -104);
 
     if (dap_chain_addr_is_blank(a_signing_addr) || a_node_addr->uint64 == 0) {
         log_it(L_WARNING, "Trying to approve bad delegating TX. Node or key addr is blank");
@@ -402,7 +506,7 @@ int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t *a_signing_addr
     }
 
     dap_chain_net_srv_stake_item_t *l_stake = NULL, *l_tmp = NULL;
-    HASH_ITER(hh, s_srv_stake->itemlist, l_stake, l_tmp){
+    HASH_ITER(hh, l_srv_stake->itemlist, l_stake, l_tmp){
         //check key not activated for other node
         if(dap_chain_addr_compare(a_signing_addr, &l_stake->signing_addr)){
             char l_key_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
@@ -427,10 +531,12 @@ int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t *a_signing_addr
     return 0;
 }
 
-static bool s_stake_cache_check_tx(dap_hash_fast_t *a_tx_hash)
+static bool s_stake_cache_check_tx(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash)
 {
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_ledger->net->pub.id);
+    dap_return_val_if_fail(l_srv_stake, false);
     dap_chain_net_srv_stake_cache_item_t *l_stake;
-    HASH_FIND(hh, s_srv_stake->cache, a_tx_hash, sizeof(*a_tx_hash), l_stake);
+    HASH_FIND(hh, l_srv_stake->cache, a_tx_hash, sizeof(*a_tx_hash), l_stake);
     if (l_stake) {
         dap_chain_net_srv_stake_key_invalidate(&l_stake->signing_addr);
         return true;
@@ -457,6 +563,9 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net)
         log_it(L_DEBUG, "Stake cache data not found");
         return -2;
     }
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net->pub.id);
+    dap_return_val_if_fail(l_srv_stake, -4);
+
     for (size_t i = 0; i < l_objs_count; i++){
         dap_chain_net_srv_stake_cache_data_t *l_cache_data =
                 (dap_chain_net_srv_stake_cache_data_t *)l_objs[i].value;
@@ -467,7 +576,7 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net)
         }
         l_cache->signing_addr   = l_cache_data->signing_addr;
         l_cache->tx_hash        = l_cache_data->tx_hash;
-        HASH_ADD(hh, s_srv_stake->cache, tx_hash, sizeof(dap_hash_fast_t), l_cache);
+        HASH_ADD(hh, l_srv_stake->cache, tx_hash, sizeof(dap_hash_fast_t), l_cache);
     }
     dap_global_db_objs_delete(l_objs, l_objs_count);
     dap_ledger_set_cache_tx_check_callback(l_ledger, s_stake_cache_check_tx);
@@ -666,7 +775,7 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t
         log_it(L_WARNING, "Requested conditional transaction have another ticker (not %s)", l_delegated_ticker);
         return NULL;
     }
-    if (compare256(l_tx_out_cond->header.value, s_srv_stake->delegate_allowed_min) == -1) {
+    if (compare256(l_tx_out_cond->header.value, dap_chain_net_srv_stake_get_allowed_min_value(a_net->pub.id)) == -1) {
         log_it(L_WARNING, "Requested conditional transaction have not enough funds");
         return NULL;
     }
@@ -688,7 +797,7 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t
         log_it(L_CRITICAL, "%s", g_error_memory_alloc);
         return NULL;
     }
-    l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH;
+    l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH;
     l_tsd->size = sizeof(dap_hash_fast_t);
     *(dap_hash_fast_t*)(l_tsd->data) = *a_stake_tx_hash;
     l_tsd_list = dap_list_append(l_tsd_list, l_tsd);
@@ -1019,85 +1128,31 @@ static dap_chain_datum_decree_t *s_stake_decree_invalidate(dap_chain_net_t *a_ne
     return l_decree;
 }
 
-static dap_chain_datum_decree_t *s_stake_decree_set_min_stake(dap_chain_net_t *a_net, uint256_t a_value, dap_cert_t *a_cert)
+static dap_chain_datum_decree_t *s_stake_decree_set_max_weight(dap_chain_net_t *a_net, dap_chain_t *a_chain,
+                                                                uint256_t a_value, dap_cert_t *a_cert)
 {
-    size_t l_total_tsd_size = 0;
-    dap_chain_datum_decree_t *l_decree = NULL;
-    dap_list_t *l_tsd_list = NULL;
-    dap_tsd_t *l_tsd = NULL;
-
-    l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(uint256_t);
-    l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size);
-    if (!l_tsd) {
-        log_it(L_CRITICAL, "%s", g_error_memory_alloc);
-        return NULL;
-    }
-    l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE;
-    l_tsd->size = sizeof(uint256_t);
-    *(uint256_t*)(l_tsd->data) = a_value;
-    l_tsd_list = dap_list_append(l_tsd_list, l_tsd);
-
-    l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size);
-    if (!l_decree) {
-        log_it(L_CRITICAL, "%s", g_error_memory_alloc);
-        dap_list_free_full(l_tsd_list, NULL);
-        return NULL;
-    }
-    l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION;
-    l_decree->header.ts_created = dap_time_now();
-    l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON;
-    l_decree->header.common_decree_params.net_id = a_net->pub.id;
-    dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR);
-    if (!l_chain)
-        l_chain =  dap_chain_net_get_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR);
-    if (!l_chain) {
-        log_it(L_ERROR, "No chain supported anchor datum type");
-        DAP_DEL_Z(l_decree);
-        dap_list_free_full(l_tsd_list, NULL);
+    size_t l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint256_t);
+    dap_chain_datum_decree_t *l_decree = dap_chain_datum_decree_new(a_net->pub.id, a_chain->id,
+                                                                    *dap_chain_net_get_cur_cell(a_net), l_total_tsd_size);
+    if (!l_decree)
         return NULL;
-    }
-    l_decree->header.common_decree_params.chain_id = l_chain->id;
-    l_decree->header.common_decree_params.cell_id = *dap_chain_net_get_cur_cell(a_net);
-    l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE;
-    l_decree->header.data_size = l_total_tsd_size;
-    l_decree->header.signs_size = 0;
-
-    size_t l_data_tsd_offset = 0;
-    for ( dap_list_t* l_iter=dap_list_first(l_tsd_list); l_iter; l_iter=l_iter->next){
-        dap_tsd_t * l_b_tsd = (dap_tsd_t *) l_iter->data;
-        size_t l_tsd_size = dap_tsd_size(l_b_tsd);
-        memcpy((byte_t*)l_decree->data_n_signs + l_data_tsd_offset, l_b_tsd, l_tsd_size);
-        l_data_tsd_offset += l_tsd_size;
-    }
-    dap_list_free_full(l_tsd_list, NULL);
-
-    size_t l_cur_sign_offset = l_decree->header.data_size + l_decree->header.signs_size;
-    size_t l_total_signs_size = l_decree->header.signs_size;
+    l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT;
+    dap_tsd_write(l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE, &a_value, sizeof(uint256_t));
+    return dap_chain_datum_decree_sign_in_cycle(&a_cert, l_decree, 1, NULL);
+}
 
-    dap_sign_t * l_sign = dap_cert_sign(a_cert,  l_decree,
-       sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size, 0);
 
-    if (l_sign) {
-        size_t l_sign_size = dap_sign_get_size(l_sign);
-        l_decree = DAP_REALLOC(l_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size);
-        if (!l_decree) {
-            log_it(L_CRITICAL, "%s", g_error_memory_alloc);
-            DAP_DELETE(l_sign);
-            return NULL;
-        }
-        memcpy((byte_t*)l_decree->data_n_signs + l_cur_sign_offset, l_sign, l_sign_size);
-        l_total_signs_size += l_sign_size;
-        l_cur_sign_offset += l_sign_size;
-        l_decree->header.signs_size = l_total_signs_size;
-        DAP_DELETE(l_sign);
-        log_it(L_DEBUG,"<-- Signed with '%s'", a_cert->name);
-    }else{
-        log_it(L_ERROR, "Decree signing failed");
-        DAP_DELETE(l_decree);
+static dap_chain_datum_decree_t *s_stake_decree_set_min_stake(dap_chain_net_t *a_net, dap_chain_t *a_chain,
+                                                              uint256_t a_value, dap_cert_t *a_cert)
+{
+    size_t l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint256_t);
+    dap_chain_datum_decree_t *l_decree = dap_chain_datum_decree_new(a_net->pub.id, a_chain->id,
+                                                                    *dap_chain_net_get_cur_cell(a_net), l_total_tsd_size);
+    if (!l_decree)
         return NULL;
-    }
-
-    return l_decree;
+    l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE;
+    dap_tsd_write(l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE, &a_value, sizeof(uint256_t));
+    return dap_chain_datum_decree_sign_in_cycle(&a_cert, l_decree, 1, NULL);
 }
 
 char *s_fee_order_create(dap_chain_net_t *a_net, uint256_t *a_fee, dap_enc_key_t *a_key, const char *a_hash_out_type)
@@ -1273,7 +1328,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
         uint256_t l_tax = dap_chain_coins_to_balance(l_tax_str);
         if (compare256(l_tax, dap_chain_coins_to_balance("100.0")) == 1 ||
                 compare256(l_tax, GET_256_FROM_64(100)) == -1) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or eqal than 100%% and higher or eqal than 1.0e-16%%");
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or equal than 100%% and higher or equal than 1.0e-16%%");
             return -10;
         }
         const char *l_cert_str = NULL;
@@ -1348,7 +1403,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
         uint256_t l_tax = dap_chain_coins_to_balance(l_tax_str);
         if (compare256(l_tax, dap_chain_coins_to_balance("100.0")) == 1 ||
                 compare256(l_tax, GET_256_FROM_64(100)) == -1) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or eqal than 100%% and higher or eqal than 1.0e-16%%");
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or equal than 100%% and higher or equal than 1.0e-16%%");
             return -10;
         }
         dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_wallet_str);
@@ -1513,7 +1568,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
                         dap_string_append(l_reply_str, "Value in this order type means minimum value of m-tokens for validator acceptable for key delegation with supplied tax\n"
                                                        "Order external params:\n");
                         struct validator_odrer_ext *l_ext = (struct validator_odrer_ext *)l_order->ext_n_sign;
-                        char *l_coins_str;
+                        const char *l_coins_str;
                         dap_uint256_to_char(l_ext->tax, &l_coins_str);
                         dap_string_append_printf(l_reply_str, "  tax:              %s%%\n", l_coins_str);
                         dap_uint256_to_char(l_ext->value_max, &l_coins_str);
@@ -1537,7 +1592,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
                             }
                         }
                         if (!l_error) {
-                            char *l_tax_str; dap_uint256_to_char(l_tax, &l_tax_str);
+                            const char *l_tax_str; dap_uint256_to_char(l_tax, &l_tax_str);
                             dap_string_append_printf(l_reply_str, "  sovereign_tax:    %s%%\n  sovereign_addr:   %s\n",
                                 l_tax_str, dap_chain_addr_to_str(&l_addr));
                         } else
@@ -1751,7 +1806,7 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
             struct validator_odrer_ext *l_ext = (struct validator_odrer_ext *)l_order->ext_n_sign;
             l_sovereign_tax = l_ext->tax;
             if (l_order_hash_str && compare256(l_value, l_order->price) == -1) {
-                char *l_coin_min_str, *l_value_min_str =
+                const char *l_coin_min_str, *l_value_min_str =
                     dap_uint256_to_char(l_order->price, &l_coin_min_str);
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Number in '-value' param %s is lower than order minimum allowed value %s(%s)",
                                                   l_value_str, l_coin_min_str, l_value_min_str);
@@ -1759,7 +1814,7 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
                 return -13;
             }
             if (l_order_hash_str && compare256(l_value, l_ext->value_max) == 1) {
-                char *l_coin_max_str, *l_value_max_str =
+                const char *l_coin_max_str, *l_value_max_str =
                     dap_uint256_to_char(l_ext->value_max, &l_coin_max_str);
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Number in '-value' param %s is higher than order minimum allowed value %s(%s)",
                                                   l_value_str, l_coin_max_str, l_value_max_str);
@@ -1787,7 +1842,7 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
         DAP_DELETE(l_order);
         if (compare256(l_sovereign_tax, dap_chain_coins_to_balance("100.0")) == 1 ||
                 compare256(l_sovereign_tax, GET_256_FROM_64(100)) == -1) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or eqal than 100%% and higher or eqal than 1.0e-16%%");
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or equal than 100%% and higher or equal than 1.0e-16%%");
             dap_enc_key_delete(l_enc_key);
             return -29;
         }
@@ -1800,8 +1855,9 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
         dap_chain_wallet_close(l_wallet);
         return l_check_result;
     }
-    if (compare256(l_value, s_srv_stake->delegate_allowed_min) == -1) {
-        char *l_coin_min_str, *l_value_min_str = dap_uint256_to_char(s_srv_stake->delegate_allowed_min, &l_coin_min_str);
+    uint256_t l_allowed_min = dap_chain_net_srv_stake_get_allowed_min_value(l_net->pub.id);
+    if (compare256(l_value, l_allowed_min) == -1) {
+        const char *l_coin_min_str, *l_value_min_str = dap_uint256_to_char(l_allowed_min, &l_coin_min_str);
         dap_cli_server_cmd_set_reply_text(a_str_reply, "Number in '-value' param %s is lower than minimum allowed value %s(%s)",
                                           l_value_str, l_coin_min_str, l_value_min_str);
         dap_enc_key_delete(l_enc_key);
@@ -1925,8 +1981,13 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index
             }
             dap_chain_addr_fill(&l_signing_addr, dap_sign_type_from_str(l_signing_pkey_type_str), &l_pkey_hash, l_net->pub.id);
         }
+        dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id);
+        if (!l_srv_stake) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified net have no stake service activated");
+            return -25;
+        }
         dap_chain_net_srv_stake_item_t *l_stake;
-        HASH_FIND(hh, s_srv_stake->itemlist, &l_signing_addr, sizeof(dap_chain_addr_t), l_stake);
+        HASH_FIND(hh, l_srv_stake->itemlist, &l_signing_addr, sizeof(dap_chain_addr_t), l_stake);
         if (!l_stake) {
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate/pkey hash is not delegated nor this delegating is approved."
                                                            " Try to invalidate with tx hash instead");
@@ -1957,8 +2018,13 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index
         }
     }
     if (l_tx_hash_str || l_cert_str) {
+        dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id);
+        if (!l_srv_stake) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified net have no stake service activated");
+            return -25;
+        }
         dap_chain_net_srv_stake_item_t *l_stake;
-        HASH_FIND(ht, s_srv_stake->tx_itemlist, &l_tx_hash, sizeof(dap_hash_t), l_stake);
+        HASH_FIND(ht, l_srv_stake->tx_itemlist, &l_tx_hash, sizeof(dap_hash_t), l_stake);
         if (l_stake) {
             char l_pkey_hash_str[DAP_HASH_FAST_STR_SIZE]; 
             dap_hash_fast_to_str(&l_stake->signing_addr.data.hash_fast, l_pkey_hash_str, DAP_HASH_FAST_STR_SIZE);
@@ -2022,17 +2088,6 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index
     return 0;
 }
 
-DAP_STATIC_INLINE bool s_chain_esbocs_started(dap_chain_net_t *a_net)
-{
-    dap_chain_t *l_chain;
-    DL_FOREACH(a_net->pub.chains, l_chain) {
-        if (!strcmp(DAP_CHAIN_PVT(l_chain)->cs_name, "esbocs") &&
-                DAP_CHAIN_PVT(l_chain)->cs_started)
-            return true;
-    }
-    return false;
-}
-
 static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, uint256_t a_total_weight, dap_string_t *a_string)
 {
     char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE], l_pkey_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
@@ -2044,9 +2099,9 @@ static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, uint256_t
     DIV_256_COIN(l_tmp, a_total_weight, &l_rel_weight);
     char *l_rel_weight_str = dap_chain_balance_to_coins(l_rel_weight);
     char l_active_str[32] = {};
-    if (s_chain_esbocs_started(a_stake->net))
+    if (dap_chain_esbocs_started(a_stake->signing_addr.net_id))
         snprintf(l_active_str, 32, "\tActive: %s\n", a_stake->is_active ? "true" : "false");
-    char *l_sov_addr_str = dap_chain_addr_is_blank(&a_stake->sovereign_addr) ?
+    const char *l_sov_addr_str = dap_chain_addr_is_blank(&a_stake->sovereign_addr) ?
                 "null" : dap_chain_addr_to_str(&a_stake->sovereign_addr);
     uint256_t l_sov_tax_percent = uint256_0;
     MULT_256_256(a_stake->sovereign_tax, GET_256_FROM_64(100), &l_sov_tax_percent);
@@ -2096,8 +2151,11 @@ static void s_get_tx_filter_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_
     dap_hash_fast_t l_datum_hash = *a_tx_hash;
     if (dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_datum_hash, l_out_idx_tmp, NULL))
         return;
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net->pub.id);
+    if (!l_srv_stake)
+        return;
     dap_chain_net_srv_stake_item_t *l_stake = NULL;
-    HASH_FIND(ht, s_srv_stake->tx_itemlist, &l_datum_hash, sizeof(dap_hash_fast_t), l_stake);
+    HASH_FIND(ht, l_srv_stake->tx_itemlist, &l_datum_hash, sizeof(dap_hash_fast_t), l_stake);
     if (!l_stake)
         l_args->ret = dap_list_append(l_args->ret,a_tx);
 }
@@ -2204,9 +2262,11 @@ int dap_chain_net_srv_stake_check_validator(dap_chain_net_t * a_net, dap_hash_fa
 
 uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id)
 {
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id);
+    dap_return_val_if_fail(l_srv_stake, uint256_0);
     uint256_t l_total_weight = uint256_0;
-    for (dap_chain_net_srv_stake_item_t *it = s_srv_stake->itemlist; it; it = it->hh.next) {
-        if (it->net->pub.id.uint64 != a_net_id.uint64)
+    for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next) {
+        if (it->signing_addr.net_id.uint64 != a_net_id.uint64)
             continue;
         SUM_256_256(l_total_weight, it->value, &l_total_weight);
     }
@@ -2216,7 +2276,7 @@ uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id)
 static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
 {
     enum {
-        CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_APPROVE, CMD_LIST, CMD_INVALIDATE, CMD_MIN_VALUE, CMD_CHECK
+        CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_APPROVE, CMD_LIST, CMD_INVALIDATE, CMD_MIN_VALUE, CMD_CHECK, CMD_MAX_WEIGHT
     };
     int l_arg_index = 1;
 
@@ -2248,10 +2308,13 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
     else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "invalidate", NULL)) {
         l_cmd_num = CMD_INVALIDATE;
     }
-    // RSetss stake minimum value
+    // Set stake minimum value
     else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "min_value", NULL)) {
         l_cmd_num = CMD_MIN_VALUE;
     }
+    else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "max_weight", NULL)) {
+        l_cmd_num = CMD_MAX_WEIGHT;
+    }
     else if(dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "check", NULL)) {
         l_cmd_num = CMD_CHECK;
     }
@@ -2413,6 +2476,11 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
                     return -4;
                 }
+                dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id);
+                if (!l_srv_stake) {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified net have no stake service activated");
+                    return -25;
+                }
                 dap_chain_net_srv_stake_item_t *l_stake = NULL;
                 dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str);
                 if (l_cert_str) {
@@ -2426,7 +2494,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
                         dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is wrong");
                         return -20;
                     }
-                    HASH_FIND(hh, s_srv_stake->itemlist, &l_signing_addr, sizeof(dap_chain_addr_t), l_stake);
+                    HASH_FIND(hh, l_srv_stake->itemlist, &l_signing_addr, sizeof(dap_chain_addr_t), l_stake);
                     if (!l_stake) {
                         dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate isn't delegated nor approved");
                         return -21;
@@ -2440,7 +2508,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
                         dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified pkey hash is wrong");
                         return -20;
                     }
-                    l_stake = dap_chain_net_srv_stake_check_pkey_hash(&l_pkey_hash);
+                    l_stake = dap_chain_net_srv_stake_check_pkey_hash(l_net->pub.id, &l_pkey_hash);
                     if (!l_stake) {
                         dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified pkey hash isn't delegated nor approved");
                         return -21;
@@ -2453,31 +2521,38 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
                 if (l_stake)
                     s_srv_stake_print(l_stake, l_total_weight, l_reply_str);
                 else
-                    for (l_stake = s_srv_stake->itemlist; l_stake; l_stake = l_stake->hh.next) {
-                        if (l_stake->net->pub.id.uint64 != l_net->pub.id.uint64)
-                            continue;
+                    for (l_stake = l_srv_stake->itemlist; l_stake; l_stake = l_stake->hh.next) {
                         l_total_count++;
                         if (!l_stake->is_active)
                             l_inactive_count++;
                         s_srv_stake_print(l_stake, l_total_weight, l_reply_str);
                     }
-                if (!HASH_CNT(hh, s_srv_stake->itemlist)) {
+                if (!HASH_CNT(hh, l_srv_stake->itemlist)) {
                     dap_string_append(l_reply_str, "No keys found\n");
                 } else {
                     if (!l_cert_str && !l_pkey_hash_str)
                         dap_string_append_printf(l_reply_str, "Total keys count: %zu\n", l_total_count);
-                    if (s_chain_esbocs_started(l_net))
+                    if (dap_chain_esbocs_started(l_net->pub.id))
                         dap_string_append_printf(l_reply_str, "Inactive keys count: %zu\n", l_inactive_count);
-                    char *l_total_weight_coins, *l_total_weight_str =
+                    const char *l_total_weight_coins, *l_total_weight_str =
                             dap_uint256_to_char(l_total_weight, &l_total_weight_coins);
                     dap_string_append_printf(l_reply_str, "Total weight: %s (%s)\n", l_total_weight_coins, l_total_weight_str);
                 }
 
-                char *l_delegate_min_str; dap_uint256_to_char(s_srv_stake->delegate_allowed_min, &l_delegate_min_str);
+                const char *l_delegate_min_str; dap_uint256_to_char(dap_chain_net_srv_stake_get_allowed_min_value(l_net->pub.id),
+                                                                    &l_delegate_min_str);
                 char l_delegated_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
                 dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker, l_net->pub.native_ticker);
-                dap_string_append_printf(l_reply_str, "Minimum value for key delegating: %s %s",
+                dap_string_append_printf(l_reply_str, "Minimum value for key delegating: %s %s\n",
                                          l_delegate_min_str, l_delegated_ticker);
+                uint256_t l_percent_max = dap_chain_net_srv_stake_get_percent_max(l_net->pub.id);
+                const char *l_percent_max_str = NULL;
+                if (!IS_ZERO_256(l_percent_max)) {
+                    MULT_256_256(l_percent_max, GET_256_FROM_64(100), &l_percent_max);
+                    dap_uint256_to_char(l_percent_max, &l_percent_max_str);
+                }
+                dap_string_append_printf(l_reply_str, "Maximum related weight of each validator: %s%%\n",
+                                         IS_ZERO_256(l_percent_max) ? "100" : l_percent_max_str);
                 *a_str_reply = dap_string_free(l_reply_str, false);
             } else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "tx", NULL)) {
                 const char *l_net_str = NULL;
@@ -2504,9 +2579,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
                 dap_chain_tx_out_cond_t *l_tx_out_cond = NULL;
                 int l_out_idx_tmp = 0;
                 char *spaces = {"--------------------------------------------------------------------------------------------------------------------"};
-                char *l_signing_addr_str = NULL;
-                char *l_balance = NULL;
-                char *l_coins = NULL;
+                const char *l_signing_addr_str = NULL, *l_balance = NULL, *l_coins = NULL;
                 char* l_node_address_text_block = NULL;
                 dap_chain_net_get_tx_all(l_net,TX_SEARCH_TYPE_NET,s_get_tx_filter_callback, l_args);
                 l_args->ret = dap_list_sort(l_args->ret, s_callback_compare_tx_list);
@@ -2560,10 +2633,16 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
                 return -4;
             }
-
-            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str);
+            dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_ANCHOR);
+            if (!l_chain)
+                l_chain =  dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_ANCHOR);
+            if (!l_chain) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "No chain supported anchor datum type");
+                return -2;
+            }
+            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-poa_cert", &l_cert_str);
             if (!l_cert_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' requires parameter -cert");
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' requires parameter -poa_cert");
                 return -3;
             }
             dap_cert_t *l_poa_cert = dap_cert_find_by_name(l_cert_str);
@@ -2587,7 +2666,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
                 return -10;
             }
 
-            dap_chain_datum_decree_t *l_decree = s_stake_decree_set_min_stake(l_net, l_value, l_poa_cert);
+            dap_chain_datum_decree_t *l_decree = s_stake_decree_set_min_stake(l_net, l_chain, l_value, l_poa_cert);
             char *l_decree_hash_str = NULL;
             if (l_decree && (l_decree_hash_str = s_stake_decree_put(l_decree, l_net))) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum stake value has been set."
@@ -2601,6 +2680,72 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
             }
         } break;
 
+        case CMD_MAX_WEIGHT: {
+            const char *l_net_str = NULL,
+                       *l_cert_str = NULL,
+                       *l_value_str = NULL;
+            l_arg_index++;
+            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
+            if (!l_net_str) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' requires parameter -net");
+                return -3;
+            }
+            dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
+            if (!l_net) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
+                return -4;
+            }
+            dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_ANCHOR);
+            if (!l_chain)
+                l_chain =  dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_ANCHOR);
+            if (!l_chain) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "No chain supported anchor datum type");
+                return -2;
+            }
+            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-poa_cert", &l_cert_str);
+            if (!l_cert_str) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' requires parameter -poa_cert");
+                return -3;
+            }
+            dap_cert_t *l_poa_cert = dap_cert_find_by_name(l_cert_str);
+            if (!l_poa_cert) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found");
+                return -25;
+            }
+            if (!s_srv_stake_is_poa_cert(l_net, l_poa_cert->enc_key)) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is not PoA root one");
+                return -26;
+            }
+
+            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-percent", &l_value_str);
+            if (!l_value_str) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' requires parameter -percent");
+                return -9;
+            }
+            uint256_t l_value = dap_chain_balance_scan(l_value_str);
+            if (IS_ZERO_256(l_value)) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-percent' param");
+                return -10;
+            }
+            if (compare256(l_value, dap_chain_coins_to_balance("100.0")) >= 0) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Percent must be lower than 100%%");
+                return -29;
+            }
+            DIV_256(l_value, GET_256_FROM_64(100), &l_value);
+            dap_chain_datum_decree_t *l_decree = s_stake_decree_set_max_weight(l_net, l_chain, l_value, l_poa_cert);
+            char *l_decree_hash_str = NULL;
+            if (l_decree && (l_decree_hash_str = s_stake_decree_put(l_decree, l_net))) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Maximum weight has been set."
+                                                                " Decree hash %s", l_decree_hash_str);
+                DAP_DELETE(l_decree);
+                DAP_DELETE(l_decree_hash_str);
+            } else {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Maximum weight setting failed");
+                DAP_DEL_Z(l_decree);
+                return -21;
+            }
+        } break;
+
         default: {
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Command %s not recognized", a_argv[l_arg_index]);
             return -1;
@@ -2672,7 +2817,7 @@ void dap_chain_net_srv_stake_get_fee_validators_str(dap_chain_net_t *a_net, dap_
     uint256_t l_min = uint256_0, l_max = uint256_0, l_average = uint256_0, l_median = uint256_0;
     dap_chain_net_srv_stake_get_fee_validators(a_net, &l_max, &l_average, &l_min, &l_median);
     const char *l_native_token  = a_net->pub.native_ticker;
-    char *l_coins_str,
+    const char *l_coins_str,
     *l_min_balance      = dap_strdup(dap_uint256_to_char(l_min, &l_coins_str)),     *l_min_coins    = dap_strdup(l_coins_str),
     *l_max_balance      = dap_strdup(dap_uint256_to_char(l_max, &l_coins_str)),     *l_max_coins    = dap_strdup(l_coins_str),
     *l_average_balance  = dap_strdup(dap_uint256_to_char(l_average, &l_coins_str)), *l_average_coins= dap_strdup(l_coins_str),
@@ -2699,7 +2844,7 @@ json_object *dap_chain_net_srv_stake_get_fee_validators_json(dap_chain_net_t  *a
                 *l_jobj_average = json_object_new_object(), *l_jobj_median  = json_object_new_object(),
                 *l_jobj_ret     = json_object_new_object();
                 
-    char *l_coins_str;
+    const char *l_coins_str;
     json_object_object_add( l_jobj_min,     "balance",  json_object_new_string(dap_uint256_to_char(l_min, &l_coins_str)) );
     json_object_object_add( l_jobj_min,     "coin",     json_object_new_string(l_coins_str) );
 
@@ -2735,12 +2880,13 @@ static void s_cache_data(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap
         log_it(L_WARNING, "Stake service cache mismatch");
 }
 
-dap_chain_net_srv_stake_item_t *dap_chain_net_srv_stake_check_pkey_hash(dap_hash_fast_t *a_pkey_hash)
+dap_chain_net_srv_stake_item_t *dap_chain_net_srv_stake_check_pkey_hash(dap_chain_net_id_t a_net_id, dap_hash_fast_t *a_pkey_hash)
 {
-    if (!s_srv_stake)
+    dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id);
+    if (!l_srv_stake)
         return NULL;
     dap_chain_net_srv_stake_item_t *l_stake, *l_tmp;
-    HASH_ITER(hh, s_srv_stake->itemlist, l_stake, l_tmp) {
+    HASH_ITER(hh, l_srv_stake->itemlist, l_stake, l_tmp) {
         if (dap_hash_fast_compare(&l_stake->signing_addr.data.hash_fast, a_pkey_hash))
             return l_stake;
     }
diff --git a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h
index d8fea0a16e67d7554772ed8bdc30411388847ace..9772663f553ca3b7d7ac53fe6c52ecf83ef84ba6 100644
--- a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h
+++ b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h
@@ -25,10 +25,9 @@
 #pragma once
 
 #include "dap_chain_ledger.h"
-#include "dap_chain_net_srv.h"
-#include "dap_chain_net_srv_order.h"
 #include "dap_math_ops.h"
 #include "dap_stream_ch_chain_net.h"
+#include "dap_chain_datum_decree.h"
 
 #define DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID 0x13
 #define DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ORDERS 0x14
@@ -36,6 +35,7 @@
 typedef struct dap_chain_net_srv_stake_item {
     bool is_active;
     dap_chain_net_t *net;
+    uint256_t locked_value;
     uint256_t value;
     dap_chain_addr_t signing_addr;
     dap_chain_hash_fast_t tx_hash;
@@ -58,7 +58,9 @@ typedef struct dap_chain_net_srv_stake_cache_item {
 } dap_chain_net_srv_stake_cache_item_t;
 
 typedef struct dap_chain_net_srv_stake {
+    dap_chain_net_id_t net_id;
     uint256_t delegate_allowed_min;
+    uint256_t delegate_percent_max;
     dap_chain_net_srv_stake_item_t *itemlist;
     dap_chain_net_srv_stake_item_t *tx_itemlist;
     dap_chain_net_srv_stake_cache_item_t *cache;
@@ -67,15 +69,18 @@ typedef struct dap_chain_net_srv_stake {
 int dap_chain_net_srv_stake_pos_delegate_init();
 void dap_chain_net_srv_stake_pos_delegate_deinit();
 
+int dap_chain_net_srv_stake_net_add(dap_chain_net_id_t a_net_id);
 void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr_t *a_signing_addr, dap_hash_fast_t *a_stake_tx_hash,
                                           uint256_t a_value, dap_chain_node_addr_t *a_node_addr);
 void dap_chain_net_srv_stake_key_invalidate(dap_chain_addr_t *a_signing_addr);
-void dap_chain_net_srv_stake_set_allowed_min_value(uint256_t a_value);
-uint256_t dap_chain_net_srv_stake_get_allowed_min_value();
+void dap_chain_net_srv_stake_set_allowed_min_value(dap_chain_net_id_t a_net_id, uint256_t a_value);
+uint256_t dap_chain_net_srv_stake_get_allowed_min_value(dap_chain_net_id_t a_net_id);
+void dap_chain_net_srv_stake_set_percent_max(dap_chain_net_id_t a_net_id, uint256_t a_value);
+uint256_t dap_chain_net_srv_stake_get_percent_max(dap_chain_net_id_t a_net_id);
 
 int dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_addr);
 int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t* a_signing_addr, dap_chain_node_addr_t* a_node_addr);
-dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id, bool a_only_active);
+dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id, bool a_only_active, uint16_t **a_excluded_list);
 
 bool dap_chain_net_srv_stake_get_fee_validators(dap_chain_net_t *a_net,
                                                 uint256_t *a_max_fee, uint256_t *a_average_fee, uint256_t *a_min_fee, uint256_t *a_median_fee);
@@ -93,5 +98,5 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t
                                                                  dap_hash_fast_t *a_stake_tx_hash, dap_cert_t *a_cert);
 int dap_chain_net_srv_stake_mark_validator_active(dap_chain_addr_t *a_signing_addr, bool a_on_off);
 
-dap_chain_net_srv_stake_item_t *dap_chain_net_srv_stake_check_pkey_hash(dap_hash_fast_t *a_pkey_hash);
+dap_chain_net_srv_stake_item_t *dap_chain_net_srv_stake_check_pkey_hash(dap_chain_net_id_t a_net_id, dap_hash_fast_t *a_pkey_hash);
 uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id);
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 388aff570582b34acc57a6d3d5ced7f4c79419a4..f4b2d1436a5ee2795e93864dfeddacd7eb2cb911 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -34,7 +34,7 @@
 #include "dap_time.h"
 #include "dap_chain_net_srv.h"
 #include "dap_chain_ledger.h"
-#include "dap_chain_node_cli.h"
+#include "dap_chain_net_srv_order.h"
 #include "dap_common.h"
 #include "dap_hash.h"
 #include "dap_math_ops.h"
@@ -42,11 +42,11 @@
 #include "dap_chain_common.h"
 #include "dap_chain_mempool.h"
 #include "dap_chain_datum_decree.h"
-#include "dap_tsd.h"
 #include "dap_chain_net_tx.h"
 #include "dap_chain_net_srv.h"
 #include "dap_chain_net_srv_xchange.h"
 #include "uthash.h"
+#include "dap_cli_server.h"
 
 #define LOG_TAG "dap_chain_net_srv_xchange"
 
@@ -647,7 +647,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
             l_datoshi_buy = a_datoshi_buy;
         
         if (s_debug_more) {
-            char *l_datoshi_sell_str; dap_uint256_to_char(l_datoshi_sell, &l_datoshi_sell_str);
+            const char *l_datoshi_sell_str; dap_uint256_to_char(l_datoshi_sell, &l_datoshi_sell_str);
             log_it(L_NOTICE, "l_value_sell = %s %s", l_datoshi_sell_str, a_price->token_sell);
         }
         
@@ -671,14 +671,14 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
     }
     // transfer unselling coins (partial exchange)
     if (s_debug_more) {
-        char *l_value_str; dap_uint256_to_char(l_tx_out_cond->header.value, &l_value_str);
+        const char *l_value_str; dap_uint256_to_char(l_tx_out_cond->header.value, &l_value_str);
         log_it(L_NOTICE, "l_value_cond = %s", l_value_str);
     }
     
     if (compare256(l_tx_out_cond->header.value, l_datoshi_sell) == 1) {
         SUBTRACT_256_256(l_tx_out_cond->header.value, l_datoshi_sell, &l_value_back);
         if (s_debug_more) {
-            char *l_value_back_str; dap_uint256_to_char(l_value_back, &l_value_back_str);
+            const char *l_value_back_str; dap_uint256_to_char(l_value_back, &l_value_back_str);
             log_it(L_NOTICE, "l_value_unselled = %s", l_value_back_str);
         }
         
@@ -703,7 +703,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
         return NULL;
     }
     if (s_debug_more) {
-        char *l_buy_str; dap_uint256_to_char(l_datoshi_buy, &l_buy_str);
+        const char *l_buy_str; dap_uint256_to_char(l_datoshi_buy, &l_buy_str);
         log_it(L_NOTICE, "l_value_buy = %s %s", l_buy_str, a_price->token_buy);
     }
     
@@ -715,7 +715,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
             return NULL;
         }
         if (s_debug_more) {
-            char *l_fee_str; dap_uint256_to_char(a_datoshi_fee, &l_fee_str);
+            const char *l_fee_str; dap_uint256_to_char(a_datoshi_fee, &l_fee_str);
             log_it (L_NOTICE, "l_validator_fee = %s", l_fee_str);
         }
     }
@@ -727,7 +727,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
             return NULL;
         }
         if (s_debug_more) {
-            char *l_net_fee_str; dap_uint256_to_char(l_net_fee, &l_net_fee_str);
+            const char *l_net_fee_str; dap_uint256_to_char(l_net_fee, &l_net_fee_str);
             log_it(L_NOTICE, "l_net_fee = %s", l_net_fee_str);
         }
     }
@@ -739,7 +739,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
             return NULL;
         }
         if (s_debug_more) {
-            char *l_srv_fee_str; dap_uint256_to_char(l_service_fee, &l_srv_fee_str);
+            const char *l_srv_fee_str; dap_uint256_to_char(l_service_fee, &l_srv_fee_str);
             log_it(L_NOTICE, "l_service_fee = %s %s", 
                              l_srv_fee_str, l_service_ticker ? l_service_ticker : "<undefined>");
         }
@@ -754,9 +754,9 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
         }
     }
     if (s_debug_more) {
-        char *l_value_transfer_str; dap_uint256_to_char(l_value_transfer, &l_value_transfer_str);
+        const char *l_value_transfer_str; dap_uint256_to_char(l_value_transfer, &l_value_transfer_str);
         log_it(L_NOTICE, "l_value_transfer = %s", l_value_transfer_str);
-        char *l_value_back_str; dap_uint256_to_char(l_value_back, &l_value_back_str);
+        const char *l_value_back_str; dap_uint256_to_char(l_value_back, &l_value_back_str);
         log_it(L_NOTICE, "l_value_back = %s", l_value_back_str);
     }
     // fee back
@@ -770,9 +770,9 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
             }
         }
         if (s_debug_more) {
-            char *l_fee_transfer_str; dap_uint256_to_char(l_fee_transfer, &l_fee_transfer_str);
+            const char *l_fee_transfer_str; dap_uint256_to_char(l_fee_transfer, &l_fee_transfer_str);
             log_it(L_NOTICE, "l_fee_transfer = %s", l_fee_transfer_str);
-            char *l_val_back_str; dap_uint256_to_char(l_value_back, &l_val_back_str);
+            const char *l_val_back_str; dap_uint256_to_char(l_value_back, &l_val_back_str);
             log_it(L_NOTICE, "l_cashback = %s", l_val_back_str);
         }
     }
@@ -1507,7 +1507,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
             dap_hash_fast_t l_tx_hash = {};
             dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
 
-            char *l_amount_coins_str = "0.0", *l_amount_datoshi_str = "0";
+            const char *l_amount_coins_str = NULL, *l_amount_datoshi_str = NULL;
 
             uint64_t l_percent_completed = dap_chain_net_srv_xchange_get_order_completion_rate(l_net, l_order_tx_hash);
 
@@ -1518,10 +1518,8 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
             dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_create);
             l_tmp_buf[strlen(l_tmp_buf) - 1] = '\0';
 
-            if (l_out_cond_last_tx) {
+            if (l_out_cond_last_tx)
                 l_amount_datoshi_str = dap_uint256_to_char(l_out_cond_last_tx->header.value, &l_amount_coins_str);
-            }
-
 
             dap_cli_server_cmd_set_reply_text(a_str_reply, "orderHash: %s\n ts_created: %s (%"DAP_UINT64_FORMAT_U")\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n",
                                      dap_chain_hash_fast_to_str_static(&l_tx_hash),
@@ -1713,9 +1711,8 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
 
     switch(l_tx_type){
         case TX_TYPE_ORDER:{
-            char *l_rate_str = dap_chain_balance_to_coins(l_out_cond_item->subtype.srv_xchange.rate),
-                 *l_amount_str, 
-                 *l_amount_datoshi_str = dap_uint256_to_char(l_out_cond_item->header.value, &l_amount_str);
+            char *l_rate_str = dap_chain_balance_to_coins(l_out_cond_item->subtype.srv_xchange.rate);
+            const char *l_amount_str, *l_amount_datoshi_str = dap_uint256_to_char(l_out_cond_item->header.value, &l_amount_str);
 
             dap_string_append_printf(a_reply_str, "Hash: %s\n", l_tx_hash_str);
             if(a_print_ts){
@@ -1760,19 +1757,20 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
             if(a_print_status)
                 dap_string_append_printf(a_reply_str, "  Status: %s,", l_is_closed ? "inactive" : "active");
             
-            char *l_value_from_str, *l_value_from_datoshi_str = dap_uint256_to_char(l_value_from, &l_value_from_str);
+            const char *l_value_from_str, *l_value_from_datoshi_str = dap_uint256_to_char(l_value_from, &l_value_from_str);
             dap_string_append_printf(a_reply_str, "  changed %s (%s) %s", l_value_from_str, l_value_from_datoshi_str, l_tx_input_ticker);
 
-            char *l_value_to_str, *l_value_to_datoshi_str = dap_uint256_to_char(l_value_to, &l_value_to_str);
+            const char *l_value_to_str, *l_value_to_datoshi_str = dap_uint256_to_char(l_value_to, &l_value_to_str);
             dap_string_append_printf(a_reply_str, " for %s (%s) %s,", l_value_to_str, l_value_to_datoshi_str, l_buy_ticker);
 
-            char *l_rate_str; dap_uint256_to_char(l_rate, &l_rate_str);
+            const char *l_rate_str; dap_uint256_to_char(l_rate, &l_rate_str);
             dap_string_append_printf(a_reply_str, "  rate (%s/%s): %s,", l_buy_ticker, l_tx_input_ticker, l_rate_str);
 
-            char *l_amount_str = "0.0",
+            const char *l_amount_str = NULL,
                  *l_amount_datoshi_str = l_out_cond_item ? dap_uint256_to_char(l_out_cond_item->header.value, &l_amount_str) : "0";
-            dap_string_append_printf(a_reply_str, "  remain amount %s (%s) %s, net: %s", l_amount_str, l_amount_datoshi_str, l_tx_input_ticker, a_net->pub.name);
-            if(a_print_prev_hash)
+            dap_string_append_printf(a_reply_str, "  remain amount %s (%s) %s, net: %s", l_amount_str ? l_amount_str : "0.0",
+                                                                        l_amount_datoshi_str, l_tx_input_ticker, a_net->pub.name);
+            if (a_print_prev_hash)
                 dap_string_append_printf(a_reply_str, "\n  Prev cond: %s", l_tx_prev_cond_hash_str);
         } break;
         case TX_TYPE_INVALIDATE:{
@@ -2039,8 +2037,8 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
                 l_cp_rate = dap_chain_balance_to_coins(l_price->rate);
 
-                char *l_amount_coins_str = "0.0",
-                     *l_amount_datoshi_str = l_out_cond_last_tx ? dap_uint256_to_char(l_out_cond_last_tx->header.value, &l_amount_coins_str) : "0";
+                const char *l_amount_coins_str = NULL,
+                     *l_amount_datoshi_str = l_out_cond_last_tx ? dap_uint256_to_char(l_out_cond_last_tx->header.value, &l_amount_coins_str) : NULL;
                 dap_string_append_printf(l_reply_str, "orderHash: %s\n ts_created: %s (%"DAP_UINT64_FORMAT_U")\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n", l_tx_hash_str,
                                          l_tmp_buf, l_ts_create, l_status_order,
                                          l_amount_coins_str ? l_amount_coins_str : "0.0",
@@ -2344,9 +2342,9 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     char l_tmp_buf[DAP_TIME_STR_SIZE];
                     dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_last_rate_time);
                     l_tmp_buf[strlen(l_tmp_buf) - 1] = '\0';
-                    char *l_rate_average_str; dap_uint256_to_char(l_rate_average, &l_rate_average_str);
+                    const char *l_rate_average_str; dap_uint256_to_char(l_rate_average, &l_rate_average_str);
                     dap_string_append_printf(l_reply_str,"Average rate: %s   \r\n", l_rate_average_str);
-                    char *l_last_rate_str; dap_uint256_to_char(l_rate, &l_last_rate_str);
+                    const char *l_last_rate_str; dap_uint256_to_char(l_rate, &l_last_rate_str);
                     dap_string_append_printf(l_reply_str, "Last rate: %s Last rate time: %s (%"DAP_UINT64_FORMAT_U")",
                                              l_last_rate_str, l_tmp_buf, l_last_rate_time);
                     *a_str_reply = dap_string_free(l_reply_str, false);
@@ -2531,7 +2529,7 @@ json_object *dap_chain_net_srv_xchange_print_fee_json(dap_chain_net_t *a_net) {
     dap_chain_addr_t l_addr = {0};
     uint16_t l_type = 0;
     if (dap_chain_net_srv_xchange_get_fee(a_net->pub.id, &l_fee, &l_addr, &l_type)) {
-        char *l_fee_coins, *l_fee_balance = dap_uint256_to_char(l_fee, &l_fee_coins);
+        const char *l_fee_coins, *l_fee_balance = dap_uint256_to_char(l_fee, &l_fee_coins);
         json_object *l_jobj_xchange = json_object_new_object();
         json_object_object_add(l_jobj_xchange, "coin",      json_object_new_string(l_fee_coins));
         json_object_object_add(l_jobj_xchange, "balance",   json_object_new_string(l_fee_balance));
@@ -2550,7 +2548,7 @@ void dap_chain_net_srv_xchange_print_fee(dap_chain_net_t *a_net, dap_string_t *a
     dap_chain_addr_t l_addr = {0};
     uint16_t l_type = 0;
     if (dap_chain_net_srv_xchange_get_fee(a_net->pub.id, &l_fee, &l_addr, &l_type)) {
-        char *l_fee_coins, *l_fee_balance = dap_uint256_to_char(l_fee, &l_fee_coins);
+        const char *l_fee_coins, *l_fee_balance = dap_uint256_to_char(l_fee, &l_fee_coins);
         dap_string_append_printf(a_string_ret, "\txchange:\n"
                                                "\t\tFee: %s (%s)\n"
                                                "\t\tAddr: %s\n"
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 d6eae10743f4e60d17fcfd12a64121568f79ae1e..d9b155a07223d6a409e8f5f2d07ec462c80404b5 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -25,7 +25,7 @@
 #pragma once
 
 #include "dap_chain_net_srv.h"
-#include "dap_chain_net_srv_order.h"
+#include "dap_chain_wallet.h"
 
 #define DAP_CHAIN_NET_SRV_XCHANGE_ID 0x2
 #define GROUP_LOCAL_XCHANGE "local.xchange"
diff --git a/modules/type/blocks/dap_chain_block.c b/modules/type/blocks/dap_chain_block.c
index 244f990165fcee593e212f771d3ffb4caf3c0303..42139e022a670e7c3bdbf3e381f9b7c91cc503b7 100644
--- a/modules/type/blocks/dap_chain_block.c
+++ b/modules/type/blocks/dap_chain_block.c
@@ -21,13 +21,11 @@
     along with any DAP SDK based project.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include <stddef.h>
-#include "string.h"
 #include "dap_common.h"
 #include "dap_config.h"
 #include "dap_hash.h"
 #include "dap_uuid.h"
 #include "dap_chain_block.h"
-#include "dap_chain_block_cache.h"
 
 #define LOG_TAG "dap_chain_block"
 
@@ -484,49 +482,65 @@ size_t dap_chain_block_meta_add(dap_chain_block_t ** a_block_ptr, size_t a_block
     return a_block_size + l_add_size;
 }
 
+static const char *s_meta_type_to_string(uint8_t a_meta_type)
+{
+    switch (a_meta_type) {
+    case DAP_CHAIN_BLOCK_META_GENESIS: return "GENESIS";
+    case DAP_CHAIN_BLOCK_META_PREV: return "PREV";
+    case DAP_CHAIN_BLOCK_META_ANCHOR: return "ANCHOR";
+    case DAP_CHAIN_BLOCK_META_LINK: return "LINK";
+    case DAP_CHAIN_BLOCK_META_NONCE: return "NONCE";
+    case DAP_CHAIN_BLOCK_META_NONCE2: return "NONCE2";
+    case DAP_CHAIN_BLOCK_META_MERKLE: return "MERKLE_ROOT";
+    case DAP_CHAIN_BLOCK_META_EMERGENCY: return "EMERGENCY";
+    case DAP_CHAIN_BLOCK_META_SYNC_ATTEMPT: return "SYNC_ATTEMPT";
+    case DAP_CHAIN_BLOCK_META_ROUND_ATTEMPT: return "ROUND_ATTEMPT";
+    case DAP_CHAIN_BLOCK_META_EXCLUDED_KEYS: return "EXCLUDED_KEYS";
+    default: return "UNNOWN";
+    }
+}
+
 static uint8_t *s_meta_extract(dap_chain_block_meta_t *a_meta)
 {
     switch (a_meta->hdr.type) {
     case DAP_CHAIN_BLOCK_META_GENESIS:
+    case DAP_CHAIN_BLOCK_META_EMERGENCY:
         if (a_meta->hdr.data_size == 0)
             return DAP_INT_TO_POINTER(1);
+        log_it(L_WARNING, "Meta %s has wrong size %hu when expecting zero size",
+               s_meta_type_to_string(a_meta->hdr.type), a_meta->hdr.data_size);
     break;
     case DAP_CHAIN_BLOCK_META_PREV:
-        if (a_meta->hdr.data_size == sizeof(dap_hash_t))
-            return a_meta->data;
-        else
-            log_it(L_WARNING, "Meta PREV has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(dap_hash_t));
-    break;
     case DAP_CHAIN_BLOCK_META_ANCHOR:
-        if (a_meta->hdr.data_size == sizeof(dap_hash_t))
-            return a_meta->data;
-        else
-            log_it(L_WARNING, "Anchor meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(dap_hash_t));
-    break;
     case DAP_CHAIN_BLOCK_META_LINK:
+    case DAP_CHAIN_BLOCK_META_MERKLE:
         if (a_meta->hdr.data_size == sizeof(dap_hash_t))
             return a_meta->data;
-        else
-            log_it(L_WARNING, "Link meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(dap_hash_t));
+        log_it(L_WARNING, "Meta %s has wrong size %hu when expecting %zu",
+               s_meta_type_to_string(a_meta->hdr.type), a_meta->hdr.data_size, sizeof(dap_hash_t));
     break;
     case DAP_CHAIN_BLOCK_META_NONCE:
-        if (a_meta->hdr.data_size == sizeof(uint64_t))
-            return a_meta->data;
-        else
-            log_it(L_WARNING, "NONCE meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(uint64_t));
-    break;
     case DAP_CHAIN_BLOCK_META_NONCE2:
+    case DAP_CHAIN_BLOCK_META_SYNC_ATTEMPT:
         if (a_meta->hdr.data_size == sizeof(uint64_t))
             return a_meta->data;
-        else
-            log_it(L_WARNING, "NONCE2 meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(uint64_t));
+        log_it(L_WARNING, "Meta %s has wrong size %hu when expecting %zu",
+               s_meta_type_to_string(a_meta->hdr.type), a_meta->hdr.data_size, sizeof(uint64_t));
     break;
-    case DAP_CHAIN_BLOCK_META_MERKLE:
-        if (a_meta->hdr.data_size == sizeof(dap_hash_t))
+    case DAP_CHAIN_BLOCK_META_ROUND_ATTEMPT:
+        if (a_meta->hdr.data_size == sizeof(uint8_t))
             return a_meta->data;
-        else
-            log_it(L_WARNING, "Merkle root meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof (dap_hash_t));
+        log_it(L_WARNING, "Meta %s has wrong size %hu when expecting %zu",
+               s_meta_type_to_string(a_meta->hdr.type), a_meta->hdr.data_size, sizeof(uint8_t));
     break;
+    case DAP_CHAIN_BLOCK_META_EXCLUDED_KEYS:
+        if (a_meta->hdr.data_size > sizeof(uint16_t)) {
+            uint16_t l_expected_size = *(uint16_t *)a_meta->data + sizeof(uint16_t);
+            if (!(l_expected_size % sizeof(uint16_t)) &&
+                    l_expected_size == a_meta->hdr.data_size)
+                return a_meta->data;
+        }
+        log_it(L_WARNING, "Meta %s has wrong size %hu", s_meta_type_to_string(a_meta->hdr.type), a_meta->hdr.data_size);
     default:
         log_it(L_WARNING, "Unknown meta type 0x%02x (size %u), possible corrupted block or you need to upgrade your software",
                           a_meta->hdr.type, a_meta->hdr.type);
@@ -574,10 +588,10 @@ uint8_t *dap_chain_block_meta_get(const dap_chain_block_t *a_block, size_t a_blo
  * @param a_reward
  */
 int dap_chain_block_meta_extract(dap_chain_block_t *a_block, size_t a_block_size,
-                                    dap_chain_hash_fast_t * a_block_prev_hash,
-                                    dap_chain_hash_fast_t * a_block_anchor_hash,
+                                    dap_chain_hash_fast_t *a_block_prev_hash,
+                                    dap_chain_hash_fast_t *a_block_anchor_hash,
                                     dap_chain_hash_fast_t *a_merkle,
-                                    dap_chain_hash_fast_t ** a_block_links,
+                                    dap_chain_hash_fast_t **a_block_links,
                                     size_t *a_block_links_count,
                                     bool *a_is_genesis,
                                     uint64_t *a_nonce,
diff --git a/modules/type/blocks/dap_chain_block_cache.c b/modules/type/blocks/dap_chain_block_cache.c
index dc1b11c3be82a2339456c17e6aa5a4900bf933c3..0a9926d4d25ca8858c1bf2214e632a2b8f4cddbb 100644
--- a/modules/type/blocks/dap_chain_block_cache.c
+++ b/modules/type/blocks/dap_chain_block_cache.c
@@ -26,7 +26,6 @@
 #include "dap_chain_block_cache.h"
 #include "dap_chain_datum_tx.h"
 #include "dap_chain_datum_tx_in.h"
-#include "dap_chain_datum_tx_out.h"
 
 #define LOG_TAG "dap_chain_block_cache"
 
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index bec9647b803bed54f3cbd8db103de739304ed029..8dbad5400da8578e5a0bd0f4e2ed1020c36057d3 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -22,7 +22,6 @@
 */
 #include <pthread.h>
 #include "dap_common.h"
-#include "dap_enc_base58.h"
 #include "dap_chain.h"
 #include "dap_chain_cell.h"
 #include "dap_chain_cs.h"
@@ -227,7 +226,7 @@ void dap_chain_cs_blocks_deinit()
     dap_chain_block_cache_deinit();
 }
 
-static int s_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config)
+static int s_chain_cs_blocks_new(dap_chain_t *a_chain, dap_config_t *a_chain_config)
 {
     dap_chain_cs_blocks_t * l_cs_blocks = DAP_NEW_Z(dap_chain_cs_blocks_t);
     if (!l_cs_blocks) {
@@ -469,7 +468,7 @@ static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_re
     for (size_t i = 0; i < l_objs_count; i++) {
         dap_global_db_obj_t *l_obj_cur = l_objs + i;
         uint256_t l_cur_value = *(uint256_t*)l_obj_cur->value;
-        char *l_value_str; dap_uint256_to_char(l_cur_value, &l_value_str);
+        const char *l_value_str; dap_uint256_to_char(l_cur_value, &l_value_str);
         dap_string_append_printf(a_reply_str, "%s\t%s\n", l_obj_cur->key, l_value_str);
         SUM_256_256(l_total_value, l_cur_value, &l_total_value);
     }
@@ -483,7 +482,7 @@ static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_re
             dap_pkey_t *l_my_sign_pkey = dap_chain_esbocs_get_sign_pkey(a_net->pub.id);
             dap_hash_t l_my_sign_pkey_hash;
             dap_hash_fast(l_my_sign_pkey->pkey, l_my_sign_pkey->header.size, &l_my_sign_pkey_hash);
-            dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_my_sign_pkey_hash);
+            dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(a_net->pub.id, &l_my_sign_pkey_hash);
             if (l_key_item && !IS_ZERO_256(l_key_item->sovereign_tax) &&
                     !dap_chain_addr_is_blank(&l_key_item->sovereign_addr)) {
                 MULT_256_COIN(l_collect_value, l_key_item->sovereign_tax, &l_collect_tax);
@@ -559,7 +558,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
     if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net) < 0)
         return -11;
 
-    const char *l_chain_type = dap_chain_net_get_type(l_chain);
+    const char *l_chain_type = dap_chain_get_cs_type(l_chain);
 
     if (!strstr(l_chain_type, "block_") && strcmp(l_chain_type, "esbocs")){
             dap_cli_server_cmd_set_reply_text(a_str_reply,
@@ -988,7 +987,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                     break;
                 } else if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "show") >= 0) {
                     uint256_t l_cur_reward = dap_chain_net_get_reward(l_net, UINT64_MAX);
-                    char *l_reward_str; dap_uint256_to_char(l_cur_reward, &l_reward_str);
+                    const char *l_reward_str; dap_uint256_to_char(l_cur_reward, &l_reward_str);
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Current base block reward is %s\n", l_reward_str);
                     break;
                 } else if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "collect") == -1) {
@@ -1099,8 +1098,8 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                     return -20;
                 }
                 dap_chain_esbocs_block_collect_t l_block_collect_params = (dap_chain_esbocs_block_collect_t){
-                        .collecting_level = l_chain->callback_get_collectiong_level(l_chain),
-                        .minimum_fee = l_chain->callback_get_minimum_fee(l_chain),
+                        .collecting_level = dap_chain_esbocs_get_collecting_level(l_chain),
+                        .minimum_fee = dap_chain_esbocs_get_fee(l_chain->net_id),
                         .chain = l_chain,
                         .blocks_sign_key = l_cert->enc_key,
                         .block_sign_pkey = l_pub_key,
diff --git a/modules/type/blocks/include/dap_chain_block.h b/modules/type/blocks/include/dap_chain_block.h
index 3c986857fc699b2d0258f6be811c81c5b06d6795..519b655c85ed90f61657cc85543473fcece94e8b 100644
--- a/modules/type/blocks/include/dap_chain_block.h
+++ b/modules/type/blocks/include/dap_chain_block.h
@@ -23,12 +23,9 @@
 #pragma once
 #include "dap_common.h"
 #include "dap_time.h"
-#include "dap_math_ops.h"
 #include "dap_hash.h"
-#include "dap_cert.h"
 #include "dap_chain_common.h"
 #include "dap_chain_datum.h"
-#include "dap_chain_datum_hashtree_roots.h"
 
 #define DAP_CHAIN_BLOCK_SIGNATURE 0xDA05BF8E
 #define DAP_CHAIN_BLOCK_ID_SIZE 4
@@ -65,13 +62,17 @@ typedef struct dap_chain_block_meta{
 
 // Block metadata types
 
-#define DAP_CHAIN_BLOCK_META_GENESIS           0x01
-#define DAP_CHAIN_BLOCK_META_PREV              0x10
-#define DAP_CHAIN_BLOCK_META_ANCHOR            0x11
-#define DAP_CHAIN_BLOCK_META_LINK              0x12
-#define DAP_CHAIN_BLOCK_META_NONCE             0x20
-#define DAP_CHAIN_BLOCK_META_NONCE2            0x21
-#define DAP_CHAIN_BLOCK_META_MERKLE            0x30
+#define DAP_CHAIN_BLOCK_META_GENESIS            0x01
+#define DAP_CHAIN_BLOCK_META_PREV               0x10
+#define DAP_CHAIN_BLOCK_META_ANCHOR             0x11
+#define DAP_CHAIN_BLOCK_META_LINK               0x12
+#define DAP_CHAIN_BLOCK_META_NONCE              0x20
+#define DAP_CHAIN_BLOCK_META_NONCE2             0x21
+#define DAP_CHAIN_BLOCK_META_MERKLE             0x30
+#define DAP_CHAIN_BLOCK_META_EMERGENCY          0x80
+#define DAP_CHAIN_BLOCK_META_SYNC_ATTEMPT       0x81
+#define DAP_CHAIN_BLOCK_META_ROUND_ATTEMPT      0x82
+#define DAP_CHAIN_BLOCK_META_EXCLUDED_KEYS      0x83
 
 /**
  * @struct dap_chain_block
diff --git a/modules/type/blocks/include/dap_chain_block_cache.h b/modules/type/blocks/include/dap_chain_block_cache.h
index 38402441020bae3a8eb74d248177a9a55eea86b3..d3231266816568044a75027e74a55a584f091b95 100644
--- a/modules/type/blocks/include/dap_chain_block_cache.h
+++ b/modules/type/blocks/include/dap_chain_block_cache.h
@@ -22,8 +22,6 @@
 */
 #pragma once
 #include "dap_chain_block.h"
-#include "dap_chain_datum_tx.h"
-#include "dap_sign.h"
 #include "dap_hash.h"
 #include "uthash.h"
 #include "dap_chain_ledger.h"
diff --git a/modules/type/blocks/include/dap_chain_cs_blocks.h b/modules/type/blocks/include/dap_chain_cs_blocks.h
index 8e7eaf5cffdc88d3400a99874f0ccd6c2e6da52e..ad4383280a43be6aafe23d42bcce8b78361c0896 100644
--- a/modules/type/blocks/include/dap_chain_cs_blocks.h
+++ b/modules/type/blocks/include/dap_chain_cs_blocks.h
@@ -32,7 +32,7 @@
 #define DAP_CHAIN_CS_BLOCKS_MAX_BLOCK_SIZE (256 * 1024) // 256 KB
 #endif
 
-#define DAP_REWARD_INIT_TIMESTAMP 1700870400UL // 25 Nov 00:00:00 GMT
+#define DAP_REWARD_INIT_TIMESTAMP 1700870400UL // 25 Nov 2023 00:00:00 GMT
 
 typedef struct dap_chain_cs_blocks dap_chain_cs_blocks_t;
 
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index dbec25fe18aefa6a354c309a66530c3d8b857d21..9f0db5d074ae31fd5070e4051d8d79192d8c2a0e 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -1332,7 +1332,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
     }
     l_dag = DAP_CHAIN_CS_DAG(l_chain);
 
-    const char *l_chain_type = dap_chain_net_get_type(l_chain);
+    const char *l_chain_type = dap_chain_get_cs_type(l_chain);
 
     if (!strstr(l_chain_type, "dag_")){
             dap_cli_server_cmd_set_reply_text(a_str_reply,