From 4e1ccc3d6458e3a46edec63e0230a0a1a8333089 Mon Sep 17 00:00:00 2001
From: Roman Khlopkov <roman.khlopkov@demlabs.net>
Date: Fri, 24 Nov 2023 09:23:37 +0000
Subject: [PATCH] feature-9808

---
 CMakeLists.txt                                |   16 +-
 dap-sdk                                       |    2 +-
 modules/CMakeLists.txt                        |    5 -
 modules/chain/dap_chain.c                     |    4 -
 modules/chain/dap_chain_tx.c                  |    1 -
 modules/chain/include/dap_chain.h             |   17 +-
 modules/chain/include/dap_chain_ledger.h      |  350 ---
 modules/chain/tests/dap_chain_ledger_tests.c  |  124 +-
 .../tests/include/dap_chain_ledger_tests.h    |    5 +-
 modules/chain/tests/main.c                    |    4 +-
 .../dap_stream_ch_chain_net_srv.c             |   10 +-
 modules/common/dap_chain_datum.c              |   16 +-
 modules/common/dap_chain_datum_decree.c       |   21 +-
 modules/common/dap_chain_datum_token.c        |   10 +-
 modules/common/dap_chain_datum_tx.c           |   11 +
 modules/common/dap_chain_datum_tx_items.c     |   49 +-
 modules/common/include/dap_chain_common.h     |   26 +-
 .../common/include/dap_chain_datum_decree.h   |   31 +-
 .../common/include/dap_chain_datum_token.h    |   16 +-
 modules/common/include/dap_chain_datum_tx.h   |    7 +
 .../include/dap_chain_datum_tx_in_cond.h      |    4 +-
 .../include/dap_chain_datum_tx_in_reward.h    |   30 +
 .../common/include/dap_chain_datum_tx_items.h |    7 +-
 .../common/include/dap_chain_datum_tx_out.h   |    2 +-
 .../include/dap_chain_datum_tx_out_cond.h     |   53 -
 .../consensus/esbocs/dap_chain_cs_esbocs.c    |   17 +-
 modules/mempool/dap_chain_mempool.c           |  174 +-
 modules/mempool/include/dap_chain_mempool.h   |    4 +-
 modules/{chain => net}/dap_chain_ledger.c     | 2078 ++++++++---------
 modules/net/dap_chain_net.c                   |  125 +-
 modules/net/dap_chain_net_anchor.c            |    1 +
 modules/net/dap_chain_net_decree.c            |   52 +-
 modules/net/dap_chain_net_tx.c                |   52 +-
 modules/net/dap_chain_node.c                  |    3 +-
 modules/net/dap_chain_node_cli_cmd.c          |   45 +-
 modules/net/dap_chain_node_cli_cmd_tx.c       |   52 +-
 modules/net/include/dap_chain_ledger.h        |  357 +++
 modules/net/include/dap_chain_net.h           |   13 +-
 modules/net/include/dap_chain_net_decree.h    |    1 -
 modules/net/include/dap_chain_net_tx.h        |    3 +-
 modules/net/srv/dap_chain_net_srv.c           |   19 +-
 modules/net/srv/dap_chain_net_srv_order.c     |    2 +-
 .../service/datum/dap_chain_net_srv_datum.c   |    2 +-
 .../stake/dap_chain_net_srv_stake_lock.c      |   49 +-
 .../dap_chain_net_srv_stake_pos_delegate.c    |   50 +-
 .../xchange/dap_chain_net_srv_xchange.c       |   76 +-
 modules/test/CMakeLists.txt                   |    9 -
 modules/test/dap_test.c                       |  112 -
 modules/test/dap_test.h                       |  113 -
 modules/test/dap_test_generator.c             |   21 -
 modules/test/dap_test_generator.h             |    7 -
 modules/type/blocks/dap_chain_block.c         |   77 +-
 modules/type/blocks/dap_chain_block_cache.c   |    8 +-
 modules/type/blocks/dap_chain_block_chunk.c   |    3 +-
 modules/type/blocks/dap_chain_cs_blocks.c     |  339 ++-
 modules/type/blocks/include/dap_chain_block.h |   12 +-
 .../blocks/include/dap_chain_block_cache.h    |    6 +-
 .../type/blocks/include/dap_chain_cs_blocks.h |    2 +-
 modules/type/dag/dap_chain_cs_dag.c           |    2 +-
 modules/wallet/dap_chain_wallet.c             |    3 +-
 60 files changed, 2363 insertions(+), 2347 deletions(-)
 delete mode 100644 modules/chain/include/dap_chain_ledger.h
 create mode 100644 modules/common/include/dap_chain_datum_tx_in_reward.h
 rename modules/{chain => net}/dap_chain_ledger.c (75%)
 create mode 100644 modules/net/include/dap_chain_ledger.h
 delete mode 100644 modules/test/CMakeLists.txt
 delete mode 100644 modules/test/dap_test.c
 delete mode 100644 modules/test/dap_test.h
 delete mode 100644 modules/test/dap_test_generator.c
 delete mode 100644 modules/test/dap_test_generator.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d1f20a536d..020c2f42ce 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,9 +6,6 @@ set(CELLFRAME_SDK_NATIVE_VERSION "3.3-0")
 
 add_definitions ("-DCELLFRAME_SDK_VERSION=\"${CELLFRAME_SDK_NATIVE_VERSION}\"")
 
-
-set(DAPSDK_MODULES "")
-
 if(NOT DEFINED CELLFRAME_MODULES)
     include (dap-sdk/cmake/OS_Detection.cmake)
 
@@ -17,9 +14,10 @@ if(NOT DEFINED CELLFRAME_MODULES)
     if(LINUX OR DARWIN)
         set(CELLFRAME_MODULES "${CELLFRAME_MODULES} srv-vpn")
     endif()
-    if (BUILD_CELLFRAME_SDK_TESTS)
-        set (CELLFRAME_MODULES ${CELLFRAME_MODULES} "test-framework")
-    endif ()
+
+    if(BUILD_CELLFRAME_SDK_TESTS)
+        set(DAPSDK_MODULES "test-framework")
+    endif()
 
     add_subdirectory(dap-sdk)
 
@@ -43,8 +41,7 @@ else()
 endif(NOT DAP_INT128_SUPPORT)
 
 if (BUILD_CELLFRAME_SDK_TESTS)
-    enable_testing()
-    add_definitions("-DDAP_CHAIN_LEDGER_TEST")
+    add_definitions("-DDAP_LEDGER_TEST")
 endif()
 
 if (BUILD_WITH_ZIP)
@@ -53,9 +50,6 @@ if (BUILD_WITH_ZIP)
 endif()
 
 add_subdirectory(3rdparty/monero_crypto)
-if(DAPSDK_MODULES MATCHES "ssl-support")
-    add_subdirectory(3rdparty/wolfssl)
-endif()
 
 add_subdirectory(modules/)
 
diff --git a/dap-sdk b/dap-sdk
index 47998bb5e3..60d9770561 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 47998bb5e3d464ee991b1bdee910db824fdca723
+Subproject commit 60d9770561950957837b9e2c2b9173d01de74510
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt
index f5d8b8fd44..5dd9d33504 100644
--- a/modules/CMakeLists.txt
+++ b/modules/CMakeLists.txt
@@ -110,8 +110,3 @@ endif()
 if (CELLFRAME_MODULES MATCHES "srv-stake")
     add_subdirectory(service/stake)
 endif()
-
-# Unit tests
-if( BUILD_TESTS)
-    add_subdirectory(test)
-endif()
diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c
index 994aecde4f..106f2ec150 100644
--- a/modules/chain/dap_chain.c
+++ b/modules/chain/dap_chain.c
@@ -35,7 +35,6 @@
 #include "dap_file_utils.h"
 #include "dap_config.h"
 #include "dap_chain.h"
-#include "dap_chain_ledger.h"
 #include "dap_cert.h"
 #include "dap_chain_cell.h"
 #include "dap_chain_cs.h"
@@ -69,7 +68,6 @@ int dap_chain_init(void)
 {
     // Cell sharding init
     dap_chain_cell_init();
-    dap_chain_ledger_init();
     dap_chain_cs_init();
     //dap_chain_show_hash_blocks_file(g_gold_hash_blocks_file);
     //dap_chain_show_hash_blocks_file(g_silver_hash_blocks_file);
@@ -85,8 +83,6 @@ void dap_chain_deinit(void)
     HASH_ITER(hh, s_chain_items, l_item, l_tmp) {
           dap_chain_delete(l_item->chain);
     }
-    dap_chain_ledger_deinit();
-
 }
 
 /**
diff --git a/modules/chain/dap_chain_tx.c b/modules/chain/dap_chain_tx.c
index 6e4fb145d2..4bd8019e9c 100644
--- a/modules/chain/dap_chain_tx.c
+++ b/modules/chain/dap_chain_tx.c
@@ -23,7 +23,6 @@
 */
 #include "dap_chain_tx.h"
 #include "dap_chain_datum_tx.h"
-#include "dap_chain_ledger.h"
 #include "dap_common.h"
 #include "uthash.h"
 #define LOG_TAG "dap_chain_tx"
diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h
index c961413784..6912588c49 100644
--- a/modules/chain/include/dap_chain.h
+++ b/modules/chain/include/dap_chain.h
@@ -115,14 +115,12 @@ typedef size_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 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);
 
-typedef enum dap_chain_type
-{
+typedef enum dap_chain_type {
     CHAIN_TYPE_FIRST,
     CHAIN_TYPE_TOKEN,
     CHAIN_TYPE_EMISSION,
@@ -195,23 +193,22 @@ typedef struct dap_chain {
     dap_chain_callback_get_count callback_count_atom;
     dap_chain_callback_get_list callback_get_atoms;
 
+    // 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_signing_certificate callback_get_signing_certificate;
-
+    dap_chain_callback_calc_reward callback_calc_reward;
     dap_chain_callback_load_from_gdb callback_load_from_gdb;
 
-    dap_list_t *atom_notifiers;
-//    dap_chain_callback_notify_t callback_notify;
-//    void *callback_notify_arg;
-
+    // Iterator callbacks
     dap_chain_datum_callback_iter_create_t callback_datum_iter_create;
     dap_chain_datum_callback_iter_get_first_t callback_datum_iter_get_first;
     dap_chain_datum_callback_iter_get_first_t callback_datum_iter_get_next;
     dap_chain_datum_callback_iter_delete_t callback_datum_iter_delete;
 
+    dap_list_t *atom_notifiers;
+
     void * _pvt; // private data
     void * _inheritor; // inheritor object
 } dap_chain_t;
diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h
deleted file mode 100644
index 12dbb04da3..0000000000
--- a/modules/chain/include/dap_chain_ledger.h
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * Alexander Lysikov <alexander.lysikov@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * DeM Labs Open source community https://github.com/demlabsinc
- * Copyright  (c) 2017-2019
- * All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
- DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- DAP is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-#include <stdint.h>
-#include <stdbool.h>
-#include "dap_common.h"
-#include "dap_hash.h"
-#include "dap_list.h"
-#include "dap_math_ops.h"
-#include "dap_chain_common.h"
-#include "dap_chain_datum_token.h"
-#include "dap_chain_datum_tx.h"
-#include "dap_chain_datum_tx_in_ems.h"
-#include "dap_chain_datum_tx_items.h"
-
-typedef struct dap_ledger {
-    char *net_name;
-    dap_chain_net_id_t net_id;
-    void *_internal;
-} dap_ledger_t;
-
-/**
- * @brief Error codes for accepting a transaction to the ledger.
- */
-typedef enum dap_chain_ledger_tx_check{
-    DAP_CHAIN_LEDGER_TX_CHECK_OK = 0,
-    DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX,
-    DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE,
-    DAP_CHAIN_LEDGER_TX_ALREADY_CACHED,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN,
-    DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED,
-    DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND,
-    DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN,
-    DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS,
-    DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS,
-    DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY,
-    DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE,
-    DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND,
-    DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET,
-    DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND,
-    DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED,
-    DAP_CHAIN_LEDGER_TX_CACHE_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS,
-    /* add custom codes here */
-
-    DAP_CHAIN_LEDGER_TX_CHECK_UNKNOWN /* MAX */
-} dap_chain_ledger_tx_check_t;
-
-typedef enum dap_chain_ledger_emission_err{
-    DAP_CHAIN_LEDGER_EMISSION_ADD_OK = 0,
-    DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL,
-    DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED,
-    DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW,
-    DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY,
-    DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS,
-    DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN,
-    DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE,
-    DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED,
-    /* add custom codes here */
-    DAP_CHAIN_LEDGER_EMISSION_ADD_MEMORY_PROBLEM,
-    DAP_CHAIN_LEDGER_EMISSION_ADD_UNKNOWN /* MAX */
-} dap_chain_ledger_emission_err_code_t;
-
-typedef enum dap_chain_ledger_token_decl_add_err{
-    DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK = 0,
-    DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL,
-    DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE,
-    DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK,
-    DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN,
-    DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN,
-    DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS,
-    /* add custom codes here */
-
-    DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_UNKNOWN /* MAX */
-} dap_chain_ledger_token_decl_add_err_t;
-
-typedef bool (*dap_chain_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner);
-typedef void (*dap_chain_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_chain_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx);
-typedef void (* dap_chain_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_chain_ledger_cache_tx_check_callback_t)(dap_hash_fast_t *a_tx_hash);
-typedef struct dap_chain_net dap_chain_net_t;
-
-//Change this UUID to automatically reload ledger cache on next node startup
-#define DAP_CHAIN_LEDGER_CACHE_RELOAD_ONCE_UUID "0c92b759-a565-448f-b8bd-99103dacf7fc"
-
-// Checks the emission of the token, usualy on zero chain
-#define DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION    0x0001
-
-// Check double spending in local cell
-#define DAP_CHAIN_LEDGER_CHECK_LOCAL_DS          0x0002
-
-// Check the double spending in all cells
-#define DAP_CHAIN_LEDGER_CHECK_CELLS_DS          0x0100
-
-#define DAP_CHAIN_LEDGER_CACHE_ENABLED           0x0200
-
-// Error code for no previous transaction (for stay in mempool)
-#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS  DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND
-// Error code for no emission for a transaction (for stay in mempoold)
-#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION  DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND
-// Error code for no decree for anchor (for stay in mempool)
-#define DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE       -1113
-
-#define DAP_CHAIN_LEDGER_TOKENS_STR              "tokens"
-#define DAP_CHAIN_LEDGER_EMISSIONS_STR           "emissions"
-#define DAP_CHAIN_LEDGER_STAKE_LOCK_STR          "stake_lock"
-#define DAP_CHAIN_LEDGER_TXS_STR                 "txs"
-#define DAP_CHAIN_LEDGER_SPENT_TXS_STR           "spent_txs"
-#define DAP_CHAIN_LEDGER_BALANCES_STR            "balances"
-
-int dap_chain_ledger_init();
-void dap_chain_ledger_deinit();
-
-dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, dap_chain_net_id_t a_net_id, char *a_net_name, const char *a_net_native_ticker, dap_list_t *a_poa_certs);
-
-void dap_chain_ledger_set_fee(dap_ledger_t *a_ledger, uint256_t a_fee, dap_chain_addr_t a_fee_addr);
-
-// Remove dap_ledger_t structure
-void dap_chain_ledger_handle_free(dap_ledger_t *a_ledger);
-
-// Load ledger from mempool
-//int dap_chain_ledger_load(const char *a_net_name, const char *a_chain_name);
-
-void dap_chain_ledger_set_local_cell_id(dap_ledger_t *a_ledger, dap_chain_cell_id_t a_local_cell_id);
-
-/**
- * @brief dap_chain_node_datum_tx_calc_hash
- * @param a_tx
- * @return
- */
-DAP_STATIC_INLINE dap_chain_hash_fast_t* dap_chain_node_datum_tx_calc_hash(dap_chain_datum_tx_t *a_tx)
-{
-    dap_chain_hash_fast_t *tx_hash = DAP_NEW_Z(dap_chain_hash_fast_t);
-    if (!tx_hash) {
-        return NULL;
-    }
-    dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), tx_hash);
-    return tx_hash;
-}
-
-DAP_STATIC_INLINE char *dap_chain_ledger_get_gdb_group(dap_ledger_t *a_ledger, const char *a_suffix)
-{
-    return a_ledger && a_ledger->net_name && a_suffix
-            ? dap_strdup_printf("local.ledger-cache.%s.%s", a_ledger->net_name, a_suffix)
-            : NULL;
-}
-
-/**
- * Add new transaction to the cache
- *
- * return 1 OK, -1 error
- */
-int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold);
-int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_hash_fast_t *a_tx_hash);
-
-
-int dap_chain_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash);
-
-char* dap_chain_ledger_tx_check_err_str(int a_code);
-
-/**
- * Print list transaction from ledger
- *
- */
-
-char * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only);
-
-/**
- * Check token ticker existance
- *
- */
-
-dap_chain_datum_token_t *dap_chain_ledger_token_ticker_check(dap_ledger_t * a_ledger, const char *a_token_ticker);
-
-/**
- * Add new token datum
- *
- */
-
-int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size);
-int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size);
-int dap_chain_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size);
-char *dap_chain_ledger_token_decl_add_err_code_to_str(int a_code);
-dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger);
-
-// Get all token-declarations
-dap_list_t* dap_chain_ledger_token_decl_all(dap_ledger_t *a_ledger);
-
-dap_string_t *dap_chain_ledger_threshold_info(dap_ledger_t *a_ledger);
-dap_string_t *dap_chain_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_tx_treshold_hash);
-dap_string_t *dap_chain_ledger_balance_info(dap_ledger_t *a_ledger);
-
-size_t dap_chain_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker);
-size_t dap_chain_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker);
-dap_list_t * dap_chain_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker);
-
-/**
- * Add token emission datum
- */
-int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size,
-                                        dap_hash_fast_t *a_emission_hash, bool a_from_threshold);
-int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_hash_fast_t *a_token_emission_hash);
-char *dap_chain_ledger_token_emission_err_code_to_str(int a_code);
-
-// Check if it addable
-int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash);
-
-/* Add stake-lock item */
-int dap_chain_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash);
-
-dap_chain_datum_token_emission_t *dap_chain_ledger_token_emission_find(dap_ledger_t *a_ledger,
-        const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash);
-
-const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,dap_chain_hash_fast_t *a_tx_hash);
-
-void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr,
-        char *** a_tickers, size_t * a_tickers_size);
-
-void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr,
-        char *** a_tickers, size_t * a_tickers_size);
-
-bool dap_chain_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx);
-
-// Checking a new transaction before adding to the cache
-int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash,
-                                    bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker);
-
-/**
- * Delete all transactions from the cache
- */
-void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db);
-
-/**
- * End of load mode with no chackes for incoming datums
- */
-void dap_chain_ledger_load_end(dap_ledger_t *a_ledger);
-
-/**
- * Return number transactions from the cache
- */
-unsigned dap_chain_ledger_count(dap_ledger_t *a_ledger);
-uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts_from, dap_time_t a_ts_to);
-size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to);
-void dap_chain_ledger_set_tps_start_time(dap_ledger_t *a_ledger);
-
-/**
- * Check whether used 'out' items
- */
-bool dap_chain_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, int a_idx_out, dap_hash_fast_t *a_out_spender);
-
-/**
- * Calculate balance of addr
- *
- */
-uint256_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr,
-        const char *a_token_ticker);
-
-uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr,
-            const char *a_token_ticker);
-
-/**
- * Get transaction in the cache by hash
- *
- * return transaction, or NULL if transaction not found in the cache
- */
-dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash);
-dap_chain_datum_tx_t* dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash);
-dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash);
-
- // Get the transaction in the cache by the addr in out item
-dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_addr(dap_ledger_t *a_ledger, const char * a_token,
-         const dap_chain_addr_t *a_addr, dap_chain_hash_fast_t *a_tx_first_hash);
-
-// Get the transaction in the cache by the public key that signed the transaction, starting with a_tx_first_hash
-const dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger,
-        char *a_public_key, size_t a_public_key_size, dap_chain_hash_fast_t *a_tx_first_hash);
-
-// Get the transaction in the cache with the out_cond item
-dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type,
-                                                              dap_chain_hash_fast_t *a_tx_first_hash, dap_chain_tx_out_cond_t **a_out_cond,
-                                                              int *a_out_cond_idx, char *a_token_ticker);
-
-// Get all transactions from the cache with the specified out_cond items
-dap_list_t* dap_chain_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, dap_chain_net_srv_uid_t a_srv_uid);
-
-// Get the value from all transactions in the cache with out_cond item
-uint256_t dap_chain_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_addr_t *a_addr,
-                                                       dap_chain_tx_out_cond_t **tx_out_cond);
-
-// Get the list of 'out' items from previous transactions with summary value >= than a_value_need
-// Put this summary value to a_value_transfer
-dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from,
-                                                       uint256_t a_value_need, uint256_t *a_value_transfer);
-
-// Get the list of 'out_cond' items with summary value >= than a_value_need
-dap_list_t *dap_chain_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker,  const dap_chain_addr_t *a_addr_from,
-        dap_chain_tx_out_cond_subtype_t a_subtype, uint256_t a_value_need, uint256_t *a_value_transfer);
-
-// Add new verificator callback with associated subtype. Returns 1 if callback replaced, overwise returns 0
-int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_chain_ledger_verificator_callback_t a_callback,
-                                     dap_chain_ledger_updater_callback_t a_callback_added);
-
-// Getting a list of transactions from the ledger.
-dap_list_t * dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only);
-
-//bool dap_chain_ledger_fee_verificator(dap_ledger_t* a_ledger, dap_chain_tx_out_cond_t* a_cond, dap_chain_datum_tx_t* a_tx, bool a_owner);
-
-void dap_chain_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_ledger_tx_add_notify_t a_callback, void *a_arg);
-void dap_chain_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_chain_ledger_bridged_tx_notify_t a_callback, void *a_arg);
-
-
-bool dap_chain_ledger_cache_enabled(dap_ledger_t *a_ledger);
-void dap_chain_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_chain_ledger_cache_tx_check_callback_t a_callback);
diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c
index 588c694695..94ff695443 100644
--- a/modules/chain/tests/dap_chain_ledger_tests.c
+++ b/modules/chain/tests/dap_chain_ledger_tests.c
@@ -1,15 +1,17 @@
+#include "dap_test.h"
 #include "dap_chain_ledger_tests.h"
 #include "dap_chain_datum.h"
 #include "dap_cert.h"
 #include "dap_chain_wallet.h"
 #include "dap_math_ops.h"
+#include "dap_chain_net.h"
 
 static const uint64_t s_fee = 2;
 static const uint64_t s_total_supply = 500;
 static const uint64_t s_standard_value_tx = 500;
 static const char* s_token_ticker = "TestCoins";
 
-dap_chain_datum_token_t  *dap_chain_ledger_test_create_datum_decl(dap_cert_t *a_cert, size_t *a_token_size,
+dap_chain_datum_token_t  *dap_ledger_test_create_datum_decl(dap_cert_t *a_cert, size_t *a_token_size,
                                                                   const char *a_token_ticker, uint256_t a_total_supply,
                                                                   byte_t *a_tsd_section, size_t a_size_tsd_section, uint16_t flags) {
     dap_chain_datum_token_t *l_token = DAP_NEW_Z(dap_chain_datum_token_t);
@@ -44,13 +46,13 @@ dap_chain_datum_token_t  *dap_chain_ledger_test_create_datum_decl(dap_cert_t *a_
     }
 }
 
-dap_chain_datum_tx_t *dap_chain_ledger_test_create_datum_base_tx(
+dap_chain_datum_tx_t *dap_ledger_test_create_datum_base_tx(
         dap_chain_datum_token_emission_t *a_emi,
         dap_chain_hash_fast_t *l_emi_hash,
         dap_chain_addr_t  a_addr_to,
         dap_cert_t *a_cert) {
 	uint256_t l_value_fee = dap_chain_uint256_from(s_fee);
-	uint256_t l_value_need = a_emi->hdr.value_256;
+    uint256_t l_value_need = a_emi->hdr.value;
     dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t));
     l_tx->header.ts_created = time(NULL);
     dap_chain_tx_in_ems_t *l_in_ems = DAP_NEW_Z(dap_chain_tx_in_ems_t);
@@ -72,7 +74,7 @@ dap_chain_datum_tx_t *dap_chain_ledger_test_create_datum_base_tx(
     return l_tx;
 }
 
-dap_chain_datum_tx_t *dap_chain_ledger_test_create_tx(dap_enc_key_t *a_key_from, dap_chain_hash_fast_t *a_hash_prev,
+dap_chain_datum_tx_t *dap_ledger_test_create_tx(dap_enc_key_t *a_key_from, dap_chain_hash_fast_t *a_hash_prev,
                                                       dap_chain_addr_t *a_addr_to, uint256_t a_value) {
     dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
     dap_chain_tx_in_t *l_in = dap_chain_datum_tx_item_in_create(a_hash_prev, 0);
@@ -85,42 +87,42 @@ dap_chain_datum_tx_t *dap_chain_ledger_test_create_tx(dap_enc_key_t *a_key_from,
     return l_tx;
 }
 
-void dap_chain_ledger_test_double_spending(
+void dap_ledger_test_double_spending(
         dap_ledger_t *a_ledger, dap_hash_fast_t *a_prev_hash, dap_enc_key_t  *a_from_key, dap_chain_net_id_t a_net_id) {
-    dap_print_module_name("dap_chain_ledger_double_spending");
+    dap_print_module_name("dap_ledger_double_spending");
     dap_cert_t *l_first_cert = dap_cert_generate_mem_with_seed("newCert", DAP_ENC_KEY_TYPE_SIG_PICNIC, "FMknbirh8*^#$RYU*H", 18);
     dap_chain_addr_t l_addr_first = {0};
     dap_chain_addr_fill_from_key(&l_addr_first, l_first_cert->enc_key, a_net_id);
-    dap_chain_datum_tx_t *l_first_tx = dap_chain_ledger_test_create_tx(a_from_key, a_prev_hash,
+    dap_chain_datum_tx_t *l_first_tx = dap_ledger_test_create_tx(a_from_key, a_prev_hash,
                                                                        &l_addr_first, dap_chain_uint256_from(s_standard_value_tx - s_fee));
     dap_assert_PIF(l_first_tx, "Can't creating base transaction.");
     dap_chain_hash_fast_t l_first_tx_hash = {0};
     dap_hash_fast(l_first_tx, dap_chain_datum_tx_get_size(l_first_tx), &l_first_tx_hash);
-    dap_assert_PIF(!dap_chain_ledger_tx_add(a_ledger, l_first_tx, &l_first_tx_hash, false), "Can't added first transaction on ledger");
-    //uint256_t l_balance = dap_chain_ledger_calc_balance(a_ledger, &l_addr_first, s_token_ticker);
+    dap_assert_PIF(!dap_ledger_tx_add(a_ledger, l_first_tx, &l_first_tx_hash, false), "Can't added first transaction on ledger");
+    //uint256_t l_balance = dap_ledger_calc_balance(a_ledger, &l_addr_first, s_token_ticker);
     // Second tx
-    dap_chain_datum_tx_t *l_second_tx = dap_chain_ledger_test_create_tx(a_from_key, a_prev_hash,
+    dap_chain_datum_tx_t *l_second_tx = dap_ledger_test_create_tx(a_from_key, a_prev_hash,
                                                                        &l_addr_first, dap_chain_uint256_from(s_standard_value_tx - s_fee));
     dap_chain_hash_fast_t l_second_tx_hash = {0};
     dap_hash_fast(l_second_tx, dap_chain_datum_tx_get_size(l_second_tx), &l_second_tx_hash);
-    dap_assert_PIF(dap_chain_ledger_tx_add(a_ledger, l_second_tx, &l_second_tx_hash, false), "Added second transaction on ledger");
+    dap_assert_PIF(dap_ledger_tx_add(a_ledger, l_second_tx, &l_second_tx_hash, false), "Added second transaction on ledger");
     dap_pass_msg("The verification test is not able to make two normal transactions per one basic transaction.");
 }
 
-void dap_chain_ledger_test_excess_supply(dap_ledger_t *a_ledger, dap_cert_t *a_cert, dap_chain_addr_t *a_addr){
-    dap_print_module_name("dap_chain_ledger_test_excess_supply");
+void dap_ledger_test_excess_supply(dap_ledger_t *a_ledger, dap_cert_t *a_cert, dap_chain_addr_t *a_addr){
+    dap_print_module_name("dap_ledger_test_excess_supply");
     const char *l_token_ticker = "Test2";
     uint256_t l_value_first_emi = dap_chain_uint256_from(s_total_supply / 2);
     uint256_t l_value_second_emi = dap_chain_uint256_from(s_total_supply);
     size_t l_decl_size = 0;
-    dap_chain_datum_token_t *l_decl = dap_chain_ledger_test_create_datum_decl(a_cert, &l_decl_size, l_token_ticker,
+    dap_chain_datum_token_t *l_decl = dap_ledger_test_create_datum_decl(a_cert, &l_decl_size, l_token_ticker,
                                                                               dap_chain_uint256_from(s_total_supply), NULL, 0, DAP_CHAIN_DATUM_TOKEN_FLAG_NONE);
-    dap_assert_PIF(!dap_chain_ledger_token_add(a_ledger, l_decl, l_decl_size), "Adding token declaration to ledger.");
+    dap_assert_PIF(!dap_ledger_token_add(a_ledger, l_decl, l_decl_size), "Adding token declaration to ledger.");
     dap_chain_datum_token_emission_t *l_femi = dap_chain_datum_emission_create(l_value_first_emi, l_token_ticker, a_addr);
     l_femi = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_femi);
     dap_chain_hash_fast_t l_femi_hash = {0};
     dap_hash_fast(l_femi, dap_chain_datum_emission_get_size((byte_t*)l_femi), &l_femi_hash);
-    dap_assert_PIF(!dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_femi,
+    dap_assert_PIF(!dap_ledger_token_emission_add(a_ledger, (byte_t*)l_femi,
                                                         dap_chain_datum_emission_get_size((byte_t*)l_femi),
                                                         &l_femi_hash, false), "Added first emission in ledger");
     //Second emi
@@ -128,7 +130,7 @@ void dap_chain_ledger_test_excess_supply(dap_ledger_t *a_ledger, dap_cert_t *a_c
     l_semi = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_semi);
     dap_chain_hash_fast_t l_semi_hash = {0};
     dap_hash_fast(l_semi, dap_chain_datum_emission_get_size((byte_t*)l_semi), &l_semi_hash);
-    int res =dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_semi,
+    int res =dap_ledger_token_emission_add(a_ledger, (byte_t*)l_semi,
                                                         dap_chain_datum_emission_get_size((byte_t*)l_semi),
                                                         &l_semi_hash, false);
     if (!res){
@@ -156,8 +158,8 @@ addr_key_container_t *gen_addr(dap_chain_net_id_t a_iddn){
     return l_container;
 }
 
-void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a_cert, dap_chain_net_id_t a_net_id) {
-    dap_print_module_name("dap_chain_ledger_test_write_back_list");
+void dap_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a_cert, dap_chain_net_id_t a_net_id) {
+    dap_print_module_name("dap_ledger_test_write_back_list");
     addr_key_container_t *l_addr_1 = gen_addr(a_net_id);
     addr_key_container_t *l_addr_2 = gen_addr(a_net_id);
     addr_key_container_t *l_addr_3 = gen_addr(a_net_id);
@@ -199,7 +201,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a
         uint16_t l_flags_decl = 0;
         l_flags_decl |= DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED;
         l_flags_decl |= DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED;
-        dap_chain_datum_token_t *l_decl = dap_chain_ledger_test_create_datum_decl(a_cert, &l_decl_size,
+        dap_chain_datum_token_t *l_decl = dap_ledger_test_create_datum_decl(a_cert, &l_decl_size,
                                                                                   l_token_ticker,
                                                                                   dap_chain_uint256_from(
                                                                                           s_total_supply),
@@ -208,7 +210,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a
                                                                                   //DAP_CHAIN_DATUM_TOKEN_FLAG_NONE);
                                                                                   l_flags_decl);
 
-        dap_assert_PIF(!dap_chain_ledger_token_add(a_ledger, l_decl, l_decl_size),
+        dap_assert_PIF(!dap_ledger_token_add(a_ledger, l_decl, l_decl_size),
                 "Can't added datum in ledger");
         //Check emission in not a white list
         dap_chain_datum_token_emission_t *l_emi = dap_chain_datum_emission_create(
@@ -216,7 +218,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a
         l_emi = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_emi);
         dap_chain_hash_fast_t l_emi_hash = {0};
         dap_hash_fast(l_emi, dap_chain_datum_emission_get_size((uint8_t*)l_emi), &l_emi_hash);
-        dap_assert(dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_emi, dap_chain_datum_emission_get_size((byte_t*)l_emi),
+        dap_assert(dap_ledger_token_emission_add(a_ledger, (byte_t*)l_emi, dap_chain_datum_emission_get_size((byte_t*)l_emi),
                                                             &l_emi_hash, false) != 0,
                        "Checking the impossibility of emission to an address not from the white list.");
         //Emission in white list
@@ -225,28 +227,28 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a
         l_emi_whi = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_emi_whi);
         dap_chain_hash_fast_t l_emi_whi_hash = {0};
         dap_hash_fast(l_emi_whi, dap_chain_datum_emission_get_size((uint8_t*)l_emi_whi), &l_emi_whi_hash);
-        dap_assert_PIF(!dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_emi_whi, dap_chain_datum_emission_get_size((byte_t*)l_emi_whi),
+        dap_assert_PIF(!dap_ledger_token_emission_add(a_ledger, (byte_t*)l_emi_whi, dap_chain_datum_emission_get_size((byte_t*)l_emi_whi),
                                             &l_emi_whi_hash, false),
                        "Can't add emission in white address");
-        dap_chain_datum_tx_t *l_btx_addr1 = dap_chain_ledger_test_create_datum_base_tx(l_emi_whi, &l_emi_whi_hash,
+        dap_chain_datum_tx_t *l_btx_addr1 = dap_ledger_test_create_datum_base_tx(l_emi_whi, &l_emi_whi_hash,
                                                                                       *l_addr_1->addr, a_cert);
         dap_hash_fast_t l_btx_addr1_hash = {0};
         dap_hash_fast(l_btx_addr1, dap_chain_datum_tx_get_size(l_btx_addr1), &l_btx_addr1_hash);
-        int l_ledger_add_code = dap_chain_ledger_tx_add(a_ledger, l_btx_addr1, &l_btx_addr1_hash, false);
+        int l_ledger_add_code = dap_ledger_tx_add(a_ledger, l_btx_addr1, &l_btx_addr1_hash, false);
         char *l_ledger_tx_add_str = dap_strdup_printf("Can't add base tx in white address. Code: %d", l_ledger_add_code);
         dap_assert_PIF(!l_ledger_add_code, l_ledger_tx_add_str);
         DAP_DELETE(l_ledger_tx_add_str);
         dap_hash_fast_t l_tx_addr4_hash = {0};
-        dap_chain_datum_tx_t *l_tx_to_addr4 = dap_chain_ledger_test_create_tx(l_addr_1->enc_key, &l_btx_addr1_hash,
+        dap_chain_datum_tx_t *l_tx_to_addr4 = dap_ledger_test_create_tx(l_addr_1->enc_key, &l_btx_addr1_hash,
                                                                               l_addr_4->addr, dap_chain_uint256_from(s_total_supply-s_fee));
         dap_hash_fast(l_tx_to_addr4, dap_chain_datum_tx_get_size(l_tx_to_addr4), &l_tx_addr4_hash);
-        dap_assert_PIF(!dap_chain_ledger_tx_add(a_ledger, l_tx_to_addr4, &l_tx_addr4_hash, false),
+        dap_assert_PIF(!dap_ledger_tx_add(a_ledger, l_tx_to_addr4, &l_tx_addr4_hash, false),
                        "Can't add transaction to address from white list in ledger");
-        dap_chain_datum_tx_t *l_tx_to_addr3 = dap_chain_ledger_test_create_tx(l_addr_4->enc_key, &l_tx_addr4_hash,
+        dap_chain_datum_tx_t *l_tx_to_addr3 = dap_ledger_test_create_tx(l_addr_4->enc_key, &l_tx_addr4_hash,
                                                                               l_addr_3->addr, dap_chain_uint256_from(s_total_supply-s_fee));
         dap_hash_fast_t l_tx_addr3_hash = {0};
         dap_hash_fast(l_tx_to_addr3, dap_chain_datum_tx_get_size(l_tx_to_addr3), &l_tx_addr3_hash);
-        int res_add_tx = dap_chain_ledger_tx_add(a_ledger, l_tx_to_addr3, &l_tx_addr3_hash, false);
+        int res_add_tx = dap_ledger_tx_add(a_ledger, l_tx_to_addr3, &l_tx_addr3_hash, false);
         if (!res_add_tx) {
             dap_fail("It was possible to carry out a transaction to a forbidden address");
         } else {
@@ -286,7 +288,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a
 //            memcpy(l_datum_token_update->data_n_tsd + l_offset, l_sign, l_sign_size);
 //            DAP_DELETE(l_sign);
 //            size_t l_token_update_size = sizeof(dap_chain_datum_token_t) + l_sign_size + l_offset;
-//            dap_assert(!dap_chain_ledger_token_add(a_ledger, l_datum_token_update, l_token_update_size),
+//            dap_assert(!dap_ledger_token_add(a_ledger, l_datum_token_update, l_token_update_size),
 //                           "Added token update in ledger.");
 //        } else {
 //            dap_fail("Can't creating sign for token update");
@@ -313,7 +315,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a
         l_flags_decl |= DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED;
         const char *l_token_ticker = "TestBL";
         size_t l_decl_size = 0;
-        dap_chain_datum_token_t *l_decl = dap_chain_ledger_test_create_datum_decl(a_cert, &l_decl_size,
+        dap_chain_datum_token_t *l_decl = dap_ledger_test_create_datum_decl(a_cert, &l_decl_size,
                                                                                   l_token_ticker,
                                                                                   dap_chain_uint256_from(
                                                                                           s_total_supply),
@@ -322,7 +324,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a
                 //DAP_CHAIN_DATUM_TOKEN_FLAG_NONE);
                                                                                   l_flags_decl);
 
-        dap_assert_PIF(!dap_chain_ledger_token_add(a_ledger, l_decl, l_decl_size),
+        dap_assert_PIF(!dap_ledger_token_add(a_ledger, l_decl, l_decl_size),
                        "Can't added datum in ledger");
         //Check emission at addr in block list
         dap_chain_datum_token_emission_t *l_emi_block = dap_chain_datum_emission_create(
@@ -330,7 +332,7 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a
         l_emi_block = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_emi_block);
         dap_chain_hash_fast_t l_emi_block_hash = {0};
         dap_hash_fast(l_emi_block, dap_chain_datum_emission_get_size((uint8_t*)l_emi_block), &l_emi_block_hash);
-        dap_assert(dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_emi_block, dap_chain_datum_emission_get_size((byte_t*)l_emi_block),
+        dap_assert(dap_ledger_token_emission_add(a_ledger, (byte_t*)l_emi_block, dap_chain_datum_emission_get_size((byte_t*)l_emi_block),
                                                             &l_emi_block_hash, false),
                        "Test for emission rejection to an address from the prohibited list.");
         //Check emission at addr
@@ -339,49 +341,53 @@ void dap_chain_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a
         l_emi = dap_chain_datum_emission_add_sign(a_cert->enc_key, l_emi);
         dap_chain_hash_fast_t l_emi_hash = {0};
         dap_hash_fast(l_emi, dap_chain_datum_emission_get_size((uint8_t*)l_emi), &l_emi_hash);
-        dap_assert(!dap_chain_ledger_token_emission_add(a_ledger, (byte_t*)l_emi, dap_chain_datum_emission_get_size((byte_t*)l_emi),
+        dap_assert(!dap_ledger_token_emission_add(a_ledger, (byte_t*)l_emi, dap_chain_datum_emission_get_size((byte_t*)l_emi),
                                                            &l_emi_hash, false),
                        "Emission test for a non-blacklisted address.");
-        dap_chain_datum_tx_t *l_btx_addr2 = dap_chain_ledger_test_create_datum_base_tx(l_emi, &l_emi_hash,
+        dap_chain_datum_tx_t *l_btx_addr2 = dap_ledger_test_create_datum_base_tx(l_emi, &l_emi_hash,
                                                                                        *l_addr_2->addr, a_cert);
         dap_hash_fast_t l_btx_addr2_hash = {0};
         dap_hash_fast(l_btx_addr2, dap_chain_datum_tx_get_size(l_btx_addr2), &l_btx_addr2_hash);
-        dap_assert_PIF(!dap_chain_ledger_tx_add(a_ledger, l_btx_addr2, &l_btx_addr2_hash, false),
+        dap_assert_PIF(!dap_ledger_tx_add(a_ledger, l_btx_addr2, &l_btx_addr2_hash, false),
                        "Can't add base tx in white address");
         //Check tx in addr from block list
-        dap_chain_datum_tx_t *l_tx_to_addr1 = dap_chain_ledger_test_create_tx(l_addr_4->enc_key, &l_btx_addr2_hash,
+        dap_chain_datum_tx_t *l_tx_to_addr1 = dap_ledger_test_create_tx(l_addr_4->enc_key, &l_btx_addr2_hash,
                                                                               l_addr_1->addr, dap_chain_uint256_from(s_total_supply));
         dap_hash_fast_t l_tx_addr1_hash = {0};
         dap_hash_fast(l_tx_to_addr1, dap_chain_datum_tx_get_size(l_tx_to_addr1), &l_tx_addr1_hash);
-        dap_assert(dap_chain_ledger_tx_add(a_ledger, l_tx_to_addr1, &l_tx_addr1_hash, false), "Transfer test to a forbidden address.");
+        dap_assert(dap_ledger_tx_add(a_ledger, l_tx_to_addr1, &l_tx_addr1_hash, false), "Transfer test to a forbidden address.");
         //Check tx in addr from list
-        dap_chain_datum_tx_t *l_tx_to_addr3 = dap_chain_ledger_test_create_tx(l_addr_4->enc_key, &l_tx_addr1_hash,
+        dap_chain_datum_tx_t *l_tx_to_addr3 = dap_ledger_test_create_tx(l_addr_4->enc_key, &l_tx_addr1_hash,
                                                                               l_addr_3->addr, dap_chain_uint256_from(s_total_supply));
         dap_hash_fast_t l_tx_addr3_hash = {0};
         dap_hash_fast(l_tx_to_addr3, dap_chain_datum_tx_get_size(l_tx_to_addr3), &l_tx_addr3_hash);
-        dap_assert(dap_chain_ledger_tx_add(a_ledger, l_tx_to_addr3, &l_tx_addr3_hash, false), "Transfer test to a not forbidden address.");
+        dap_assert(dap_ledger_tx_add(a_ledger, l_tx_to_addr3, &l_tx_addr3_hash, false), "Transfer test to a not forbidden address.");
     }
 }
 
-void dap_chain_ledger_test_run(void){
+void dap_ledger_test_run(void){
     dap_chain_net_id_t l_iddn = {0};
     dap_sscanf("0xFA0", "0x%16"DAP_UINT64_FORMAT_x, &l_iddn.uint64);
-    dap_print_module_name("dap_chain_ledger");
+    dap_print_module_name("dap_ledger");
     uint16_t l_flags = 0;
-    l_flags |= DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION;
-    dap_ledger_t *l_ledger = dap_chain_ledger_create(l_flags, l_iddn, "Snet", s_token_ticker, NULL);
+    l_flags |= DAP_LEDGER_CHECK_TOKEN_EMISSION;
+    dap_chain_net_t *l_net = DAP_NEW_Z(dap_chain_net_t);
+    l_net->pub.id = l_iddn;
+    l_net->pub.native_ticker = s_token_ticker;
+    l_net->pub.name = "Snet";
+    dap_ledger_t *l_ledger = dap_ledger_create(l_net, l_flags);
     char *l_seed_ph = "H58i9GJKbn91238937^#$t6cjdf";
     size_t l_seed_ph_size = strlen(l_seed_ph);
     dap_cert_t *l_cert = dap_cert_generate_mem_with_seed("testCert", DAP_ENC_KEY_TYPE_SIG_PICNIC, l_seed_ph, l_seed_ph_size);
     size_t l_token_decl_size = 0;
-    dap_chain_datum_token_t *l_token_decl = dap_chain_ledger_test_create_datum_decl(l_cert,
+    dap_chain_datum_token_t *l_token_decl = dap_ledger_test_create_datum_decl(l_cert,
                                                                                     &l_token_decl_size, s_token_ticker,
                                                                                     dap_chain_uint256_from(s_total_supply), NULL, 0, DAP_CHAIN_DATUM_TOKEN_FLAG_NONE);
     dap_assert_PIF(l_token_decl || l_token_decl_size == 0, "Generate token declaration.");
     int l_check_added_decl_token = 0;
-    l_check_added_decl_token = dap_chain_ledger_token_decl_add_check(l_ledger, l_token_decl, l_token_decl_size);
+    l_check_added_decl_token = dap_ledger_token_decl_add_check(l_ledger, l_token_decl, l_token_decl_size);
     dap_assert_PIF(l_check_added_decl_token == 0, "Checking whether it is possible to add a token declaration to ledger.");
-    dap_assert_PIF(!dap_chain_ledger_token_add(l_ledger, l_token_decl, l_token_decl_size), "Adding token declaration to ledger.");
+    dap_assert_PIF(!dap_ledger_token_add(l_ledger, l_token_decl, l_token_decl_size), "Adding token declaration to ledger.");
 	
     // Create emission
     dap_chain_addr_t l_addr = {0};
@@ -391,38 +397,38 @@ void dap_chain_ledger_test_run(void){
     size_t l_emi_size = dap_chain_datum_emission_get_size((byte_t*)l_emi_sign);
     dap_chain_hash_fast_t l_emi_hash = {0};
     dap_hash_fast(l_emi, l_emi_size, &l_emi_hash);
-    int l_emi_check = dap_chain_ledger_token_emission_add_check(l_ledger, (byte_t*)l_emi_sign, l_emi_size, &l_emi_hash);
+    int l_emi_check = dap_ledger_token_emission_add_check(l_ledger, (byte_t*)l_emi_sign, l_emi_size, &l_emi_hash);
     dap_assert_PIF(l_emi_check == 0, "check emission for add in ledger");
-    dap_assert_PIF(!dap_chain_ledger_token_emission_add(l_ledger, (byte_t*)l_emi_sign, l_emi_size, &l_emi_hash, false), "Added emission in ledger");
+    dap_assert_PIF(!dap_ledger_token_emission_add(l_ledger, (byte_t*)l_emi_sign, l_emi_size, &l_emi_hash, false), "Added emission in ledger");
     //first base tx
-    dap_chain_datum_tx_t *l_base_tx = dap_chain_ledger_test_create_datum_base_tx(l_emi_sign, &l_emi_hash, l_addr, l_cert);
+    dap_chain_datum_tx_t *l_base_tx = dap_ledger_test_create_datum_base_tx(l_emi_sign, &l_emi_hash, l_addr, l_cert);
     size_t l_base_tx_size = dap_chain_datum_tx_get_size(l_base_tx);
     dap_hash_fast_t l_hash_btx = {0};
     dap_hash_fast(l_base_tx, l_base_tx_size, &l_hash_btx);
-    dap_assert_PIF(!dap_chain_ledger_tx_add_check(l_ledger, l_base_tx, l_base_tx_size, &l_hash_btx), "Check can added base tx in ledger");
-    dap_assert_PIF(!dap_chain_ledger_tx_add(l_ledger, l_base_tx, &l_hash_btx, false), "Added base tx in ledger.");
+    dap_assert_PIF(!dap_ledger_tx_add_check(l_ledger, l_base_tx, l_base_tx_size, &l_hash_btx), "Check can added base tx in ledger");
+    dap_assert_PIF(!dap_ledger_tx_add(l_ledger, l_base_tx, &l_hash_btx, false), "Added base tx in ledger.");
     uint256_t l_balance_example = dap_chain_uint256_from(s_standard_value_tx);
-    uint256_t l_balance = dap_chain_ledger_calc_balance(l_ledger, &l_addr, s_token_ticker);	
+    uint256_t l_balance = dap_ledger_calc_balance(l_ledger, &l_addr, s_token_ticker);
 	uint256_t l_fee = dap_chain_uint256_from(s_fee);
 	SUM_256_256(l_balance,l_fee,&l_balance);
     dap_assert_PIF(!compare256(l_balance, l_balance_example), "Checking the availability of the necessary balance "
                                                              "on the wallet after the first transaction.");
     dap_pass_msg("Validation of the declaration of the tocen, creation of an emission and a basic transaction using this in the ledger.");
     //second base tx
-    dap_chain_datum_tx_t  *l_base_tx_second = dap_chain_ledger_test_create_datum_base_tx(l_emi_sign, &l_emi_hash, l_addr, l_cert);
+    dap_chain_datum_tx_t  *l_base_tx_second = dap_ledger_test_create_datum_base_tx(l_emi_sign, &l_emi_hash, l_addr, l_cert);
     size_t l_base_tx_size2 = dap_chain_datum_tx_get_size(l_base_tx_second);
     dap_hash_fast_t l_hash_btx_second = {0};
     dap_hash_fast(l_base_tx_second, l_base_tx_size2, &l_hash_btx_second);
-    if (dap_chain_ledger_tx_add_check(l_ledger, l_base_tx_second, l_base_tx_size2, &l_hash_btx_second)) {
+    if (dap_ledger_tx_add_check(l_ledger, l_base_tx_second, l_base_tx_size2, &l_hash_btx_second)) {
         dap_pass_msg("Checking can added second base tx in ledger");
     }
-    if (dap_chain_ledger_tx_add(l_ledger, l_base_tx_second, &l_hash_btx_second, false)){
+    if (dap_ledger_tx_add(l_ledger, l_base_tx_second, &l_hash_btx_second, false)){
         dap_pass_msg("Checking for a failure to add a second base transaction for the same issue to the ledger.");
     } else {
         dap_fail("Checking for a failure to add a second base transaction for the same issue to the ledger.");
     }	
-    dap_chain_ledger_test_double_spending(l_ledger, &l_hash_btx, l_cert->enc_key, l_iddn);
-    dap_chain_ledger_test_excess_supply(l_ledger, l_cert, &l_addr);
-    dap_chain_ledger_test_write_back_list(l_ledger, l_cert, l_iddn);
+    dap_ledger_test_double_spending(l_ledger, &l_hash_btx, l_cert->enc_key, l_iddn);
+    dap_ledger_test_excess_supply(l_ledger, l_cert, &l_addr);
+    dap_ledger_test_write_back_list(l_ledger, l_cert, l_iddn);
 	
 }
diff --git a/modules/chain/tests/include/dap_chain_ledger_tests.h b/modules/chain/tests/include/dap_chain_ledger_tests.h
index 5d36be4f1b..0018b3e6ce 100644
--- a/modules/chain/tests/include/dap_chain_ledger_tests.h
+++ b/modules/chain/tests/include/dap_chain_ledger_tests.h
@@ -1,6 +1,3 @@
-#include "dap_test.h"
 #include "dap_chain_ledger.h"
 
-void dap_chain_ledger_test_run(void);
-
-//dap_ledger_t *dap_chain_ledger_create_test();
+void dap_ledger_test_run(void);
diff --git a/modules/chain/tests/main.c b/modules/chain/tests/main.c
index 0d111fd5e9..2af8441cfc 100644
--- a/modules/chain/tests/main.c
+++ b/modules/chain/tests/main.c
@@ -1,5 +1,5 @@
 #include "dap_chain_ledger_tests.h"
 int main(void){
-    dap_chain_ledger_test_run();
+    dap_ledger_test_run();
     return 0;
-}
\ No newline at end of file
+}
diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
index a0d7fb5a36..2481153ee9 100644
--- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
+++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
@@ -412,7 +412,7 @@ static void s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
         return;
     }
 
-    l_tx = a_grace->usage->is_waiting_new_tx_cond ? NULL : dap_chain_ledger_tx_find_by_hash(l_ledger, &a_grace->usage->tx_cond_hash);
+    l_tx = a_grace->usage->is_waiting_new_tx_cond ? NULL : dap_ledger_tx_find_by_hash(l_ledger, &a_grace->usage->tx_cond_hash);
     if (!l_tx) { // No tx cond transaction, start grace-period
         if (!a_grace->usage->is_active){
             dap_chain_net_srv_banlist_item_t *l_item = NULL;
@@ -569,7 +569,7 @@ static void s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
             return;
         }
 
-        const char *l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &a_grace->usage->tx_cond_hash);
+        const char *l_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &a_grace->usage->tx_cond_hash);
         if (!l_ticker) {
             char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' };
             dap_hash_fast_to_str(&a_grace->usage->tx_cond_hash, l_hash_str, sizeof(l_hash_str));
@@ -806,7 +806,7 @@ static bool s_grace_period_finish(usages_in_grace_t *a_grace_item)
         RET_WITH_DEL_A_GRACE;
     }
     log_it(L_INFO, "Grace period is over! Check tx in ledger.");
-    l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &l_grace->usage->tx_cond_hash);
+    l_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_grace->usage->tx_cond_hash);
     if ( ! l_tx ){ // No tx cond transaction, start grace-period
         log_it( L_WARNING, "No tx cond transaction");
         l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_FOUND ;
@@ -843,7 +843,7 @@ static bool s_grace_period_finish(usages_in_grace_t *a_grace_item)
 
         dap_chain_net_srv_price_t * l_price = NULL;
         const char * l_ticker = NULL;
-        l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_grace->usage->tx_cond_hash);
+        l_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_grace->usage->tx_cond_hash);
         dap_stpcpy(l_grace->usage->token_ticker, l_ticker);
 
         if (dap_hash_fast_is_blank(&l_grace->usage->static_order_hash)){
@@ -1543,7 +1543,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
             break;
         }
 
-        dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_usage->net->pub.ledger, &l_responce->hdr.tx_cond);
+        dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_usage->net->pub.ledger, &l_responce->hdr.tx_cond);
         if (l_tx){
             // Replace
             if (l_curr_grace_item){
diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c
index dc3cae2a85..0dfb3c3f6e 100644
--- a/modules/common/dap_chain_datum.c
+++ b/modules/common/dap_chain_datum.c
@@ -317,6 +317,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                                                 ((dap_chain_tx_in_ems_t*)item)->header.token_emission_chain_id.uint64);
             DAP_DELETE(l_hash_str);
         } break;
+            /*
         case TX_ITEM_TYPE_IN_EMS_EXT: {
             l_hash_tmp = &((dap_chain_tx_in_ems_ext_t*)item)->header.ext_tx_hash;
             l_hash_str = dap_strcmp(a_hash_out_type, "hex")
@@ -336,7 +337,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                                      l_hash_str,
                                      ((dap_chain_tx_in_ems_ext_t*)item)->header.ext_tx_out_idx);
             DAP_DELETE(l_hash_str);
-        } break;
+        } break; */
         case TX_ITEM_TYPE_SIG: {
             l_sign_tmp = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)item);
             dap_sign_get_information(l_sign_tmp, a_str_out, a_hash_out_type);
@@ -503,11 +504,10 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                     DAP_DELETE(l_hash_str);
                 } break;
                 case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: {
-//                    char *l_value_str = dap_chain_balance_print(((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_value);
                     char *l_rate_str = dap_chain_balance_to_coins(((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.rate);
                     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"
-                                                        "\t\t\t rate: %s (%s)\n",
+                                                        "\t\t\t rate: %s\n",
                                              ((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_net_id.uint64,
                                              ((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_token,
                                              l_rate_str);
@@ -556,9 +556,9 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
 /**
  * @brief dap_chain_net_dump_datum
  * process datum verification process. Can be:
- * if DAP_CHAIN_DATUM_TX, called dap_chain_ledger_tx_add_check
- * if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_chain_ledger_token_decl_add_check
- * if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_chain_ledger_token_emission_add_check
+ * if DAP_CHAIN_DATUM_TX, called dap_ledger_tx_add_check
+ * if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_ledger_token_decl_add_check
+ * if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_ledger_token_emission_add_check
  * @param a_str_out
  * @param a_datum
  */
@@ -688,8 +688,8 @@ 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_emisssion_size = a_datum->header.data_size;
             dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_datum->data, &l_emisssion_size);
-            char *l_value_str = dap_chain_balance_print(l_emission->hdr.value_256);
-            char *l_coins_str = dap_chain_balance_to_coins(l_emission->hdr.value_256);
+            char *l_value_str = dap_chain_balance_print(l_emission->hdr.value);
+            char *l_coins_str = dap_chain_balance_to_coins(l_emission->hdr.value);
             char *l_addr_str = dap_chain_addr_to_str(&(l_emission->hdr.address));
             dap_string_append_printf(a_str_out, "emission: hash %s\n\t%s(%s) %s, type: %s, version: %d\n",
                                     l_hash_str,
diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c
index 5c9ca94b59..a4e94e5859 100644
--- a/modules/common/dap_chain_datum_decree.c
+++ b/modules/common/dap_chain_datum_decree.c
@@ -61,6 +61,13 @@ int dap_chain_datum_decree_get_fee(dap_chain_datum_decree_t *a_decree, uint256_t
     return l_tsd ? ({ _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;
+}
+
 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) {
@@ -179,9 +186,19 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
         dap_tsd_t *l_tsd = (dap_tsd_t *)((byte_t*)a_decree->data_n_signs + l_offset);
         l_offset += dap_tsd_size(l_tsd);
         switch(l_tsd->type) {
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE:
+                if (l_tsd->size > sizeof(uint256_t)){
+                    dap_string_append_printf(a_str_out, "\tValue: <WRONG SIZE>\n");
+                    break;
+                }
+                uint256_t l_value = uint256_0;
+                _dap_tsd_get_scalar(l_tsd, &l_value);
+                char *l_value_str = dap_chain_balance_print(l_value);
+                dap_string_append_printf(a_str_out, "\tValue: %s\n", l_value_str);
+                DAP_DELETE(l_value_str);
+                break;
             case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN:
             break;
-//                return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN";
             case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE:
                 if (l_tsd->size > sizeof(uint256_t)){
                     dap_string_append_printf(a_str_out, "\tFee: <WRONG SIZE>\n");
@@ -358,7 +375,7 @@ 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_in_cycle(dap_cert_t ** a_certs, dap_chain_datum_decree_t *a_datum_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;
diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c
index 4566139492..352b87901f 100644
--- a/modules/common/dap_chain_datum_token.c
+++ b/modules/common/dap_chain_datum_token.c
@@ -358,7 +358,7 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_create(uint256_t a_va
         return NULL;
     }
     l_emission->hdr.version = 3;
-    l_emission->hdr.value_256 = a_value;
+    l_emission->hdr.value = a_value;
     strncpy(l_emission->hdr.ticker, a_ticker, DAP_CHAIN_TICKER_SIZE_MAX - 1);
     l_emission->hdr.type = DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH;
     l_emission->hdr.address = *a_addr;
@@ -406,8 +406,8 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_read(byte_t *a_emissi
         memcpy((byte_t *)l_emission + sizeof(l_emission->hdr),
                a_emission_serial + l_old_hdr_size,
                (uint32_t)(l_emission_size - l_old_hdr_size));
-        l_emission->hdr.value_256 = dap_chain_uint256_from(
-                    ((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.value);
+        l_emission->hdr.value = dap_chain_uint256_from(
+                    ((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.value64);
         l_emission_size += l_add_size;
         (*a_emission_size) = l_emission_size;
     } else {
@@ -417,8 +417,8 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_read(byte_t *a_emissi
             return NULL;
         }
         if (((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.version == 1)
-            l_emission->hdr.value_256 = dap_chain_uint256_from(
-                        ((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.value);
+            l_emission->hdr.value = dap_chain_uint256_from(
+                        ((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.value64);
     }
     return l_emission;
 }
diff --git a/modules/common/dap_chain_datum_tx.c b/modules/common/dap_chain_datum_tx.c
index 01c40f6e37..78e9268f6c 100644
--- a/modules/common/dap_chain_datum_tx.c
+++ b/modules/common/dap_chain_datum_tx.c
@@ -158,6 +158,17 @@ uint256_t dap_chain_datum_tx_add_in_cond_item_list(dap_chain_datum_tx_t **a_tx,
    }
    return l_value_to_items;
 }
+
+int dap_chain_datum_tx_add_in_reward_item(dap_chain_datum_tx_t **a_tx, dap_chain_hash_fast_t *a_block_hash)
+{
+    dap_chain_tx_in_reward_t *l_tx_in_reward = dap_chain_datum_tx_item_in_reward_create(a_block_hash);
+    if (!l_tx_in_reward)
+        return -1;
+    dap_chain_datum_tx_add_item(a_tx, (uint8_t*)l_tx_in_reward);
+    DAP_DELETE(l_tx_in_reward);
+    return 1;
+}
+
 /**
  * Create 'out_cond' item with fee value and insert to transaction
  *
diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c
index 233099e58e..782c239dfa 100644
--- a/modules/common/dap_chain_datum_tx_items.c
+++ b/modules/common/dap_chain_datum_tx_items.c
@@ -31,10 +31,6 @@
 #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"
-#include "dap_chain_datum_tx_out_cond.h"
 #include "dap_chain_datum_tx_items.h"
 
 static size_t dap_chain_tx_in_get_size(const dap_chain_tx_in_t *a_item)
@@ -92,13 +88,19 @@ static size_t dap_chain_tx_sig_get_size(const dap_chain_tx_sig_t *a_item)
     return size;
 }
 
-static size_t dap_chain_tx_token_get_size(const dap_chain_tx_in_ems_t *a_item)
+static size_t dap_chain_tx_in_ems_get_size(const dap_chain_tx_in_ems_t *a_item)
 {
     (void) a_item;
     size_t size = sizeof(dap_chain_tx_in_ems_t);
     return size;
 }
 
+static size_t dap_chain_tx_in_reward_get_size(const dap_chain_tx_in_reward_t UNUSED_ARG *a_item)
+{
+    size_t size = sizeof(dap_chain_tx_in_reward_t);
+    return size;
+}
+
 static size_t dap_chain_datum_tx_receipt_get_size(const dap_chain_datum_tx_receipt_t *a_item)
 {
     size_t size = a_item->size;
@@ -120,6 +122,10 @@ dap_chain_tx_item_type_t dap_chain_datum_tx_item_str_to_type(const char *a_datum
         return TX_ITEM_TYPE_UNKNOWN;
     if(!dap_strcmp(a_datum_name, "in"))
         return TX_ITEM_TYPE_IN;
+    else if(!dap_strcmp(a_datum_name, "in_ems"))
+        return TX_ITEM_TYPE_IN_EMS;
+    else if(!dap_strcmp(a_datum_name, "in_reward"))
+        return TX_ITEM_TYPE_IN_REWARD;
     else if(!dap_strcmp(a_datum_name, "out"))
         return TX_ITEM_TYPE_OUT;
     else if(!dap_strcmp(a_datum_name, "out_ext"))
@@ -186,10 +192,10 @@ size_t dap_chain_datum_item_tx_get_size(const void *a_item)
     case TX_ITEM_TYPE_IN: // Transaction inputs
         size = dap_chain_tx_in_get_size((const dap_chain_tx_in_t*) a_item);
         break;
-    case TX_ITEM_TYPE_OUT_OLD: // Transaction outputs
+    case TX_ITEM_TYPE_OUT_OLD: //64
         size = dap_chain_tx_out_get_size((const dap_chain_tx_out_old_t*) a_item);
         break;
-    case TX_ITEM_TYPE_OUT: // 256
+    case TX_ITEM_TYPE_OUT: // Transaction outputs
         size = dap_chain_256_tx_out_get_size((const dap_chain_tx_out_t*) a_item);
         break;
     case TX_ITEM_TYPE_OUT_EXT: // Exchange transaction outputs
@@ -201,10 +207,7 @@ size_t dap_chain_datum_item_tx_get_size(const void *a_item)
     case TX_ITEM_TYPE_IN_COND: // Transaction inputs with condition
         size = dap_chain_tx_in_cond_get_size((const dap_chain_tx_in_cond_t*) a_item);
         break;
-    case TX_ITEM_TYPE_OUT_COND_OLD: // Transaction output with condition
-        size = 0; // obsolete dap_chain_tx_out_cond_get_size((const dap_chain_tx_out_cond_t*) a_item);
-        break;
-    case TX_ITEM_TYPE_OUT_COND: // 256
+    case TX_ITEM_TYPE_OUT_COND: // Condtional output
         size = dap_chain_tx_out_cond_get_size((const dap_chain_tx_out_cond_t *)a_item);
         break;
     case TX_ITEM_TYPE_PKEY: // Transaction public keys
@@ -213,8 +216,11 @@ size_t dap_chain_datum_item_tx_get_size(const void *a_item)
     case TX_ITEM_TYPE_SIG: // Transaction signatures
         size = dap_chain_tx_sig_get_size((const dap_chain_tx_sig_t*) a_item);
         break;
-    case TX_ITEM_TYPE_IN_EMS: // token item
-        size = dap_chain_tx_token_get_size((const dap_chain_tx_in_ems_t*) a_item);
+    case TX_ITEM_TYPE_IN_EMS: // token emission pointer
+        size = dap_chain_tx_in_ems_get_size((const dap_chain_tx_in_ems_t*) a_item);
+        break;
+    case TX_ITEM_TYPE_IN_REWARD: // block emission pointer
+        size = dap_chain_tx_in_reward_get_size((const dap_chain_tx_in_reward_t *)a_item);
         break;
     case TX_ITEM_TYPE_TSD:
         size = dap_chain_tx_tsd_get_size((const dap_chain_tx_tsd_t*)a_item);
@@ -269,15 +275,26 @@ dap_chain_tx_in_t* dap_chain_datum_tx_item_in_create(dap_chain_hash_fast_t *a_tx
     if(!a_tx_prev_hash)
         return NULL;
     dap_chain_tx_in_t *l_item = DAP_NEW_Z(dap_chain_tx_in_t);
-        if (!l_item) {
+    if (!l_item)
         return NULL;
-    }
     l_item->header.type = TX_ITEM_TYPE_IN;
     l_item->header.tx_out_prev_idx = a_tx_out_prev_idx;
     l_item->header.tx_prev_hash = *a_tx_prev_hash;
     return l_item;
 }
 
+dap_chain_tx_in_reward_t *dap_chain_datum_tx_item_in_reward_create(dap_chain_hash_fast_t *a_block_hash)
+{
+    if (!a_block_hash)
+        return NULL;
+    dap_chain_tx_in_reward_t *l_item = DAP_NEW_Z(dap_chain_tx_in_reward_t);
+    if (!l_item)
+        return NULL;
+    l_item->type = TX_ITEM_TYPE_IN_REWARD;
+    l_item->block_hash = *a_block_hash;
+    return l_item;
+}
+
 /**
  * Create tsd section
  */
@@ -741,7 +758,7 @@ uint8_t* dap_chain_datum_tx_item_get( dap_chain_datum_tx_t *a_tx, int *a_item_id
                     (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN) ||
                     (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN_COND) ||
                     (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN_EMS) ||
-                    (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN_EMS_EXT)) {
+                    (a_type == TX_ITEM_TYPE_IN_ALL && l_type == TX_ITEM_TYPE_IN_REWARD)) {
                 if(a_item_idx)
                     *a_item_idx = l_item_idx;
                 if(a_item_out_size)
diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h
index 86e0a0d917..ddef34874a 100644
--- a/modules/common/include/dap_chain_common.h
+++ b/modules/common/include/dap_chain_common.h
@@ -112,7 +112,7 @@ typedef struct dap_chain_addr{
         dap_chain_hash_fast_t hash_fast;
     } DAP_ALIGN_PACKED data;
     dap_chain_hash_fast_t checksum;
-}  DAP_ALIGN_PACKED dap_chain_addr_t;
+} DAP_ALIGN_PACKED dap_chain_addr_t;
 
 #define DAP_CHAIN_NET_SRV_UID_SIZE 8
 
@@ -182,26 +182,26 @@ typedef union {
 } DAP_ALIGN_PACKED dap_chain_net_srv_price_unit_uid_t;
 
 enum dap_chain_tx_item_type {
-    TX_ITEM_TYPE_IN = 0x00, /// @brief  Transaction: inputs
+    /// @brief Transaction: inputs
+    TX_ITEM_TYPE_IN = 0x00,
+    TX_ITEM_TYPE_IN_COND = 0x50,
+    TX_ITEM_TYPE_IN_REWARD = 0x07,
+    TX_ITEM_TYPE_IN_EMS = 0x40,
 
-    TX_ITEM_TYPE_OUT_OLD = 0x10, /// @brief  Transaction: outputs
+    /// @brief Transaction: outputs
+    TX_ITEM_TYPE_OUT_OLD = 0x10,        // Deprecated
     TX_ITEM_TYPE_OUT_EXT = 0x11,
-    TX_ITEM_TYPE_OUT = 0x12, // 256
+    TX_ITEM_TYPE_OUT = 0x12,
+    TX_ITEM_TYPE_OUT_COND = 0x61,
 
+    /// @brief Transaction: misc
     TX_ITEM_TYPE_PKEY = 0x20,
     TX_ITEM_TYPE_SIG = 0x30,
-    TX_ITEM_TYPE_IN_EMS = 0x40,
-    TX_ITEM_TYPE_IN_EMS_EXT = 0x41,
-
-    TX_ITEM_TYPE_IN_COND = 0x50, /// @brief  Transaction: conditon inputs
-
-    TX_ITEM_TYPE_OUT_COND_OLD = 0x60, // Obsolete
-    TX_ITEM_TYPE_OUT_COND = 0x61, /// @brief  Transaction: 256 bit conditon outputs
-
     TX_ITEM_TYPE_RECEIPT = 0x70,
-
     TX_ITEM_TYPE_TSD = 0x80,
 
+    /// @brief Virtual types for items enumearting
+    TX_ITEM_TYPE_IN_EMS_LOCK = 0xf1,
     TX_ITEM_TYPE_IN_ALL = 0xfd,
     TX_ITEM_TYPE_OUT_ALL = 0xfe,
     TX_ITEM_TYPE_ANY = 0xff
diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h
index 2d88482561..6cef21196f 100644
--- a/modules/common/include/dap_chain_datum_decree.h
+++ b/modules/common/include/dap_chain_datum_decree.h
@@ -72,8 +72,10 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_
 #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT    0x0008
 #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
 
 // DECREE TSD types
+#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE                               0x0100
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN                                0x0101
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE                                 0x0102
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER                               0x0103
@@ -99,17 +101,19 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_d
     case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS_MIN:
         return "DECREE_COMMON_SUBTYPE_OWNERS_MIN";
     case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE:
-        return "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE";
+        return "DECREE_COMMON_SUBTYPE_STAKE_APPROVE";
     case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE:
-        return "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE";
+        return "DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE";
     case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE:
-        return "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE";
+        return "DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE";
     case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT:
-        return"DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT";
+        return "COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT";
     case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN:
-        return "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN";
+        return "DECREE_COMMON_SUBTYPE_BAN";
     case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN:
-        return "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN";
+        return "DECREE_COMMON_SUBTYPE_UNBAN";
+    case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD:
+        return "DECREE_COMMON_SUBTYPE_REWARD";
     default:
         return "DECREE_SUBTYPE_UNKNOWN";
     }
@@ -117,6 +121,8 @@ 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:
@@ -207,6 +213,15 @@ int dap_chain_datum_decree_get_stake_tx_hash(dap_chain_datum_decree_t *a_decree,
  */
 int dap_chain_datum_decree_get_stake_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_stake_value);
 
+
+/**
+ * @brief dap_chain_datum_decree_get_stake_value get stake value
+ * @param a_decree pointer to decree
+ * @param a_stake_value pointer to stake value buffer
+ * @return result code. 0 - success
+ */
+int dap_chain_datum_decree_get_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_value);
+
 /**
  * @brief dap_chain_datum_decree_get_stake_signing_addr get signing address
  * @param a_decree pointer to decree
@@ -257,7 +272,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
 void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type);
 
 /**
- * @brief dap_chain_datum_decree_in_cycle
+ * @brief dap_chain_datum_decree_sign_in_cycle
  * sign data (datum_decree) by certificates (1 or more)
  * successful count of signes return in l_sign_counter
  * @param l_certs - array with certificates loaded from dcert file
@@ -267,5 +282,5 @@ void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_sign
  * @param l_sign_counter - counter of successful data signing operation
  * @return dap_chain_datum_token_t*
  */
-dap_chain_datum_decree_t* dap_chain_datum_decree_in_cycle(dap_cert_t ** a_certs, dap_chain_datum_decree_t *a_datum_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);
diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h
index a47c216189..dcc0c1ce25 100644
--- a/modules/common/include/dap_chain_datum_token.h
+++ b/modules/common/include/dap_chain_datum_token.h
@@ -438,15 +438,15 @@ struct DAP_ALIGN_PACKED dap_chain_emission_header_v0 {
 };
 
 // Token emission
-typedef struct dap_chain_datum_token_emission{
+typedef struct dap_chain_datum_token_emission {
     struct  {
         uint8_t version;
-        uint8_t type; // Emission Type
+        uint8_t type;               // Emission Type
         char ticker[DAP_CHAIN_TICKER_SIZE_MAX];
-        dap_chain_addr_t address; // Emission holder's address
+        dap_chain_addr_t address;   // Emission holder's address
         union {
-            uint64_t value;
-            uint256_t value_256;
+            uint64_t value64;       // Deprecated
+            uint256_t value;
         };
         uint8_t nonce[DAP_CHAIN_DATUM_NONCE_SIZE];
     } DAP_ALIGN_PACKED hdr;
@@ -457,7 +457,7 @@ typedef struct dap_chain_datum_token_emission{
             uint64_t lock_time;
         } DAP_ALIGN_PACKED type_presale;
         struct {
-            uint64_t value_start;// Default value. Static if nothing else is defined
+            uint64_t value_start;   // Default value. Static if nothing else is defined
             char value_change_algo_codename[32];
         } DAP_ALIGN_PACKED type_atom_owner;
         struct {
@@ -467,10 +467,10 @@ typedef struct dap_chain_datum_token_emission{
             uint64_t size;
             uint64_t tsd_total_size;
             uint16_t signs_count;
-        } DAP_ALIGN_PACKED type_auth;// Signs if exists
+        } DAP_ALIGN_PACKED type_auth;
         byte_t free_space[128];     // For future changes
     } data;
-    byte_t tsd_n_signs[];
+    byte_t tsd_n_signs[];           // TSD sections and signs if any
 } DAP_ALIGN_PACKED dap_chain_datum_token_emission_t;
 
 // Different emissions type
diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h
index 92b0a8cacb..f2cc1c7e4e 100644
--- a/modules/common/include/dap_chain_datum_tx.h
+++ b/modules/common/include/dap_chain_datum_tx.h
@@ -99,6 +99,13 @@ int dap_chain_datum_tx_add_in_cond_item(dap_chain_datum_tx_t **a_tx, dap_chain_h
  */
 uint256_t dap_chain_datum_tx_add_in_cond_item_list(dap_chain_datum_tx_t **a_tx, dap_list_t *a_list_used_out_cound);
 
+/**
+ *  Create 'in_reward' item and insert to transaction
+ *
+ * return 1 Ok, -1 Error
+ */
+int dap_chain_datum_tx_add_in_reward_item(dap_chain_datum_tx_t **a_tx, dap_chain_hash_fast_t *a_block_hash);
+
 /**
  * Create 'out' item and insert to transaction
  *
diff --git a/modules/common/include/dap_chain_datum_tx_in_cond.h b/modules/common/include/dap_chain_datum_tx_in_cond.h
index eda89c996f..cea12feffd 100644
--- a/modules/common/include/dap_chain_datum_tx_in_cond.h
+++ b/modules/common/include/dap_chain_datum_tx_in_cond.h
@@ -38,5 +38,5 @@ typedef struct dap_chain_tx_in_cond {
         dap_chain_hash_fast_t tx_prev_hash; /// @param tx_prev_hash    @brief Hash of the previous transaction. 0 for generation TX
         uint32_t tx_out_prev_idx; ///      @param   tx_prev_idx     @brief Previous tx_out index. 0 for generation TX
         uint32_t receipt_idx;
-    } header; /// Only header's hash is used for verification
-}DAP_ALIGN_PACKED dap_chain_tx_in_cond_t;
+    } header;
+} DAP_ALIGN_PACKED dap_chain_tx_in_cond_t;
diff --git a/modules/common/include/dap_chain_datum_tx_in_reward.h b/modules/common/include/dap_chain_datum_tx_in_reward.h
new file mode 100644
index 0000000000..4a12539114
--- /dev/null
+++ b/modules/common/include/dap_chain_datum_tx_in_reward.h
@@ -0,0 +1,30 @@
+/*
+* Authors:
+* Roman Khlopkov <roman.khlopkov@demlabs.net>
+* Cellframe       https://cellframe.net
+* DeM Labs Inc.   https://demlabs.net
+* Copyright  (c) 2017-2023
+* All rights reserved.
+
+This file is part of DAP SDK the open source project
+
+DAP SDK is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+DAP SDK is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with any DAP SDK based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "dap_common.h"
+#include "dap_chain_datum_tx_items.h"
+
+typedef struct dap_chain_tx_in_reward {
+    dap_chain_tx_item_type_t type : 8;      /// @param type             @brief Transaction item type
+    dap_hash_t block_hash;                  /// @param block_hash       @brief Hash of the block signed with current validator
+} DAP_ALIGN_PACKED dap_chain_tx_in_reward_t;
diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h
index d9815983dd..9d31a756c3 100644
--- a/modules/common/include/dap_chain_datum_tx_items.h
+++ b/modules/common/include/dap_chain_datum_tx_items.h
@@ -42,6 +42,7 @@
 #include "dap_chain_datum_tx_in_ems.h"
 #include "dap_chain_datum_tx_receipt.h"
 #include "dap_chain_datum_tx_tsd.h"
+#include "dap_chain_datum_tx_in_reward.h"
 
 /**
  * Get item type
@@ -71,13 +72,11 @@ DAP_STATIC_INLINE const char * dap_chain_datum_tx_item_type_to_str(dap_chain_tx_
         case TX_ITEM_TYPE_PKEY: return "TX_ITEM_TYPE_PKEY";
         case TX_ITEM_TYPE_SIG: return "TX_ITEM_TYPE_SIG";
         case TX_ITEM_TYPE_IN_EMS: return "TX_ITEM_TYPE_IN_EMS";
-        case TX_ITEM_TYPE_IN_EMS_EXT: return "TX_ITEM_TYPE_IN_EMS_EXT";
+        case TX_ITEM_TYPE_IN_REWARD: return "TX_ITEM_TYPE_IN_REWARD";
         case TX_ITEM_TYPE_IN_COND: return "TX_ITEM_TYPE_IN_COND";
         case TX_ITEM_TYPE_OUT_COND: return "TX_ITEM_TYPE_OUT_COND"; // 256
         case TX_ITEM_TYPE_RECEIPT: return "TX_ITEM_TYPE_RECEIPT";
         case TX_ITEM_TYPE_TSD: return "TX_ITEM_TYPE_TSD";
-        case TX_ITEM_TYPE_OUT_ALL: return "TX_ITEM_TYPE_OUT_OLDALL";
-        case TX_ITEM_TYPE_ANY: return "TX_ITEM_TYPE_ANY";
         default: return "UNDEFINED";
     }
 }
@@ -119,6 +118,8 @@ json_object *dap_chain_datum_tx_item_in_ems_to_json(const dap_chain_tx_in_ems_t
  */
 dap_chain_tx_in_t* dap_chain_datum_tx_item_in_create(dap_chain_hash_fast_t *a_tx_prev_hash, uint32_t a_tx_out_prev_idx);
 
+dap_chain_tx_in_reward_t *dap_chain_datum_tx_item_in_reward_create(dap_chain_hash_fast_t *a_block_hash);
+
 json_object* dap_chain_datum_tx_item_in_to_json(dap_chain_tx_in_t *a_in);
 
 dap_chain_tx_tsd_t *dap_chain_datum_tx_item_tsd_create(void *a_data, int a_type, size_t a_size);
diff --git a/modules/common/include/dap_chain_datum_tx_out.h b/modules/common/include/dap_chain_datum_tx_out.h
index 852975d64c..19e136671f 100644
--- a/modules/common/include/dap_chain_datum_tx_out.h
+++ b/modules/common/include/dap_chain_datum_tx_out.h
@@ -45,6 +45,6 @@ typedef struct dap_chain_tx_out {
     struct {
         dap_chain_tx_item_type_t type; ///           @param    type            @brief  Transaction item type
         uint256_t value; ///                       @param    value           @brief  Number of Datoshis ( DAP/10^9 ) to be transfered
-    } header; /// Only header's hash is used for verification
+    } header;
     dap_chain_addr_t addr; ////
 } DAP_ALIGN_PACKED dap_chain_tx_out_t;
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 0348c717a2..94fdd48b6c 100644
--- a/modules/common/include/dap_chain_datum_tx_out_cond.h
+++ b/modules/common/include/dap_chain_datum_tx_out_cond.h
@@ -125,56 +125,3 @@ typedef struct dap_chain_tx_out_cond {
     uint32_t tsd_size; // Condition parameters size
     uint8_t tsd[]; // condition parameters, pkey, hash or smth like this
 } DAP_ALIGN_PACKED dap_chain_tx_out_cond_t;
-
-
-/**
- * @struct dap_chain_tx_out
- * @brief Transaction item out_cond
- */
-typedef struct dap_chain_tx_out_cond_old {      // Obsolete
-    struct {
-        /// Transaction item type
-        dap_chain_tx_item_type_t item_type;
-        /// Condition subtype
-        dap_chain_tx_out_cond_subtype_t subtype;
-        /// Number of Datoshis ( DAP/10^9 ) to be reserver for service
-        uint64_t value;
-        /// When time expires this output could be used only by transaction owner
-        dap_time_t ts_expires;
-    } header;
-    union {
-        /// Structure with specific for service pay condition subtype
-        struct {
-            /// Public key hash that could use this conditioned outout
-            dap_chain_hash_fast_t pkey_hash;
-            /// Service uid that only could be used for this outout
-            dap_chain_net_srv_uid_t srv_uid;
-            /// Price unit thats used to check price max
-            dap_chain_net_srv_price_unit_uid_t unit;
-            /// Maximum price per unit
-            uint64_t unit_price_max_datoshi;
-        } srv_pay;
-        struct {
-            // Service uid that only could be used for this outout
-            dap_chain_net_srv_uid_t srv_uid;
-            // Token ticker to change to
-            char token[DAP_CHAIN_TICKER_SIZE_MAX];
-            // Chain network to change to
-            dap_chain_net_id_t net_id;
-            // Total amount of datoshi to change to
-            uint64_t value;
-        } srv_xchange;
-        struct {
-            // Service uid that only could be used for this outout
-            dap_chain_net_srv_uid_t srv_uid;
-            // Stake holder address
-            dap_chain_addr_t hldr_addr;
-            // Fee address
-            dap_chain_addr_t fee_addr;
-            // Fee value in percent
-            long double fee_value;
-        } srv_stake;
-    } subtype;
-    uint32_t params_size; // Condition parameters size
-    uint8_t params[]; // condition parameters, pkey, hash or smth like this
-} DAP_ALIGN_PACKED dap_chain_tx_out_cond_old_t;
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index fae28da629..4b2e112bdc 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -851,7 +851,7 @@ static void s_session_attempt_new(dap_chain_esbocs_session_t *a_session)
             return;
         }
     }
-    debug_if(PVT(a_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U"."
+    debug_if(PVT(a_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U". "
                                                     "All synced validators already tryed their attempts",
                                                         a_session->chain->net_name, a_session->chain->name,
                                                             a_session->cur_round.id);
@@ -1470,7 +1470,7 @@ static bool s_check_db_callback_fee_collect (UNUSED_ARG dap_global_db_instance_t
     dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain);
     dap_list_t *l_block_list = NULL;
     log_it(L_MSG, "Fee collector start work");
-    l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_arg->block_hash);
+    l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_arg->block_hash);
     if(!l_block_cache) {
         log_it(L_WARNING, "The block_cache is empty");
         return false;
@@ -1482,10 +1482,10 @@ static bool s_check_db_callback_fee_collect (UNUSED_ARG dap_global_db_instance_t
         return false;
     }
     dap_list_free_full(l_list_used_out, NULL);
-    l_block_list = dap_list_append(l_block_list, l_block_cache);
+    l_block_list = dap_list_append(l_block_list, DAP_DUP(&l_arg->block_hash));
     if(!a_values_count){
         if(compare256(l_value_out_block,l_arg->fee_need_cfg) == 1) {
-            char *l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_arg->key_from, l_arg->a_addr_to,
+            char *l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_blocks, l_arg->key_from, l_arg->a_addr_to,
                                                  l_block_list, l_arg->value_fee, "hex");
             if(l_hash_tx) {
                 log_it(L_NOTICE, "Fee collect transaction successfully created, hash=%s\n",l_hash_tx);
@@ -1503,13 +1503,12 @@ static bool s_check_db_callback_fee_collect (UNUSED_ARG dap_global_db_instance_t
         for(size_t i=0;i<a_values_count;i++) {
             dap_hash_fast_t block_hash;
             dap_chain_hash_fast_from_hex_str(a_values[i].key,&block_hash);
-            dap_chain_block_cache_t *block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &block_hash);
-            l_block_list = dap_list_append(l_block_list, block_cache);
+            l_block_list = dap_list_append(l_block_list, DAP_DUP(&block_hash));
             SUM_256_256(*(uint256_t*)a_values[i].value,l_value_gdb,&l_value_gdb);
         }
         SUM_256_256(l_value_out_block,l_value_gdb,&l_value_total);
         if(compare256(l_value_total,l_arg->fee_need_cfg) == 1) {
-            char *l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_arg->key_from, l_arg->a_addr_to,
+            char *l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_blocks, l_arg->key_from, l_arg->a_addr_to,
                                                  l_block_list, l_arg->value_fee, "hex");
             if(l_hash_tx) {
                 dap_global_db_del(s_block_fee_group, NULL, NULL, NULL);
@@ -1524,7 +1523,7 @@ static bool s_check_db_callback_fee_collect (UNUSED_ARG dap_global_db_instance_t
                 log_it(L_NOTICE, "The block was successfully added to the database");
         }
     }
-    dap_list_free(l_block_list);
+    dap_list_free_full(l_block_list, NULL);
     DAP_DEL_Z(l_arg->a_addr_to);
     DAP_DELETE(l_arg);
     return true;
@@ -2037,7 +2036,7 @@ static void s_session_packet_in(void *a_arg, dap_chain_node_addr_t *a_sender_nod
                                         l_session->chain->net_name, l_session->chain->name, l_message->hdr.round_id,
                                             l_validator_addr_str, l_sync_attempt);
         if (!PVT(l_session->esbocs)->emergency_mode &&
-                !dap_global_db_driver_hash_compare(((struct sync_params *)l_message_data)->db_hash, l_session->db_hash)) {
+                dap_global_db_driver_hash_compare(((struct sync_params *)l_message_data)->db_hash, l_session->db_hash)) {
             debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", sync_attempt %"DAP_UINT64_FORMAT_U
                                         " SYNC message is rejected cause DB hash mismatch",
                                            l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id,
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index 2b5537d756..b27a585e03 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -163,14 +163,14 @@ char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_fr
     if (l_single_channel)
         SUM_256_256(l_value_need, l_total_fee, &l_value_need);
     else if (!IS_ZERO_256(l_total_fee)) {
-        l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
+        l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
                                                                     a_addr_from, l_total_fee, &l_fee_transfer);
         if (!l_list_fee_out) {
             log_it(L_WARNING, "Not enough funds to pay fee");
             return NULL;
         }
     }
-    dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker,
+    dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker,
                                                                              a_addr_from, l_value_need, &l_value_transfer);
     if (!l_list_used_out) {
         log_it(L_WARNING, "Not enough funds to transfer");
@@ -285,22 +285,17 @@ char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_fr
  *
  * return hash_tx Ok, , NULL other Error
  */
-char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_chain_addr_t* a_addr_to,dap_list_t *a_block_list,
+char *dap_chain_mempool_tx_coll_fee_create(dap_chain_cs_blocks_t *a_blocks, dap_enc_key_t *a_key_from,
+                                           const dap_chain_addr_t *a_addr_to, dap_list_t *a_block_list,
                                            uint256_t a_value_fee, const char *a_hash_out_type)
 {
     uint256_t                   l_value_out = {};
     uint256_t                   l_net_fee = {};
     dap_chain_datum_tx_t        *l_tx;
     dap_chain_addr_t            l_addr_fee = {};
-    dap_chain_t                 *l_chain = NULL;
 
-    if(a_block_list)
-        l_chain = DAP_CHAIN_CS_BLOCKS((dap_chain_block_cache_t *)a_block_list->data)->chain;
-    else
-    {
-        log_it(L_WARNING, "There aren't block hash");
-        return NULL;
-    }
+    dap_return_val_if_fail(a_blocks && a_key_from && a_addr_to && a_block_list, NULL);
+    dap_chain_t *l_chain = a_blocks->chain;
     bool l_net_fee_used = dap_chain_net_tx_get_fee(l_chain->net_id, &l_net_fee, &l_addr_fee);
     //add tx
     if (NULL == (l_tx = dap_chain_datum_tx_create())) {
@@ -308,9 +303,33 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_c
         return NULL;
     }
     dap_ledger_t *l_ledger = dap_chain_net_by_id(l_chain->net_id)->pub.ledger;
+    dap_pkey_t *l_sign_pkey = dap_pkey_from_enc_key(a_key_from);
+    if (!l_sign_pkey) {
+        log_it(L_ERROR, "Can't serialize public key of sign certificate");
+        dap_chain_datum_tx_delete(l_tx);
+        return NULL;
+    }
     for(dap_list_t *bl = a_block_list; bl; bl = bl->next) {
         uint256_t l_value_out_block = {};
-        dap_chain_block_cache_t *l_block_cache = (dap_chain_block_cache_t *)bl->data;
+        dap_hash_fast_t *l_block_hash = bl->data;
+        dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(a_blocks, l_block_hash);
+        if (!l_block_cache) {
+            char l_block_hash_str[DAP_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(l_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE);
+            log_it(L_ERROR, "Can't find cache for block hash %s", l_block_hash_str);
+            DAP_DELETE(l_sign_pkey);
+            dap_chain_datum_tx_delete(l_tx);
+            return NULL;
+        }
+        //verification of signatures of all blocks
+        dap_sign_t *l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0);
+        if (!l_sign || !dap_pkey_compare_with_sign(l_sign_pkey, l_sign)) {
+            log_it(L_WARNING, "Block %s signature does not match certificate key", l_block_cache->block_hash_str);
+            DAP_DELETE(l_sign_pkey);
+            dap_chain_datum_tx_delete(l_tx);
+            return NULL;
+        }
+
         dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val(l_ledger, l_block_cache, &l_value_out_block);
         if (!l_list_used_out) continue;
 
@@ -373,8 +392,115 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from,const dap_c
     }
 
     size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
-    //dap_hash_fast_t l_tx_hash;
-    //dap_hash_fast(l_tx, l_tx_size, &l_tx_hash);
+    dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size);
+    DAP_DELETE(l_tx);
+    char *l_ret = dap_chain_mempool_datum_add(l_datum, l_chain, a_hash_out_type);
+    DAP_DELETE(l_datum);
+    return l_ret;
+}
+
+
+/**
+ * Make transfer transaction to collect block sign rewards and place it to the mempool
+ *
+ * return hash_tx Ok, NULL Error
+ */
+char *dap_chain_mempool_tx_reward_create(dap_chain_cs_blocks_t *a_blocks, dap_enc_key_t *a_sign_key,
+                                         dap_chain_addr_t *a_addr_to, dap_list_t *a_block_list,
+                                         uint256_t a_value_fee, const char *a_hash_out_type)
+{
+    dap_return_val_if_fail(a_blocks && a_sign_key && a_addr_to && a_block_list, NULL);
+    dap_chain_t *l_chain = a_blocks->chain;
+    //add tx
+    dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
+    if (!l_tx) {
+        log_it(L_ERROR, "Can't create datum tx");
+        return NULL;
+    }
+    dap_pkey_t *l_sign_pkey = dap_pkey_from_enc_key(a_sign_key);
+    if (!l_sign_pkey) {
+        log_it(L_ERROR, "Can't serialize public key of sign certificate");
+        dap_chain_datum_tx_delete(l_tx);
+        return NULL;
+    }
+    dap_hash_fast_t l_sign_pkey_hash;
+    dap_pkey_get_hash(l_sign_pkey, &l_sign_pkey_hash);
+    uint256_t l_value_out = uint256_0;
+    dap_ledger_t *l_ledger = dap_chain_net_by_id(l_chain->net_id)->pub.ledger;
+    for (dap_list_t *it = a_block_list; it; it = it->next) {
+        dap_hash_fast_t *l_block_hash = it->data;
+        uint256_t l_reward_value = l_chain->callback_calc_reward(l_chain, l_block_hash, l_sign_pkey);
+        if (IS_ZERO_256(l_reward_value)) {
+            char l_block_hash_str[DAP_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(l_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE);
+            log_it(L_WARNING, "Block %s signatures does not match certificate key", l_block_hash_str);
+            DAP_DELETE(l_sign_pkey);
+            dap_chain_datum_tx_delete(l_tx);
+            return NULL;
+        }
+        if (dap_ledger_is_used_reward(l_ledger, l_block_hash, &l_sign_pkey_hash)) {
+            char l_block_hash_str[DAP_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(l_block_hash, l_block_hash_str, DAP_HASH_FAST_STR_SIZE);
+            char l_sign_pkey_hash_str[DAP_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(&l_sign_pkey_hash, l_sign_pkey_hash_str, DAP_HASH_FAST_STR_SIZE);
+            log_it(L_WARNING, "Block %s reward is already collected by signer %s", l_block_hash_str, l_sign_pkey_hash_str);
+            DAP_DELETE(l_sign_pkey);
+            dap_chain_datum_tx_delete(l_tx);
+            return NULL;
+        }
+        //add 'in_reward' items
+        if (dap_chain_datum_tx_add_in_reward_item(&l_tx, l_block_hash) != 1) {
+            log_it(L_ERROR, "Can't create in_reward item for reward collect TX");
+            DAP_DELETE(l_sign_pkey);
+            dap_chain_datum_tx_delete(l_tx);
+            return NULL;
+        }
+        SUM_256_256(l_value_out, l_reward_value, &l_value_out);
+    }
+    DAP_DELETE(l_sign_pkey);
+
+    uint256_t l_net_fee = uint256_0, l_total_fee = uint256_0;
+    dap_chain_addr_t l_addr_fee = c_dap_chain_addr_blank;
+    bool l_net_fee_used = dap_chain_net_tx_get_fee(l_chain->net_id, &l_net_fee, &l_addr_fee);
+    // Network fee
+    if (l_net_fee_used) {
+        if (dap_chain_datum_tx_add_out_item(&l_tx, &l_addr_fee, l_net_fee) == 1)
+            SUM_256_256(l_total_fee, l_net_fee, &l_total_fee);
+        else {
+            log_it(L_WARNING, "Can't create network fee out item for reward collect TX");
+            dap_chain_datum_tx_delete(l_tx);
+            return NULL;
+        }
+    }
+    // Validator's fee
+    if (!IS_ZERO_256(a_value_fee)) {
+        if (dap_chain_datum_tx_add_fee_item(&l_tx, a_value_fee) == 1)
+            SUM_256_256(l_total_fee, a_value_fee, &l_total_fee);
+        else {
+            log_it(L_WARNING, "Can't create validator fee out item for reward collect TX");
+            dap_chain_datum_tx_delete(l_tx);
+            return NULL;
+        }
+    }
+    if (SUBTRACT_256_256(l_value_out, l_total_fee, &l_value_out)) {
+        log_it(L_WARNING, "The transaction fee is greater than the sum of the block sign rewards");
+        dap_chain_datum_tx_delete(l_tx);
+        return NULL;
+    }
+    //add 'out' item
+    if (dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to, l_value_out) != 1) {
+        dap_chain_datum_tx_delete(l_tx);
+        log_it(L_WARNING, "Can't create out item in transaction fee");
+        return NULL;
+    }
+    // add 'sign' item
+    if(dap_chain_datum_tx_add_sign_item(&l_tx, a_sign_key) != 1) {
+        dap_chain_datum_tx_delete(l_tx);
+        log_it(L_WARNING, "Can't sign item in transaction fee");
+        return NULL;
+    }
+
+    size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
     dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size);
     DAP_DELETE(l_tx);
     char *l_ret = dap_chain_mempool_datum_add(l_datum, l_chain, a_hash_out_type);
@@ -421,7 +547,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
     log_it(L_DEBUG, "Create %"DAP_UINT64_FORMAT_U" transactions, summary %s", a_tx_num, l_balance);
     DAP_DELETE(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_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker,
+    dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker,
                                                                              a_addr_from, l_value_need, &l_value_transfer);
     if (!l_list_used_out) {
         log_it(L_WARNING,"Not enough funds to transfer");
@@ -567,7 +693,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
         dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx_new, l_tx_size);
 
         dap_chain_datum_tx_delete(l_tx_new);
-        //dap_chain_ledger_tx_add( a_chain->ledger, l_tx);
+        //dap_ledger_tx_add( a_chain->ledger, l_tx);
 
         l_objs[i].key = dap_chain_hash_fast_to_str_new(&l_tx_new_hash);
         //continue;
@@ -621,7 +747,7 @@ char* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *a_net, dap_chain_h
                                                           const dap_chain_addr_t *a_addr_to, dap_enc_key_t *a_key_tx_sign,
                                                           dap_chain_datum_tx_receipt_t *a_receipt, const char *a_hash_out_type, int *a_ret_status)
 {
-    dap_ledger_t * l_ledger = a_net ? dap_chain_ledger_by_net_name( a_net->pub.name ) : NULL;
+    dap_ledger_t * l_ledger = a_net ? dap_ledger_by_net_name( a_net->pub.name ) : NULL;
     if ( ! a_net || ! l_ledger || ! a_addr_to ){
         if (a_ret_status)
             *a_ret_status = DAP_CHAIN_MEMPOOL_RET_STATUS_BAD_ARGUMENTS;
@@ -634,20 +760,20 @@ char* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *a_net, dap_chain_h
             *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_WRONG_ADDR;
         return NULL;
     }
-    dap_chain_hash_fast_t *l_tx_final_hash = dap_chain_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, a_tx_prev_hash);
+    dap_chain_hash_fast_t *l_tx_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, a_tx_prev_hash);
     if (!l_tx_final_hash) {
         log_it(L_WARNING, "Requested conditional transaction is already used out");
         if (a_ret_status)
             *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_CANT_FIND_FINAL_TX_HASH;
         return NULL;
     }
-    if (dap_strcmp(a_net->pub.native_ticker, dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, l_tx_final_hash))) {
+    if (dap_strcmp(a_net->pub.native_ticker, dap_ledger_tx_get_token_ticker_by_hash(l_ledger, l_tx_final_hash))) {
         log_it(L_WARNING, "Pay for service should be only in native token ticker");
         if (a_ret_status)
             *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_NOT_NATIVE_TOKEN;
         return NULL;
     }
-    dap_chain_datum_tx_t *l_tx_cond = dap_chain_ledger_tx_find_by_hash(l_ledger, l_tx_final_hash);
+    dap_chain_datum_tx_t *l_tx_cond = dap_ledger_tx_find_by_hash(l_ledger, l_tx_final_hash);
     int l_out_cond_idx = 0;
     dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_cond, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, &l_out_cond_idx);
     if (!l_out_cond) {
@@ -752,7 +878,7 @@ char *dap_chain_mempool_tx_create_cond(dap_chain_net_t *a_net,
         uint256_t a_value_fee, const void *a_cond,
         size_t a_cond_size, const char *a_hash_out_type)
 {
-    dap_ledger_t * l_ledger = a_net ? dap_chain_ledger_by_net_name( a_net->pub.name ) : NULL;
+    dap_ledger_t * l_ledger = a_net ? dap_ledger_by_net_name( a_net->pub.name ) : NULL;
     // check valid param
     if (!a_net || !l_ledger || !a_key_from || !a_key_cond ||
             !a_key_from->priv_key_data || !a_key_from->priv_key_data_size || IS_ZERO_256(a_value))
@@ -774,7 +900,7 @@ char *dap_chain_mempool_tx_create_cond(dap_chain_net_t *a_net,
     dap_chain_addr_t l_addr_from;
     dap_chain_addr_fill_from_key(&l_addr_from, a_key_from, a_net->pub.id);
     // list of transaction with 'out' items
-    dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker,
+    dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker,
                                                                              &l_addr_from, l_value_need, &l_value_transfer);
     if(!l_list_used_out) {
         log_it( L_ERROR, "Nothing to transfer (not enough funds)");
@@ -885,7 +1011,7 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast
         }
         dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger;
         // list of transaction with 'out' items
-        l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
+        l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
                                                                      &l_addr_from_fee, l_total_fee, &l_value_transfer);
         if (!l_list_used_out) {
             log_it(L_WARNING,"Not enough funds to transfer");
@@ -1000,7 +1126,7 @@ dap_chain_datum_token_emission_t *dap_chain_mempool_datum_emission_extract(dap_c
     dap_chain_net_t *l_net = dap_chain_net_by_name(a_chain->net_name);
     if (!l_net)
         return NULL;
-    dap_chain_datum_token_t *l_token = dap_chain_ledger_token_ticker_check(l_net->pub.ledger, l_ticker);
+    dap_chain_datum_token_t *l_token = dap_ledger_token_ticker_check(l_net->pub.ledger, l_ticker);
     if (!l_token)
         return NULL;
     if (l_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE && l_token->type == DAP_CHAIN_DATUM_TOKEN_DECL)
diff --git a/modules/mempool/include/dap_chain_mempool.h b/modules/mempool/include/dap_chain_mempool.h
index 97a3042c19..7e436c23f2 100644
--- a/modules/mempool/include/dap_chain_mempool.h
+++ b/modules/mempool/include/dap_chain_mempool.h
@@ -104,5 +104,7 @@ char *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast
 
 dap_chain_datum_token_emission_t *dap_chain_mempool_emission_get(dap_chain_t *a_chain, const char *a_emission_hash_str);
 dap_chain_datum_token_emission_t *dap_chain_mempool_datum_emission_extract(dap_chain_t *a_chain, byte_t *a_data, size_t a_size);
-char *dap_chain_mempool_tx_coll_fee_create(dap_enc_key_t *a_key_from, const dap_chain_addr_t* a_addr_to, dap_list_t *a_block_list,
+char *dap_chain_mempool_tx_coll_fee_create(dap_chain_cs_blocks_t *a_blocks, dap_enc_key_t *a_key_from, const dap_chain_addr_t* a_addr_to, dap_list_t *a_block_list,
                                            uint256_t a_value_fee, const char *a_hash_out_type);
+char *dap_chain_mempool_tx_reward_create(dap_chain_cs_blocks_t *a_blocks, dap_enc_key_t *a_sign_key, dap_chain_addr_t *a_addr_to, dap_list_t *a_block_list,
+                                         uint256_t a_value_fee, const char *a_hash_out_type);
diff --git a/modules/chain/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
similarity index 75%
rename from modules/chain/dap_chain_ledger.c
rename to modules/net/dap_chain_ledger.c
index 5472dd7928..5ebbb90e5b 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -58,107 +58,107 @@
 #include "dap_notify_srv.h"
 
 
-#define LOG_TAG "dap_chain_ledger"
+#define LOG_TAG "dap_ledger"
 
-typedef struct dap_chain_ledger_verificator {
+typedef struct dap_ledger_verificator {
     int subtype;    // hash key
-    dap_chain_ledger_verificator_callback_t callback;
-    dap_chain_ledger_updater_callback_t callback_added;
+    dap_ledger_verificator_callback_t callback;
+    dap_ledger_updater_callback_t callback_added;
     UT_hash_handle hh;
-} dap_chain_ledger_verificator_t;
+} dap_ledger_verificator_t;
 
-static dap_chain_ledger_verificator_t *s_verificators;
+static dap_ledger_verificator_t *s_verificators;
 static  pthread_rwlock_t s_verificators_rwlock;
 
 #define MAX_OUT_ITEMS   10
 
-static const char *s_ledger_tx_check_err_str[] = {
-    [DAP_CHAIN_LEDGER_TX_CHECK_OK] = "DAP_CHAIN_LEDGER_TX_CHECK_OK",
-    [DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX] = "DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX",
-    [DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE] = "DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE",
-    [DAP_CHAIN_LEDGER_TX_ALREADY_CACHED] = "DAP_CHAIN_LEDGER_TX_ALREADY_CACHED",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN",
-    [DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED] = "DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED",
-    [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_EMISSION_NOT_FOUND",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND",
-    [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN",
-    [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS",
-    [DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE] = "DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS",
-    [DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX] = "DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY",
-    [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE",
-    [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND",
-    [DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED] = "DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TX_NOT_FOUND",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET",
-    [DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE] = "DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND",
-    [DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED] = "DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED",
-    [DAP_CHAIN_LEDGER_TX_CACHE_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS] = "DAP_CHAIN_LEDGER_TX_CACHE_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS"
+static const char * const s_ledger_tx_check_err_str[] = {
+    [DAP_LEDGER_TX_CHECK_OK] = "DAP_LEDGER_TX_CHECK_OK",
+    [DAP_LEDGER_TX_CHECK_NULL_TX] = "DAP_LEDGER_TX_CHECK_NULL_TX",
+    [DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE] = "DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE",
+    [DAP_LEDGER_TX_ALREADY_CACHED] = "DAP_LEDGER_TX_ALREADY_CACHED",
+    [DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN] = "DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN",
+    [DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED",
+    [DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED",
+    [DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND",
+    [DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS] = "DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS",
+    [DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND",
+    [DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN",
+    [DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS",
+    [DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE] = "DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE",
+    [DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS] = "DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS",
+    [DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX] = "DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX",
+    [DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY] = "DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY",
+    [DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE",
+    [DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND",
+    [DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED] = "DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED",
+    [DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED",
+    [DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND",
+    [DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND",
+    [DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH] = "DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH",
+    [DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX] = "DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX",
+    [DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET] = "DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET",
+    [DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE] = "DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE",
+    [DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND",
+    [DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND] = "DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND",
+    [DAP_LEDGER_PERMISSION_CHECK_FAILED] = "DAP_LEDGER_PERMISSION_CHECK_FAILED",
+    [DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS] = "DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS",
+    [DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED] = "DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED",
+    [DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL] = "DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL"
 };
 
-static const char *s_ledger_emission_add_err_str[] = {
-    [DAP_CHAIN_LEDGER_EMISSION_ADD_OK] = "DAP_CHAIN_LEDGER_EMISSION_ADD_OK",
-    [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL",
-    [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED",
-    [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW",
-    [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY",
-    [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS",
-    [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN",
-    [DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE] = "DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE",
-    [DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED] = "DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED"
+static const char * const s_ledger_emission_add_err_str[] = {
+    [DAP_LEDGER_EMISSION_ADD_OK] = "DAP_LEDGER_EMISSION_ADD_OK",
+    [DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL] = "DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL",
+    [DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED] = "DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED",
+    [DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW] = "DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW",
+    [DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY] = "DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY",
+    [DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS] = "DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS",
+    [DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN] = "DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN",
+    [DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE] = "DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE",
+    [DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED] = "DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED"
 };
 
-static const char *s_ledger_token_decl_err_str[] = {
-    [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK",
-    [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL",
-    [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE",
-    [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK",
-    [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN",
-    [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN",
-    [DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS] = "DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS"
+static const char * const s_ledger_token_decl_err_str[] = {
+    [DAP_LEDGER_TOKEN_DECL_ADD_OK] = "DAP_LEDGER_TOKEN_DECL_ADD_OK",
+    [DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL",
+    [DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE",
+    [DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK",
+    [DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN",
+    [DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN",
+    [DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS] = "DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS"
 };
 
-char *dap_chain_ledger_tx_check_err_str(int a_code) {
-    return (a_code >= DAP_CHAIN_LEDGER_TX_CHECK_OK) && (a_code < DAP_CHAIN_LEDGER_TX_CHECK_UNKNOWN)
-            ? (char*)s_ledger_tx_check_err_str[(dap_chain_ledger_tx_check_t)a_code]
+char *dap_ledger_tx_check_err_str(int a_code) {
+    return (a_code >= DAP_LEDGER_TX_CHECK_OK) && (a_code < DAP_LEDGER_TX_CHECK_UNKNOWN)
+            ? (char*)s_ledger_tx_check_err_str[(dap_ledger_tx_check_t)a_code]
             : dap_itoa(a_code);
 }
 
-typedef struct dap_chain_ledger_stake_lock_item {
+typedef struct dap_ledger_stake_lock_item {
     dap_chain_hash_fast_t	tx_for_stake_lock_hash;
     dap_chain_hash_fast_t	tx_used_out;
-    uint256_t ems_value;
     UT_hash_handle hh;
-} dap_chain_ledger_stake_lock_item_t;
+} dap_ledger_stake_lock_item_t;
 
-typedef struct dap_chain_ledger_token_emission_item {
+typedef struct dap_ledger_token_emission_item {
     dap_chain_hash_fast_t datum_token_emission_hash;
     dap_chain_datum_token_emission_t *datum_token_emission;
     size_t datum_token_emission_size;
     dap_chain_hash_fast_t tx_used_out;
     dap_nanotime_t ts_added;
     UT_hash_handle hh;
-} dap_chain_ledger_token_emission_item_t;
+} dap_ledger_token_emission_item_t;
 
-typedef struct dap_chain_ledger_token_update_item {
+typedef struct dap_ledger_token_update_item {
     dap_hash_fast_t			update_token_hash;
     dap_chain_datum_token_t	*datum_token_update;
     size_t					datum_token_update_size;
     time_t					updated_time;
     UT_hash_handle hh;
-} dap_chain_ledger_token_update_item_t;
+} dap_ledger_token_update_item_t;
 
-typedef struct dap_chain_ledger_token_item {
+typedef struct dap_ledger_token_item {
     uint16_t version;
     char ticker[DAP_CHAIN_TICKER_SIZE_MAX];
     uint16_t type;
@@ -170,10 +170,10 @@ typedef struct dap_chain_ledger_token_item {
     uint256_t current_supply;
 
     pthread_rwlock_t token_emissions_rwlock;
-    dap_chain_ledger_token_emission_item_t * token_emissions;
+    dap_ledger_token_emission_item_t * token_emissions;
 
     pthread_rwlock_t token_ts_updated_rwlock;
-    dap_chain_ledger_token_update_item_t * token_ts_updated;
+    dap_ledger_token_update_item_t * token_ts_updated;
     time_t last_update_token_time;
 
     // for auth operations
@@ -193,10 +193,10 @@ typedef struct dap_chain_ledger_token_item {
     char *description_token;
     size_t description_token_size;
     UT_hash_handle hh;
-} dap_chain_ledger_token_item_t;
+} dap_ledger_token_item_t;
 
 // ledger cache item - one of unspent outputs
-typedef struct dap_chain_ledger_tx_item {
+typedef struct dap_ledger_tx_item {
     dap_chain_hash_fast_t tx_hash_fast;
     dap_chain_datum_tx_t *tx;
     dap_nanotime_t ts_added;
@@ -213,35 +213,44 @@ typedef struct dap_chain_ledger_tx_item {
         dap_chain_hash_fast_t tx_hash_spent_fast[MAX_OUT_ITEMS]; // spent outs list
     } DAP_ALIGN_PACKED cache_data;
     UT_hash_handle hh;
-} dap_chain_ledger_tx_item_t;
+} dap_ledger_tx_item_t;
 
-typedef struct dap_chain_ledger_tokenizer {
+typedef struct dap_ledger_tokenizer {
     char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
     uint256_t sum;
     UT_hash_handle hh;
-} dap_chain_ledger_tokenizer_t;
+} dap_ledger_tokenizer_t;
 
-typedef struct dap_chain_ledger_tx_bound {
-    dap_chain_hash_fast_t tx_prev_hash;
-    dap_chain_datum_tx_t *tx_prev;
-    union {
-        dap_chain_tx_in_t *tx_cur_in;
-        dap_chain_tx_in_cond_t *tx_cur_in_cond;
-        dap_chain_tx_in_ems_t *tx_cur_in_ems;
-    } in;
+typedef struct dap_ledger_reward_key {
+    dap_hash_fast_t block_hash;
+    dap_hash_fast_t sign_pkey_hash;
+} DAP_ALIGN_PACKED dap_ledger_reward_key_t;
+
+typedef struct dap_ledger_reward_item {
+    dap_ledger_reward_key_t key;
+    dap_hash_fast_t spender_tx;
+    UT_hash_handle hh;
+} dap_ledger_reward_item_t;
+
+typedef struct dap_ledger_tx_bound {
+    uint8_t type;
+    uint16_t prev_out_idx;
+    uint256_t value;
     union {
-        dap_chain_tx_out_old_t *tx_prev_out;
-        // 256
-        dap_chain_tx_out_t *tx_prev_out_256;
-        dap_chain_tx_out_ext_t *tx_prev_out_ext_256;
-        dap_chain_tx_out_cond_t *tx_prev_out_cond_256;
-    } out;
+        dap_ledger_token_item_t *token_item;    // For current_supply update on emissions
+        dap_chain_tx_out_cond_t *cond;          // For conditional output
+        struct {
+            char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
+            dap_chain_addr_t addr_from;
+        } in;
+    };
     union {
-        dap_chain_ledger_tx_item_t *item_out;
-        dap_chain_ledger_token_emission_item_t *item_emission;
-        dap_chain_ledger_stake_lock_item_t *stake_lock_item;
+        dap_ledger_tx_item_t *prev_item;        // For not emission TX
+        dap_ledger_token_emission_item_t *emission_item;
+        dap_ledger_stake_lock_item_t *stake_lock_item;
+        dap_ledger_reward_key_t reward_key;
     };
-} dap_chain_ledger_tx_bound_t;
+} dap_ledger_tx_bound_t;
 
 // in-memory wallet balance
 typedef struct dap_ledger_wallet_balance {
@@ -261,32 +270,29 @@ typedef struct dap_ledger_cache_str_item {
     bool found;
 } dap_ledger_cache_str_item_t;
 
-typedef struct dap_chain_ledger_tx_notifier {
-    dap_chain_ledger_tx_add_notify_t callback;
+typedef struct dap_ledger_tx_notifier {
+    dap_ledger_tx_add_notify_t callback;
     void *arg;
-} dap_chain_ledger_tx_notifier_t;
+} dap_ledger_tx_notifier_t;
 
-typedef struct dap_chain_ledger_bridged_tx_notifier {
-    dap_chain_ledger_bridged_tx_notify_t callback;
+typedef struct dap_ledger_bridged_tx_notifier {
+    dap_ledger_bridged_tx_notify_t callback;
     void *arg;
-} dap_chain_ledger_bridged_tx_notifier_t;
+} dap_ledger_bridged_tx_notifier_t;
 
 // dap_ledget_t private section
 typedef struct dap_ledger_private {
-    const char *net_native_ticker;
-    uint256_t fee_value;
-    dap_chain_addr_t fee_addr;
-    dap_list_t *poa_certs;
     // List of ledger - unspent transactions cache
-    dap_chain_ledger_tx_item_t *threshold_txs;
-    dap_chain_ledger_token_emission_item_t * threshold_emissions;
+    dap_ledger_tx_item_t *threshold_txs;
+    dap_ledger_token_emission_item_t * threshold_emissions;
 
-    dap_chain_ledger_tx_item_t *ledger_items;
-    dap_chain_ledger_token_item_t *tokens;
-    dap_chain_ledger_stake_lock_item_t *emissions_for_stake_lock;
+    dap_ledger_tx_item_t *ledger_items;
+    dap_ledger_token_item_t *tokens;
+    dap_ledger_stake_lock_item_t *emissions_for_stake_lock;
+    dap_ledger_reward_item_t *rewards;
     dap_ledger_wallet_balance_t *balance_accounts;
 
-    // for separate access to ledger
+    // for separate access to transactions
     pthread_rwlock_t ledger_rwlock;
     // for separate access to tokens
     pthread_rwlock_t tokens_rwlock;
@@ -294,16 +300,19 @@ typedef struct dap_ledger_private {
     pthread_rwlock_t threshold_txs_rwlock;
     pthread_rwlock_t threshold_emissions_rwlock;
     pthread_rwlock_t balance_accounts_rwlock;
+    pthread_rwlock_t rewards_rwlock;
 
     // Save/load operations condition
     pthread_mutex_t load_mutex;
     pthread_cond_t load_cond;
     bool load_end;
 
-    uint16_t flags;
+    // Ledger flags
     bool check_ds;
     bool check_cells_ds;
     bool check_token_emission;
+    bool cached;
+
     dap_chain_cell_id_t local_cell_id;
 
     //notifiers
@@ -311,8 +320,7 @@ typedef struct dap_ledger_private {
     dap_list_t *tx_add_notifiers;
 
     bool load_mode;
-    bool cached;
-    dap_chain_ledger_cache_tx_check_callback_t cache_tx_check_callback;
+    dap_ledger_cache_tx_check_callback_t cache_tx_check_callback;
     // TPS section
     dap_timerfd_t *tps_timer;
     struct timespec tps_start_time;
@@ -331,25 +339,17 @@ typedef struct dap_ledger_hal_item {
 
 static dap_ledger_hal_item_t *s_hal_items = NULL;
 
-static  dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
+static  dap_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
         const dap_chain_addr_t *a_addr, const char * a_token, dap_chain_hash_fast_t *a_tx_first_hash);
 static void s_threshold_emissions_proc( dap_ledger_t * a_ledger);
 static void s_threshold_txs_proc( dap_ledger_t * a_ledger);
 static void s_threshold_txs_free(dap_ledger_t *a_ledger);
 static void s_threshold_emission_free(dap_ledger_t *a_ledger);
-static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size);
-static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t *a_token, size_t a_token_size);
-static int s_ledger_permissions_check(dap_chain_ledger_token_item_t *  a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size );
+static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size);
+static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_ledger_token_item_t *a_token_item , dap_chain_datum_token_t *a_token, size_t a_token_size);
+static int s_ledger_permissions_check(dap_ledger_token_item_t *  a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size );
 static bool s_ledger_tps_callback(void *a_arg);
-static int s_sort_ledger_tx_item(dap_chain_ledger_tx_item_t* a, dap_chain_ledger_tx_item_t* b);
-
-static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold, bool a_safe_call);
-static int s_tx_add_unsafe(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold);
-
-static int s_token_emission_add_unsafe(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size,
-                                        dap_hash_fast_t *a_emission_hash, bool a_from_threshold);
-static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size,
-                                        dap_hash_fast_t *a_emission_hash, bool a_from_threshold, bool a_safe_call);
+static int s_sort_ledger_tx_item(dap_ledger_tx_item_t* a, dap_ledger_tx_item_t* b);
 
 static size_t s_threshold_emissions_max = 1000;
 static size_t s_threshold_txs_max = 10000;
@@ -359,11 +359,11 @@ static size_t s_threshold_free_timer_tick = 900000; // 900000 ms = 15 minutes.
 struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_wallet_balance_t* a_bal);
 
 /**
- * @brief dap_chain_ledger_init
+ * @brief dap_ledger_init
  * current function version set s_debug_more parameter, if it define in config, and returns 0
  * @return
  */
-int dap_chain_ledger_init()
+int dap_ledger_init()
 {
     s_debug_more = dap_config_get_item_bool_default(g_config,"ledger","debug_more",false);
     pthread_rwlock_init(&s_verificators_rwlock, NULL);
@@ -371,27 +371,20 @@ int dap_chain_ledger_init()
 }
 
 /**
- * @brief dap_chain_ledger_deinit
+ * @brief dap_ledger_deinit
  * nothing do
  */
-void dap_chain_ledger_deinit()
+void dap_ledger_deinit()
 {
-    // TODO write correct deinit of all net ledgers
-/*    uint16_t l_net_count = 0;
-    dap_chain_net_t **l_net_list = dap_chain_net_list(&l_net_count);
-    for(uint16_t i =0; i < l_net_count; i++) {
-        dap_chain_ledger_purge(l_net_list[i]->pub.ledger, true);
-    }
-    DAP_DELETE(l_net_list); */
     pthread_rwlock_destroy(&s_verificators_rwlock);
 }
 
 /**
- * @brief dap_chain_ledger_handle_new
+ * @brief dap_ledger_handle_new
  * Create empty dap_ledger_t structure
  * @return dap_ledger_t*
  */
-static dap_ledger_t * dap_chain_ledger_handle_new(void)
+static dap_ledger_t * dap_ledger_handle_new(void)
 {
     dap_ledger_t *l_ledger = DAP_NEW_Z(dap_ledger_t);
     if ( !l_ledger ) {
@@ -412,6 +405,7 @@ static dap_ledger_t * dap_chain_ledger_handle_new(void)
     pthread_rwlock_init(&l_ledger_pvt->threshold_emissions_rwlock , NULL);
     pthread_rwlock_init(&l_ledger_pvt->balance_accounts_rwlock , NULL);
     pthread_rwlock_init(&l_ledger_pvt->stake_lock_rwlock, NULL);
+    pthread_rwlock_init(&l_ledger_pvt->rewards_rwlock, NULL);
     l_ledger_pvt->threshold_txs_free_timer = dap_interval_timer_create(s_threshold_free_timer_tick,
                                                                       (dap_timer_callback_t)s_threshold_txs_free, l_ledger);
     l_ledger_pvt->threshold_emissions_free_timer = dap_interval_timer_create(s_threshold_free_timer_tick,
@@ -420,15 +414,15 @@ static dap_ledger_t * dap_chain_ledger_handle_new(void)
 }
 
 /**
- * @brief dap_chain_ledger_handle_free
+ * @brief dap_ledger_handle_free
  * Remove dap_ledger_t structure
  * @param a_ledger
  */
-void dap_chain_ledger_handle_free(dap_ledger_t *a_ledger)
+void dap_ledger_handle_free(dap_ledger_t *a_ledger)
 {
     if(!a_ledger)
         return;
-    log_it(L_INFO,"Ledger %s destroyed", a_ledger->net_name);
+    log_it(L_INFO,"Ledger for network %s destroyed", a_ledger->net->pub.name);
     // Destroy Read/Write Lock
     pthread_rwlock_destroy(&PVT(a_ledger)->ledger_rwlock);
     pthread_rwlock_destroy(&PVT(a_ledger)->tokens_rwlock);
@@ -436,12 +430,13 @@ void dap_chain_ledger_handle_free(dap_ledger_t *a_ledger)
     pthread_rwlock_destroy(&PVT(a_ledger)->threshold_emissions_rwlock);
     pthread_rwlock_destroy(&PVT(a_ledger)->balance_accounts_rwlock);
     pthread_rwlock_destroy(&PVT(a_ledger)->stake_lock_rwlock);
+    pthread_rwlock_destroy(&PVT(a_ledger)->rewards_rwlock);
     DAP_DELETE(PVT(a_ledger));
     DAP_DELETE(a_ledger);
 
 }
 
-void dap_chain_ledger_load_end(dap_ledger_t *a_ledger)
+void dap_ledger_load_end(dap_ledger_t *a_ledger)
 {
     PVT(a_ledger)->load_mode = false;
 }
@@ -450,7 +445,7 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_
     struct json_object *l_json = json_object_new_object();
     json_object_object_add(l_json, "class", json_object_new_string("Wallet"));
     struct json_object *l_network = json_object_new_object();
-    json_object_object_add(l_network, "name", json_object_new_string(a_ledger->net_name));
+    json_object_object_add(l_network, "name", json_object_new_string(a_ledger->net->pub.name));
     char *pos = strrchr(a_bal->key, ' ');
     if (pos) {
         size_t l_addr_len = pos - a_bal->key;
@@ -477,18 +472,18 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_
 }
 
 /**
- * @brief s_chain_ledger_token_update_check
+ * @brief s_ledger_token_update_check
  * @param a_cur_token_item
  * @param a_token_update
  * @param a_token_update_size
  * @return true or false
  */
-static bool s_ledger_token_update_check(dap_chain_ledger_token_item_t *a_cur_token_item, dap_chain_datum_token_t *a_token_update, size_t a_token_update_size)
+static bool s_ledger_token_update_check(dap_ledger_token_item_t *a_cur_token_item, dap_chain_datum_token_t *a_token_update, size_t a_token_update_size)
 {
     dap_sign_t								**l_signs_upd_token;
     size_t									auth_signs_total = 0;
     size_t									auth_signs_valid = 0;
-    dap_chain_ledger_token_update_item_t	*l_token_update_item;
+    dap_ledger_token_update_item_t	*l_token_update_item;
     dap_hash_fast_t							l_hash_token_update;
 
     dap_hash_fast(a_token_update, a_token_update_size, &l_hash_token_update);
@@ -531,7 +526,7 @@ static bool s_ledger_token_update_check(dap_chain_ledger_token_item_t *a_cur_tok
     if(auth_signs_total) {
         size_t l_valid_pkeys = 0;
         for(uint16_t i = 0; i < auth_signs_total; i++){
-            dap_pkey_t *l_pkey_upd_token = dap_pkey_get_from_sign_deserialization(l_signs_upd_token[i]);
+            dap_pkey_t *l_pkey_upd_token = dap_pkey_get_from_sign(l_signs_upd_token[i]);
             for (size_t j = 0; j < a_cur_token_item->auth_signs_total; j++) {
                 if (dap_pkey_match(a_cur_token_item->auth_pkeys[j], l_pkey_upd_token)) {
                     l_valid_pkeys++;
@@ -710,41 +705,41 @@ static bool s_ledger_token_update_check(dap_chain_ledger_token_item_t *a_cur_tok
 }
 
 
+inline static dap_ledger_token_item_t *s_ledger_find_token(dap_ledger_t *a_ledger, const char *a_token_ticker)
+{
+    dap_ledger_token_item_t *l_token_item;
+    pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
+    HASH_FIND_STR(PVT(a_ledger)->tokens, a_token_ticker, l_token_item);
+    pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
+    return l_token_item;
+}
+
 /**
- * @brief dap_chain_ledger_token_check
+ * @brief dap_ledger_token_check
  * @param a_ledger
  * @param a_token
  * @param a_token_size
  * @return
  */
-int dap_chain_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size)
+int dap_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size)
 {
     if ( !a_ledger){
         if(s_debug_more)
             log_it(L_ERROR, "NULL ledger, can't add datum with token declaration!");
-        return  DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL;
+        return  DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL;
     }
 
-
-    bool update_token = false;
-    dap_chain_ledger_token_item_t *l_token_item;
-    pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
-    HASH_FIND_STR(PVT(a_ledger)->tokens, a_token->ticker, l_token_item);
-    pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
-    if (a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE)
-        update_token = true;
-
+    bool l_update_token = a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE;
+    dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token->ticker);
     if	(l_token_item != NULL) {
-        if (update_token == false) {
-            log_it(L_WARNING,"Duplicate token declaration for ticker '%s' ", a_token->ticker);
-            return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE;
-        } else if (s_ledger_token_update_check(l_token_item, a_token, a_token_size) == false) {
-            return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK;
-        }
-    }
-    else if	(l_token_item == NULL && update_token == true) {
-        log_it(L_WARNING,"Can't update token that doesn't exist for ticker '%s' ", a_token->ticker);
-        return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN;
+        if (!l_update_token) {
+            log_it(L_WARNING, "Duplicate token declaration for ticker '%s'", a_token->ticker);
+            return DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE;
+        } else if (!s_ledger_token_update_check(l_token_item, a_token, a_token_size))
+            return DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK;
+    } else if (!l_token_item && l_update_token) {
+        log_it(L_WARNING, "Can't update token that doesn't exist for ticker '%s'", a_token->ticker);
+        return DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN;
     }
     // Check signs
     size_t l_signs_unique = 0;
@@ -778,43 +773,39 @@ int dap_chain_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datu
                 l_signs_approve++;
         a_token->signs_total = l_tmp_auth_signs;
         if (l_signs_approve == a_token->signs_total){
-            return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK;
+            return DAP_LEDGER_TOKEN_DECL_ADD_OK;
         } else {
             log_it(L_WARNING, "The token declaration has %zu valid signatures out of %hu.", l_signs_approve, a_token->signs_total);
-            return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN;
+            return DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN;
         }
     } else {
         log_it(L_WARNING, "The number of unique token signs %zu is less than total token signs set to %hu.",
                l_signs_unique, a_token->signs_total);
-        return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS;
+        return DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS;
     }
     // Checks passed
-    return DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK;
+    return DAP_LEDGER_TOKEN_DECL_ADD_OK;
 }
 
-char *dap_chain_ledger_token_decl_add_err_code_to_str(int a_code) {
-    return (a_code >= DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_OK) && (a_code < DAP_CHAIN_LEDGER_TOKEN_DECL_ADD_UNKNOWN)
-            ? (char*)s_ledger_token_decl_err_str[(dap_chain_ledger_token_decl_add_err_t)a_code]
+char *dap_ledger_token_decl_add_err_code_to_str(int a_code) {
+    return (a_code >= DAP_LEDGER_TOKEN_DECL_ADD_OK) && (a_code < DAP_LEDGER_TOKEN_DECL_ADD_UNKNOWN)
+            ? (char*)s_ledger_token_decl_err_str[(dap_ledger_token_decl_add_err_t)a_code]
             : dap_itoa(a_code);
 }
 
 /**
- * @brief dap_chain_ledger_token_ticker_check
+ * @brief dap_ledger_token_ticker_check
  * @param a_ledger
  * @param a_token_ticker
  * @return
  */
-dap_chain_datum_token_t *dap_chain_ledger_token_ticker_check(dap_ledger_t * a_ledger, const char *a_token_ticker)
+dap_chain_datum_token_t *dap_ledger_token_ticker_check(dap_ledger_t *a_ledger, const char *a_token_ticker)
 {
-    if ( !a_ledger){
-        if(s_debug_more)
-            log_it(L_WARNING, "NULL ledger, can't find token ticker");
+    if (!a_ledger) {
+        debug_if(s_debug_more, L_WARNING, "NULL ledger, can't find token ticker");
         return NULL;
     }
-    dap_chain_ledger_token_item_t *l_token_item;
-    pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
-    HASH_FIND_STR(PVT(a_ledger)->tokens, a_token_ticker, l_token_item);
-    pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
+    dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token_ticker);
     return l_token_item ? l_token_item->datum_token : NULL;
 }
 
@@ -844,7 +835,7 @@ static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_datum_tx_t *a_t
     DAP_DELETE(l_tx_hash_str);
 }
 
-static void s_dump_datum_tx_for_addr(dap_chain_ledger_tx_item_t *a_item, bool a_unspent, dap_ledger_t *a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, dap_string_t *a_str_out) {
+static void s_dump_datum_tx_for_addr(dap_ledger_tx_item_t *a_item, bool a_unspent, dap_ledger_t *a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, dap_string_t *a_str_out) {
     if (a_unspent && a_item->cache_data.ts_spent) {
         // With 'unspent' flag spent ones are ignored
         return;
@@ -882,7 +873,7 @@ static void s_dump_datum_tx_for_addr(dap_chain_ledger_tx_item_t *a_item, bool a_
                 l_src_token = l_token->header.ticker;
             break;
         }
-        l_tx_prev = dap_chain_ledger_tx_find_by_hash (a_ledger,l_tx_prev_hash);
+        l_tx_prev = dap_ledger_tx_find_by_hash (a_ledger,l_tx_prev_hash);
         if (l_tx_prev) {
             uint8_t *l_prev_out_union = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_tx_prev_out_idx);
             if (!l_prev_out_union)
@@ -943,7 +934,7 @@ static void s_dump_datum_tx_for_addr(dap_chain_ledger_tx_item_t *a_item, bool a_
                 s_tx_header_print(a_str_out, l_tx, a_hash_out_type, l_tx_hash);
                 l_header_printed = true;
             }
-            //const char *l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash);
+            //const char *l_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash);
             const char *l_dst_addr_str = l_dst_addr ? dap_chain_addr_to_str(l_dst_addr)
                                                     : dap_chain_tx_out_cond_subtype_to_str(
                                                           ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.subtype);
@@ -985,16 +976,16 @@ char *dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a
 {
     dap_string_t *l_str_out = dap_string_new(NULL);
     if (!l_str_out) {
-    log_it(L_CRITICAL, "Memory allocation error");
+        log_it(L_CRITICAL, "Memory allocation error");
         return NULL;
     }
 
     //dap_chain_tx_hash_processed_ht_t *l_tx_data_ht = NULL;
-    dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp;
+    dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp;
     dap_ledger_private_t * l_ledger_pvt = PVT(a_ledger);
 
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
-    //unsigned test = dap_chain_ledger_count(a_ledger);
+    //unsigned test = dap_ledger_count(a_ledger);
     HASH_ITER(hh, l_ledger_pvt->ledger_items, l_tx_item, l_tx_tmp) {
         s_dump_datum_tx_for_addr(l_tx_item, a_unspent_only, a_ledger, a_addr, a_hash_out_type, l_str_out);
     }
@@ -1013,9 +1004,11 @@ char *dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a
  * @param a_ledger ledger object
  * @param l_token_item token item object
  */
-void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_t *l_token_item)
+void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_ledger_token_item_t *l_token_item)
 {
-    char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR);
+    if (!PVT(a_ledger)->cached)
+        return;
+    char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TOKENS_STR);
     size_t l_cache_size = l_token_item->datum_token_size + sizeof(uint256_t);
     uint8_t *l_cache = DAP_NEW_STACK_SIZE(uint8_t, l_cache_size);
     if ( !l_cache ) {
@@ -1032,6 +1025,43 @@ void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_chain_ledger_token_
     DAP_DELETE(l_gdb_group);
 }
 
+static bool s_ledger_token_supply_check_unsafe(dap_ledger_token_item_t *a_token_item, uint256_t a_value)
+{
+    if (compare256(a_token_item->current_supply, a_value) >= 0)
+        return true;
+    char *l_supply_str = dap_chain_balance_print(a_token_item->current_supply);
+    char *l_value_str = dap_chain_balance_print(a_value);
+    log_it(L_WARNING, "Token current supply %s < emission value %s", l_supply_str, l_value_str);
+    DAP_DEL_Z(l_supply_str);
+    DAP_DEL_Z(l_value_str);
+    return false;
+}
+
+static bool s_ledger_token_supply_check(dap_ledger_token_item_t *a_token_item, uint256_t a_value)
+{
+    assert(a_token_item);
+    if (IS_ZERO_256(a_token_item->total_supply) || IS_ZERO_256(a_value))
+        return true;
+    return s_ledger_token_supply_check_unsafe(a_token_item, a_value);
+}
+
+static bool s_ledger_token_supply_check_update(dap_ledger_t *a_ledger, dap_ledger_token_item_t *a_token_item, uint256_t a_value)
+{
+    assert(a_token_item);
+    if (IS_ZERO_256(a_token_item->total_supply) || IS_ZERO_256(a_value))
+        return true;
+    if (!s_ledger_token_supply_check_unsafe(a_token_item, a_value))
+        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_chain_balance_to_coins(a_token_item->current_supply);
+    log_it(L_NOTICE, "New current supply %s for token %s", l_balance, a_token_item->ticker);
+    DAP_DELETE(l_balance);
+    s_ledger_token_cache_update(a_ledger, a_token_item);
+    return true;
+}
+
+
 /**
  * @brief s_ledger_update_token_add_in_hash_table
  * @param a_cur_token_item
@@ -1039,9 +1069,9 @@ void s_ledger_token_cache_update(dap_ledger_t *a_ledger, dap_chain_ledger_token_
  * @param a_token_update_size
  * @return true or false
  */
-static bool s_ledger_update_token_add_in_hash_table(dap_chain_ledger_token_item_t *a_cur_token_item, dap_chain_datum_token_t *a_token_update, size_t a_token_update_size)
+static bool s_ledger_update_token_add_in_hash_table(dap_ledger_token_item_t *a_cur_token_item, dap_chain_datum_token_t *a_token_update, size_t a_token_update_size)
 {
-    dap_chain_ledger_token_update_item_t	*l_token_update_item;
+    dap_ledger_token_update_item_t	*l_token_update_item;
     dap_hash_fast_t							l_hash_token_update;
     bool									new_item = false;
 
@@ -1053,17 +1083,17 @@ static bool s_ledger_update_token_add_in_hash_table(dap_chain_ledger_token_item_
     if (l_token_update_item
     &&	a_cur_token_item->last_update_token_time == l_token_update_item->updated_time) {
         if (s_debug_more)
-            log_it(L_WARNING, "Error: item 'dap_chain_ledger_token_update_item_t' already exist in hash-table");
+            log_it(L_WARNING, "Error: item 'dap_ledger_token_update_item_t' already exist in hash-table");
         return false;
     } else if (!l_token_update_item){
         new_item = true;
-        l_token_update_item = DAP_NEW(dap_chain_ledger_token_update_item_t);
+        l_token_update_item = DAP_NEW(dap_ledger_token_update_item_t);
         if (!l_token_update_item) {
             if (s_debug_more)
-                log_it(L_ERROR, "Error: memory allocation when try adding item 'dap_chain_ledger_token_update_item_t' to hash-table");
+                log_it(L_ERROR, "Error: memory allocation when try adding item 'dap_ledger_token_update_item_t' to hash-table");
             return false;
         }
-        *l_token_update_item = (dap_chain_ledger_token_update_item_t) {
+        *l_token_update_item = (dap_ledger_token_update_item_t) {
                 .update_token_hash			= l_hash_token_update,
                 .datum_token_update			= a_token_update,
                 .datum_token_update_size	= a_token_update_size
@@ -1090,24 +1120,20 @@ static bool s_ledger_update_token_add_in_hash_table(dap_chain_ledger_token_item_
 }
 
 /**
- * @brief dap_chain_ledger_token_add
+ * @brief dap_ledger_token_add
  * @param a_token
  * @param a_token_size
  * @return
  */
-int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size) {
+int dap_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size)
+{
     if (!a_ledger || !a_token) {
         debug_if(s_debug_more, L_ERROR, "NULL ledger, can't add datum with token declaration!");
         return -1;
     }
 
     dap_chain_datum_token_t *l_token = a_token;
-
-    dap_chain_ledger_token_item_t *l_token_item;
-    pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
-    HASH_FIND_STR(PVT(a_ledger)->tokens, l_token->ticker, l_token_item);
-    pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
-
+    dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token->ticker);
     if (l_token_item) {
         if (l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE
                 && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE
@@ -1149,13 +1175,13 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
             DAP_DEL_Z(l_token);
             return -7;
         }
-        l_token_item = DAP_NEW_Z(dap_chain_ledger_token_item_t);
+        l_token_item = DAP_NEW_Z(dap_ledger_token_item_t);
         if ( !l_token_item ) {
             DAP_DEL_Z(l_token);
-        log_it(L_CRITICAL, "Memory allocation error");
+            log_it(L_CRITICAL, "Memory allocation error");
             return -8;
         }
-        *l_token_item = (dap_chain_ledger_token_item_t) {
+        *l_token_item = (dap_ledger_token_item_t) {
                 .version        = l_token->version,
                 .type           = l_token->type,
                 .subtype        = l_token->subtype,
@@ -1173,7 +1199,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
             if (l_token)
                 DAP_DELETE(l_token);
             DAP_DELETE(l_token_item);
-        log_it(L_CRITICAL, "Memory allocation error");
+            log_it(L_CRITICAL, "Memory allocation error");
             return -6;
         };
         if ( !l_token_item->auth_pkeys ) {
@@ -1181,12 +1207,12 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
                 DAP_DELETE(l_token);
             DAP_DEL_Z(l_token_item->auth_pkeys);
             DAP_DELETE(l_token_item);
-        log_it(L_CRITICAL, "Memory allocation error");
+            log_it(L_CRITICAL, "Memory allocation error");
             return -6;
         }
         dap_stpcpy(l_token_item->ticker, l_token->ticker);
         for (uint16_t k = 0; k < l_token_item->auth_signs_total; k++) {
-            l_token_item->auth_pkeys[k] = dap_pkey_get_from_sign_deserialization(l_signs[k]);
+            l_token_item->auth_pkeys[k] = dap_pkey_get_from_sign(l_signs[k]);
             dap_pkey_get_hash(l_token_item->auth_pkeys[k], &l_token_item->auth_pkeys_hash[k]);
         }
         DAP_DELETE(l_signs);
@@ -1290,8 +1316,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
 #undef CLEAN_UP
     DAP_DELETE(l_balance_dbg);
     s_threshold_emissions_proc(a_ledger); /* TODO process thresholds only for no-consensus chains */
-    if (PVT(a_ledger)->cached)
-        s_ledger_token_cache_update(a_ledger, l_token_item);
+    s_ledger_token_cache_update(a_ledger, l_token_item);
     return 0;
 }
 
@@ -1304,7 +1329,7 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
  * @param a_token_size
  * @return int
  */
-static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size)
+static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_ledger_token_item_t *a_token_item , dap_chain_datum_token_t * a_token, size_t a_token_size)
 {
     UNUSED(a_ledger);
     dap_tsd_t * l_tsd= dap_chain_datum_token_tsd_get(a_token,a_token_size);
@@ -1709,7 +1734,7 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite
     return 0;
 }
 
-static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_t *a_token_item , dap_chain_datum_token_t *a_token, size_t a_token_size){
+static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_ledger_token_item_t *a_token_item , dap_chain_datum_token_t *a_token, size_t a_token_size){
     dap_tsd_t * l_tsd= dap_chain_datum_token_tsd_get(a_token,a_token_size);
     size_t l_tsd_size=0;
     size_t l_tsd_total_size = a_token->header_native_decl.tsd_total_size;
@@ -1783,15 +1808,12 @@ static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_
     return 0;
 }
 
-int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size)
+int dap_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size)
 {
     dap_chain_datum_token_t *l_token = dap_chain_datum_token_read(a_token, &a_token_size);
 
     if (PVT(a_ledger)->load_mode) {
-        dap_chain_ledger_token_item_t *l_token_item;
-        pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
-        HASH_FIND_STR(PVT(a_ledger)->tokens, l_token->ticker, l_token_item);
-        pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
+        dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token->ticker);
         if (l_token_item
                 && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE
                 && l_token->type != DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE
@@ -1800,13 +1822,13 @@ int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t
             return 0;
         }
     }
-    return dap_chain_ledger_token_add(a_ledger, l_token, a_token_size);
+    return dap_ledger_token_add(a_ledger, l_token, a_token_size);
 }
 
-dap_string_t *dap_chain_ledger_threshold_info(dap_ledger_t *a_ledger)
+dap_string_t *dap_ledger_threshold_info(dap_ledger_t *a_ledger)
 {
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp;
+    dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp;
     dap_string_t *l_str_ret = dap_string_new("");
     uint32_t l_counter = 0;
     pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock);
@@ -1832,7 +1854,7 @@ dap_string_t *dap_chain_ledger_threshold_info(dap_ledger_t *a_ledger)
 
     pthread_rwlock_rdlock(&l_ledger_pvt->threshold_emissions_rwlock);
     l_counter = 0;
-    dap_chain_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp;
+    dap_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp;
     HASH_ITER(hh, l_ledger_pvt->threshold_emissions, l_emission_item, l_emission_tmp){
         char l_emission_hash_str[70]={0};
         char l_item_size[70] = {0};
@@ -1851,10 +1873,10 @@ dap_string_t *dap_chain_ledger_threshold_info(dap_ledger_t *a_ledger)
     return l_str_ret;
 }
 
-dap_string_t *dap_chain_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_threshold_hash)
+dap_string_t *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_threshold_hash)
 {
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp;
+    dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp;
     dap_string_t *l_str_ret = dap_string_new("");
     pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock);
     HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp){
@@ -1871,7 +1893,7 @@ dap_string_t *dap_chain_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_c
     pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock);
 
     pthread_rwlock_rdlock(&l_ledger_pvt->threshold_emissions_rwlock);
-    dap_chain_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp;
+    dap_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp;
     HASH_ITER(hh, l_ledger_pvt->threshold_emissions, l_emission_item, l_emission_tmp){
         if (!memcmp(&l_emission_item->datum_token_emission_hash,l_threshold_hash, sizeof(dap_chain_hash_fast_t))){
             char l_emission_hash_str[70]={0};
@@ -1888,7 +1910,7 @@ dap_string_t *dap_chain_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_c
     return l_str_ret;
 }
 
-dap_string_t *dap_chain_ledger_balance_info(dap_ledger_t *a_ledger)
+dap_string_t *dap_ledger_balance_info(dap_ledger_t *a_ledger)
 {
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
     dap_string_t *l_str_ret = dap_string_new("");
@@ -1916,14 +1938,14 @@ dap_string_t *dap_chain_ledger_balance_info(dap_ledger_t *a_ledger)
 }
 
 /**
- * @breif dap_chain_ledger_token_auth_signs_valid
+ * @breif dap_ledger_token_auth_signs_valid
  * @param a_ledger
  * @param a_token_ticker
  * @return 0 if no ticker found
  */
-size_t dap_chain_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker)
+size_t dap_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker)
 {
-    dap_chain_ledger_token_item_t *l_token_item, *l_tmp_item;
+    dap_ledger_token_item_t *l_token_item, *l_tmp_item;
     pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
     size_t l_res = 0;
     HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) {
@@ -1937,14 +1959,14 @@ size_t dap_chain_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const cha
 }
 
 /**
- * @breif dap_chain_ledger_token_auth_signs_total
+ * @breif dap_ledger_token_auth_signs_total
  * @param a_ledger
  * @param a_token_ticker
  * @return
  */
-size_t dap_chain_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker)
+size_t dap_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker)
 {
-    dap_chain_ledger_token_item_t *l_token_item, *l_tmp_item;
+    dap_ledger_token_item_t *l_token_item, *l_tmp_item;
     pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
     size_t l_res = 0;
     HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) {
@@ -1958,15 +1980,15 @@ size_t dap_chain_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const cha
 }
 
 /**
- * @breif dap_chain_ledger_token_auth_signs_hashes
+ * @breif dap_ledger_token_auth_signs_hashes
  * @param a_ledger
  * @param a_token_ticker
  * @return
  */
-dap_list_t * dap_chain_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker)
+dap_list_t * dap_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker)
 {
     dap_list_t * l_ret = NULL;
-    dap_chain_ledger_token_item_t *l_token_item, *l_tmp_item;
+    dap_ledger_token_item_t *l_token_item, *l_tmp_item;
     pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
     HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) {
         if (!dap_strcmp(l_token_item->ticker, a_token_ticker)) {
@@ -1986,11 +2008,11 @@ dap_list_t * dap_chain_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, co
  * @param a_ledger
  * @return
  */
-dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger)
+dap_list_t *dap_ledger_token_info(dap_ledger_t *a_ledger)
 {
     dap_list_t *l_ret_list = NULL;
     dap_string_t *l_str_tmp;// = dap_string_new("");
-    dap_chain_ledger_token_item_t *l_token_item, *l_tmp_item;
+    dap_ledger_token_item_t *l_token_item, *l_tmp_item;
     pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
     HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) {
         l_str_tmp = dap_string_new("");
@@ -2081,10 +2103,10 @@ dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger)
  * @param a_ledger
  * @return
  */
-dap_list_t* dap_chain_ledger_token_decl_all(dap_ledger_t *a_ledger)
+dap_list_t* dap_ledger_token_decl_all(dap_ledger_t *a_ledger)
 {
     dap_list_t * l_ret = NULL;
-    dap_chain_ledger_token_item_t *l_token_item, *l_tmp_item;
+    dap_ledger_token_item_t *l_token_item, *l_tmp_item;
     pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
 
     HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) {
@@ -2105,10 +2127,10 @@ static void s_threshold_emissions_proc(dap_ledger_t * a_ledger)
     bool l_success;
     do {
         l_success = false;
-        dap_chain_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp;
+        dap_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp;
         pthread_rwlock_wrlock(&PVT(a_ledger)->threshold_emissions_rwlock);
         HASH_ITER(hh, PVT(a_ledger)->threshold_emissions, l_emission_item, l_emission_tmp) {
-            int l_res = s_token_emission_add_unsafe(a_ledger, (byte_t *)l_emission_item->datum_token_emission,
+            int l_res = dap_ledger_token_emission_add(a_ledger, (byte_t *)l_emission_item->datum_token_emission,
                                                             l_emission_item->datum_token_emission_size,
                                                             &l_emission_item->datum_token_emission_hash, true);
             if (l_res != DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE) {
@@ -2135,9 +2157,9 @@ static void s_threshold_txs_proc( dap_ledger_t *a_ledger)
     pthread_rwlock_wrlock(&l_ledger_pvt->threshold_txs_rwlock);
     do {
         l_success = false;
-        dap_chain_ledger_tx_item_t *l_tx_item, *l_tx_tmp;
+        dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp;
         HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp) {
-            int l_res = s_tx_add_unsafe(a_ledger, l_tx_item->tx, &l_tx_item->tx_hash_fast, true);
+            int l_res = dap_ledger_tx_add(a_ledger, l_tx_item->tx, &l_tx_item->tx_hash_fast, true);
             if (l_res != DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION &&
                     l_res != DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS) {
                 HASH_DEL(l_ledger_pvt->threshold_txs, l_tx_item);
@@ -2157,7 +2179,7 @@ static void s_threshold_txs_proc( dap_ledger_t *a_ledger)
 static void s_threshold_txs_free(dap_ledger_t *a_ledger){
     log_it(L_DEBUG, "Start free threshold txs");
     dap_ledger_private_t *l_pvt = PVT(a_ledger);
-    dap_chain_ledger_tx_item_t *l_current = NULL, *l_tmp = NULL;
+    dap_ledger_tx_item_t *l_current = NULL, *l_tmp = NULL;
     dap_nanotime_t l_time_cut_off = dap_nanotime_now() - dap_nanotime_from_sec(7200); //7200 sec = 2 hours.
     pthread_rwlock_wrlock(&l_pvt->threshold_txs_rwlock);
     HASH_ITER(hh, l_pvt->threshold_txs, l_current, l_tmp) {
@@ -2180,7 +2202,7 @@ static void s_threshold_txs_free(dap_ledger_t *a_ledger){
 static void s_threshold_emission_free(dap_ledger_t *a_ledger){
     log_it(L_DEBUG, "Start free threshold emission");
     dap_ledger_private_t *l_pvt = PVT(a_ledger);
-    dap_chain_ledger_token_emission_item_t *l_current = NULL, *l_tmp = NULL;
+    dap_ledger_token_emission_item_t *l_current = NULL, *l_tmp = NULL;
     dap_nanotime_t l_time_cut_off = dap_nanotime_now() - dap_nanotime_from_sec(7200); //7200 sec = 2 hours.
     pthread_rwlock_wrlock(&l_pvt->threshold_emissions_rwlock);
     HASH_ITER(hh, l_pvt->threshold_emissions, l_current, l_tmp) {
@@ -2218,12 +2240,12 @@ static bool s_load_cache_gdb_loaded_balances_callback(dap_global_db_instance_t *
     for (size_t i = 0; i < a_values_count; i++) {
         dap_ledger_wallet_balance_t *l_balance_item = DAP_NEW_Z(dap_ledger_wallet_balance_t);
         if (!l_balance_item) {
-        log_it(L_CRITICAL, "Memory allocation error");
+            log_it(L_CRITICAL, "Memory allocation error");
             return false;
         }
         l_balance_item->key = DAP_NEW_Z_SIZE(char, strlen(a_values[i].key) + 1);
         if (!l_balance_item->key) {
-        log_it(L_CRITICAL, "Memory allocation error");
+            log_it(L_CRITICAL, "Memory allocation error");
             DAP_DEL_Z(l_balance_item);
             return false;
         }
@@ -2267,7 +2289,7 @@ static bool s_load_cache_gdb_loaded_txs_callback(dap_global_db_instance_t *a_dbi
     dap_ledger_t * l_ledger = (dap_ledger_t*) a_arg;
     dap_ledger_private_t * l_ledger_pvt = PVT(l_ledger);
     for (size_t i = 0; i < a_values_count; i++) {
-        dap_chain_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_chain_ledger_tx_item_t);
+        dap_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_ledger_tx_item_t);
         if ( !l_tx_item ) {
             log_it(L_CRITICAL, "Memory allocation error");
             return false;
@@ -2298,9 +2320,9 @@ static bool s_load_cache_gdb_loaded_stake_lock_callback(dap_global_db_instance_t
     for (size_t i = 0; i < a_values_count; i++) {
         if (a_values[i].value_len != sizeof(dap_hash_fast_t))
             continue;
-        dap_chain_ledger_stake_lock_item_t *l_new_stake_lock_emission = DAP_NEW(dap_chain_ledger_stake_lock_item_t);
+        dap_ledger_stake_lock_item_t *l_new_stake_lock_emission = DAP_NEW(dap_ledger_stake_lock_item_t);
         if (!l_new_stake_lock_emission) {
-            debug_if(s_debug_more, L_ERROR, "Error: memory allocation when try adding item 'dap_chain_ledger_stake_lock_item_t' to hash-table");
+            debug_if(s_debug_more, L_ERROR, "Error: memory allocation when try adding item 'dap_ledger_stake_lock_item_t' to hash-table");
             continue;
         }
         dap_chain_hash_fast_from_str(a_values[i].key, &l_new_stake_lock_emission->tx_for_stake_lock_hash);
@@ -2308,7 +2330,7 @@ static bool s_load_cache_gdb_loaded_stake_lock_callback(dap_global_db_instance_t
         HASH_ADD(hh, l_ledger_pvt->emissions_for_stake_lock, tx_for_stake_lock_hash, sizeof(dap_chain_hash_fast_t), l_new_stake_lock_emission);
     }
 
-    char* l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_LEDGER_TXS_STR);
+    char* l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_LEDGER_TXS_STR);
     dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_txs_callback, l_ledger);
     DAP_DELETE(l_gdb_group);
     return true;
@@ -2341,13 +2363,13 @@ static bool s_load_cache_gdb_loaded_emissions_callback(dap_global_db_instance_t
             continue;
         const char *c_token_ticker = ((dap_chain_datum_token_emission_t *)
                                       (a_values[i].value + sizeof(dap_hash_fast_t)))->hdr.ticker;
-        dap_chain_ledger_token_item_t *l_token_item = NULL;
+        dap_ledger_token_item_t *l_token_item = NULL;
         HASH_FIND_STR(l_ledger_pvt->tokens, c_token_ticker, l_token_item);
         if (!l_token_item) {
             log_it(L_WARNING, "Not found token with ticker [%s], need to 'ledger reload' to update cache", c_token_ticker);
             continue;
         }
-        dap_chain_ledger_token_emission_item_t *l_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t);
+        dap_ledger_token_emission_item_t *l_emission_item = DAP_NEW_Z(dap_ledger_token_emission_item_t);
         if ( !l_emission_item ) {
             log_it(L_CRITICAL, "Memory allocation error");
             return false;
@@ -2361,7 +2383,7 @@ static bool s_load_cache_gdb_loaded_emissions_callback(dap_global_db_instance_t
                  sizeof(dap_chain_hash_fast_t), l_emission_item);
     }
 
-    char* l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_LEDGER_STAKE_LOCK_STR);
+    char* l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_LEDGER_STAKE_LOCK_STR);
     dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_stake_lock_callback, l_ledger);
     DAP_DELETE(l_gdb_group);
     return true;
@@ -2405,8 +2427,8 @@ static bool s_load_cache_gdb_loaded_tokens_callback(dap_global_db_instance_t *a_
             continue;
         }
         // TODO: rework! Old token types may be passed unchecked!
-        dap_chain_ledger_token_add(l_ledger, l_token, l_token_size);
-        dap_chain_ledger_token_item_t *l_token_item = NULL;
+        dap_ledger_token_add(l_ledger, l_token, l_token_size);
+        dap_ledger_token_item_t *l_token_item = NULL;
         HASH_FIND_STR(l_ledger_pvt->tokens, l_token->ticker, l_token_item);
         if (!l_token_item) {
             log_it(L_WARNING, "Can't load token with ticker [%s], need to 'ledger reload' to update cache", l_token->ticker);
@@ -2415,7 +2437,7 @@ static bool s_load_cache_gdb_loaded_tokens_callback(dap_global_db_instance_t *a_
         l_token_item->current_supply = *(uint256_t*)a_values[i].value;
     }
 
-    char *l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR);
+    char *l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_LEDGER_EMISSIONS_STR);
     dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_emissions_callback, l_ledger);
     DAP_DELETE(l_gdb_group);
     return true;
@@ -2425,10 +2447,10 @@ static bool s_load_cache_gdb_loaded_tokens_callback(dap_global_db_instance_t *a_
  * @brief Load ledger from cache (stored in GDB)
  * @param a_ledger
  */
-void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger)
+void dap_ledger_load_cache(dap_ledger_t *a_ledger)
 {
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR);
+    char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TOKENS_STR);
 
     pthread_mutex_lock(& l_ledger_pvt->load_mutex);
     dap_global_db_get_all(l_gdb_group, 0, s_load_cache_gdb_loaded_tokens_callback, a_ledger);
@@ -2445,34 +2467,30 @@ void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger)
  * create ledger for specific net
  * load ledger cache
  * @param a_check_flags checking flags
- *          DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION
- *          DAP_CHAIN_LEDGER_CHECK_CELLS_DS
- *          DAP_CHAIN_LEDGER_CHECK_CELLS_DS
+ *          DAP_LEDGER_CHECK_TOKEN_EMISSION
+ *          DAP_LEDGER_CHECK_CELLS_DS
+ *          DAP_LEDGER_CHECK_CELLS_DS
  * @param a_net_name char * network name, for example "kelvin-testnet"
  * @return dap_ledger_t*
  */
-dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, dap_chain_net_id_t a_net_id, char *a_net_name, const char *a_net_native_ticker, dap_list_t *a_poa_certs)
+dap_ledger_t *dap_ledger_create(dap_chain_net_t *a_net, uint16_t a_flags)
 {
-    dap_ledger_t *l_ledger = dap_chain_ledger_handle_new();
+    dap_ledger_t *l_ledger = dap_ledger_handle_new();
     if (!l_ledger) {
         log_it(L_CRITICAL, "Memory allocation error");
         return NULL;
     }
-    l_ledger->net_name = a_net_name;
-    l_ledger->net_id = a_net_id;
+    l_ledger->net = a_net;
     dap_ledger_private_t *l_ledger_pvt = PVT(l_ledger);
-    l_ledger_pvt->net_native_ticker = a_net_native_ticker;
-    l_ledger_pvt->poa_certs = a_poa_certs;
-    l_ledger_pvt->flags = a_flags;
-    l_ledger_pvt->check_ds = a_flags & DAP_CHAIN_LEDGER_CHECK_LOCAL_DS;
-    l_ledger_pvt->check_cells_ds = a_flags & DAP_CHAIN_LEDGER_CHECK_CELLS_DS;
-    l_ledger_pvt->check_token_emission = a_flags & DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION;
-    l_ledger_pvt->cached = a_flags & DAP_CHAIN_LEDGER_CACHE_ENABLED;
+    l_ledger_pvt->check_ds = a_flags & DAP_LEDGER_CHECK_LOCAL_DS;
+    l_ledger_pvt->check_cells_ds = a_flags & DAP_LEDGER_CHECK_CELLS_DS;
+    l_ledger_pvt->check_token_emission = a_flags & DAP_LEDGER_CHECK_TOKEN_EMISSION;
+    l_ledger_pvt->cached = a_flags & DAP_LEDGER_CACHE_ENABLED;
     pthread_cond_init(&l_ledger_pvt->load_cond, NULL);
     pthread_mutex_init(&l_ledger_pvt->load_mutex, NULL);
 
-#ifndef DAP_CHAIN_LEDGER_TEST
-    char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), a_net_name);
+#ifndef DAP_LEDGER_TEST
+    char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), a_net->pub.name);
     DIR * l_chains_dir = opendir(l_chains_path);
     DAP_DEL_Z(l_chains_path);
 
@@ -2485,7 +2503,7 @@ dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, dap_chain_net_id_t a_net
             if ( strncmp (l_entry_name + strlen(l_entry_name)-4,".cfg",4) == 0 ) { // its .cfg file
                 l_entry_name [strlen(l_entry_name)-4] = 0;
                 log_it(L_DEBUG,"Open chain config \"%s\"...",l_entry_name);
-                l_chains_path = dap_strdup_printf("network/%s/%s", a_net_name, l_entry_name);
+                l_chains_path = dap_strdup_printf("network/%s/%s", a_net->pub.name, l_entry_name);
                 dap_config_t * l_cfg = dap_config_open(l_chains_path);
                 uint16_t l_whitelist_size;
                 char **l_whitelist = dap_config_get_array_str(l_cfg, "ledger", "hard_accept_list", &l_whitelist_size);
@@ -2513,38 +2531,28 @@ dap_ledger_t *dap_chain_ledger_create(uint16_t a_flags, dap_chain_net_id_t a_net
 
     if ( l_ledger_pvt->cached )
         // load ledger cache from GDB
-        dap_chain_ledger_load_cache(l_ledger);
+        dap_ledger_load_cache(l_ledger);
 #endif
 
     return l_ledger;
 }
 
-void dap_chain_ledger_set_fee(dap_ledger_t *a_ledger, uint256_t a_fee, dap_chain_addr_t a_fee_addr)
-{
-    PVT(a_ledger)->fee_value = a_fee;
-    PVT(a_ledger)->fee_addr = a_fee_addr;
-}
-
-int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash)
+int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash)
 {
     if (!a_token_emission || !a_token_emission_size)
-        return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL;
+        return DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL;
 
-    int l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_OK;
+    int l_ret = DAP_LEDGER_EMISSION_ADD_OK;
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
 
     const char *l_token_ticker = ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.ticker;
-    dap_chain_ledger_token_item_t * l_token_item = NULL;
-    pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock);
-    HASH_FIND_STR(l_ledger_pvt->tokens, l_token_ticker, l_token_item);
-    pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock);
-
+    dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token_ticker);
     if (!l_token_item) {
         log_it(L_ERROR, "Check emission: token %s was not found", l_token_ticker);
-        return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN;
+        return DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN;
     }
 
-    dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL;
+    dap_ledger_token_emission_item_t * l_token_emission_item = NULL;
     // check if such emission is already present in table
     pthread_rwlock_rdlock(l_token_item ? &l_token_item->token_emissions_rwlock
                                        : &l_ledger_pvt->threshold_emissions_rwlock);
@@ -2553,25 +2561,24 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_
     unsigned long long l_threshold_emissions_count = HASH_COUNT( l_ledger_pvt->threshold_emissions);
     pthread_rwlock_unlock(l_token_item ? &l_token_item->token_emissions_rwlock
                                        : &l_ledger_pvt->threshold_emissions_rwlock);
-    if(l_token_emission_item ) {
+    if (l_token_emission_item) {
         if(s_debug_more) {
             char l_token_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
             dap_chain_hash_fast_to_str(a_emission_hash, l_token_hash_str, sizeof(l_token_hash_str));
             if ( l_token_emission_item->datum_token_emission->hdr.version >= 2 ) {
-                char *l_balance = dap_chain_balance_print(l_token_emission_item->datum_token_emission->hdr.value_256);
+                char *l_balance = dap_chain_balance_print(l_token_emission_item->datum_token_emission->hdr.value);
                 log_it(L_ERROR, "Can't add token emission datum of %s %s ( %s ): already present in cache",
                         l_balance, l_token_ticker, l_token_hash_str);
                 DAP_DELETE(l_balance);
-            }
-            else
+            } else
                 log_it(L_ERROR, "Can't add token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s ): already present in cache",
-                    l_token_emission_item->datum_token_emission->hdr.value, l_token_ticker, l_token_hash_str);
+                    l_token_emission_item->datum_token_emission->hdr.value64, l_token_ticker, l_token_hash_str);
         }
-        l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED;
+        l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED;
     }else if ( (! l_token_item) && ( l_threshold_emissions_count >= s_threshold_emissions_max)) {
         if(s_debug_more)
             log_it(L_WARNING,"Emissions threshold overflow, max %zu items", s_threshold_emissions_max);
-        l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW;
+        l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW;
     }
     if (l_ret || !PVT(a_ledger)->check_token_emission)
         return l_ret;
@@ -2591,25 +2598,14 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_
     size_t l_emission_size = a_token_emission_size;
     dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_token_emission, &l_emission_size);
 
-    if (IS_ZERO_256((l_emission->hdr.value_256))) {
+    if (IS_ZERO_256((l_emission->hdr.value))) {
         log_it(L_ERROR, "Emission check: zero %s emission value", l_token_item->ticker);
         DAP_DELETE(l_emission);
-        return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE;
+        return DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE;
     }
 
-    // if total_supply > 0 we can check current_supply
-    if (!IS_ZERO_256(l_token_item->total_supply)){
-        if(compare256(l_token_item->current_supply, l_emission->hdr.value_256) < 0) {
-            char *l_balance_cur = dap_chain_balance_print(l_token_item->current_supply);
-            char *l_balance_em = dap_chain_balance_print(l_emission->hdr.value_256);
-            log_it(L_ERROR, "Emission check: current_supply %s < emission value %s",
-                    l_balance_cur, l_balance_em);
-            DAP_DELETE(l_balance_cur);
-            DAP_DELETE(l_balance_em);
-            DAP_DELETE(l_emission);
-            return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY;
-        }
-    }
+    if (!s_ledger_token_supply_check(l_token_item, l_emission->hdr.value))
+        return DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY;
 
     //additional check for private tokens
     if ((l_token_item->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE)
@@ -2620,11 +2616,8 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_
     }
     switch (l_emission->hdr.type){
         case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH:{
-            dap_chain_ledger_token_item_t *l_token_item=NULL;
-            pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
-            HASH_FIND_STR(PVT(a_ledger)->tokens, l_emission->hdr.ticker, l_token_item);
-            pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
-            if (l_token_item){
+            dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_emission->hdr.ticker);
+            if (l_token_item) {
                 assert(l_token_item->datum_token);
                 dap_sign_t *l_sign = (dap_sign_t *)(l_emission->tsd_n_signs + l_emission->data.type_auth.tsd_total_size);
                 size_t l_offset = (byte_t *)l_sign - (byte_t *)l_emission;
@@ -2665,20 +2658,20 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_
                 }
                 if (l_aproves < l_aproves_valid ){
                     if(s_debug_more) {
-                        char *l_balance = dap_chain_balance_print(l_emission->hdr.value_256);
+                        char *l_balance = dap_chain_balance_print(l_emission->hdr.value);
                         log_it(L_WARNING, "Emission of %s datoshi of %s:%s is wrong: only %u valid aproves when %u need",
-                                l_balance, a_ledger->net_name, l_emission->hdr.ticker, l_aproves, l_aproves_valid);
+                                l_balance, a_ledger->net->pub.name, l_emission->hdr.ticker, l_aproves, l_aproves_valid);
                         DAP_DELETE(l_balance);
                     }
-                    l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS;
+                    l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS;
                     char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' };
                     dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str));
                     log_it(L_MSG, "!!! Datum hash for HAL: %s", l_hash_str);
                 }
             }else{
                 if(s_debug_more)
-                    log_it(L_WARNING,"Can't find token declaration %s:%s thats pointed in token emission datum", a_ledger->net_name, l_emission->hdr.ticker);
-                l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN;
+                    log_it(L_WARNING,"Can't find token declaration %s:%s thats pointed in token emission datum", a_ledger->net->pub.name, l_emission->hdr.ticker);
+                l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN;
             }
         }break;
         default:{}
@@ -2687,7 +2680,7 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_
     return l_ret;
 }
 
-bool s_chain_ledger_token_address_check(dap_chain_addr_t * a_addrs, dap_chain_datum_token_emission_t *a_token_emission, size_t a_addrs_count)
+bool s_ledger_token_address_check(dap_chain_addr_t * a_addrs, dap_chain_datum_token_emission_t *a_token_emission, size_t a_addrs_count)
 {
     // if l_addrs is empty - nothing to check
     dap_return_val_if_pass(!a_addrs, true);
@@ -2701,7 +2694,7 @@ bool s_chain_ledger_token_address_check(dap_chain_addr_t * a_addrs, dap_chain_da
     return false;
 }
 
-bool s_chain_ledger_token_tsd_check(dap_chain_ledger_token_item_t * a_token_item, dap_chain_datum_token_emission_t *a_token_emission)
+bool s_ledger_token_tsd_check(dap_ledger_token_item_t * a_token_item, dap_chain_datum_token_emission_t *a_token_emission)
 {
     if (!a_token_item){
         log_it(L_WARNING, "Token object is null. Probably, you set unknown token ticker in -token parameter");
@@ -2712,7 +2705,7 @@ bool s_chain_ledger_token_tsd_check(dap_chain_ledger_token_item_t * a_token_item
 
     if ((a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED) ||
         (a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN)) { // in white list
-        if (!s_chain_ledger_token_address_check(a_token_item->tx_recv_allow, a_token_emission, a_token_item->tx_recv_allow_size)){
+        if (!s_ledger_token_address_check(a_token_item->tx_recv_allow, a_token_emission, a_token_item->tx_recv_allow_size)){
             log_it(L_WARNING, "Address %s is not in tx_recv_allow for emission for token %s",
                    dap_chain_addr_to_str(&a_token_emission->hdr.address), a_token_item->ticker);
             return false;
@@ -2721,7 +2714,7 @@ bool s_chain_ledger_token_tsd_check(dap_chain_ledger_token_item_t * a_token_item
     }
 
     if (a_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_ALLOWED) {
-        if (s_chain_ledger_token_address_check(a_token_item->tx_recv_block, a_token_emission, a_token_item->tx_recv_block_size)){
+        if (s_ledger_token_address_check(a_token_item->tx_recv_block, a_token_emission, a_token_item->tx_recv_block_size)){
             log_it(L_WARNING, "Address %s is in tx_recv_block for emission for token %s",
                    dap_chain_addr_to_str(&a_token_emission->hdr.address), a_token_item->ticker);
             return false;
@@ -2731,9 +2724,11 @@ bool s_chain_ledger_token_tsd_check(dap_chain_ledger_token_item_t * a_token_item
     return true;
 }
 
-static void s_ledger_emission_cache_update(dap_ledger_t *a_ledger, dap_chain_ledger_token_emission_item_t *a_emission_item)
+static void s_ledger_emission_cache_update(dap_ledger_t *a_ledger, dap_ledger_token_emission_item_t *a_emission_item)
 {
-    char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR);
+    if (!PVT(a_ledger)->cached)
+        return;
+    char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_EMISSIONS_STR);
     size_t l_cache_size = a_emission_item->datum_token_emission_size + sizeof(dap_hash_fast_t);
     uint8_t *l_cache = DAP_NEW_STACK_SIZE(uint8_t, l_cache_size);
     memcpy(l_cache, &a_emission_item->tx_used_out, sizeof(dap_hash_fast_t));
@@ -2747,64 +2742,33 @@ static void s_ledger_emission_cache_update(dap_ledger_t *a_ledger, dap_chain_led
 }
 
 /**
- * @brief dap_chain_ledger_token_emission_add
+ * @brief dap_ledger_token_emission_add
  * @param a_token_emission
  * @param a_token_emision_size
  * @return
  */
 
-int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size,
+int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size,
                                         dap_hash_fast_t *a_emission_hash, bool a_from_threshold)
-{
-    return s_token_emission_add(a_ledger, a_token_emission, a_token_emission_size, a_emission_hash, a_from_threshold, true);
-}
-
-/**
- * @brief s_token_emission_add_unsafe
- * @param a_ledger
- * @param a_token_emission
- * @param a_token_emission_size
- * @param a_emission_hash
- * @param a_from_threshold
- * @return
- */
-static int s_token_emission_add_unsafe(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size,
-                                        dap_hash_fast_t *a_emission_hash, bool a_from_threshold)
-{
-    return s_token_emission_add(a_ledger, a_token_emission, a_token_emission_size, a_emission_hash, a_from_threshold, false);
-}
-
-/**
- * @brief s_token_emission_add
- * @param a_ledger
- * @param a_token_emission
- * @param a_token_emission_size
- * @param a_emission_hash
- * @param a_from_threshold
- * @param a_safe_call
- * @return
- */
-static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size,
-                                        dap_hash_fast_t *a_emission_hash, bool a_from_threshold, bool a_safe_call)
 {
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL;
+    dap_ledger_token_emission_item_t * l_token_emission_item = NULL;
     char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
     dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str));
-    int l_ret = dap_chain_ledger_token_emission_add_check(a_ledger, a_token_emission, a_token_emission_size, a_emission_hash);
+    int l_ret = dap_ledger_token_emission_add_check(a_ledger, a_token_emission, a_token_emission_size, a_emission_hash);
     if (l_ret) {
         if (l_ret == DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE) { // TODO remove emissions threshold
             if (HASH_COUNT(l_ledger_pvt->threshold_emissions) < s_threshold_emissions_max) {
-                l_token_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t);
+                l_token_emission_item = DAP_NEW_Z(dap_ledger_token_emission_item_t);
                 if ( !l_token_emission_item ) {
-        log_it(L_CRITICAL, "Memory allocation error");
-                    return DAP_CHAIN_LEDGER_EMISSION_ADD_MEMORY_PROBLEM;
+                    log_it(L_CRITICAL, "Memory allocation error");
+                    return DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM;
                 }
                 l_token_emission_item->datum_token_emission = DAP_DUP_SIZE(a_token_emission, a_token_emission_size);
                 if ( !l_token_emission_item->datum_token_emission ) {
                     DAP_DELETE(l_token_emission_item);
-        log_it(L_CRITICAL, "Memory allocation error");
-                    return DAP_CHAIN_LEDGER_EMISSION_ADD_MEMORY_PROBLEM;
+                    log_it(L_CRITICAL, "Memory allocation error");
+                    return DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM;
                 }
                 l_token_emission_item->datum_token_emission_size = a_token_emission_size;
                 dap_hash_fast_t l_emi_hash = {0};
@@ -2823,26 +2787,23 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e
         }
         return l_ret;
     }
-    const char * c_token_ticker = ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.ticker;
-    dap_chain_ledger_token_item_t * l_token_item = NULL;
-    pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock);
-    HASH_FIND_STR(l_ledger_pvt->tokens, c_token_ticker, l_token_item);
-    pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock);
+    const char *c_token_ticker = ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.ticker;
+    dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, c_token_ticker);
     if (!l_token_item && a_from_threshold)
-        return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN;
+        return DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN;
 
     // check if such emission is already present in table
-    if(a_safe_call) pthread_rwlock_rdlock( l_token_item ? &l_token_item->token_emissions_rwlock
+    pthread_rwlock_rdlock( l_token_item ? &l_token_item->token_emissions_rwlock
                                         : &l_ledger_pvt->threshold_emissions_rwlock);
     HASH_FIND(hh,l_token_item ? l_token_item->token_emissions : l_ledger_pvt->threshold_emissions,
               a_emission_hash, sizeof(*a_emission_hash), l_token_emission_item);
-    if(a_safe_call) pthread_rwlock_unlock(l_token_item ? &l_token_item->token_emissions_rwlock
+    pthread_rwlock_unlock(l_token_item ? &l_token_item->token_emissions_rwlock
                                        : &l_ledger_pvt->threshold_emissions_rwlock);
     if (!l_token_emission_item) {
-        l_token_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t);
+        l_token_emission_item = DAP_NEW_Z(dap_ledger_token_emission_item_t);
         if ( !l_token_emission_item ) {
-        log_it(L_CRITICAL, "Memory allocation error");
-            return DAP_CHAIN_LEDGER_EMISSION_ADD_MEMORY_PROBLEM;
+            log_it(L_CRITICAL, "Memory allocation error");
+            return DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM;
         }
         l_token_emission_item->datum_token_emission_size = a_token_emission_size;
         l_token_emission_item->datum_token_emission_hash = *a_emission_hash;
@@ -2853,46 +2814,29 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e
             //additional check for private tokens
             if((l_token_item->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE)
                 ||  (l_token_item->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE)) {
-                if (!s_chain_ledger_token_tsd_check(l_token_item, (dap_chain_datum_token_emission_t *)a_token_emission)) {
+                if (!s_ledger_token_tsd_check(l_token_item, (dap_chain_datum_token_emission_t *)a_token_emission)) {
                     DAP_DELETE(l_token_emission_item->datum_token_emission);
                     DAP_DELETE(l_token_emission_item);
-                    return DAP_CHAIN_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED;
+                    return DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED;
                 }
             }
             //Update value in ledger memory object
-            if (!IS_ZERO_256(l_token_item->total_supply)) {
-                uint256_t l_emission_value = l_token_emission_item->datum_token_emission->hdr.value_256;
-                if (compare256(l_token_item->current_supply, l_emission_value) >= 0){
-                    SUBTRACT_256_256(l_token_item->current_supply, l_emission_value, &l_token_item->current_supply);
-                    char *l_balance = dap_chain_balance_print(l_token_item->current_supply);
-                    log_it(L_DEBUG,"New current supply %s for token %s", l_balance, l_token_item->ticker);
-                    DAP_DELETE(l_balance);
-                } else {
-                    char *l_balance = dap_chain_balance_print(l_token_item->current_supply);
-                    char *l_value = dap_chain_balance_print(l_emission_value);
-
-                    log_it(L_WARNING,"Token %s current supply %s < emission value %s",
-                                        l_token_item->ticker, l_balance, l_value);
-                    DAP_DELETE(l_balance);
-                    DAP_DELETE(l_value);
-                    DAP_DELETE(l_token_emission_item->datum_token_emission);
-                    DAP_DELETE(l_token_emission_item);
-                    return DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY;
-                }
-                if (PVT(a_ledger)->cached)
-                    s_ledger_token_cache_update(a_ledger, l_token_item);
+            if (!s_ledger_token_supply_check_update(a_ledger, l_token_item,
+                                                    l_token_emission_item->datum_token_emission->hdr.value)) {
+                DAP_DELETE(l_token_emission_item->datum_token_emission);
+                DAP_DELETE(l_token_emission_item);
+                return DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY;
             }
 
             pthread_rwlock_wrlock(&l_token_item->token_emissions_rwlock);
             HASH_ADD(hh, l_token_item->token_emissions, datum_token_emission_hash,
                      sizeof(*a_emission_hash), l_token_emission_item);
             pthread_rwlock_unlock(&l_token_item->token_emissions_rwlock);
-            if (PVT(a_ledger)->cached)
-                // Add it to cache
-                s_ledger_emission_cache_update(a_ledger, l_token_emission_item);
-            if(s_debug_more) {
+            // Add it to cache
+            s_ledger_emission_cache_update(a_ledger, l_token_emission_item);
+            if (s_debug_more) {
                 char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_emission_item->datum_token_emission->hdr.address));
-                char *l_balance = dap_chain_balance_to_coins(l_token_emission_item->datum_token_emission->hdr.value_256);
+                char *l_balance = dap_chain_balance_to_coins(l_token_emission_item->datum_token_emission->hdr.value);
                 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, l_token_emission_address_str);
@@ -2903,22 +2847,23 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e
         } else if (HASH_COUNT(l_ledger_pvt->threshold_emissions) < s_threshold_emissions_max) {
             l_token_emission_item->datum_token_emission = DAP_DUP_SIZE(a_token_emission, a_token_emission_size);
             l_token_emission_item->datum_token_emission_size = a_token_emission_size;
-            if(a_safe_call) pthread_rwlock_wrlock(&l_ledger_pvt->threshold_emissions_rwlock);
+            pthread_rwlock_wrlock(&l_ledger_pvt->threshold_emissions_rwlock);
             l_token_emission_item->ts_added = dap_nanotime_now();
             dap_chain_hash_fast_t l_emi_hash = {0};
             dap_hash_fast(a_token_emission, a_token_emission_size, &l_emi_hash);
             l_token_emission_item->datum_token_emission_hash = l_emi_hash;
             HASH_ADD(hh, l_ledger_pvt->threshold_emissions, datum_token_emission_hash,
                      sizeof(*a_emission_hash), l_token_emission_item);
-            if(a_safe_call) pthread_rwlock_unlock(&l_ledger_pvt->threshold_emissions_rwlock);
+            pthread_rwlock_unlock(&l_ledger_pvt->threshold_emissions_rwlock);
             l_ret = -5;
-            if(s_debug_more) {
+            if (s_debug_more) {
                 char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_emission_item->datum_token_emission->hdr.address));
-                log_it(L_NOTICE, "Added token emission datum to emissions threshold: type=%s value=%.1Lf token=%s to_addr=%s ",
+                char *l_balance = dap_chain_balance_to_coins(l_token_emission_item->datum_token_emission->hdr.value);
+                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],
-                               dap_chain_datoshi_to_coins(l_token_emission_item->datum_token_emission->hdr.value),
-                               c_token_ticker, l_token_emission_address_str);
+                               l_balance, c_token_ticker, l_token_emission_address_str);
                 DAP_DELETE(l_token_emission_address_str);
+                DAP_DELETE(l_balance);
             }
         } else {
             DAP_DELETE(l_token_emission_item->datum_token_emission);
@@ -2926,7 +2871,7 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e
             if(s_debug_more)
                 log_it(L_WARNING,"threshold for emissions is overfulled (%zu max), dropping down new data, added nothing",
                    s_threshold_emissions_max);
-            l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW;
+            l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW;
         }
     } else {
         if (l_token_item) {
@@ -2934,34 +2879,35 @@ static inline int s_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_e
                 char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
                 dap_chain_hash_fast_to_str(a_emission_hash, l_hash_str, sizeof(l_hash_str));
                 if ( ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.version == 2 ) {
-                    char *l_balance = dap_chain_balance_print(((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value_256);
+                    char *l_balance = dap_chain_balance_print(((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value);
                     log_it(L_ERROR, "Duplicate token emission datum of %s %s ( %s )", l_balance, c_token_ticker, l_hash_str);
                     DAP_DELETE(l_balance);
-                }
-                else
+                } else
                     log_it(L_ERROR, "Duplicate token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s )",
-                            ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value, c_token_ticker, l_hash_str);
+                            ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value64, c_token_ticker, l_hash_str);
             }
         }
-        l_ret = DAP_CHAIN_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED;
+        l_ret = DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED;
     }
     return l_ret;
 }
 
-void s_ledger_stake_lock_cache_update(dap_ledger_t *a_ledger, dap_chain_ledger_stake_lock_item_t *a_stake_lock_item)
+void s_ledger_stake_lock_cache_update(dap_ledger_t *a_ledger, dap_ledger_stake_lock_item_t *a_stake_lock_item)
 {
+    if (!PVT(a_ledger)->cached)
+        return;
     char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
     dap_chain_hash_fast_to_str(&a_stake_lock_item->tx_for_stake_lock_hash, l_hash_str, sizeof(l_hash_str));
-    char *l_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_STAKE_LOCK_STR);
+    char *l_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_STAKE_LOCK_STR);
     if (dap_global_db_set(l_group, l_hash_str, &a_stake_lock_item->tx_used_out, sizeof(dap_hash_fast_t), false, NULL, NULL))
         log_it(L_WARNING, "Ledger cache mismatch");
     DAP_DEL_Z(l_group);
 }
 
-int dap_chain_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash)
+int dap_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash)
 {
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    dap_chain_ledger_stake_lock_item_t *l_new_stake_lock_emission;
+    dap_ledger_stake_lock_item_t *l_new_stake_lock_emission;
     pthread_rwlock_rdlock(&l_ledger_pvt->stake_lock_rwlock);
     HASH_FIND(hh, l_ledger_pvt->emissions_for_stake_lock, a_tx_hash, sizeof(dap_hash_fast_t),
               l_new_stake_lock_emission);
@@ -2969,10 +2915,10 @@ int dap_chain_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, co
     if (l_new_stake_lock_emission) {
         return -1;
     }
-    l_new_stake_lock_emission = DAP_NEW_Z(dap_chain_ledger_stake_lock_item_t);
+    l_new_stake_lock_emission = DAP_NEW_Z(dap_ledger_stake_lock_item_t);
     if (!l_new_stake_lock_emission) {
         if (s_debug_more) {
-            log_it(L_ERROR, "Error: memory allocation when try adding item 'dap_chain_ledger_stake_lock_item_t' to hash-table");
+            log_it(L_ERROR, "Error: memory allocation when try adding item 'dap_ledger_stake_lock_item_t' to hash-table");
         }
         return -13;
     }
@@ -2981,19 +2927,16 @@ int dap_chain_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, co
     HASH_ADD(hh, l_ledger_pvt->emissions_for_stake_lock, tx_for_stake_lock_hash, sizeof(dap_chain_hash_fast_t), l_new_stake_lock_emission);
     pthread_rwlock_unlock(&l_ledger_pvt->stake_lock_rwlock);
 
-    if (!l_new_stake_lock_emission)
-        debug_if(s_debug_more, L_ERROR, "Error: adding to hash-table. Be careful, there may be leaks");
-    else if (PVT(a_ledger)->cached)
-        s_ledger_stake_lock_cache_update(a_ledger, l_new_stake_lock_emission);
+    s_ledger_stake_lock_cache_update(a_ledger, l_new_stake_lock_emission);
 
     return 0;
 
 }
 
-dap_chain_ledger_stake_lock_item_t *s_emissions_for_stake_lock_item_find(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_token_emission_hash)
+dap_ledger_stake_lock_item_t *s_emissions_for_stake_lock_item_find(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_token_emission_hash)
 {
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    dap_chain_ledger_stake_lock_item_t *l_new_stake_lock_emission;
+    dap_ledger_stake_lock_item_t *l_new_stake_lock_emission;
     pthread_rwlock_rdlock(&l_ledger_pvt->stake_lock_rwlock);
     HASH_FIND(hh, l_ledger_pvt->emissions_for_stake_lock, a_token_emission_hash, sizeof(dap_chain_hash_fast_t),
               l_new_stake_lock_emission);
@@ -3002,12 +2945,12 @@ dap_chain_ledger_stake_lock_item_t *s_emissions_for_stake_lock_item_find(dap_led
 }
 
 
-int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission,
+int dap_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission,
                                          size_t a_token_emission_size, dap_hash_fast_t *a_token_emission_hash)
 {
     if (PVT(a_ledger)->load_mode) {
-        dap_chain_ledger_token_emission_item_t *l_token_emission_item;
-        dap_chain_ledger_token_item_t *l_token_item, *l_item_tmp;
+        dap_ledger_token_emission_item_t *l_token_emission_item;
+        dap_ledger_token_item_t *l_token_item, *l_item_tmp;
         pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
         HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_item_tmp) {
             pthread_rwlock_rdlock(&l_token_item->token_emissions_rwlock);
@@ -3028,63 +2971,59 @@ int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token
             return -5;
         }
     }
-    return dap_chain_ledger_token_emission_add(a_ledger, a_token_emission, a_token_emission_size, a_token_emission_hash, false);
+    return dap_ledger_token_emission_add(a_ledger, a_token_emission, a_token_emission_size, a_token_emission_hash, false);
 }
 
-char *dap_chain_ledger_token_emission_err_code_to_str(int a_code) {
-    return (a_code >= DAP_CHAIN_LEDGER_EMISSION_ADD_OK && a_code < DAP_CHAIN_LEDGER_EMISSION_ADD_UNKNOWN)
-            ? (char*)s_ledger_emission_add_err_str[(dap_chain_ledger_emission_err_code_t)a_code]
+char *dap_ledger_token_emission_err_code_to_str(int a_code) {
+    return (a_code >= DAP_LEDGER_EMISSION_ADD_OK && a_code < DAP_LEDGER_EMISSION_ADD_UNKNOWN)
+            ? (char*)s_ledger_emission_add_err_str[(dap_ledger_emission_err_code_t)a_code]
             : dap_itoa(a_code);
 }
 
-dap_chain_ledger_token_emission_item_t *s_emission_item_find(dap_ledger_t *a_ledger,
-                const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash)
+dap_ledger_token_emission_item_t *s_emission_item_find(dap_ledger_t *a_ledger,
+                const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash, dap_ledger_token_item_t **a_token_item)
 {
-    dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    dap_chain_ledger_token_item_t * l_token_item = NULL;
-    pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock);
-    HASH_FIND_STR(l_ledger_pvt->tokens, a_token_ticker, l_token_item);
-    pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock);
-
+    dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, a_token_ticker);
     if (!l_token_item)
         return NULL;
-    dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL;
+    else if (a_token_item)
+        *a_token_item = l_token_item;
+    dap_ledger_token_emission_item_t *l_token_emission_item = NULL;
     pthread_rwlock_rdlock(&l_token_item->token_emissions_rwlock);
-    HASH_FIND(hh, l_token_item->token_emissions, a_token_emission_hash, sizeof(*a_token_emission_hash),
-            l_token_emission_item);
+    HASH_FIND(hh, l_token_item->token_emissions, a_token_emission_hash, sizeof(*a_token_emission_hash), l_token_emission_item);
     pthread_rwlock_unlock(&l_token_item->token_emissions_rwlock);
     return l_token_emission_item;
 }
 
 /**
- * @brief dap_chain_ledger_token_emission_find
+ * @brief dap_ledger_token_emission_find
  * @param a_token_ticker
  * @param a_token_emission_hash
  * @return
  */
-dap_chain_datum_token_emission_t *dap_chain_ledger_token_emission_find(dap_ledger_t *a_ledger,
+dap_chain_datum_token_emission_t *dap_ledger_token_emission_find(dap_ledger_t *a_ledger,
         const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash)
 {
-    dap_chain_ledger_token_emission_item_t *l_emission_item = s_emission_item_find(a_ledger, a_token_ticker, a_token_emission_hash);
+    dap_ledger_token_emission_item_t *l_emission_item = s_emission_item_find(a_ledger, a_token_ticker, a_token_emission_hash, NULL);
     return l_emission_item ? l_emission_item->datum_token_emission : NULL;
 }
 
 /**
- * @brief dap_chain_ledger_set_local_cell_id
+ * @brief dap_ledger_set_local_cell_id
  * @param a_local_cell_id
  */
-void dap_chain_ledger_set_local_cell_id(dap_ledger_t *a_ledger, dap_chain_cell_id_t a_local_cell_id)
+void dap_ledger_set_local_cell_id(dap_ledger_t *a_ledger, dap_chain_cell_id_t a_local_cell_id)
 {
     PVT(a_ledger)->local_cell_id.uint64 = a_local_cell_id.uint64;
 }
 
 /**
- * @brief dap_chain_ledger_tx_get_token_ticker_by_hash
+ * @brief dap_ledger_tx_get_token_ticker_by_hash
  * @param a_ledger
  * @param a_tx_hash
  * @return
  */
-const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,dap_chain_hash_fast_t *a_tx_hash)
+const char* dap_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,dap_chain_hash_fast_t *a_tx_hash)
 {
     if(!a_ledger || !a_tx_hash)
         return NULL;
@@ -3093,7 +3032,7 @@ const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,
     if ( dap_hash_fast_is_blank(a_tx_hash) )
         return NULL;
 
-    dap_chain_ledger_tx_item_t *l_item;
+    dap_ledger_tx_item_t *l_item;
     unsigned l_hash_value;
     HASH_VALUE(a_tx_hash, sizeof(*a_tx_hash), l_hash_value);
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
@@ -3103,16 +3042,16 @@ const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,
 }
 
 /**
- * @brief dap_chain_ledger_addr_get_token_ticker_all_depricated
+ * @brief dap_ledger_addr_get_token_ticker_all_depricated
  * @param a_addr
  * @param a_tickers
  * @param a_tickers_size
  */
-void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr,
+void dap_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr,
         char *** a_tickers, size_t * a_tickers_size)
 {
     dap_chain_hash_fast_t l_tx_first_hash = { 0 };
-    const dap_chain_ledger_tx_item_t * l_tx_item = tx_item_find_by_addr(a_ledger, a_addr,NULL, &l_tx_first_hash);
+    const dap_ledger_tx_item_t * l_tx_item = tx_item_find_by_addr(a_ledger, a_addr,NULL, &l_tx_first_hash);
     char ** l_tickers = NULL;
     size_t l_tickers_size = 10;
     size_t l_tickers_pos = 0;
@@ -3138,7 +3077,7 @@ void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledge
                     l_tickers_size += (l_tickers_size / 2);
                     l_tickers = DAP_REALLOC(l_tickers, l_tickers_size);
                     if ( !l_tickers ) {
-            log_it(L_CRITICAL, "Memory allocation error");
+                        log_it(L_CRITICAL, "Memory allocation error");
                         return;
                     }
                 }
@@ -3168,14 +3107,14 @@ void dap_chain_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledge
  * @param a_tickers
  * @param a_tickers_size
  */
-void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr,
+void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr,
         char *** a_tickers, size_t * a_tickers_size)
 {
     if (a_addr == NULL){ // Get all tockens
         pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
         size_t l_count = HASH_COUNT(PVT(a_ledger)->tokens);
         if (l_count && a_tickers){
-            dap_chain_ledger_token_item_t * l_token_item, *l_tmp;
+            dap_ledger_token_item_t * l_token_item, *l_tmp;
             char **l_tickers = DAP_NEW_Z_SIZE(char*, l_count * sizeof(char*));
             if (!l_tickers) {
                 log_it(L_CRITICAL, "Memory allocation error");
@@ -3229,7 +3168,7 @@ void dap_chain_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chai
  * return transaction, or NULL if transaction not found in the cache
  */
 static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger,
-        dap_chain_hash_fast_t *a_tx_hash, dap_chain_ledger_tx_item_t **a_item_out, bool a_unspent_only)
+        dap_chain_hash_fast_t *a_tx_hash, dap_ledger_tx_item_t **a_item_out, bool a_unspent_only)
 {
     if(!a_tx_hash)
         return NULL;
@@ -3238,7 +3177,7 @@ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger,
 
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
     dap_chain_datum_tx_t *l_tx_ret = NULL;
-    dap_chain_ledger_tx_item_t *l_tx_item;
+    dap_ledger_tx_item_t *l_tx_item;
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
     HASH_FIND(hh, l_ledger_pvt->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item);
     pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
@@ -3253,27 +3192,27 @@ static dap_chain_datum_tx_t* s_find_datum_tx_by_hash(dap_ledger_t *a_ledger,
 }
 
 /**
- * @brief dap_chain_ledger_tx_find_by_hash
+ * @brief dap_ledger_tx_find_by_hash
  * @param a_tx_hash
  * @return
  */
 
-dap_chain_datum_tx_t *dap_chain_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash)
+dap_chain_datum_tx_t *dap_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash)
 {
     return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL, true);
 }
 
-dap_chain_datum_tx_t *dap_chain_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash)
+dap_chain_datum_tx_t *dap_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash)
 {
     return s_find_datum_tx_by_hash(a_ledger, a_tx_hash, NULL, false);
 }
 
-dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash)
+dap_hash_fast_t *dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash)
 {
     if (!a_ledger || !a_tx_hash || dap_hash_fast_is_blank(a_tx_hash))
         return NULL;
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    dap_chain_ledger_tx_item_t *l_item;
+    dap_ledger_tx_item_t *l_item;
     unsigned l_hash_value;
     dap_chain_hash_fast_t *l_tx_hash = a_tx_hash;
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
@@ -3299,7 +3238,7 @@ dap_hash_fast_t *dap_chain_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger
 /**
  * Check whether used 'out' items (local function)
  */
-static bool s_ledger_tx_hash_is_used_out_item(dap_chain_ledger_tx_item_t *a_item, int a_idx_out, dap_hash_fast_t *a_out_spender_hash)
+static bool s_ledger_tx_hash_is_used_out_item(dap_ledger_tx_item_t *a_item, int a_idx_out, dap_hash_fast_t *a_out_spender_hash)
 {
     if (!a_item || !a_item->cache_data.n_outs) {
         //log_it(L_DEBUG, "list_cached_item is NULL");
@@ -3319,15 +3258,30 @@ static bool s_ledger_tx_hash_is_used_out_item(dap_chain_ledger_tx_item_t *a_item
     return false;
 }
 
+static dap_ledger_reward_item_t *s_find_reward(dap_ledger_t *a_ledger, dap_ledger_reward_key_t *a_search_key)
+{
+    dap_ledger_reward_item_t *l_reward_item = NULL;
+    pthread_rwlock_rdlock(&PVT(a_ledger)->rewards_rwlock);
+    HASH_FIND(hh, PVT(a_ledger)->rewards, a_search_key, sizeof(*a_search_key), l_reward_item);
+    pthread_rwlock_unlock(&PVT(a_ledger)->rewards_rwlock);
+    return l_reward_item;
+}
+
+bool dap_ledger_is_used_reward(dap_ledger_t *a_ledger, dap_hash_fast_t *a_block_hash, dap_hash_fast_t *a_sign_pkey_hash)
+{
+    dap_ledger_reward_key_t l_search_key = { .block_hash = *a_block_hash, .sign_pkey_hash = *a_sign_pkey_hash };
+    return s_find_reward(a_ledger, &l_search_key);
+}
+
 /**
- * @brief dap_chain_ledger_permissions_check
+ * @brief dap_ledger_permissions_check
  * @param a_token_item
  * @param a_permission_id
  * @param a_data
  * @param a_data_size
  * @return
  */
-static int s_ledger_permissions_check(dap_chain_ledger_token_item_t *  a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size )
+static int s_ledger_permissions_check(dap_ledger_token_item_t *  a_token_item, uint16_t a_permission_id, const void * a_data,size_t a_data_size )
 {
     dap_chain_addr_t * l_addrs = NULL;
     size_t l_addrs_count =0;
@@ -3402,8 +3356,8 @@ bool s_tx_match_sign(dap_chain_datum_token_emission_t *a_datum_emission, dap_cha
     // For each emission signs
     for(int l_sign_em_num = 0; l_sign_em_num < l_emission_sign_num && l_emission_sign_offset < l_emission_size; l_sign_em_num++) {
         // For each tx signs
-        for(dap_list_t *l_list_tmp = l_list_sig; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp)) {
-            dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) l_list_tmp->data;
+        for(dap_list_t *it = l_list_sig; it; it = dap_list_next(it)) {
+            dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) it->data;
             // Get sign from sign item
             dap_sign_t *l_tx_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*) l_tx_sig);
             // Compare signs
@@ -3432,13 +3386,21 @@ static int s_callback_sign_compare(dap_list_t *a_list_elem, dap_list_t *a_sign_e
     return !dap_pkey_match_sign(l_key, l_sign);
 }
 
-bool dap_chain_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx)
+bool dap_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx)
 {
     dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
     dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig);
-    return dap_list_find(PVT(a_ledger)->poa_certs, l_sign, s_callback_sign_compare);
+    return dap_list_find(a_ledger->net->pub.keys, l_sign, s_callback_sign_compare);
 }
 
+inline static bool s_ledger_check_token_ticker(const char *a_ticker)
+{
+    const char *c = a_ticker;
+    for (int i = 0; i < DAP_CHAIN_TICKER_SIZE_MAX; i++, c++)
+        if (*c == '\0')
+            return true;
+    return false;
+}
 
 /**
  * Checking a new transaction before adding to the cache
@@ -3446,11 +3408,15 @@ bool dap_chain_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
  * return 0 OK, otherwise error
  */
 // Checking a new transaction before adding to the cache
-int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash,
+int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash,
                                     bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker)
 {
+    if (!a_tx) {
+        log_it(L_DEBUG, "NULL transaction, check broken");
+        return DAP_LEDGER_TX_CHECK_NULL_TX;
+    }
     if (!PVT(a_ledger)->load_mode && !a_from_threshold) {
-        dap_chain_ledger_tx_item_t *l_ledger_item;
+        dap_ledger_tx_item_t *l_ledger_item;
         pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock);
         HASH_FIND(hh, PVT(a_ledger)->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_ledger_item);
         pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock);
@@ -3460,16 +3426,16 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                 dap_chain_hash_fast_to_str(a_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
                 log_it(L_WARNING, "Transaction %s already present in the cache", l_tx_hash_str);
             }
-            return DAP_CHAIN_LEDGER_TX_ALREADY_CACHED;
+            return DAP_LEDGER_TX_ALREADY_CACHED;
         }
     }
 /*
  * Steps of checking for current transaction tx2 and every previous transaction tx1:
  * 1. valid(tx2.dap_chain_datum_tx_sig.pkey)
  * &&
- * 2. !is_used_out(tx1.dap_chain_datum_tx_out)
+ * 2. tx2.input != tx2.inputs.used
  * &&
- * 3. tx1.output != tx2.bound_items.outputs.used
+ * 3. !is_used_out(tx1.dap_chain_datum_tx_out)
  * &&
  * 4. tx1.dap_chain_datum_tx_out.addr.data.key == tx2.dap_chain_datum_tx_sig.pkey for unconditional output
  * \\
@@ -3479,117 +3445,78 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
  * &&
  * 7. valid(fee)
 */
-    dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    if(!a_tx){
-        log_it(L_DEBUG, "NULL transaction, check broken");
-        return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NULL_TX;
-    }
 
     dap_list_t *l_list_bound_items = NULL;
-
-    dap_list_t* l_list_tx_out = NULL;
-    if (a_list_tx_out)
-        *a_list_tx_out = l_list_tx_out;
+    dap_list_t *l_list_tx_out = NULL;
 
     // sum of values in 'out' items from the previous transactions
-    dap_chain_ledger_tokenizer_t *l_values_from_prev_tx = NULL, *l_values_from_cur_tx = NULL,
+    dap_ledger_tokenizer_t *l_values_from_prev_tx = NULL, *l_values_from_cur_tx = NULL,
                                  *l_value_cur = NULL, *l_tmp = NULL, *l_res = NULL;
     const char *l_token = NULL, *l_main_ticker = NULL;
-    dap_chain_ledger_token_item_t * l_token_item = NULL;
-    dap_chain_hash_fast_t *l_emission_hash = NULL;
 
-    // check all previous transactions
-    int l_err_num = DAP_CHAIN_LEDGER_TX_CHECK_OK;
+    int l_err_num = DAP_LEDGER_TX_CHECK_OK;
     int l_prev_tx_count = 0;
 
     // 1. Verify signature in current transaction
     if (!a_from_threshold && dap_chain_datum_tx_verify_sign(a_tx) != 1)
-        return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_INVALID_TX_SIGN;
+        return DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN;
 
     // ----------------------------------------------------------------
-    // find all 'in' & conditional 'in' items in current transaction
-    dap_list_t *l_list_in = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_IN_ALL,
-                                                          &l_prev_tx_count);
+    // find all 'in' && 'in_cond' && 'in_ems' && 'in_reward'  items in current transaction
+    dap_list_t *l_list_in = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_IN_ALL, &l_prev_tx_count);
     if (!l_list_in) {
         log_it(L_WARNING, "Tx check: no valid inputs found");
-        return DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TX_NO_VALID_INPUTS;
+        return DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS;
     }
-    dap_chain_ledger_tx_bound_t *bound_item;
-    dap_chain_hash_fast_t l_hash_pkey = {};
+    dap_chain_hash_fast_t l_tx_first_sign_pkey_hash = {};
+    dap_pkey_t *l_tx_first_sign_pkey = NULL;
     bool l_girdled_ems_used = false;
-     // find all previous transactions
-    dap_list_t *l_list_tmp = l_list_in;
-    for (int l_list_tmp_num = 0; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_list_tmp_num++) {
-        bound_item = DAP_NEW_Z(dap_chain_ledger_tx_bound_t);
-        if (!bound_item) {
-        log_it(L_CRITICAL, "Memory allocation error");
-            if ( l_list_bound_items )
-                dap_list_free_full(l_list_bound_items, NULL);
-            if (l_list_tx_out)
-                dap_list_free(l_list_tx_out);
-            HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) {
-                HASH_DEL(l_values_from_prev_tx, l_value_cur);
-                DAP_DELETE(l_value_cur);
-            }
-            HASH_ITER(hh, l_values_from_cur_tx, l_value_cur, l_tmp) {
-                HASH_DEL(l_values_from_cur_tx, l_value_cur);
-                DAP_DELETE(l_value_cur);
-            }
-            return -1;
-        }
-        dap_chain_tx_in_t *l_tx_in = NULL;
-        dap_chain_addr_t l_tx_in_from={0};
-        dap_chain_tx_in_cond_t *l_tx_in_cond = NULL;
-        dap_chain_tx_in_ems_t * l_tx_in_ems = NULL;
-        dap_chain_hash_fast_t l_tx_prev_hash={0};
-        uint8_t l_cond_type = *(uint8_t *)l_list_tmp->data;
-        // one of the previous transaction
-        switch (l_cond_type) {
-        case TX_ITEM_TYPE_IN:
-            l_tx_in = (dap_chain_tx_in_t *)l_list_tmp->data;
-            l_tx_prev_hash = l_tx_in->header.tx_prev_hash;
-            bound_item->in.tx_cur_in = l_tx_in;
-            if (dap_hash_fast_is_blank(&l_tx_prev_hash))
-                continue; // old base tx compliance
-            break;
-        case TX_ITEM_TYPE_IN_COND:
-            l_tx_in_cond = (dap_chain_tx_in_cond_t *)l_list_tmp->data;
-            l_tx_prev_hash = l_tx_in_cond->header.tx_prev_hash;
-            bound_item->in.tx_cur_in_cond = l_tx_in_cond;
-            break;
-        case TX_ITEM_TYPE_IN_EMS:
-            l_tx_in_ems = (dap_chain_tx_in_ems_t *)l_list_tmp->data;
-            l_tx_prev_hash =l_tx_in_ems->header.token_emission_hash;
-            bound_item->in.tx_cur_in_ems = l_tx_in_ems;
-            break;
-        default:
+
+    // find all previous transactions
+    for (dap_list_t *it = l_list_in; it; it = it->next) {
+         dap_ledger_tx_bound_t *l_bound_item = DAP_NEW_Z(dap_ledger_tx_bound_t);
+        if (!l_bound_item) {
+            log_it(L_CRITICAL, "Memory allocation error");
+            l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM;
             break;
         }
-        bound_item->tx_prev_hash = l_tx_prev_hash;
+        l_list_bound_items = dap_list_append(l_list_bound_items, l_bound_item);
 
-        char l_tx_prev_hash_str[70]={[0]='\0'};
-        dap_chain_hash_fast_to_str(&l_tx_prev_hash, l_tx_prev_hash_str, sizeof(l_tx_prev_hash_str));
-        uint256_t l_value;
+        uint8_t l_cond_type = *(uint8_t *)it->data;
+        l_bound_item->type = l_cond_type;
+        uint256_t l_value = uint256_0;
         void *l_tx_prev_out = NULL;
         dap_chain_datum_tx_t *l_tx_prev = NULL;
-        dap_chain_ledger_token_emission_item_t *l_emission_item = NULL;
-        dap_chain_ledger_stake_lock_item_t *l_stake_lock_emission = NULL;
+        dap_ledger_token_emission_item_t *l_emission_item = NULL;
+        dap_ledger_stake_lock_item_t *l_stake_lock_emission = NULL;
         bool l_girdled_ems = false;
-        if (l_cond_type == TX_ITEM_TYPE_IN_EMS) {   // It's the emission (base) TX
+
+        switch (l_cond_type) {
+        case TX_ITEM_TYPE_IN_EMS: {   // It's the emission (base) TX
+            dap_chain_tx_in_ems_t *l_tx_in_ems = it->data;
             l_token = l_tx_in_ems->header.ticker;
-            l_emission_hash = &l_tx_in_ems->header.token_emission_hash;
-            if ( (l_emission_item = s_emission_item_find(a_ledger, l_token, l_emission_hash)) ) {
-                // check AUTH token emission
-                if (!dap_hash_fast_is_blank(&l_emission_item->tx_used_out)) {
-                    debug_if(s_debug_more, L_WARNING, "Emission for IN_EMS [%s] is already used", l_tx_in_ems->header.ticker);
-                    l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_IN_EMS_ALREADY_USED;
+            if (!s_ledger_check_token_ticker(l_token)) {
+                l_err_num = DAP_LEDGER_TX_CHECK_INVALID_TICKER;
+                break;
+            }
+            dap_hash_fast_t *l_emission_hash = &l_tx_in_ems->header.token_emission_hash;
+            // 2. Check current transaction for doubles in input items list
+            for (dap_list_t *l_iter = l_list_in; l_iter; l_iter = l_iter->next) {
+                dap_chain_tx_in_ems_t *l_in_ems_check = l_iter->data;
+                if (l_tx_in_ems != l_in_ems_check &&
+                        l_in_ems_check->header.type == TX_ITEM_TYPE_IN_EMS &&
+                        dap_hash_fast_compare(&l_in_ems_check->header.token_emission_hash, l_emission_hash)) {
+                    debug_if(s_debug_more, L_ERROR, "Emission output already used in current tx");
+                    l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX;
                     break;
                 }
-                bound_item->item_emission = l_emission_item;
-            } else if ((l_girdled_ems = dap_hash_fast_is_blank(l_emission_hash)) ||
-                            (l_stake_lock_emission = s_emissions_for_stake_lock_item_find(a_ledger, l_emission_hash))) {
+            }
+            if (l_err_num)
+                break;
+            if ((l_girdled_ems = dap_hash_fast_is_blank(l_emission_hash)) ||
+                    (l_stake_lock_emission = s_emissions_for_stake_lock_item_find(a_ledger, l_emission_hash))) {
                 dap_chain_datum_tx_t *l_tx_stake_lock = a_tx;
-                // check emission for STAKE_LOCK
+                // 3. Check emission for STAKE_LOCK
                 if (!dap_hash_fast_is_blank(l_emission_hash)) {
                     dap_hash_fast_t cur_tx_hash;
                     dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &cur_tx_hash);
@@ -3598,14 +3525,15 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                             debug_if(s_debug_more, L_WARNING, "stake_lock_emission already present in cache for IN_EMS [%s]", l_token);
                         else
                             debug_if(s_debug_more, L_WARNING, "stake_lock_emission is used out for IN_EMS [%s]", l_token);
-                        l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED;
+                        l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED;
                         break;
                     }
-                    l_tx_stake_lock = dap_chain_ledger_tx_find_by_hash(a_ledger, l_emission_hash);
+                    l_tx_stake_lock = dap_ledger_tx_find_by_hash(a_ledger, l_emission_hash);
                 } else {
-                    if (l_girdled_ems_used) {    // Only one allowed item with girdled emission
+                    // 2. The only allowed item with girdled emission
+                    if (l_girdled_ems_used) {
                         debug_if(s_debug_more, L_WARNING, "stake_lock_emission is used out for IN_EMS [%s]", l_token);
-                        l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_IN_EMS_ALREADY_USED;
+                        l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED;
                         break;
                     } else
                         l_girdled_ems_used = true;
@@ -3616,13 +3544,10 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                     break;
                 }
                 dap_tsd_t *l_tsd;
-                dap_chain_ledger_token_item_t *l_delegated_item = NULL;
-                pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock);
-                HASH_FIND_STR(PVT(a_ledger)->tokens, l_token, l_delegated_item);
-                pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
+                dap_ledger_token_item_t *l_delegated_item = s_ledger_find_token(a_ledger, l_token);
                 if (!l_delegated_item) {
                     debug_if(s_debug_more, L_WARNING, "Token [%s] not found", l_token);
-                    l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND;
+                    l_err_num = DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND;
                     break;
                 }
                 dap_chain_datum_token_t *l_datum_token = l_delegated_item->datum_token;
@@ -3631,13 +3556,13 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                                                   l_datum_token->header_native_decl.tsd_total_size,
                                                   DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK))) {
                     debug_if(s_debug_more, L_WARNING, "Token [%s] not valid for stake_lock transaction", l_token);
-                    l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_INVALID_TOKEN;
+                    l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN;
                     break;
                 }
                 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);
-                if (!dap_chain_ledger_token_ticker_check(a_ledger, (char*)l_tsd_section->ticker_token_from)) {
+                if (!dap_ledger_token_ticker_check(a_ledger, (char*)l_tsd_section->ticker_token_from)) {
                     debug_if(s_debug_more, L_WARNING, "Token [%s] not found", l_tsd_section->ticker_token_from);
-                    l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TICKER_NOT_FOUND;
+                    l_err_num = DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND;
                     break;
                 }
 
@@ -3647,7 +3572,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                 dap_chain_tx_out_cond_t *l_tx_stake_lock_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_stake_lock, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, NULL);
                 if (!l_tx_stake_lock_out_cond) {
                     debug_if(s_debug_more, L_WARNING, "No OUT_COND of stake_lock subtype for IN_EMS [%s]", l_tx_in_ems->header.ticker);
-                    l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS;
+                    l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS;
                     break;
                 }
                 uint256_t l_value_expected ={};
@@ -3660,7 +3585,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                         DAP_DEL_Z(l_emission_rate_str);
                         DAP_DEL_Z(l_locked_value_str);
                     }
-                    l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_MULT256_OVERFLOW_EMS_LOCKED_X_RATE;
+                    l_err_num = DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE;
                     break;
                 }
                 dap_chain_tx_out_ext_t *l_tx_out_ext = NULL;
@@ -3671,7 +3596,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                     if (!l_tx_out_ext) {
                         if (l_girdled_ems) {
                             debug_if(s_debug_more, L_WARNING, "No OUT_EXT for girdled IN_EMS [%s]", l_tx_in_ems->header.ticker);
-                            l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS;
+                            l_err_num = DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS;
                         }
                         break;
                     }
@@ -3681,21 +3606,14 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                     dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_OUT, NULL);
                     if (!l_tx_out) {
                         debug_if(true, L_WARNING, "Can't find OUT nor OUT_EXT item for base TX with IN_EMS [%s]", l_tx_in_ems->header.ticker);
-                        l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_NO_OUT_ITEMS_FOR_BASE_TX;
+                        l_err_num = DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX;
                         break;
                     } else
                         l_stake_lock_ems_value = l_tx_out->header.value;
                 } else
                     l_stake_lock_ems_value = l_tx_out_ext->header.value;
-                if (!IS_ZERO_256(l_delegated_item->total_supply) &&
-                        compare256(l_delegated_item->current_supply, l_stake_lock_ems_value) < 0) {
-                    char *l_balance = dap_chain_balance_print(l_delegated_item->current_supply);
-                    char *l_value_ch = dap_chain_balance_print(l_stake_lock_ems_value);
-                    log_it(L_WARNING, "Token current supply %s < emission value %s",
-                           l_balance, l_value_ch);
-                    DAP_DEL_Z(l_balance);
-                    DAP_DEL_Z(l_value_ch);
-                    l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY;
+                if (!s_ledger_token_supply_check(l_delegated_item, l_stake_lock_ems_value)) {
+                    l_err_num = DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY;
                     break;
                 }
                 if (!EQUAL_256(l_value_expected, l_stake_lock_ems_value)) {
@@ -3710,58 +3628,189 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
 
                             DAP_DEL_Z(l_value_expected_str);
                             DAP_DEL_Z(l_locked_value_str);
-                            l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_UNEXPECTED_VALUE;
+                            l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE;
                             break;
                     }
                 }
                 if (!l_girdled_ems) {
                     // check tiker
-                    const char *l_tx_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, l_emission_hash);
+                    const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_ledger, l_emission_hash);
                     if (!l_tx_ticker) {
                         debug_if(s_debug_more, L_WARNING, "No ticker found for stake_lock tx [expected '%s']", l_tx_in_ems->header.ticker);
-                        l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_TICKER_NOT_FOUND;
+                        l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND;
                         break;
                     }
                     if (strcmp(l_tx_ticker, (char *)l_tsd_section->ticker_token_from)) {
                         debug_if(s_debug_more, L_WARNING, "Ticker '%s' != expected '%s'", l_tx_ticker, l_tx_in_ems->header.ticker);
-                        l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_STAKE_LOCK_OTHER_TICKER_EXPECTED;
+                        l_err_num = DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED;
                         break;
                     }
                 }
                 debug_if(s_debug_more, L_NOTICE, "Check emission passed for IN_EMS [%s]", l_tx_in_ems->header.ticker);
-                bound_item->tx_prev = l_tx_stake_lock;
                 if (l_stake_lock_emission) {
-                    bound_item->stake_lock_item = l_stake_lock_emission;
-                    bound_item->stake_lock_item->ems_value = l_value_expected;
+                    l_bound_item->stake_lock_item = l_stake_lock_emission;
+                    l_value = l_stake_lock_ems_value;
                 } else // girdled emission
-                    bound_item->out.tx_prev_out_ext_256 = l_tx_out_ext;
+                    l_value = l_tx_out_ext->header.value;
+                l_bound_item->token_item = l_delegated_item;
+                l_bound_item->type = TX_ITEM_TYPE_IN_EMS_LOCK;
+            } else if ( (l_emission_item = s_emission_item_find(a_ledger, l_token, l_emission_hash, &l_bound_item->token_item)) ) {
+                // 3. Check AUTH token emission
+                if (!dap_hash_fast_is_blank(&l_emission_item->tx_used_out)) {
+                    debug_if(s_debug_more, L_WARNING, "Emission for IN_EMS [%s] is already used", l_tx_in_ems->header.ticker);
+                    l_err_num = DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED;
+                    break;
+                }
+                l_value = l_emission_item->datum_token_emission->hdr.value;
+                l_bound_item->emission_item = l_emission_item;
             } else {
                 l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION;
                 break;
             }
-        } else { //It's not the emission TX
+        } break;
+
+        case TX_ITEM_TYPE_IN_REWARD: {
+            dap_chain_tx_in_reward_t *l_tx_in_reward = it->data;
+            dap_hash_fast_t *l_block_hash = &l_tx_in_reward->block_hash;
+            // 2. Check current transaction for doubles in input items list
+            for (dap_list_t *l_iter = l_list_in; l_iter; l_iter = l_iter->next) {
+                dap_chain_tx_in_reward_t *l_in_reward_check = l_iter->data;
+                if (l_tx_in_reward != l_in_reward_check &&
+                        l_in_reward_check->type == TX_ITEM_TYPE_IN_REWARD &&
+                        dap_hash_fast_compare(&l_in_reward_check->block_hash, l_block_hash)) {
+                    debug_if(s_debug_more, L_ERROR, "Reward for this block sign already used in current tx");
+                    l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX;
+                    break;
+                }
+            }
+            if (l_err_num)
+                break;
+            if (!l_tx_first_sign_pkey) {
+                // Get sign item
+                dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL,
+                        TX_ITEM_TYPE_SIG, NULL);
+                assert(l_tx_sig);
+                // Get sign from sign item
+                dap_sign_t *l_tx_first_sign = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig);
+                assert(l_tx_first_sign);
+                // calculate hash from sign public key
+                dap_sign_get_pkey_hash(l_tx_first_sign, &l_tx_first_sign_pkey_hash);
+                l_tx_first_sign_pkey = dap_pkey_get_from_sign(l_tx_first_sign);
+            }
+            // 3. Check if already spent reward
+            dap_ledger_reward_key_t l_search_key = { .block_hash = *l_block_hash, .sign_pkey_hash = l_tx_first_sign_pkey_hash };
+            dap_ledger_reward_item_t *l_reward_item = s_find_reward(a_ledger, &l_search_key);
+            if (l_reward_item) {
+                l_err_num = DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED;
+                char l_block_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE],
+                     l_sign_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE],
+                     l_spender_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+                dap_chain_hash_fast_to_str(l_block_hash, l_block_hash_str, sizeof(l_block_hash_str));
+                dap_chain_hash_fast_to_str(&l_tx_first_sign_pkey_hash, l_sign_hash_str, sizeof(l_sign_hash_str));
+                dap_chain_hash_fast_to_str(&l_reward_item->spender_tx, l_spender_hash_str, sizeof(l_spender_hash_str));
+                debug_if(s_debug_more, L_WARNING, "Reward for block %s sign %s already spent by %s", l_block_hash_str, l_sign_hash_str, l_spender_hash_str);
+                break;
+            }
+            // Check reward legitimacy & amount
+            dap_chain_t *l_chain;
+            DL_FOREACH(a_ledger->net->pub.chains, l_chain) {
+                if (l_chain->callback_calc_reward) {
+                    l_value = l_chain->callback_calc_reward(l_chain, l_block_hash, l_tx_first_sign_pkey);
+                    break;
+                }
+            }
+            if (IS_ZERO_256(l_value)) {
+                l_err_num = DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL;
+                char l_block_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE],
+                     l_sign_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+                dap_chain_hash_fast_to_str(l_block_hash, l_block_hash_str, sizeof(l_block_hash_str));
+                dap_chain_hash_fast_to_str(&l_tx_first_sign_pkey_hash, l_sign_hash_str, sizeof(l_sign_hash_str));
+                debug_if(s_debug_more, L_DEBUG, "Can't find block %s with sign %s", l_block_hash_str, l_sign_hash_str);
+                break;
+            }
+            // Reward nominated in net native ticker only
+            l_token = l_main_ticker = a_ledger->net->pub.native_ticker;
+            dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token);
+            if (!l_token_item) {
+                debug_if(s_debug_more, L_ERROR, "Native token ticker not found");
+                l_err_num = DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND;
+                break;
+            }
+            if (!s_ledger_token_supply_check(l_token_item, l_value)) {
+                l_err_num = DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY;
+                break;
+            }
+            l_bound_item->token_item = l_token_item;
+            l_bound_item->reward_key = l_search_key;
+        } break;
+
+        case TX_ITEM_TYPE_IN:
+        case TX_ITEM_TYPE_IN_COND: { // Not emission types
+            uint32_t l_idx = (uint32_t)-1;
+            dap_hash_fast_t *l_tx_prev_hash;
+            if (l_cond_type == TX_ITEM_TYPE_IN) {
+                dap_chain_tx_in_t *l_tx_in = it->data;
+                l_tx_prev_hash = &l_tx_in->header.tx_prev_hash;
+                if (dap_hash_fast_is_blank(l_tx_prev_hash)) {
+                    DAP_DELETE(l_bound_item);
+                    continue; // old base tx compliance
+                }
+                l_idx = l_tx_in->header.tx_out_prev_idx;
+                // 2. Check current transaction for doubles in input items list
+                for (dap_list_t *l_iter = l_list_in; l_iter; l_iter = l_iter->next) {
+                    dap_chain_tx_in_t *l_in_check = l_iter->data;
+                    if (l_tx_in != l_in_check &&
+                            l_in_check->header.type == TX_ITEM_TYPE_IN &&
+                            l_in_check->header.tx_out_prev_idx == l_idx &&
+                            dap_hash_fast_compare(&l_in_check->header.tx_prev_hash, l_tx_prev_hash)) {
+                        debug_if(s_debug_more, L_ERROR, "This previous tx output already used in current tx");
+                        l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX;
+                        break;
+                    }
+                }
+                if (l_err_num)
+                    break;
+            } else {
+                dap_chain_tx_in_cond_t *l_tx_in_cond = it->data;
+                l_tx_prev_hash = &l_tx_in_cond->header.tx_prev_hash;
+                l_idx = l_tx_in_cond->header.tx_out_prev_idx;
+                // 2. Check current transaction for doubles in input items list
+                for (dap_list_t *l_iter = l_list_in; l_iter; l_iter = l_iter->next) {
+                    dap_chain_tx_in_cond_t *l_in_cond_check = l_iter->data;
+                    if (l_tx_in_cond != l_in_cond_check &&
+                            l_in_cond_check->header.type == TX_ITEM_TYPE_IN_COND &&
+                            l_in_cond_check->header.tx_out_prev_idx == l_idx &&
+                            dap_hash_fast_compare(&l_in_cond_check->header.tx_prev_hash, l_tx_prev_hash)) {
+                        debug_if(s_debug_more, L_ERROR, "This previous tx output already used in current tx");
+                        l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX;
+                        break;
+                    }
+                }
+                if (l_err_num)
+                    break;
+            }
             // Get previous transaction in the cache by hash
-            dap_chain_ledger_tx_item_t *l_item_out = NULL;
-            l_tx_prev = s_find_datum_tx_by_hash(a_ledger, &l_tx_prev_hash, &l_item_out, false);
+            dap_ledger_tx_item_t *l_item_out = NULL;
+            l_tx_prev = s_find_datum_tx_by_hash(a_ledger, l_tx_prev_hash, &l_item_out, false);
+            char l_tx_prev_hash_str[DAP_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(l_tx_prev_hash, l_tx_prev_hash_str, DAP_HASH_FAST_STR_SIZE);
             if (!l_tx_prev) { // Unchained transaction or previous TX was already spent and removed from ledger
                 debug_if(s_debug_more && !a_from_threshold, L_DEBUG, "No previous transaction was found for hash %s", l_tx_prev_hash_str);
                 l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS;
                 break;
             } else if (l_item_out->cache_data.ts_spent) {
-                l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED;
-                debug_if(s_debug_more, L_INFO, "All 'out' items of previous tx %s were already spent", l_tx_prev_hash_str);
+                l_err_num = DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED;
+                debug_if(s_debug_more, L_WARNING, "All 'out' items of previous tx %s were already spent", l_tx_prev_hash_str);
                 break;
             }
-            bound_item->item_out = l_item_out;
+            l_bound_item->prev_item = l_item_out;
             l_token = l_item_out->cache_data.token_ticker;
             debug_if(s_debug_more && !a_from_threshold, L_INFO, "Previous transaction was found for hash %s",l_tx_prev_hash_str);
-            bound_item->tx_prev = l_tx_prev;
 
             // 2. Check if out in previous transaction has spent
-            int l_idx = (l_cond_type == TX_ITEM_TYPE_IN) ? l_tx_in->header.tx_out_prev_idx : l_tx_in_cond->header.tx_out_prev_idx;
             dap_hash_fast_t l_spender;
             if (s_ledger_tx_hash_is_used_out_item(l_item_out, l_idx, &l_spender)) {
-                l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_OUT_ITEM_ALREADY_USED;
+                l_err_num = DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED;
                 char l_hash[DAP_CHAIN_HASH_FAST_STR_SIZE];
                 dap_chain_hash_fast_to_str(&l_spender, l_hash, sizeof(l_hash));
                 debug_if(s_debug_more, L_INFO, "'Out' item of previous tx %s already spent by %s", l_tx_prev_hash_str, l_hash);
@@ -3771,191 +3820,166 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
             // Get one 'out' item in previous transaction bound with current 'in' item
             l_tx_prev_out = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_idx);
             if(!l_tx_prev_out) {
-                l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND;
+                l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND;
                 break;
             }
-            // 3. Compare out in previous transaction with currently used out
-            dap_list_t *l_bound_item;
-            DL_FOREACH(l_list_bound_items, l_bound_item) {
-                if (l_tx_prev_out == ((dap_chain_ledger_tx_bound_t*)l_bound_item->data)->out.tx_prev_out) {
-                    debug_if(s_debug_more, L_ERROR, "Previous transaction output already used in current tx");
-                    l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX;
+
+            if (l_cond_type == TX_ITEM_TYPE_IN) {
+                dap_chain_addr_t *l_addr_from = NULL;
+                dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_prev_out;
+                switch (l_type) {
+                case TX_ITEM_TYPE_OUT_OLD: // Deprecated
+                    l_addr_from = &((dap_chain_tx_out_old_t *)l_tx_prev_out)->addr;
+                    l_value = dap_chain_uint256_from(((dap_chain_tx_out_old_t *)l_tx_prev_out)->header.value);
+                    break;
+                case TX_ITEM_TYPE_OUT:
+                    l_addr_from = &((dap_chain_tx_out_t *)l_tx_prev_out)->addr;
+                    l_value = ((dap_chain_tx_out_t *)l_tx_prev_out)->header.value;
+                    break;
+                case TX_ITEM_TYPE_OUT_EXT:
+                    l_addr_from = &((dap_chain_tx_out_ext_t *)l_tx_prev_out)->addr;
+                    l_value = ((dap_chain_tx_out_ext_t *)l_tx_prev_out)->header.value;
+                    l_token = ((dap_chain_tx_out_ext_t *)l_tx_prev_out)->token;
+                    break;
+                default:
+                    l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_MISSTYPED;
+                    break;
+                }
+                if (l_err_num)
+                    break;
+                l_bound_item->in.addr_from = *l_addr_from;
+                strncpy(l_bound_item->in.token_ticker, l_token, DAP_CHAIN_TICKER_SIZE_MAX - 1);
+                // 4. compare public key hashes in the signature of the current transaction and in the 'out' item of the previous transaction
+                if (dap_hash_fast_is_blank(&l_tx_first_sign_pkey_hash)) {
+                    // Get sign item
+                    dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL,
+                            TX_ITEM_TYPE_SIG, NULL);
+                    assert(l_tx_sig);
+                    // Get sign from sign item
+                    dap_sign_t *l_tx_first_sign = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig);
+                    assert(l_tx_first_sign);
+                    // calculate hash from sign public key
+                    dap_sign_get_pkey_hash(l_tx_first_sign, &l_tx_first_sign_pkey_hash);
+                }
+                if (!dap_hash_fast_compare(&l_tx_first_sign_pkey_hash, &l_addr_from->data.hash_fast)) {
+                    l_err_num = DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH;
                     break;
                 }
-            }
-        }
-        if (l_err_num)
-            break;
-
-        if (l_cond_type == TX_ITEM_TYPE_IN) {
-            dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_prev_out;
-            dap_hash_fast_t *l_prev_out_addr_key = NULL;
-            switch (l_type) {
-            case TX_ITEM_TYPE_OUT_OLD:
-                bound_item->out.tx_prev_out = l_tx_prev_out;
-                l_tx_in_from = bound_item->out.tx_prev_out->addr;
-                l_prev_out_addr_key = &bound_item->out.tx_prev_out->addr.data.hash_fast;
-                l_value = dap_chain_uint256_from(bound_item->out.tx_prev_out->header.value);
-                break;
-            case TX_ITEM_TYPE_OUT: // 256
-                bound_item->out.tx_prev_out_256 = l_tx_prev_out;
-                l_tx_in_from = bound_item->out.tx_prev_out_256->addr;
-                l_prev_out_addr_key = &bound_item->out.tx_prev_out_256->addr.data.hash_fast;
-                l_value = bound_item->out.tx_prev_out_256->header.value;
-                break;
-            case TX_ITEM_TYPE_OUT_EXT: // 256
-                bound_item->out.tx_prev_out_ext_256 = l_tx_prev_out;
-                l_tx_in_from = bound_item->out.tx_prev_out_ext_256->addr;
-                l_prev_out_addr_key = &bound_item->out.tx_prev_out_ext_256->addr.data.hash_fast;
-                l_value = bound_item->out.tx_prev_out_ext_256->header.value;
-                l_token = bound_item->out.tx_prev_out_ext_256->token;
-                break;
-            default:
-                l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND;
-                break;
-            }
-            if (l_err_num)
-                break;
 
-            // 4. compare public key hashes in the signature of the current transaction and in the 'out' item of the previous transaction
-            if (dap_hash_fast_is_blank(&l_hash_pkey)) {
-                // Get sign item
-                dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL,
-                        TX_ITEM_TYPE_SIG, NULL);
-                // Get sign from sign item
-                dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig);
-                // calculate hash from sign public key
-                dap_sign_get_pkey_hash(l_sign, &l_hash_pkey);
-            }
-            if (!dap_hash_fast_compare(&l_hash_pkey, l_prev_out_addr_key)) {
-                l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PKEY_HASHES_DONT_MATCH;
-                break;
-            }
-        } else if(l_cond_type == TX_ITEM_TYPE_IN_COND) { // TX_ITEM_TYPE_IN_COND
-            if(*(uint8_t *)l_tx_prev_out != TX_ITEM_TYPE_OUT_COND) {
-                l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_OUT_ITEM_NOT_FOUND;
-                break;
-            }
-            // 5a. Check for condition owner
-            dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_tx_prev, NULL, TX_ITEM_TYPE_SIG, NULL);
-            dap_sign_t *l_prev_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_prev_sig);
-            dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
-            dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig);
-
-            dap_chain_tx_out_cond_t *l_tx_prev_out_cond = NULL;
-            l_tx_prev_out_cond = (dap_chain_tx_out_cond_t *)l_tx_prev_out;
-            if (l_tx_prev_out_cond->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE)
+                if ( !l_token || !*l_token ) {
+                    log_it(L_WARNING, "No token ticker found in previous transaction");
+                    l_err_num = DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND;
+                    break;
+                }
+                // Get permissions
+                dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token);
+                if (!l_token_item) {
+                    debug_if(s_debug_more, L_WARNING, "Token with ticker %s not found", l_token);
+                    l_err_num = DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND;
+                    break;
+                }
+                // Check permissions
+                if ( (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED ) ||  // If all is blocked - check if we're
+                     (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN) ){ // in white list
+
+                    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);
+                        debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)");
+                        DAP_DEL_Z(l_tmp_tx_in_from);
+                        l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED;
+                        break;
+                    }
+                }
+                if ((l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED ) || // If all is allowed - check if we're
+                    (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);
+                        debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)");
+                        DAP_DEL_Z(l_tmp_tx_in_from);
+                        l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED;
+                        break;
+                    }
+                }
+            } else { // l_cond_type == TX_ITEM_TYPE_IN_COND
+                if(*(uint8_t *)l_tx_prev_out != TX_ITEM_TYPE_OUT_COND) {
+                    l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_MISSTYPED;
+                    break;
+                }
+                // 5a. Check for condition owner
+                dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_tx_prev, NULL, TX_ITEM_TYPE_SIG, NULL);
+                dap_sign_t *l_prev_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_prev_sig);
+                dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
+                dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig);
+
+                dap_chain_tx_out_cond_t *l_tx_prev_out_cond = NULL;
+                l_tx_prev_out_cond = (dap_chain_tx_out_cond_t *)l_tx_prev_out;
+                if (l_tx_prev_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE)
+                    l_token = a_ledger->net->pub.native_ticker;
                 l_main_ticker = l_token;
-            else
-                l_token = l_main_ticker = l_ledger_pvt->net_native_ticker;
-
-            bool l_owner = false;
-            l_owner = dap_sign_match_pkey_signs(l_prev_sign,l_sign);
-
-            // 5b. Call verificator for conditional output
-            dap_chain_ledger_verificator_t *l_verificator;
-            int l_sub_tmp = l_tx_prev_out_cond->header.subtype;
-
-            pthread_rwlock_rdlock(&s_verificators_rwlock);
-            HASH_FIND_INT(s_verificators, &l_sub_tmp, l_verificator);
-            pthread_rwlock_unlock(&s_verificators_rwlock);
-            if (!l_verificator || !l_verificator->callback) {
-                debug_if(s_debug_more, L_ERROR, "No verificator set for conditional output subtype %d", l_sub_tmp);
-                l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_NO_VERIFICATOR_SET;
-                break;
-            }
-            if (l_verificator->callback(a_ledger, l_tx_prev_out_cond, a_tx, l_owner) == false) {
-                debug_if(s_debug_more, L_WARNING, "Verificator check error for conditional output %s",
-                                                    dap_chain_tx_out_cond_subtype_to_str(l_sub_tmp));
-                l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_VERIFICATOR_CHECK_FAILURE;
-                break;
-            }
-            // calculate sum of values from previous transactions
-            bound_item->out.tx_prev_out_cond_256 = l_tx_prev_out_cond;
-            l_value = l_tx_prev_out_cond->header.value;
-        } else if(l_cond_type == TX_ITEM_TYPE_IN_EMS) {
-            if (l_stake_lock_emission) {
-                l_token = bound_item->in.tx_cur_in_ems->header.ticker;
-                l_value = bound_item->stake_lock_item->ems_value;
-            } else if (l_girdled_ems) {
-                l_token = bound_item->in.tx_cur_in_ems->header.ticker;
-                l_value = bound_item->out.tx_prev_out_ext_256->header.value;
-            } else {
-                l_token = bound_item->item_emission->datum_token_emission->hdr.ticker;
-                l_value = bound_item->item_emission->datum_token_emission->hdr.value_256;
+                bool l_owner = false;
+                l_owner = dap_sign_match_pkey_signs(l_prev_sign, l_sign);
+
+                // 5b. Call verificator for conditional output
+                dap_ledger_verificator_t *l_verificator;
+                int l_sub_tmp = l_tx_prev_out_cond->header.subtype;
+
+                pthread_rwlock_rdlock(&s_verificators_rwlock);
+                HASH_FIND_INT(s_verificators, &l_sub_tmp, l_verificator);
+                pthread_rwlock_unlock(&s_verificators_rwlock);
+                if (!l_verificator || !l_verificator->callback) {
+                    debug_if(s_debug_more, L_ERROR, "No verificator set for conditional output subtype %d", l_sub_tmp);
+                    l_err_num = DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET;
+                    break;
+                }
+                if (l_verificator->callback(a_ledger, l_tx_prev_out_cond, a_tx, l_owner) == false) {
+                    debug_if(s_debug_more, L_WARNING, "Verificator check error for conditional output %s",
+                                                        dap_chain_tx_out_cond_subtype_to_str(l_sub_tmp));
+                    l_err_num = DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE;
+                    break;
+                }
+                l_bound_item->cond = l_tx_prev_out_cond;
+                l_value = l_tx_prev_out_cond->header.value;
             }
-        }
-        if (! l_token || !*l_token ) {
-            log_it(L_WARNING, "No token ticker found in previous transaction");
-            l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TICKER_NOT_FOUND;
+        } break;
+
+        default:
             break;
         }
-        // Get permissions
-        l_token_item = NULL;
-        pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock);
-        HASH_FIND_STR(l_ledger_pvt->tokens, l_token, l_token_item);
-        pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock);
-        if (! l_token_item){
-            if(s_debug_more)
-                log_it(L_WARNING, "No token item found for token %s", l_token);
-            l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_PREV_TOKEN_NOT_FOUND;
+        if (l_err_num)
             break;
-        }
-        // Check permissions
-        if ( (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED ) ||  // If all is blocked - check if we're
-             (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN) ){ // in white list
 
-            if(!dap_chain_addr_is_blank(&l_tx_in_from) && s_ledger_permissions_check(l_token_item,
-                                           DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD,&l_tx_in_from,
-                                          sizeof (l_tx_in_from)) != 0 ){
-                char * l_tmp_tx_in_from = dap_chain_addr_to_str(&l_tx_in_from);
-                if(s_debug_more)
-                    log_it(L_WARNING, "No permission for addr %s", l_tmp_tx_in_from?l_tmp_tx_in_from:"(null)");
-                DAP_DELETE(l_tmp_tx_in_from);
-                l_err_num = DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED;
-                break;
-            }
-        }
-        if ((l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED ) || // If all is allowed - check if we're
-            (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_tx_in_from,
-                                          sizeof (l_tx_in_from)) == 0 ){
-                char * l_tmp_tx_in_from = dap_chain_addr_to_str(&l_tx_in_from);
-                if(s_debug_more)
-                    log_it(L_WARNING, "No permission for addr %s", l_tmp_tx_in_from?l_tmp_tx_in_from:"(null)");
-                DAP_DELETE(l_tmp_tx_in_from);
-                l_err_num = DAP_CHAIN_LEDGER_PERMISSION_CHECK_FAILED;
+        l_bound_item->value = l_value;
+
+        if (l_cond_type != TX_ITEM_TYPE_IN) {
+            // If not checked earlier
+            if (!l_token || !*l_token) {
+                log_it(L_WARNING, "No token ticker found in previous transaction");
+                l_err_num = DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND;
                 break;
             }
         }
-
         HASH_FIND_STR(l_values_from_prev_tx, l_token, l_value_cur);
         if (!l_value_cur) {
-            l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t);
+            l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t);
             if ( !l_value_cur ) {
-        log_it(L_CRITICAL, "Memory allocation error");
-                if (bound_item)
-                    DAP_DELETE(bound_item);
-                if ( l_list_bound_items )
-                    dap_list_free_full(l_list_bound_items, NULL);
-                if (l_list_tx_out)
-                    dap_list_free(l_list_tx_out);
-                return -1;
+                log_it(L_CRITICAL, "Memory allocation error");
+                l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM;
+                break;
             }
             strcpy(l_value_cur->token_ticker, l_token);
             HASH_ADD_STR(l_values_from_prev_tx, token_ticker, l_value_cur);
         }
         // calculate  from previous transactions per each token
         SUM_256_256(l_value_cur->sum, l_value, &l_value_cur->sum);
-
-        l_list_bound_items = dap_list_append(l_list_bound_items, bound_item);
     }
 
     if (l_list_in)
         dap_list_free(l_list_in);
-
+    DAP_DEL_Z(l_tx_first_sign_pkey);
     if (l_err_num) {
-        DAP_DELETE(bound_item);
         if ( l_list_bound_items )
             dap_list_free_full(l_list_bound_items, NULL);
         HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) {
@@ -3971,23 +3995,24 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
     if (HASH_COUNT(l_values_from_prev_tx) > 1) {
         l_multichannel = true;
         if (HASH_COUNT(l_values_from_prev_tx) == 2 && !l_main_ticker) {
-            HASH_FIND_STR(l_values_from_prev_tx, PVT(a_ledger)->net_native_ticker, l_value_cur);
+            HASH_FIND_STR(l_values_from_prev_tx, a_ledger->net->pub.native_ticker, l_value_cur);
             if (l_value_cur) {
                 l_value_cur = l_value_cur->hh.next ? l_value_cur->hh.next : l_value_cur->hh.prev;
                 l_main_ticker = l_value_cur->token_ticker;
             }
         }
     } else {
-        l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t);
+        l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t);
         if ( !l_value_cur ) {
-        log_it(L_CRITICAL, "Memory allocation error");
-            if (bound_item)
-                DAP_DELETE(bound_item);
+            log_it(L_CRITICAL, "Memory allocation error");
+            l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM;
             if ( l_list_bound_items )
                 dap_list_free_full(l_list_bound_items, NULL);
-            if (l_list_tx_out)
-                dap_list_free(l_list_tx_out);
-            return -1;
+            HASH_ITER(hh, l_values_from_prev_tx, l_value_cur, l_tmp) {
+                HASH_DEL(l_values_from_prev_tx, l_value_cur);
+                DAP_DELETE(l_value_cur);
+            }
+            return l_err_num;
         }
         dap_stpcpy(l_value_cur->token_ticker, l_token);
         if (!l_main_ticker)
@@ -3998,14 +4023,14 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
     // find 'out' items
     dap_list_t *l_list_out = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) a_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
     uint256_t l_value = {}, l_fee_sum = {};
-    bool l_fee_check = !IS_ZERO_256(l_ledger_pvt->fee_value) && !dap_chain_addr_is_blank(&l_ledger_pvt->fee_addr);
+    bool l_fee_check = !IS_ZERO_256(a_ledger->net->pub.fee_value) && !dap_chain_addr_is_blank(&a_ledger->net->pub.fee_addr);
     int l_item_idx = 0;
-    for (l_list_tmp = l_list_out; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_item_idx++) {
-        dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data;
+    for (dap_list_t *it = l_list_out; it; it = it->next, l_item_idx++) {
+        dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data;
         dap_chain_addr_t l_tx_out_to={0};
         switch (l_type) {
         case TX_ITEM_TYPE_OUT_OLD: {
-            dap_chain_tx_out_old_t *l_tx_out = (dap_chain_tx_out_old_t *)l_list_tmp->data;
+            dap_chain_tx_out_old_t *l_tx_out = (dap_chain_tx_out_old_t *)it->data;
             if (l_multichannel) { // token ticker is mandatory for multichannel transactions
                 l_err_num = -16;
                 break;
@@ -4015,7 +4040,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
             l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out);
         } break;
         case TX_ITEM_TYPE_OUT: { // 256
-            dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)l_list_tmp->data;
+            dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)it->data;
             if (l_multichannel) { // token ticker is mandatory for multichannel transactions
                 if (l_main_ticker)
                     l_token = l_main_ticker;
@@ -4029,7 +4054,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
             l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out);
         } break;
         case TX_ITEM_TYPE_OUT_EXT: { // 256
-            dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)l_list_tmp->data;
+            dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)it->data;
             if (!l_multichannel) { // token ticker is depricated for single-channel transactions
                 l_err_num = -16;
                 break;
@@ -4040,10 +4065,10 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
             l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out);
         } break;
         case TX_ITEM_TYPE_OUT_COND: {
-            dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t *)l_list_tmp->data;
+            dap_chain_tx_out_cond_t *l_tx_out = (dap_chain_tx_out_cond_t *)it->data;
             if (l_multichannel) {
                 if (l_tx_out->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE)
-                    l_token = (char *)PVT(a_ledger)->net_native_ticker;
+                    l_token = (char *)a_ledger->net->pub.native_ticker;
                 else if (l_main_ticker)
                     l_token = l_main_ticker;
                 else {
@@ -4057,19 +4082,16 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
         } break;
         default: {}
         }
+        if (l_err_num)
+            break;
         if (l_multichannel) {
             HASH_FIND_STR(l_values_from_cur_tx, l_token, l_value_cur);
             if (!l_value_cur) {
-                l_value_cur = DAP_NEW_Z(dap_chain_ledger_tokenizer_t);
+                l_value_cur = DAP_NEW_Z(dap_ledger_tokenizer_t);
                 if ( !l_value_cur ) {
                     log_it(L_CRITICAL, "Memory allocation error");
-                    if (bound_item)
-                        DAP_DELETE(bound_item);
-                    if ( l_list_bound_items )
-                        dap_list_free_full(l_list_bound_items, NULL);
-                    if (l_list_tx_out)
-                        dap_list_free(l_list_tx_out);
-                    return -1;
+                    l_err_num = DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM;
+                    break;
                 }
                 strcpy(l_value_cur->token_ticker, l_token);
                 HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur);
@@ -4083,14 +4105,9 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
         }
 
         // Get permissions for token
-        l_token_item = NULL;
-        pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock);
-        if(l_ledger_pvt->tokens)
-            HASH_FIND_STR(l_ledger_pvt->tokens,l_token, l_token_item);
-        pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock);
-        if (! l_token_item){
-            if(s_debug_more)
-                log_it(L_WARNING, "No token item found for token %s", l_token);
+        dap_ledger_token_item_t *l_token_item = s_ledger_find_token(a_ledger, l_token);
+        if (!l_token_item) {
+            debug_if(s_debug_more, L_WARNING, "Token with ticker %s not found", l_token);
             l_err_num = -15;
             break;
         }
@@ -4122,8 +4139,8 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
             }
         }
 
-        if (l_fee_check && dap_chain_addr_compare(&l_tx_out_to, &l_ledger_pvt->fee_addr) &&
-                !dap_strcmp(l_value_cur->token_ticker, PVT(a_ledger)->net_native_ticker)) {
+        if (l_fee_check && dap_chain_addr_compare(&l_tx_out_to, &a_ledger->net->pub.fee_addr) &&
+                !dap_strcmp(l_value_cur->token_ticker, a_ledger->net->pub.native_ticker)) {
             SUM_256_256(l_fee_sum, l_value, &l_fee_sum);
         }
     }
@@ -4139,23 +4156,23 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                 if (s_debug_more) {
                     char *l_balance = dap_chain_balance_to_coins(l_res ? l_res->sum : uint256_0);
                     char *l_balance_cur = dap_chain_balance_to_coins(l_value_cur->sum);
-                    log_it(L_ERROR, "Sum of values of out items from current tx (%s) is not equal outs from previous tx (%s) for token %s",
+                    log_it(L_ERROR, "Sum of values of out items from current tx (%s) is not equal outs from previous txs (%s) for token %s",
                             l_balance, l_balance_cur, l_value_cur->token_ticker);
                     DAP_DELETE(l_balance);
                     DAP_DELETE(l_balance_cur);
                 }
-                l_err_num = DAP_CHAIN_LEDGER_TX_CACHE_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS;
+                l_err_num = DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS;
                 break;
             }
         }
     }
 
     // 7. Check the network fee
-    if (l_fee_check && compare256(l_fee_sum, l_ledger_pvt->fee_value) == -1) {
+    if (!l_err_num && l_fee_check && compare256(l_fee_sum, a_ledger->net->pub.fee_value) == -1) {
         // Check for PoA-cert-signed "service" no-tax tx
-        if (!dap_chain_ledger_tx_poa_signed(a_ledger, a_tx)) {
+        if (!dap_ledger_tx_poa_signed(a_ledger, a_tx)) {
             char *l_current_fee = dap_chain_balance_to_coins(l_fee_sum);
-            char *l_expected_fee = dap_chain_balance_to_coins(l_ledger_pvt->fee_value);
+            char *l_expected_fee = dap_chain_balance_to_coins(a_ledger->net->pub.fee_value);
             log_it(L_ERROR, "Fee value is invalid, expected %s pointed %s", l_expected_fee, l_current_fee);
             l_err_num = -55;
             DAP_DEL_Z(l_current_fee);
@@ -4190,30 +4207,30 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
 }
 
 /**
- * @brief dap_chain_ledger_tx_check
+ * @brief dap_ledger_tx_check
  * @param a_ledger
  * @param a_tx
  * @return
  */
-int dap_chain_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash)
+int dap_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash)
 {
     if (!a_tx)
-        return DAP_CHAIN_LEDGER_TX_CHECK_NULL_TX;
+        return DAP_LEDGER_TX_CHECK_NULL_TX;
 
     size_t l_tx_size = dap_chain_datum_tx_get_size(a_tx);
     if (l_tx_size != a_datum_size) {
         log_it (L_WARNING, "Inconsistent datum TX: datum size %zu != tx size %zu", a_datum_size, l_tx_size);
-        return DAP_CHAIN_LEDGER_TX_CHECK_INVALID_TX_SIZE;
+        return DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE;
     }
 
-    int l_ret_check = dap_chain_ledger_tx_cache_check(a_ledger, a_tx, a_datum_hash,
+    int l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_datum_hash,
                                                       false, NULL, NULL, NULL);
     if(s_debug_more) {
         char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
         dap_chain_hash_fast_to_str(a_datum_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
         if (l_ret_check)
             log_it(L_NOTICE, "Ledger TX adding check not passed for TX %s: error %s",
-                   l_tx_hash_str, dap_chain_ledger_tx_check_err_str(l_ret_check));
+                   l_tx_hash_str, dap_ledger_tx_check_err_str(l_ret_check));
         else
             log_it(L_INFO, "Ledger TX adding check passed for TX %s", l_tx_hash_str);
     }
@@ -4230,7 +4247,7 @@ int dap_chain_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *
 static int s_balance_cache_update(dap_ledger_t *a_ledger, dap_ledger_wallet_balance_t *a_balance)
 {
     if (PVT(a_ledger)->cached) {
-        char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_BALANCES_STR);
+        char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_BALANCES_STR);
         if (dap_global_db_set(l_gdb_group, a_balance->key, &a_balance->balance, sizeof(uint256_t), false, NULL, NULL)) {
             debug_if(s_debug_more, L_WARNING, "Ledger cache mismatch");
             return -1;
@@ -4244,40 +4261,13 @@ static int s_balance_cache_update(dap_ledger_t *a_ledger, dap_ledger_wallet_bala
     return 0;
 }
 
-static int s_sort_ledger_tx_item(dap_chain_ledger_tx_item_t* a, dap_chain_ledger_tx_item_t* b)
+static int s_sort_ledger_tx_item(dap_ledger_tx_item_t* a, dap_ledger_tx_item_t* b)
 {
     return a->tx->header.ts_created == b->tx->header.ts_created ? 0 :
                 a->tx->header.ts_created < b->tx->header.ts_created ? -1 : 1;
 }
 
-
-/**
- * @brief Add new transaction to the cache list
- * @param a_ledger
- * @param a_tx
- * @param a_tx_hash
- * @param a_from_threshold
- * @return return 1 OK, -1 error
- */
-int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold)
-{
-    return s_tx_add(a_ledger,a_tx,a_tx_hash,a_from_threshold,true);
-}
-
-/**
- * @brief Add new transaction to the cache list, without rwlocks lock
- * @param a_ledger
- * @param a_tx
- * @param a_tx_hash
- * @param a_from_threshold
- * @return return 1 OK, -1 error
- */
-static int s_tx_add_unsafe(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold)
-{
-    return s_tx_add(a_ledger,a_tx,a_tx_hash,a_from_threshold,false);
-}
-
-void dap_chain_ledger_set_tps_start_time(dap_ledger_t *a_ledger)
+void dap_ledger_set_tps_start_time(dap_ledger_t *a_ledger)
 {
     clock_gettime(CLOCK_REALTIME, &PVT(a_ledger)->tps_start_time);
 }
@@ -4288,10 +4278,9 @@ void dap_chain_ledger_set_tps_start_time(dap_ledger_t *a_ledger)
  * @param a_tx
  * @param a_tx_hash
  * @param a_from_threshold
- * @param a_safe_call True if we need to lock rwlock, false if not
  * @return return 1 OK, -1 error
  */
-static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold, bool a_safe_call)
+int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold)
 {
     if(!a_tx) {
         debug_if(s_debug_more, L_ERROR, "NULL tx detected");
@@ -4301,12 +4290,12 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
     dap_list_t *l_list_bound_items = NULL;
     dap_list_t *l_list_tx_out = NULL;
-    dap_chain_ledger_tx_item_t *l_item_tmp = NULL;
+    dap_ledger_tx_item_t *l_item_tmp = NULL;
     char *l_main_token_ticker = NULL;
 
     if (!l_ledger_pvt->tps_timer) {
 #ifndef DAP_TPS_TEST
-        dap_chain_ledger_set_tps_start_time(a_ledger);
+        dap_ledger_set_tps_start_time(a_ledger);
 #endif
         l_ledger_pvt->tps_current_time.tv_sec = l_ledger_pvt->tps_start_time.tv_sec;
         l_ledger_pvt->tps_current_time.tv_nsec = l_ledger_pvt->tps_start_time.tv_nsec;
@@ -4322,7 +4311,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
 
     int l_ret_check;
     l_item_tmp = NULL;
-    if( (l_ret_check = dap_chain_ledger_tx_cache_check(a_ledger, a_tx, a_tx_hash, a_from_threshold,
+    if( (l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_tx_hash, a_from_threshold,
                                                        &l_list_bound_items, &l_list_tx_out,
                                                        &l_main_token_ticker))) {
         if (l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS ||
@@ -4339,7 +4328,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
                             log_it(L_WARNING, "Threshold for tranactions is overfulled (%zu max), dropping down new data, added nothing",
                                        s_threshold_txs_max);
                     } else {
-                        l_item_tmp = DAP_NEW_Z(dap_chain_ledger_tx_item_t);
+                        l_item_tmp = DAP_NEW_Z(dap_ledger_tx_item_t);
                         if ( !l_item_tmp ) {
                             log_it(L_CRITICAL, "Memory allocation error");
                             return -1;
@@ -4360,13 +4349,12 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
                 pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock);
             }
         } else {
-            debug_if(s_debug_more, L_WARNING, "dap_chain_ledger_tx_add() tx %s not passed the check: %s ", l_tx_hash_str,
-                        dap_chain_ledger_tx_check_err_str(l_ret_check));
+            debug_if(s_debug_more, L_WARNING, "dap_ledger_tx_add() tx %s not passed the check: %s ", l_tx_hash_str,
+                        dap_ledger_tx_check_err_str(l_ret_check));
         }
         return l_ret_check;
     }
-    if(s_debug_more)
-        log_it ( L_DEBUG, "dap_chain_ledger_tx_add() check passed for tx %s",l_tx_hash_str);
+    debug_if(s_debug_more, L_DEBUG, "dap_ledger_tx_add() check passed for tx %s", l_tx_hash_str);
 
     // Mark 'out' items in cache if they were used & delete previous transactions from cache if it need
     // find all bound pairs 'in' and 'out'
@@ -4377,113 +4365,75 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
     if (PVT(a_ledger)->cached) {
         dap_store_obj_t *l_cache_used_outs = DAP_NEW_Z_SIZE(dap_store_obj_t, sizeof(dap_store_obj_t) * (l_outs_used + 1));
         if ( !l_cache_used_outs ) {
-            if (l_item_tmp) {
-                DAP_DEL_Z(l_item_tmp->tx);
-                DAP_DELETE(l_item_tmp);
-            }
-            dap_list_free(l_list_bound_items);
             log_it(L_CRITICAL, "Memory allocation error");
-            return -1;
+            l_ret = -1;
+            goto FIN;
         }
-        l_ledger_cache_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_STR);
+        l_ledger_cache_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TXS_STR);
     }
     const char *l_cur_token_ticker = NULL;
-    dap_list_t *l_list_tmp = l_list_bound_items;
+
     // Update balance: deducts
-    for (int i = 1; l_list_tmp; i++) {
-        dap_chain_ledger_tx_bound_t *bound_item = l_list_tmp->data;
-        void *l_item_in = *(void **)&bound_item->in;
-        dap_chain_tx_item_type_t l_type = *(uint8_t *)l_item_in;
-        if (l_type == TX_ITEM_TYPE_IN_EMS) {
+    int l_spent_idx = 0;
+    for (dap_list_t *it = l_list_bound_items; it; it = it->next) {
+        dap_ledger_tx_bound_t *l_bound_item = it->data;
+        dap_chain_tx_item_type_t l_type = l_bound_item->type;
+        if (l_type == TX_ITEM_TYPE_IN || l_type == TX_ITEM_TYPE_IN_COND) {
+            if (l_bound_item->prev_item->cache_data.n_outs <= l_bound_item->prev_item->cache_data.n_outs_used) {
+                log_it(L_ERROR, "[!] Irrelevant prev tx: out items mismatch %d <= %d",
+                       l_bound_item->prev_item->cache_data.n_outs, l_bound_item->prev_item->cache_data.n_outs_used);
+                l_outs_used--;
+                continue;
+            }
+            l_spent_idx++;
+        }
+
+        switch (l_type) {
+        case TX_ITEM_TYPE_IN_EMS:
+        case TX_ITEM_TYPE_IN_EMS_LOCK:
+        case TX_ITEM_TYPE_IN_REWARD: {
              // It's the emission behind
-            dap_chain_tx_in_ems_t *l_in_ems = bound_item->in.tx_cur_in_ems;
-            const char *l_delegated_ticker_str = l_in_ems->header.ticker;
-            if (bound_item->tx_prev) { // It's the stake lock emission
-                dap_chain_ledger_token_item_t *l_token_item = NULL;
-                pthread_rwlock_rdlock(&l_ledger_pvt->tokens_rwlock);
-                HASH_FIND_STR(l_ledger_pvt->tokens, l_delegated_ticker_str, l_token_item);
-                pthread_rwlock_unlock(&l_ledger_pvt->tokens_rwlock);
-                if (l_token_item) {
-                    if (!IS_ZERO_256(l_token_item->total_supply)) {
-                        uint256_t *l_value = bound_item->stake_lock_item ?
-                                    &bound_item->stake_lock_item->ems_value :
-                                    &bound_item->out.tx_prev_out_ext_256->header.value;
-                        SUBTRACT_256_256(l_token_item->current_supply, *l_value,
-                                         &l_token_item->current_supply);
-                        char *l_balance = dap_chain_balance_print(l_token_item->current_supply);
-                        log_it(L_DEBUG, "New current supply %s for token %s", l_balance, l_token_item->ticker);
-                        DAP_DEL_Z(l_balance);
-                        if (PVT(a_ledger)->cached)
-                            s_ledger_token_cache_update(a_ledger, l_token_item);
-                    }
-                } else
-                    log_it(L_ERROR, "No token item found for token %s", l_delegated_ticker_str);
-                if (bound_item->stake_lock_item) {
-                    bound_item->stake_lock_item->tx_used_out = *a_tx_hash;
-                    if (PVT(a_ledger)->cached)
-                        // Mirror it in cache
-                        s_ledger_stake_lock_cache_update(a_ledger, bound_item->stake_lock_item);
+            if (!s_ledger_token_supply_check_update(a_ledger, l_bound_item->token_item, l_bound_item->value))
+                log_it(L_ERROR, "Insufficient supply for token %s", l_bound_item->token_item->ticker);
+            if (l_type == TX_ITEM_TYPE_IN_EMS_LOCK) {
+                // Mark it as used with current tx hash
+                l_bound_item->stake_lock_item->tx_used_out = *a_tx_hash;
+                s_ledger_stake_lock_cache_update(a_ledger, l_bound_item->stake_lock_item);
+            } else if (l_type == TX_ITEM_TYPE_IN_EMS) {
+                // Mark it as used with current tx hash
+                l_bound_item->emission_item->tx_used_out = *a_tx_hash;
+                s_ledger_emission_cache_update(a_ledger, l_bound_item->emission_item);
+            } else { // l_type == TX_ITEM_TYPE_IN_REWARD
+                dap_ledger_reward_item_t *l_item = DAP_NEW_Z(dap_ledger_reward_item_t);
+                if (!l_item) {
+                    log_it(L_CRITICAL, "Memory allocation error");
+                    l_ret = -1;
+                    goto FIN;
                 }
-            } else {    // It's the general emission
-                // Mark it as used with base tx hash
-                bound_item->item_emission->tx_used_out = *a_tx_hash;
-                if (PVT(a_ledger)->cached)
-                    // Mirror it in cache
-                    s_ledger_emission_cache_update(a_ledger, bound_item->item_emission);
+                l_item->key = l_bound_item->reward_key;
+                l_item->spender_tx = *a_tx_hash;
+                pthread_rwlock_wrlock(&l_ledger_pvt->rewards_rwlock);
+                HASH_ADD(hh, l_ledger_pvt->rewards, key, sizeof(l_item->key), l_item);
+                pthread_rwlock_unlock(&l_ledger_pvt->rewards_rwlock);
             }
-            l_list_tmp = dap_list_next(l_list_tmp);
-            i--;    // Do not calc this output with tx used items
-            l_outs_used--;
-            continue;
-        }
-        dap_chain_ledger_tx_item_t *l_prev_item_out = bound_item->item_out;
-        if (l_prev_item_out->cache_data.n_outs <= l_prev_item_out->cache_data.n_outs_used) {
-            log_it(L_ERROR, "[!] Irrelevant prev tx: out items mismatch %d <= %d",
-                   l_prev_item_out->cache_data.n_outs, l_prev_item_out->cache_data.n_outs_used);
-            l_list_tmp = dap_list_next(l_list_tmp);
-            i--;
-            l_outs_used--;
-            continue;
-        }
-        l_cur_token_ticker = l_prev_item_out->cache_data.token_ticker;
-        int l_tx_prev_out_used_idx = 0;
-        if (l_type == TX_ITEM_TYPE_IN) {
-            dap_chain_tx_in_t *l_tx_in = bound_item->in.tx_cur_in;
+            l_outs_used--; // Do not calc this output with tx used items
+        } continue;
+
+        case TX_ITEM_TYPE_IN: {
             dap_ledger_wallet_balance_t *wallet_balance = NULL;
-            uint256_t l_value = {};
-            dap_chain_addr_t *l_addr = NULL;
-            void *l_item_out = *(void **)&bound_item->out;
-            dap_chain_tx_item_type_t l_out_type = *(uint8_t *)l_item_out;
-            switch (l_out_type) {
-            case TX_ITEM_TYPE_OUT:
-                l_addr = &bound_item->out.tx_prev_out_256->addr;
-                l_value = bound_item->out.tx_prev_out_256->header.value;
-                break;
-            case TX_ITEM_TYPE_OUT_OLD:
-                l_addr = &bound_item->out.tx_prev_out->addr;
-                l_value = GET_256_FROM_64(bound_item->out.tx_prev_out->header.value);
-                break;
-            case TX_ITEM_TYPE_OUT_EXT:
-                l_addr = &bound_item->out.tx_prev_out_ext_256->addr;
-                l_value = bound_item->out.tx_prev_out_ext_256->header.value;
-                l_cur_token_ticker = bound_item->out.tx_prev_out_ext_256->token;
-                break;
-            default:
-                log_it(L_DEBUG, "Unknown item type %d", l_out_type);
-                break;
-            }
-            char *l_addr_str = dap_chain_addr_to_str(l_addr);
+            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);
             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);
             pthread_rwlock_unlock(&PVT(a_ledger)->balance_accounts_rwlock);
             if (wallet_balance) {
                 if(s_debug_more) {
-                    char *l_balance = dap_chain_balance_print(l_value);
+                    char *l_balance = dap_chain_balance_print(l_bound_item->value);
                     log_it(L_DEBUG,"SPEND %s from addr: %s", l_balance, l_wallet_balance_key);
                     DAP_DELETE(l_balance);
                 }
-                SUBTRACT_256_256(wallet_balance->balance, l_value, &wallet_balance->balance);
+                SUBTRACT_256_256(wallet_balance->balance, l_bound_item->value, &wallet_balance->balance);
                 // Update the cache
                 s_balance_cache_update(a_ledger, wallet_balance);
             } else {
@@ -4492,28 +4442,27 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
             }
             DAP_DELETE(l_addr_str);
             DAP_DELETE(l_wallet_balance_key);
-            /// Mark 'out' item in cache because it used
-            l_tx_prev_out_used_idx = l_tx_in->header.tx_out_prev_idx;
-        } else {//TX_ITEM_TYPE_IN_COND
-            // all balance deducts performed with previous conditional transaction
-            dap_chain_tx_in_cond_t *l_tx_in_cond = bound_item->in.tx_cur_in_cond;
-            /// Mark 'out' item in cache because it used
-            l_tx_prev_out_used_idx = l_tx_in_cond->header.tx_out_prev_idx;
-            dap_chain_tx_out_cond_t *l_cond = bound_item->out.tx_prev_out_cond_256;
-            if (l_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE)
-                l_cur_token_ticker = (char *)PVT(a_ledger)->net_native_ticker;
+        } break;
+
+        case TX_ITEM_TYPE_IN_COND: { // all balance deducts performed with previous conditional transaction
             // Update service items if any
-            dap_chain_ledger_verificator_t *l_verificator;
-            int l_tmp = l_cond->header.subtype;
+            dap_ledger_verificator_t *l_verificator;
+            int l_tmp = l_bound_item->cond->header.subtype;
             pthread_rwlock_rdlock(&s_verificators_rwlock);
             HASH_FIND_INT(s_verificators, &l_tmp, l_verificator);
             pthread_rwlock_unlock(&s_verificators_rwlock);
             if (l_verificator && l_verificator->callback_added)
-                l_verificator->callback_added(a_ledger, a_tx, l_cond);
+                l_verificator->callback_added(a_ledger, a_tx, l_bound_item->cond);
+        } break;
+
+        default:
+            log_it(L_ERROR, "Unknown item type %d in ledger TX bound for IN part", l_type);
+            break;
         }
 
         // add a used output
-        l_prev_item_out->cache_data.tx_hash_spent_fast[l_tx_prev_out_used_idx] = *a_tx_hash;
+        dap_ledger_tx_item_t *l_prev_item_out = l_bound_item->prev_item;
+        l_prev_item_out->cache_data.tx_hash_spent_fast[l_bound_item->prev_out_idx] = *a_tx_hash;
         l_prev_item_out->cache_data.n_outs_used++;
         if (PVT(a_ledger)->cached) {
             // mirror it in the cache
@@ -4523,22 +4472,18 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
             memcpy(l_tx_cache, &l_prev_item_out->cache_data, sizeof(l_prev_item_out->cache_data));
             memcpy(l_tx_cache + sizeof(l_prev_item_out->cache_data), l_prev_item_out->tx, l_tx_size);
             char *l_tx_i_hash = dap_chain_hash_fast_to_str_new(&l_prev_item_out->tx_hash_fast);
-            l_cache_used_outs[i] = (dap_store_obj_t) {
+            l_cache_used_outs[l_spent_idx] = (dap_store_obj_t) {
                     .key        = l_tx_i_hash,
                     .value      = l_tx_cache,
                     .value_len  = l_tx_cache_sz,
                     .group      = l_ledger_cache_group,
                     .type       = DAP_GLOBAL_DB_OPTYPE_ADD
             };
-            l_cache_used_outs[i].timestamp = dap_nanotime_now();
+            l_cache_used_outs[l_spent_idx].timestamp = dap_nanotime_now();
         }
-
         // mark previous transactions as used with the extra timestamp
         if(l_prev_item_out->cache_data.n_outs_used == l_prev_item_out->cache_data.n_outs)
             l_prev_item_out->cache_data.ts_spent = a_tx->header.ts_created;
-
-        // go to next previous transaction
-        l_list_tmp = dap_list_next(l_list_tmp);
     }
 
 
@@ -4554,7 +4499,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
         if (l_type == TX_ITEM_TYPE_OUT_COND) {
             // Update service items if any
             dap_chain_tx_out_cond_t *l_cond = (dap_chain_tx_out_cond_t *)l_tx_out->data;
-            dap_chain_ledger_verificator_t *l_verificator;
+            dap_ledger_verificator_t *l_verificator;
             int l_tmp = l_cond->header.subtype;
             pthread_rwlock_rdlock(&s_verificators_rwlock);
             HASH_FIND_INT(s_verificators, &l_tmp, l_verificator);
@@ -4592,7 +4537,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
         }
         if (!l_addr)
             continue;
-        else if (l_addr->net_id.uint64 != a_ledger->net_id.uint64 &&
+        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);
@@ -4616,7 +4561,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
         } else {
             wallet_balance = DAP_NEW_Z(dap_ledger_wallet_balance_t);
             if (!wallet_balance) {
-                log_it(L_ERROR, "Memoru allocation error in s_load_cache_gdb_loaded_txs_callback");
+                log_it(L_CRITICAL, "Memory allocation error in s_load_cache_gdb_loaded_txs_callback");
                 l_ret = -1;
                 goto FIN;
             }
@@ -4636,7 +4581,7 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
     }
 
     // add transaction to the cache list
-    dap_chain_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_chain_ledger_tx_item_t);
+    dap_ledger_tx_item_t *l_tx_item = DAP_NEW_Z(dap_ledger_tx_item_t);
     if ( !l_tx_item ) {
         log_it(L_CRITICAL, "Memory allocation error");
         l_ret = -1;
@@ -4647,30 +4592,30 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
     l_tx_item->tx = DAP_DUP_SIZE(a_tx, l_tx_size);
     l_tx_item->cache_data.ts_created = dap_time_now(); // Time of transasction added to ledger
     int l_outs_count = 0;
-    dap_list_t *l_list_tmp2 = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, &l_outs_count);
+    dap_list_t *l_list_tmp = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, &l_outs_count);
     l_tx_item->cache_data.n_outs = l_outs_count;
     // TODO: dump the UTXO in debug mode if need
 
-    if(l_list_tmp2)
-        dap_list_free(l_list_tmp2);
+    if(l_list_tmp)
+        dap_list_free(l_list_tmp);
     dap_stpcpy(l_tx_item->cache_data.token_ticker, l_main_token_ticker);
 
     l_tx_item->cache_data.multichannel = l_multichannel;
-    if(a_safe_call) pthread_rwlock_wrlock(&l_ledger_pvt->ledger_rwlock);
+    pthread_rwlock_wrlock(&l_ledger_pvt->ledger_rwlock);
     l_tx_item->ts_added = dap_nanotime_now();
     HASH_ADD_INORDER(hh, l_ledger_pvt->ledger_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t),
                          l_tx_item, s_sort_ledger_tx_item); // tx_hash_fast: name of key field
-    if(a_safe_call) pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
+    pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
     // Callable callback
     dap_list_t *l_notifier;
     DL_FOREACH(PVT(a_ledger)->tx_add_notifiers, l_notifier) {
-        dap_chain_ledger_tx_notifier_t *l_notify = (dap_chain_ledger_tx_notifier_t*)l_notifier->data;
+        dap_ledger_tx_notifier_t *l_notify = (dap_ledger_tx_notifier_t*)l_notifier->data;
         l_notify->callback(l_notify->arg, a_ledger, l_tx_item->tx);
     }
     if (l_cross_network) {
         dap_list_t *l_notifier;
         DL_FOREACH(PVT(a_ledger)->bridged_tx_notifiers, l_notifier) {
-            dap_chain_ledger_bridged_tx_notifier_t *l_notify = l_notifier->data;
+            dap_ledger_bridged_tx_notifier_t *l_notify = l_notifier->data;
             l_notify->callback(a_ledger, a_tx, a_tx_hash, l_notify->arg);
         }
     }
@@ -4708,8 +4653,8 @@ FIN:
             DAP_DEL_Z(l_cache_used_outs[i].key);
             DAP_DEL_Z(l_cache_used_outs[i].value);
         }
-        DAP_DELETE(l_cache_used_outs);
-        DAP_DELETE(l_ledger_cache_group);
+        DAP_DEL_Z(l_cache_used_outs);
+        DAP_DEL_Z(l_ledger_cache_group);
     }
     return l_ret;
 }
@@ -4727,19 +4672,19 @@ static bool s_ledger_tps_callback(void *a_arg)
     return false;
 }
 
-int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_hash_fast_t *a_tx_hash)
+int dap_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_hash_fast_t *a_tx_hash)
 {
     if (PVT(a_ledger)->load_mode) {
         if (PVT(a_ledger)->cache_tx_check_callback)
             PVT(a_ledger)->cache_tx_check_callback(a_tx_hash);
-        dap_chain_ledger_tx_item_t *l_tx_item;
+        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);
         pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock);
         HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_item);
         if (l_tx_item) {
             pthread_rwlock_unlock(&PVT(a_ledger)->ledger_rwlock);
-            return DAP_CHAIN_LEDGER_TX_ALREADY_CACHED;
+            return DAP_LEDGER_TX_ALREADY_CACHED;
         }
         HASH_FIND_BYHASHVALUE(hh, PVT(a_ledger)->threshold_txs, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value, l_tx_item);
         if (l_tx_item) {
@@ -4747,13 +4692,13 @@ int dap_chain_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
             return DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS;
         }
     }
-    return dap_chain_ledger_tx_add(a_ledger, a_tx, a_tx_hash, false);
+    return dap_ledger_tx_add(a_ledger, a_tx, a_tx_hash, false);
 }
 
 /**
  * Delete all transactions from the cache
  */
-void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
+void dap_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
 {
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
     pthread_rwlock_wrlock(&l_ledger_pvt->ledger_rwlock);
@@ -4764,7 +4709,7 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
     pthread_rwlock_wrlock(&l_ledger_pvt->stake_lock_rwlock);
 
     /* Delete regular transactions */
-    dap_chain_ledger_tx_item_t *l_item_current, *l_item_tmp;
+    dap_ledger_tx_item_t *l_item_current, *l_item_tmp;
     char *l_gdb_group;
     HASH_ITER(hh, l_ledger_pvt->ledger_items , l_item_current, l_item_tmp) {
         HASH_DEL(l_ledger_pvt->ledger_items, l_item_current);
@@ -4772,13 +4717,13 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
         DAP_DEL_Z(l_item_current);
     }
     if (!a_preserve_db) {
-        l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TXS_STR);
+        l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TXS_STR);
         dap_global_db_del(l_gdb_group, NULL, NULL, NULL);
         DAP_DELETE(l_gdb_group);
     }
 
     if (!a_preserve_db) {
-        l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_SPENT_TXS_STR);
+        l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_SPENT_TXS_STR);
         dap_global_db_del(l_gdb_group, NULL, NULL, NULL);
         DAP_DELETE(l_gdb_group);
     }
@@ -4791,14 +4736,14 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
         DAP_DELETE(l_balance_current);
     }
     if (!a_preserve_db) {
-        l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_BALANCES_STR);
+        l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_BALANCES_STR);
         dap_global_db_del(l_gdb_group, NULL, NULL, NULL);
         DAP_DELETE(l_gdb_group);
     }
 
     /* Delete tokens and their emissions */
-    dap_chain_ledger_token_item_t *l_token_current, *l_token_tmp;
-    dap_chain_ledger_token_emission_item_t *l_emission_current, *l_emission_tmp;
+    dap_ledger_token_item_t *l_token_current, *l_token_tmp;
+    dap_ledger_token_emission_item_t *l_emission_current, *l_emission_tmp;
     HASH_ITER(hh, l_ledger_pvt->tokens, l_token_current, l_token_tmp) {
         HASH_DEL(l_ledger_pvt->tokens, l_token_current);
         pthread_rwlock_wrlock(&l_token_current->token_emissions_rwlock);
@@ -4819,22 +4764,22 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
         DAP_DELETE(l_token_current);
     }
     if (!a_preserve_db) {
-        l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR);
+        l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_TOKENS_STR);
         dap_global_db_del(l_gdb_group, NULL, NULL, NULL);
         DAP_DELETE(l_gdb_group);
-        l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR);
+        l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_EMISSIONS_STR);
         dap_global_db_del(l_gdb_group, NULL, NULL, NULL);
         DAP_DELETE(l_gdb_group);
     }
 
     /* Delete stake-lock items */
-    dap_chain_ledger_stake_lock_item_t *l_stake_item_current, *l_stake_item_tmp;
+    dap_ledger_stake_lock_item_t *l_stake_item_current, *l_stake_item_tmp;
     HASH_ITER(hh, l_ledger_pvt->emissions_for_stake_lock, l_stake_item_current, l_stake_item_tmp) {
         HASH_DEL(l_ledger_pvt->emissions_for_stake_lock, l_stake_item_current);
         DAP_DELETE(l_stake_item_current);
     }
     if (!a_preserve_db) {
-        l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_STAKE_LOCK_STR);
+        l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_LEDGER_STAKE_LOCK_STR);
         dap_global_db_del(l_gdb_group, NULL, NULL, NULL);
         DAP_DELETE(l_gdb_group);
     }
@@ -4872,7 +4817,7 @@ void dap_chain_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
  * Return number transactions from the cache
  * According to UT_hash_handle size of return value is sizeof(unsigned int)
  */
-unsigned dap_chain_ledger_count(dap_ledger_t *a_ledger)
+unsigned dap_ledger_count(dap_ledger_t *a_ledger)
 {
     pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock);
     unsigned long ret = HASH_COUNT(PVT(a_ledger)->ledger_items);
@@ -4881,17 +4826,17 @@ unsigned dap_chain_ledger_count(dap_ledger_t *a_ledger)
 }
 
 /**
- * @brief dap_chain_ledger_count_from_to
+ * @brief dap_ledger_count_from_to
  * @param a_ledger
  * @param a_ts_from
  * @param a_ts_to
  * @return
  */
-uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts_from, dap_time_t a_ts_to)
+uint64_t dap_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts_from, dap_time_t a_ts_to)
 {
     uint64_t l_ret = 0;
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    dap_chain_ledger_tx_item_t *l_iter_current, *l_item_tmp;
+    dap_ledger_tx_item_t *l_iter_current, *l_item_tmp;
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
     if ( a_ts_from && a_ts_to) {
         HASH_ITER(hh, l_ledger_pvt->ledger_items , l_iter_current, l_item_tmp){
@@ -4918,7 +4863,7 @@ uint64_t dap_chain_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts
     return l_ret;
 }
 
-size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to)
+size_t dap_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to)
 {
     if (!a_ledger)
         return 0;
@@ -4937,9 +4882,9 @@ size_t dap_chain_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_
 /**
  * Check whether used 'out' items
  */
-bool dap_chain_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, int a_idx_out, dap_hash_fast_t *a_out_spender)
+bool dap_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, int a_idx_out, dap_hash_fast_t *a_out_spender)
 {
-    dap_chain_ledger_tx_item_t *l_item_out = NULL;
+    dap_ledger_tx_item_t *l_item_out = NULL;
     /*dap_chain_datum_tx_t *l_tx =*/ s_find_datum_tx_by_hash(a_ledger, a_tx_hash, &l_item_out, false);
     return l_item_out ? s_ledger_tx_hash_is_used_out_item(l_item_out, a_idx_out, a_out_spender) : true;
 }
@@ -4948,7 +4893,7 @@ bool dap_chain_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain
  * Calculate balance of addr
  *
  */
-uint256_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr,
+uint256_t dap_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr,
                                         const char *a_token_ticker)
 {
     uint256_t l_ret = uint256_0;
@@ -4975,7 +4920,7 @@ uint256_t dap_chain_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_
     return l_ret;
 }
 
-uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr,
+uint256_t dap_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr,
                                              const char *a_token_ticker)
 {
     uint256_t balance = uint256_0;
@@ -4984,7 +4929,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c
         return balance;
 
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    dap_chain_ledger_tx_item_t *l_iter_current, *l_item_tmp;
+    dap_ledger_tx_item_t *l_iter_current, *l_item_tmp;
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
     HASH_ITER(hh, l_ledger_pvt->ledger_items , l_iter_current, l_item_tmp)
     {
@@ -5007,14 +4952,13 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c
             }
         }
         int l_out_idx_tmp = 0;
-        for (dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_out_idx_tmp++) {
-            assert(l_list_tmp->data);
-            dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data;
-            if (l_type == TX_ITEM_TYPE_OUT_COND_OLD || (l_type == TX_ITEM_TYPE_OUT_COND)) {
+        for (dap_list_t *it = l_list_out_items; it; it = it->next, l_out_idx_tmp++) {
+            assert(it->data);
+            dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data;
+            if (l_type == TX_ITEM_TYPE_OUT_COND)
                 continue;
-            }
-            if (l_type == TX_ITEM_TYPE_OUT_OLD) {
-                const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t*) l_list_tmp->data;
+            if (l_type == TX_ITEM_TYPE_OUT_OLD) { // 64
+                const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t*) it->data;
                 // Check for token name
                 if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_ticker))
                 {   // if transaction has the out item with requested addr
@@ -5022,8 +4966,6 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c
                         // if 'out' item not used & transaction is valid
                         if(!s_ledger_tx_hash_is_used_out_item(l_iter_current, l_out_idx_tmp, NULL) &&
                                 dap_chain_datum_tx_verify_sign(l_cur_tx)) {
-                            // uint128_t l_add = dap_chain_uint128_from(l_tx_out->header.value);
-                            // balance = dap_uint128_add(balance, l_add);
                             uint256_t l_add = dap_chain_uint256_from(l_tx_out->header.value);
                             SUM_256_256(balance, l_add, &balance);
                         }
@@ -5031,8 +4973,8 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c
                 }
             }
             if (l_type == TX_ITEM_TYPE_OUT) { // 256
-                const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data;
-                // const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t*) l_list_tmp->data;
+                const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) it->data;
+                // const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t*) it->data;
                 // Check for token name
                 if (!strcmp(a_token_ticker, l_iter_current->cache_data.token_ticker))
                 {   // if transaction has the out item with requested addr
@@ -5046,8 +4988,8 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c
                 }
             }
             if (l_type == TX_ITEM_TYPE_OUT_EXT) { // 256
-                const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) l_list_tmp->data;
-                // const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) l_list_tmp->data;
+                const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) it->data;
+                // const dap_chain_tx_out_ext_t *l_tx_out = (const dap_chain_tx_out_ext_t*) it->data;
                 // Check for token name
                 if (!strcmp(a_token_ticker, l_tx_out->token))
                 {   // if transaction has the out item with requested addr
@@ -5074,7 +5016,7 @@ uint256_t dap_chain_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_c
  * a_public_key_size[in] public key size
  * a_tx_first_hash [in/out] hash of the initial transaction/ found transaction, if 0 start from the beginning
  */
-static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr,
+static dap_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr,
                                                         const char * a_token, dap_chain_hash_fast_t *a_tx_first_hash)
 {
     if(!a_addr || !a_tx_first_hash)
@@ -5083,7 +5025,7 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
     bool is_tx_found = false;
     bool is_null_hash = dap_hash_fast_is_blank(a_tx_first_hash);
     bool is_search_enable = is_null_hash;
-    dap_chain_ledger_tx_item_t *l_iter_current, *l_item_tmp;
+    dap_ledger_tx_item_t *l_iter_current, *l_item_tmp;
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
     HASH_ITER(hh, l_ledger_pvt->ledger_items , l_iter_current, l_item_tmp)
     {
@@ -5103,14 +5045,13 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
         }
         // Get 'out' items from transaction
         dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
-        for(dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp)) {
-            assert(l_list_tmp->data);
-            dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data;
-            if (l_type == TX_ITEM_TYPE_OUT_COND || l_type == TX_ITEM_TYPE_OUT_COND_OLD) {
+        for(dap_list_t *it = l_list_out_items; it; it = dap_list_next(it)) {
+            assert(it->data);
+            dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data;
+            if (l_type == TX_ITEM_TYPE_OUT_COND)
                 continue;
-            }
             if (l_type == TX_ITEM_TYPE_OUT) {
-                const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t *)l_list_tmp->data;
+                const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t *)it->data;
                 // if transaction has the out item with requested addr
                 if(!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) {
                     memcpy(a_tx_first_hash, l_tx_hash, sizeof(dap_chain_hash_fast_t));
@@ -5119,7 +5060,7 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
                 }
             }
             if (l_type == TX_ITEM_TYPE_OUT_OLD) {
-                const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t *)l_list_tmp->data;
+                const dap_chain_tx_out_old_t *l_tx_out = (const dap_chain_tx_out_old_t *)it->data;
                 // if transaction has the out item with requested addr
                 if(!memcmp(a_addr, &l_tx_out->addr, sizeof(dap_chain_addr_t))) {
                     memcpy(a_tx_first_hash, l_tx_hash, sizeof(dap_chain_hash_fast_t));
@@ -5128,7 +5069,7 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
                 }
             }
             if (l_type == TX_ITEM_TYPE_OUT_EXT) {
-                const dap_chain_tx_out_ext_t *l_tx_out_ext = (const dap_chain_tx_out_ext_t *)l_list_tmp->data;
+                const dap_chain_tx_out_ext_t *l_tx_out_ext = (const dap_chain_tx_out_ext_t *)it->data;
                 // If a_token is setup we check if its not our token - miss it
                 if (a_token && dap_strcmp(l_tx_out_ext->token, a_token)) {
                     continue;
@@ -5154,15 +5095,15 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
 }
 
 /**
- * @brief dap_chain_ledger_tx_find_by_addr
+ * @brief dap_ledger_tx_find_by_addr
  * @param a_addr
  * @param a_tx_first_hash
  * @return
  */
- dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_addr(dap_ledger_t *a_ledger , const char * a_token ,
+ dap_chain_datum_tx_t* dap_ledger_tx_find_by_addr(dap_ledger_t *a_ledger , const char * a_token ,
          const dap_chain_addr_t *a_addr, dap_chain_hash_fast_t *a_tx_first_hash)
 {
-    dap_chain_ledger_tx_item_t* l_tx_item = tx_item_find_by_addr(a_ledger, a_addr, a_token, a_tx_first_hash);
+    dap_ledger_tx_item_t* l_tx_item = tx_item_find_by_addr(a_ledger, a_addr, a_token, a_tx_first_hash);
     return (l_tx_item) ? l_tx_item->tx : NULL;
 }
 
@@ -5176,7 +5117,7 @@ static dap_chain_ledger_tx_item_t* tx_item_find_by_addr(dap_ledger_t *a_ledger,
  * a_public_key_size[in] public key size
  * a_tx_first_hash [in/out] hash of the initial transaction/ found transaction, if 0 start from the beginning
  */
-const dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger,
+const dap_chain_datum_tx_t* dap_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger,
         char *a_public_key, size_t a_public_key_size, dap_chain_hash_fast_t *a_tx_first_hash)
 {
     if(!a_public_key || !a_tx_first_hash)
@@ -5185,7 +5126,7 @@ const dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_pkey(dap_ledger_t *a_led
     dap_chain_datum_tx_t *l_cur_tx = NULL;
     bool is_null_hash = dap_hash_fast_is_blank(a_tx_first_hash);
     bool is_search_enable = is_null_hash;
-    dap_chain_ledger_tx_item_t *l_iter_current, *l_item_tmp;
+    dap_ledger_tx_item_t *l_iter_current, *l_item_tmp;
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
     HASH_ITER(hh, l_ledger_pvt->ledger_items , l_iter_current, l_item_tmp) {
         dap_chain_datum_tx_t *l_tx_tmp = l_iter_current->tx;
@@ -5221,11 +5162,11 @@ const dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_pkey(dap_ledger_t *a_led
  * @param a_srv_uid
  * @return
  */
-dap_list_t* dap_chain_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, dap_chain_net_srv_uid_t a_srv_uid)
+dap_list_t* dap_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, dap_chain_net_srv_uid_t a_srv_uid)
 {
     dap_list_t * l_ret = NULL;
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
-    dap_chain_ledger_tx_item_t *l_iter_current = NULL, *l_item_tmp = NULL;
+    dap_ledger_tx_item_t *l_iter_current = NULL, *l_item_tmp = NULL;
     HASH_ITER(hh, l_ledger_pvt->ledger_items, l_iter_current, l_item_tmp) {
         dap_chain_datum_tx_t *l_tx = l_iter_current->tx;
         dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_COND, NULL), *l_out_item;
@@ -5244,7 +5185,7 @@ dap_list_t* dap_chain_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger,
  *
  * a_addr[in] wallet address, whose owner can use the service
  */
-dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type,
+dap_chain_datum_tx_t* dap_ledger_tx_cache_find_out_cond(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type,
         dap_chain_hash_fast_t *a_tx_first_hash, dap_chain_tx_out_cond_t **a_out_cond, int *a_out_cond_idx, char *a_token_ticker)
 {
     if (!a_tx_first_hash)
@@ -5253,7 +5194,7 @@ dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_le
     dap_chain_datum_tx_t *l_cur_tx = NULL;
     bool is_null_hash = dap_hash_fast_is_blank(a_tx_first_hash);
     bool is_search_enable = is_null_hash;
-    dap_chain_ledger_tx_item_t *l_iter_current = NULL, *l_item_tmp = NULL;
+    dap_ledger_tx_item_t *l_iter_current = NULL, *l_item_tmp = NULL;
     dap_chain_tx_out_cond_t *l_tx_out_cond = NULL;
     int l_tx_out_cond_idx = 0;
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
@@ -5298,7 +5239,7 @@ dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_le
  * a_public_key[in] public key that signed the transaction
  * a_public_key_size[in] public key size
  */
-uint256_t dap_chain_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type,
+uint256_t dap_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type,
                                                        dap_chain_addr_t *a_addr, dap_chain_tx_out_cond_t **tx_out_cond)
 
 {
@@ -5311,7 +5252,7 @@ uint256_t dap_chain_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, d
     dap_chain_tx_out_cond_t *l_tx_out_cond;
     // Find all transactions
     do {
-        l_tx_tmp = dap_chain_ledger_tx_cache_find_out_cond(a_ledger, a_cond_type, &l_tx_first_hash, &l_tx_out_cond, NULL, NULL);
+        l_tx_tmp = dap_ledger_tx_cache_find_out_cond(a_ledger, a_cond_type, &l_tx_first_hash, &l_tx_out_cond, NULL, NULL);
         // Get out_cond item from transaction
         if(l_tx_tmp) {
             UNUSED(a_addr);
@@ -5327,7 +5268,7 @@ uint256_t dap_chain_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, d
 }
 
 /**
- * @brief dap_chain_ledger_get_list_tx_outs_with_val
+ * @brief dap_ledger_get_list_tx_outs_with_val
  * @param a_ledger
  * @param a_token_ticker
  * @param a_addr_from
@@ -5335,7 +5276,7 @@ uint256_t dap_chain_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, d
  * @param a_value_transfer
  * @return list of dap_chain_tx_used_out_item_t
  */
-dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from,
+dap_list_t *dap_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from,
                                                        uint256_t a_value_need, uint256_t *a_value_transfer)
 {
     dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items
@@ -5344,7 +5285,7 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c
     while(compare256(l_value_transfer, a_value_need) == -1)
     {
         // Get the transaction in the cache by the addr in out item
-        dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from,
+        dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from,
                                                                              &l_tx_cur_hash);
         if(!l_tx)
             break;
@@ -5352,26 +5293,26 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c
         dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
 
         uint32_t l_out_idx_tmp = 0; // current index of 'out' item
-        for (dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_out_idx_tmp++) {
-            dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data;
+        for (dap_list_t *it = l_list_out_items; it; it = dap_list_next(it), l_out_idx_tmp++) {
+            dap_chain_tx_item_type_t l_type = *(uint8_t *)it->data;
             uint256_t l_value = {};
             switch (l_type) {
                 case TX_ITEM_TYPE_OUT_OLD: {
-                    dap_chain_tx_out_old_t *l_out = (dap_chain_tx_out_old_t *)l_list_tmp->data;
+                    dap_chain_tx_out_old_t *l_out = (dap_chain_tx_out_old_t *)it->data;
                     if (!l_out->header.value || memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t)))
                         continue;
                     l_value = GET_256_FROM_64(l_out->header.value);
                 } break;
                 case TX_ITEM_TYPE_OUT: {
-                    dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t *)l_list_tmp->data;
+                    dap_chain_tx_out_t *l_out = (dap_chain_tx_out_t *)it->data;
                     if (memcmp(a_addr_from, &l_out->addr, sizeof(dap_chain_addr_t)) ||
-                            dap_strcmp(dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_cur_hash), a_token_ticker) ||
+                            dap_strcmp(dap_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_cur_hash), a_token_ticker) ||
                             IS_ZERO_256(l_out->header.value))
                         continue;
                     l_value = l_out->header.value;
                 } break;
                 case TX_ITEM_TYPE_OUT_EXT: {
-                    dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)l_list_tmp->data;
+                    dap_chain_tx_out_ext_t *l_out_ext = (dap_chain_tx_out_ext_t *)it->data;
                     if (memcmp(a_addr_from, &l_out_ext->addr, sizeof(dap_chain_addr_t)) ||
                             strcmp((char *)a_token_ticker, l_out_ext->token) ||
                             IS_ZERO_256(l_out_ext->header.value) ) {
@@ -5379,13 +5320,12 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c
                     }
                     l_value = l_out_ext->header.value;
                 } break;
-                case TX_ITEM_TYPE_OUT_COND_OLD:
                 case TX_ITEM_TYPE_OUT_COND:
                 default:
                     continue;
             }
             // Check whether used 'out' items
-            if (!dap_chain_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp, NULL)) {
+            if (!dap_ledger_tx_hash_is_used_out_item (a_ledger, &l_tx_cur_hash, l_out_idx_tmp, NULL)) {
                 dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
                 if ( !l_item ) {
                     log_it(L_CRITICAL, "Out of memory");
@@ -5421,9 +5361,9 @@ dap_list_t *dap_chain_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, c
 }
 
 // Add new verificator callback with associated subtype. Returns 1 if callback replaced, -1 error, overwise returns 0
-int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_chain_ledger_verificator_callback_t a_callback, dap_chain_ledger_updater_callback_t a_callback_added)
+int dap_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_ledger_verificator_callback_t a_callback, dap_ledger_updater_callback_t a_callback_added)
 {
-    dap_chain_ledger_verificator_t *l_new_verificator;
+    dap_ledger_verificator_t *l_new_verificator;
     int l_tmp = (int)a_subtype;
     pthread_rwlock_rdlock(&s_verificators_rwlock);
     HASH_FIND_INT(s_verificators, &l_tmp, l_new_verificator);
@@ -5432,7 +5372,7 @@ int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype,
         l_new_verificator->callback = a_callback;
         return 1;
     }
-    l_new_verificator = DAP_NEW(dap_chain_ledger_verificator_t);
+    l_new_verificator = DAP_NEW(dap_ledger_verificator_t);
     if (!l_new_verificator) {
         log_it(L_CRITICAL, "Memory allocation error");
         return -1;
@@ -5446,7 +5386,7 @@ int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype,
     return 0;
 }
 
-dap_list_t *dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only)
+dap_list_t *dap_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only)
 {
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
     pthread_rwlock_rdlock(&PVT(a_ledger)->ledger_rwlock);
@@ -5457,7 +5397,7 @@ dap_list_t *dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, siz
     dap_list_t *l_list = NULL;
     size_t l_counter = 0;
     size_t l_end = l_offset + a_count;
-    dap_chain_ledger_tx_item_t *l_item_current, *l_item_tmp;
+    dap_ledger_tx_item_t *l_item_current, *l_item_tmp;
     HASH_ITER(hh, l_ledger_pvt->ledger_items, l_item_current, l_item_tmp) {
         if (l_counter++ >= l_offset) {
             if (!a_unspent_only || !l_item_current->cache_data.ts_spent)
@@ -5471,7 +5411,7 @@ dap_list_t *dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, siz
 }
 
 /**
- * @brief dap_chain_ledger_get_list_tx_cond_outs_with_val
+ * @brief dap_ledger_get_list_tx_cond_outs_with_val
  * @param a_ledger
  * @param a_token_ticker
  * @param a_addr_from
@@ -5480,7 +5420,7 @@ dap_list_t *dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, siz
  * @param a_value_transfer
  * @return
  */
-dap_list_t *dap_chain_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker,  const dap_chain_addr_t *a_addr_from,
+dap_list_t *dap_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker,  const dap_chain_addr_t *a_addr_from,
         dap_chain_tx_out_cond_subtype_t a_subtype, uint256_t a_value_need, uint256_t *a_value_transfer)
 {
     dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items
@@ -5489,19 +5429,19 @@ dap_list_t *dap_chain_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledg
     while(compare256(l_value_transfer, a_value_need) == -1)
     {
         // Get the transaction in the cache by the addr in out item
-        dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash);
+        dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash);
         if(!l_tx)
             break;
         // Get all item from transaction by type
         dap_list_t *l_list_out_cond_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_COND, NULL);
 
         uint32_t l_out_idx_tmp = 0; // current index of 'out' item
-        for(dap_list_t *l_list_tmp = l_list_out_cond_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_out_idx_tmp++) {
-            dap_chain_tx_item_type_t l_type = *(uint8_t*) l_list_tmp->data;
+        for(dap_list_t *it = l_list_out_cond_items; it; it = dap_list_next(it), l_out_idx_tmp++) {
+            dap_chain_tx_item_type_t l_type = *(uint8_t*) it->data;
             uint256_t l_value = { };
             switch (l_type) {
             case TX_ITEM_TYPE_OUT_COND: {
-                dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t*) l_list_tmp->data;
+                dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t*) it->data;
                 if(IS_ZERO_256(l_out_cond->header.value) || a_subtype != l_out_cond->header.subtype) {
                     continue;
                 }
@@ -5545,18 +5485,18 @@ dap_list_t *dap_chain_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledg
     return l_list_used_out;
 }
 
-void dap_chain_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_ledger_tx_add_notify_t a_callback, void *a_arg) {
+void dap_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_ledger_tx_add_notify_t a_callback, void *a_arg) {
     if (!a_ledger) {
-        log_it(L_ERROR, "NULL ledger passed to dap_chain_ledger_tx_add_notify()");
+        log_it(L_ERROR, "NULL ledger passed to dap_ledger_tx_add_notify()");
         return;
     }
     if (!a_callback) {
-        log_it(L_ERROR, "NULL callback passed to dap_chain_ledger_tx_add_notify()");
+        log_it(L_ERROR, "NULL callback passed to dap_ledger_tx_add_notify()");
         return;
     }
-    dap_chain_ledger_tx_notifier_t *l_notifier = DAP_NEW(dap_chain_ledger_tx_notifier_t);
+    dap_ledger_tx_notifier_t *l_notifier = DAP_NEW(dap_ledger_tx_notifier_t);
     if (!l_notifier){
-        log_it(L_ERROR, "Can't allocate memory for notifier in dap_chain_ledger_tx_add_notify()");
+        log_it(L_ERROR, "Can't allocate memory for notifier in dap_ledger_tx_add_notify()");
         return;
     }
     l_notifier->callback = a_callback;
@@ -5564,13 +5504,13 @@ void dap_chain_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_ledger_tx_
     PVT(a_ledger)->tx_add_notifiers = dap_list_append(PVT(a_ledger)->tx_add_notifiers, l_notifier);
 }
 
-void dap_chain_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_chain_ledger_bridged_tx_notify_t a_callback, void *a_arg)
+void dap_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_ledger_bridged_tx_notify_t a_callback, void *a_arg)
 {
     if (!a_ledger || !a_callback)
         return;
-    dap_chain_ledger_bridged_tx_notifier_t *l_notifier = DAP_NEW_Z(dap_chain_ledger_bridged_tx_notifier_t);
+    dap_ledger_bridged_tx_notifier_t *l_notifier = DAP_NEW_Z(dap_ledger_bridged_tx_notifier_t);
     if (!l_notifier) {
-        log_it(L_ERROR, "Can't allocate memory for notifier in dap_chain_ledger_tx_add_notify()");
+        log_it(L_ERROR, "Can't allocate memory for notifier in dap_ledger_tx_add_notify()");
         return;
     }
     l_notifier->callback = a_callback;
@@ -5578,12 +5518,12 @@ void dap_chain_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_chain_le
     PVT(a_ledger)->bridged_tx_notifiers = dap_list_append(PVT(a_ledger)->bridged_tx_notifiers , l_notifier);
 }
 
-bool dap_chain_ledger_cache_enabled(dap_ledger_t *a_ledger)
+bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger)
 {
     return PVT(a_ledger)->cached;
 }
 
-void dap_chain_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_chain_ledger_cache_tx_check_callback_t a_callback)
+void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_cache_tx_check_callback_t a_callback)
 {
     PVT(a_ledger)->cache_tx_check_callback = a_callback;
 }
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 88481d80d1..24ab71f8ae 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -257,6 +257,7 @@ static bool s_new_balancer_link_request(dap_chain_net_t *a_net, int a_link_repla
  */
 int dap_chain_net_init()
 {
+    dap_ledger_init();
     dap_stream_ch_chain_init();
     dap_stream_ch_chain_net_init();
     dap_chain_node_client_init();
@@ -1373,7 +1374,7 @@ const char* dap_chain_net_get_type(dap_chain_t *l_chain)
  */
 static void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net)
 {
-    dap_chain_ledger_purge(l_net->pub.ledger, false);
+    dap_ledger_purge(l_net->pub.ledger, false);
     dap_chain_net_srv_stake_purge(l_net);
     dap_chain_net_decree_purge(l_net);
     dap_chain_t *l_chain = NULL;
@@ -1382,7 +1383,8 @@ static void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net)
             l_chain->callback_purge(l_chain);
         if (l_chain->callback_set_min_validators_count)
             l_chain->callback_set_min_validators_count(l_chain, 0);
-        dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank);
+        l_net->pub.fee_value = uint256_0;
+        l_net->pub.fee_addr = c_dap_chain_addr_blank;
         dap_chain_load_all(l_chain);
     }
     DL_FOREACH(l_net->pub.chains, l_chain) {
@@ -1413,7 +1415,7 @@ static bool s_chain_net_reload_ledger_cache_once(dap_chain_net_t *l_net)
         return false;
     }
     // Check the file with provided UUID. Change this UUID to automatically reload cache on next node startup
-    char *l_cache_file = dap_strdup_printf( "%s/%s.cache", l_cache_dir, DAP_CHAIN_LEDGER_CACHE_RELOAD_ONCE_UUID);
+    char *l_cache_file = dap_strdup_printf( "%s/%s.cache", l_cache_dir, DAP_LEDGER_CACHE_RELOAD_ONCE_UUID);
     DAP_DELETE(l_cache_dir);
     // create file, if it not presented. If file exists, ledger cache operation is stopped
     if (dap_file_simple_test(l_cache_file)) {
@@ -1622,7 +1624,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
                 dap_string_t * l_ret_str = dap_string_new("Transactions statistics:\n");
                 dap_string_append_printf( l_ret_str, "\tFrom: %s\tTo: %s\n", l_from_str_new, l_to_str_new);
                 log_it(L_INFO, "Calc TPS from %s to %s", l_from_str_new, l_to_str_new);
-                uint64_t l_tx_count = dap_chain_ledger_count_from_to ( l_net->pub.ledger, l_from_ts, l_to_ts);
+                uint64_t l_tx_count = dap_ledger_count_from_to ( l_net->pub.ledger, l_from_ts, l_to_ts);
                 long double l_tps = l_to_ts == l_from_ts ? 0 :
                                                      (long double) l_tx_count / (long double) ( l_to_ts - l_from_ts );
                 dap_string_append_printf( l_ret_str, "\tSpeed:  %.3Lf TPS\n", l_tps );
@@ -1632,7 +1634,7 @@ static int s_cli_net(int argc, char **argv, char **a_str_reply)
             } else if (strcmp(l_stats_str, "tps") == 0) {
                 struct timespec l_from_time_acc = {}, l_to_time_acc = {};
                 dap_string_t * l_ret_str = dap_string_new("Transactions per second peak values:\n");
-                size_t l_tx_num = dap_chain_ledger_count_tps(l_net->pub.ledger, &l_from_time_acc, &l_to_time_acc);
+                size_t l_tx_num = dap_ledger_count_tps(l_net->pub.ledger, &l_from_time_acc, &l_to_time_acc);
                 if (l_tx_num) {
                     localtime_r(&l_from_time_acc.tv_sec, &l_from_tm);
                     strftime(l_from_str_new, sizeof(l_from_str_new), c_time_fmt, &l_from_tm);
@@ -2029,6 +2031,8 @@ void dap_chain_net_delete(dap_chain_net_t *a_net)
     DAP_DEL_Z(PVT(a_net)->seed_nodes_ipv4);
     DAP_DEL_Z(PVT(a_net)->seed_nodes_ipv6);
     DAP_DEL_Z(PVT(a_net)->node_info);
+    dap_ledger_purge(a_net->pub.ledger, true);
+    dap_ledger_handle_free(a_net->pub.ledger);
     DAP_DELETE(a_net);
 }
 
@@ -2198,34 +2202,6 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx)
         l_net_pvt->seed_nodes_ipv4[j] = tmp;
     }
 
-    l_net_pvt->node_info = dap_chain_node_info_read(l_net, &g_node_addr);
-    if ( !l_net_pvt->node_info ) { // If not present - create it
-        l_net_pvt->node_info = DAP_NEW_Z(dap_chain_node_info_t);
-        if (!l_net_pvt->node_info) {
-            log_it(L_CRITICAL, "Memory allocation error");
-            dap_chain_net_delete(l_net);
-            return -6;
-        }
-        l_net_pvt->node_info->hdr.address = g_node_addr;
-        if (dap_config_get_item_bool_default(g_config, "server", "enabled", false)) {
-            const char *l_ext_addr_v4 = dap_config_get_item_str_default(g_config, "server", "ext_address", NULL);
-            const char *l_ext_addr_v6 = dap_config_get_item_str_default(g_config, "server", "ext_address6", NULL);
-            uint16_t l_node_info_port = dap_config_get_item_uint16_default(g_config, "server", "ext_port_tcp",
-                                        dap_config_get_item_uint16_default(g_config, "server", "listen_port_tcp", 8079));
-            if (l_ext_addr_v4)
-                inet_pton(AF_INET, l_ext_addr_v4, &l_net_pvt->node_info->hdr.ext_addr_v4);
-            if (l_ext_addr_v6)
-                inet_pton(AF_INET6, l_ext_addr_v6, &l_net_pvt->node_info->hdr.ext_addr_v6);
-            l_net_pvt->node_info->hdr.ext_port = l_node_info_port;
-        } else
-            log_it(L_INFO, "Server is disabled, add only node address in nodelist");
-    }
-
-    log_it(L_NOTICE, "Net load information: node_addr " NODE_ADDR_FP_STR ", balancers links %u, cell_id 0x%016"DAP_UINT64_FORMAT_X,
-           NODE_ADDR_FP_ARGS_S(g_node_addr),
-           l_net_pvt->seed_nodes_count,
-           l_net_pvt->node_info->hdr.cell_id.uint64);
-
     /* *** Chains init by configs *** */
     char * l_chains_path = dap_strdup_printf("%s/network/%s", dap_config_path(), l_net->pub.name);
     DIR * l_chains_dir = opendir(l_chains_path);
@@ -2323,11 +2299,11 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx)
     case NODE_ROLE_LIGHT:
         break;
     case NODE_ROLE_FULL:
-        l_ledger_flags |= DAP_CHAIN_LEDGER_CHECK_LOCAL_DS;
+        l_ledger_flags |= DAP_LEDGER_CHECK_LOCAL_DS;
         if (dap_config_get_item_bool_default(g_config, "ledger", "cache_enabled", false))
-            l_ledger_flags |= DAP_CHAIN_LEDGER_CACHE_ENABLED;
+            l_ledger_flags |= DAP_LEDGER_CACHE_ENABLED;
     default:
-        l_ledger_flags |= DAP_CHAIN_LEDGER_CHECK_CELLS_DS | DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION;
+        l_ledger_flags |= DAP_LEDGER_CHECK_CELLS_DS | DAP_LEDGER_CHECK_TOKEN_EMISSION;
     }
     for (dap_chain_t *l_chain = l_net->pub.chains; l_chain; l_chain = l_chain->next) {
         if (!l_chain->callback_get_poa_certs)
@@ -2339,7 +2315,7 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx)
     if (!l_net->pub.keys)
         log_it(L_WARNING, "PoA certificates for net %s not found", l_net->pub.name);
     // init LEDGER model
-    l_net->pub.ledger = dap_chain_ledger_create(l_ledger_flags, l_net->pub.id, l_net->pub.name, l_net->pub.native_ticker, l_net->pub.keys);
+    l_net->pub.ledger = dap_ledger_create(l_net, l_ledger_flags);
 
     return 0;
 }
@@ -2363,7 +2339,7 @@ int s_net_load(dap_chain_net_t *a_net)
     // reload ledger cache at once
     if (s_chain_net_reload_ledger_cache_once(l_net)) {
         log_it(L_WARNING,"Start one time ledger cache reloading");
-        dap_chain_ledger_purge(l_net->pub.ledger, false);
+        dap_ledger_purge(l_net->pub.ledger, false);
         dap_chain_net_srv_stake_purge(l_net);
     } else
         dap_chain_net_srv_stake_load_cache(l_net);
@@ -2373,7 +2349,8 @@ int s_net_load(dap_chain_net_t *a_net)
     // load chains
     dap_chain_t *l_chain = l_net->pub.chains;
     while(l_chain){
-        dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank);
+        l_net->pub.fee_value = uint256_0;
+        l_net->pub.fee_addr = c_dap_chain_addr_blank;
         if (!dap_chain_load_all(l_chain)) {
             log_it (L_NOTICE, "Loaded chain files");
             if (DAP_CHAIN_PVT(l_chain)->need_reorder) {
@@ -2385,8 +2362,9 @@ int s_net_load(dap_chain_net_t *a_net)
                 DAP_CHAIN_PVT(l_chain)->need_reorder = false;
                 if (l_chain->callback_purge) {
                     l_chain->callback_purge(l_chain);
-                    dap_chain_ledger_purge(l_net->pub.ledger, false);
-                    dap_chain_ledger_set_fee(l_net->pub.ledger, uint256_0, c_dap_chain_addr_blank);
+                    dap_ledger_purge(l_net->pub.ledger, false);
+                    l_net->pub.fee_value = uint256_0;
+                    l_net->pub.fee_addr = c_dap_chain_addr_blank;
                     dap_chain_net_decree_purge(l_net);
                     dap_chain_load_all(l_chain);
                 } else
@@ -2468,7 +2446,7 @@ int s_net_load(dap_chain_net_t *a_net)
 
     l_net_pvt->load_mode = false;
     if (l_net->pub.ledger)
-        dap_chain_ledger_load_end(l_net->pub.ledger);
+        dap_ledger_load_end(l_net->pub.ledger);
 
     l_net_pvt->balancer_http = !dap_config_get_item_bool_default(l_cfg, "general", "use_dns_links", false);
 
@@ -2526,6 +2504,34 @@ int s_net_load(dap_chain_net_t *a_net)
         if (l_chain->callback_created)
             l_chain->callback_created(l_chain, l_cfg);
 
+    l_net_pvt->node_info = dap_chain_node_info_read(l_net, &g_node_addr);
+    if ( !l_net_pvt->node_info ) { // If not present - create it
+        l_net_pvt->node_info = DAP_NEW_Z(dap_chain_node_info_t);
+        if (!l_net_pvt->node_info) {
+            log_it(L_CRITICAL, "Memory allocation error");
+            dap_chain_net_delete(l_net);
+            return -6;
+        }
+        l_net_pvt->node_info->hdr.address = g_node_addr;
+        if (dap_config_get_item_bool_default(g_config, "server", "enabled", false)) {
+            const char *l_ext_addr_v4 = dap_config_get_item_str_default(g_config, "server", "ext_address", NULL);
+            const char *l_ext_addr_v6 = dap_config_get_item_str_default(g_config, "server", "ext_address6", NULL);
+            uint16_t l_node_info_port = dap_config_get_item_uint16_default(g_config, "server", "ext_port_tcp",
+                                        dap_config_get_item_uint16_default(g_config, "server", "listen_port_tcp", 8079));
+            if (l_ext_addr_v4)
+                inet_pton(AF_INET, l_ext_addr_v4, &l_net_pvt->node_info->hdr.ext_addr_v4);
+            if (l_ext_addr_v6)
+                inet_pton(AF_INET6, l_ext_addr_v6, &l_net_pvt->node_info->hdr.ext_addr_v6);
+            l_net_pvt->node_info->hdr.ext_port = l_node_info_port;
+        } else
+            log_it(L_INFO, "Server is disabled, add only node address in nodelist");
+    }
+
+    log_it(L_NOTICE, "Net load information: node_addr " NODE_ADDR_FP_STR ", balancers links %u, cell_id 0x%016"DAP_UINT64_FORMAT_X,
+           NODE_ADDR_FP_ARGS_S(g_node_addr),
+           l_net_pvt->seed_nodes_count,
+           l_net_pvt->node_info->hdr.cell_id.uint64);
+
     // TODO rework alias concept
     const char * l_node_addr_type = dap_config_get_item_str_default(l_cfg , "general", "node_addr_type", "auto");
     if (!dap_strcmp(l_node_addr_type, "static")) {
@@ -2667,11 +2673,11 @@ dap_chain_net_t *dap_chain_net_by_name(const char *a_name)
 }
 
 /**
- * @brief dap_chain_ledger_by_net_name
+ * @brief dap_ledger_by_net_name
  * @param a_net_name
  * @return
  */
-dap_ledger_t * dap_chain_ledger_by_net_name( const char * a_net_name)
+dap_ledger_t * dap_ledger_by_net_name( const char * a_net_name)
 {
     dap_chain_net_t *l_net = dap_chain_net_by_name(a_net_name);
     return l_net ? l_net->pub.ledger : NULL;
@@ -2914,9 +2920,9 @@ void dap_chain_net_proc_mempool(dap_chain_net_t *a_net)
 /**
  * @brief dap_chain_net_verify_datum_for_add
  * process datum verification process. Can be:
- *   if DAP_CHAIN_DATUM_TX, called dap_chain_ledger_tx_add_check
- *   if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_chain_ledger_token_decl_add_check
- *   if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_chain_ledger_token_emission_add_check
+ *   if DAP_CHAIN_DATUM_TX, called dap_ledger_tx_add_check
+ *   if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_ledger_token_decl_add_check
+ *   if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_ledger_token_emission_add_check
  *   if DAP_CHAIN_DATUM_DECREE
  * @param a_net
  * @param a_datum
@@ -2931,15 +2937,18 @@ int dap_chain_net_verify_datum_for_add(dap_chain_t *a_chain, dap_chain_datum_t *
     dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id);
     switch (a_datum->header.type_id) {
     case DAP_CHAIN_DATUM_TX:
-        return dap_chain_ledger_tx_add_check(l_net->pub.ledger, (dap_chain_datum_tx_t *)a_datum->data, a_datum->header.data_size, a_datum_hash);
+        return dap_ledger_tx_add_check(l_net->pub.ledger, (dap_chain_datum_tx_t *)a_datum->data, a_datum->header.data_size, a_datum_hash);
     case DAP_CHAIN_DATUM_TOKEN_DECL:
-        return dap_chain_ledger_token_decl_add_check(l_net->pub.ledger, (dap_chain_datum_token_t *)a_datum->data, a_datum->header.data_size);
+        return dap_ledger_token_decl_add_check(l_net->pub.ledger, (dap_chain_datum_token_t *)a_datum->data, a_datum->header.data_size);
     case DAP_CHAIN_DATUM_TOKEN_EMISSION:
-        return dap_chain_ledger_token_emission_add_check(l_net->pub.ledger, a_datum->data, a_datum->header.data_size, a_datum_hash);
+        return dap_ledger_token_emission_add_check(l_net->pub.ledger, a_datum->data, a_datum->header.data_size, a_datum_hash);
     case DAP_CHAIN_DATUM_DECREE:
         return dap_chain_net_decree_verify((dap_chain_datum_decree_t *)a_datum->data, l_net, a_datum->header.data_size, a_datum_hash);
-    case DAP_CHAIN_DATUM_ANCHOR:
-        return dap_chain_net_anchor_verify((dap_chain_datum_anchor_t *)a_datum->data, a_datum->header.data_size);
+    case DAP_CHAIN_DATUM_ANCHOR: {
+        int l_result = dap_chain_net_anchor_verify((dap_chain_datum_anchor_t *)a_datum->data, a_datum->header.data_size);
+        if (l_result)
+            return l_result;
+    }
     default:
         if (a_chain->callback_datum_find_by_hash &&
                 a_chain->callback_datum_find_by_hash(a_chain, a_datum_hash, NULL, NULL))
@@ -2951,11 +2960,11 @@ int dap_chain_net_verify_datum_for_add(dap_chain_t *a_chain, dap_chain_datum_t *
 char *dap_chain_net_verify_datum_err_code_to_str(dap_chain_datum_t *a_datum, int a_code){
     switch (a_datum->header.type_id) {
     case DAP_CHAIN_DATUM_TX:
-        return dap_chain_ledger_tx_check_err_str(a_code);
+        return dap_ledger_tx_check_err_str(a_code);
     case DAP_CHAIN_DATUM_TOKEN_DECL:
-        return dap_chain_ledger_token_decl_add_err_code_to_str(a_code);
+        return dap_ledger_token_decl_add_err_code_to_str(a_code);
     case DAP_CHAIN_DATUM_TOKEN_EMISSION:
-        return dap_chain_ledger_token_emission_err_code_to_str(a_code);
+        return dap_ledger_token_emission_err_code_to_str(a_code);
     default:
         return !a_code ? "DAP_CHAIN_DATUM_VERIFY_OK" : dap_itoa(a_code);
 
@@ -3161,10 +3170,10 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t
             return dap_chain_net_anchor_load(l_anchor, a_chain);
         }
         case DAP_CHAIN_DATUM_TOKEN_DECL:
-            return dap_chain_ledger_token_load(l_ledger, a_datum->data, a_datum->header.data_size);
+            return dap_ledger_token_load(l_ledger, a_datum->data, a_datum->header.data_size);
 
         case DAP_CHAIN_DATUM_TOKEN_EMISSION:
-            return dap_chain_ledger_token_emission_load(l_ledger, a_datum->data, a_datum->header.data_size, a_datum_hash);
+            return dap_ledger_token_emission_load(l_ledger, a_datum->data, a_datum->header.data_size, a_datum_hash);
 
         case DAP_CHAIN_DATUM_TX: {
             dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)a_datum->data;
@@ -3173,7 +3182,7 @@ int dap_chain_datum_add(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, size_t
                 log_it(L_WARNING, "Corrupted trnsaction, datum size %zd is not equal to size of TX %zd", l_datum_data_size, l_tx_size);
                 return -102;
             }
-            return dap_chain_ledger_tx_load(l_ledger, l_tx, a_datum_hash);
+            return dap_ledger_tx_load(l_ledger, l_tx, a_datum_hash);
         }
         case DAP_CHAIN_DATUM_CA:
             return dap_cert_chain_file_save(a_datum, a_chain->net_name);
diff --git a/modules/net/dap_chain_net_anchor.c b/modules/net/dap_chain_net_anchor.c
index 4e8ac387c3..dfa2bb8e58 100644
--- a/modules/net/dap_chain_net_anchor.c
+++ b/modules/net/dap_chain_net_anchor.c
@@ -28,6 +28,7 @@
 #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_datum_decree.h"
 
diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c
index bef168e6f6..119ce7317a 100644
--- a/modules/net/dap_chain_net_decree.c
+++ b/modules/net/dap_chain_net_decree.c
@@ -106,7 +106,6 @@ int dap_chain_net_decree_deinit(dap_chain_net_t *a_net)
 {
     dap_chain_net_decree_t *l_decree = a_net->pub.decree;
     dap_list_free_full(l_decree->pkeys, NULL);
-    DAP_DELETE(l_decree->fee_addr);
     DAP_DELETE(l_decree);
     struct decree_hh *l_decree_hh, *l_tmp;
     HASH_ITER(hh, s_decree_hh, l_decree_hh, l_tmp) {
@@ -185,6 +184,11 @@ int dap_chain_net_decree_verify(dap_chain_datum_decree_t *a_decree, dap_chain_ne
     size_t l_num_of_unique_signs = 0;
     dap_sign_t **l_unique_signs = dap_sign_get_unique_signs(l_signs_block, l_signs_size, &l_num_of_unique_signs);
 
+    if (!a_net->pub.decree) {
+        log_it(L_ERROR, "Decree module hasn't been initialized yet");
+        return -404;
+    }
+
     uint16_t l_min_signs = a_net->pub.decree->min_num_of_owners;
     if (l_num_of_unique_signs < l_min_signs) {
         log_it(L_WARNING, "Not enough unique signatures, get %zu from %hu", l_num_of_unique_signs, l_min_signs);
@@ -369,37 +373,21 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai
     switch (a_decree->header.sub_type)
     {
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_FEE:
-                if(dap_chain_datum_decree_get_fee_addr(a_decree, &l_addr)){
-                    if(l_net->pub.decree->fee_addr != NULL)
-                    {
-                        l_addr = *l_net->pub.decree->fee_addr;
-                    } else
-                    {
+                if (dap_chain_datum_decree_get_fee_addr(a_decree, &l_addr)) {
+                    if (dap_chain_addr_is_blank(&l_net->pub.fee_addr)) {
                         log_it(L_WARNING, "Fee wallet address not set.");
                         return -111;
-                    }
-                } else{
-                    dap_chain_addr_t *l_decree_addr = DAP_NEW_Z_SIZE(dap_chain_addr_t, sizeof(dap_chain_addr_t));
-                    if (!l_decree_addr) {
-                        log_it(L_CRITICAL, "Memory allocation error");
-                        return -1;
-                    }
-                    memcpy(l_decree_addr, &l_addr, sizeof(dap_chain_addr_t));
-                    l_net->pub.decree->fee_addr = l_decree_addr;
+                    } else
+                        l_addr = l_net->pub.fee_addr;
                 }
-
-                if (!dap_chain_datum_decree_get_fee(a_decree, &l_uint256_buffer)){
-                    if (!a_apply)
-                        break;
-
-                    if (!dap_chain_net_tx_add_fee(a_chain->net_id, l_uint256_buffer, l_addr)) {
-                        log_it(L_WARNING,"Can't add/replace fee value.");
-                        return -102;
-                    }
-                }else{
+                if (dap_chain_datum_decree_get_fee(a_decree, &l_uint256_buffer)) {
                     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_chain->net_id, l_uint256_buffer, l_addr))
+                    log_it(L_ERROR, "Can't set fee value for network %s", a_chain->net_name);
             break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS:
             l_owners_list = dap_chain_datum_decree_get_owners(a_decree, &l_uint16_buffer);
@@ -550,7 +538,17 @@ static int s_common_decree_handler(dap_chain_datum_decree_t * a_decree, dap_chai
                 l_tsd_offset += l_tsd_size;
             }
         } break;
-        default: return -1;
+        case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD: {
+            if (dap_chain_datum_decree_get_value(a_decree, &l_uint256_buffer)) {
+                log_it(L_WARNING,"Can't get value from decree.");
+                return -103;
+            }
+            if (!a_apply)
+                break;
+            a_net->pub.base_reward = l_uint256_buffer;
+        } break;
+        default:
+            return -1;
     }
 
     return 0;
diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c
index 3a47bb05b7..ecc2fe7917 100644
--- a/modules/net/dap_chain_net_tx.c
+++ b/modules/net/dap_chain_net_tx.c
@@ -26,6 +26,7 @@
 #include "dap_chain_net_tx.h"
 #include "dap_chain_cell.h"
 #include "dap_chain_common.h"
+#include "dap_chain_ledger.h"
 #include "dap_chain_datum_tx_in_cond.h"
 #include "dap_chain_tx.h"
 #include "dap_list.h"
@@ -93,7 +94,7 @@ dap_chain_datum_tx_spends_items_t * dap_chain_net_get_tx_cond_all_with_spends_by
 
                                 if(a_search_type == TX_SEARCH_TYPE_CELL_SPENT || a_search_type == TX_SEARCH_TYPE_NET_SPENT ){
                                     dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx);
-                                    bool l_is_spent = !!dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash);
+                                    bool l_is_spent = !!dap_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash);
                                     DAP_DELETE(l_tx_hash);
                                     if(!l_is_spent)
                                         continue;
@@ -399,7 +400,7 @@ static void s_get_tx_cond_all_for_addr_callback(dap_chain_net_t* a_net, dap_chai
 //                dap_chain_tx_t * l_tx = dap_chain_tx_hh_find( l_args->tx_all_hh, &l_in->header.tx_prev_hash);
                 if( dap_chain_tx_hh_find( l_args->tx_all_hh, &l_in->header.tx_prev_hash) ){ // Its input thats closing output for target address - we note it
                     l_tx_from_addr = true;
-                    //l_tx_from_addr_token = dap_chain_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx->hash);
+                    //l_tx_from_addr_token = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx->hash);
                 }
             }break;
             case TX_ITEM_TYPE_IN_COND:{
@@ -537,7 +538,7 @@ dap_list_t * dap_chain_net_get_tx_cond_all_by_srv_uid(dap_chain_net_t * a_net, c
 
                                 if(a_search_type == TX_SEARCH_TYPE_CELL_SPENT || a_search_type == TX_SEARCH_TYPE_NET_SPENT ){
                                     dap_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx);
-                                    bool l_is_spent = !!dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash);
+                                    bool l_is_spent = !!dap_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash);
                                     DAP_DELETE(l_tx_hash);
                                     if(!l_is_spent)
                                         continue;
@@ -566,7 +567,7 @@ dap_list_t * dap_chain_net_get_tx_cond_all_by_srv_uid(dap_chain_net_t * a_net, c
 
         case TX_SEARCH_TYPE_NET_UNSPENT:
         case TX_SEARCH_TYPE_CELL_UNSPENT:
-            l_ret = dap_chain_ledger_tx_cache_find_out_cond_all(l_ledger, a_srv_uid);
+            l_ret = dap_ledger_tx_cache_find_out_cond_all(l_ledger, a_srv_uid);
             break;
     }
     return l_ret;
@@ -637,70 +638,43 @@ dap_chain_datum_tx_t *dap_chain_net_get_tx_by_hash(dap_chain_net_t *a_net, dap_c
                 continue;
             if ((a_search_type == TX_SEARCH_TYPE_CELL_SPENT ||
                     a_search_type == TX_SEARCH_TYPE_NET_SPENT) &&
-                    (!dap_chain_ledger_tx_spent_find_by_hash(l_ledger, a_tx_hash)))
+                    (!dap_ledger_tx_spent_find_by_hash(l_ledger, a_tx_hash)))
                 return NULL;
             return (dap_chain_datum_tx_t *)l_datum->data;
         }
     case TX_SEARCH_TYPE_NET_UNSPENT:
     case TX_SEARCH_TYPE_CELL_UNSPENT:
-        return dap_chain_ledger_tx_find_by_hash(l_ledger, a_tx_hash);
+        return dap_ledger_tx_find_by_hash(l_ledger, a_tx_hash);
     default: break;
     }
     return NULL;
 }
 
-static struct net_fee {
-    dap_chain_net_id_t net_id;
-    uint256_t value;            // Network fee value
-    dap_chain_addr_t fee_addr;  // Addr collector
-    UT_hash_handle hh;
-} *s_net_fees = NULL; // Governance statements for networks
-
 bool dap_chain_net_tx_get_fee(dap_chain_net_id_t a_net_id, uint256_t *a_value, dap_chain_addr_t *a_addr)
 {
-    struct net_fee *l_net_fee;
     dap_chain_net_t *l_net = dap_chain_net_by_id(a_net_id);
-
     if (!l_net){
         log_it(L_WARNING, "Can't find net with id 0x%016"DAP_UINT64_FORMAT_x"", a_net_id.uint64);
         return false;
     }
-
-    HASH_FIND(hh, s_net_fees, &a_net_id, sizeof(dap_chain_net_id_t), l_net_fee);
-    if (!l_net_fee || IS_ZERO_256(l_net_fee->value))
+    if (IS_ZERO_256(l_net->pub.fee_value))
         return false;
     if (a_value)
-        *a_value = l_net_fee->value;
+        *a_value = l_net->pub.fee_value;
     if (a_addr)
-        *a_addr = l_net_fee->fee_addr;
+        *a_addr = l_net->pub.fee_addr;
     return true;
 }
 
-bool dap_chain_net_tx_add_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, dap_chain_addr_t a_addr)
+bool dap_chain_net_tx_set_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, dap_chain_addr_t a_addr)
 {
-    struct net_fee *l_net_fee = NULL;
-    bool l_found = false;
     dap_chain_net_t *l_net = dap_chain_net_by_id(a_net_id);
-
     if (!l_net){
         log_it(L_WARNING, "Can't find net with id 0x%016"DAP_UINT64_FORMAT_x"", a_net_id.uint64);
         return false;
     }
-
-    HASH_FIND(hh, s_net_fees, &a_net_id, sizeof(dap_chain_net_id_t), l_net_fee);
-
-    if (l_net_fee)
-        l_found = true;
-    else
-        l_net_fee = DAP_NEW(struct net_fee);
-    l_net_fee->net_id = a_net_id;
-    l_net_fee->value = a_value;
-    l_net_fee->fee_addr = a_addr;
-
-    if (!l_found)
-        HASH_ADD(hh, s_net_fees, net_id, sizeof(dap_chain_net_id_t), l_net_fee);
-
-    dap_chain_ledger_set_fee(l_net->pub.ledger, a_value, a_addr);
+    l_net->pub.fee_value = a_value;
+    l_net->pub.fee_addr = a_addr;
 
     return true;
 }
diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c
index 6519c1026c..8de6289a3b 100644
--- a/modules/net/dap_chain_node.c
+++ b/modules/net/dap_chain_node.c
@@ -46,6 +46,7 @@
 #include "dap_global_db.h"
 #include "dap_chain_node.h"
 #include "dap_chain_cell.h"
+#include "dap_chain_ledger.h"
 
 #define LOG_TAG "chain_node"
 
@@ -227,7 +228,7 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force)
                     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) ||
                             IS_ZERO_256(l_tx_fee)) {
-                        if (!dap_chain_ledger_tx_poa_signed(l_net->pub.ledger, l_tx)) {
+                        if (!dap_ledger_tx_poa_signed(l_net->pub.ledger, l_tx)) {
                             log_it(L_WARNING, "Can't get fee value from tx %s", l_objs[i].key);
                             continue;
                         } else
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 360c3f2a1f..595e06cde4 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -569,7 +569,7 @@ void s_dap_chain_net_purge(dap_chain_net_t * a_net)
     if (!a_net)
         return;
     dap_chain_t *l_chain = NULL;
-    dap_chain_ledger_purge(a_net->pub.ledger, false);
+    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) {
@@ -579,7 +579,8 @@ void s_dap_chain_net_purge(dap_chain_net_t * a_net)
             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);
-        dap_chain_ledger_set_fee(a_net->pub.ledger, uint256_0, c_dap_chain_addr_blank);
+        a_net->pub.fee_value = uint256_0;
+        a_net->pub.fee_addr = c_dap_chain_addr_blank;
         dap_chain_load_all(l_chain);
     }
 }
@@ -1478,7 +1479,7 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
         l_decree->header.signs_size = 0;
         memcpy(l_decree->data_n_signs, l_addr_tsd, dap_tsd_size(l_addr_tsd));
         size_t l_total_signs_success = 0;
-        l_decree = dap_chain_datum_decree_in_cycle(l_certs, l_decree, l_certs_count, &l_total_signs_success);
+        l_decree = dap_chain_datum_decree_sign_in_cycle(l_certs, l_decree, l_certs_count, &l_total_signs_success);
         if (!l_decree || !l_total_signs_success) {
             dap_cli_server_cmd_set_reply_text(a_str_reply,
                                               "Decree creation failed. Successful count of certificate signing is 0");
@@ -1539,7 +1540,7 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
         l_decree->header.signs_size = 0;
         memcpy(l_decree->data_n_signs, l_addr_tsd, dap_tsd_size(l_addr_tsd));
         size_t l_total_signs_success = 0;
-        l_decree = dap_chain_datum_decree_in_cycle(l_certs, l_decree, l_certs_count, &l_total_signs_success);
+        l_decree = dap_chain_datum_decree_sign_in_cycle(l_certs, l_decree, l_certs_count, &l_total_signs_success);
         if (!l_decree || !l_total_signs_success) {
             dap_cli_server_cmd_set_reply_text(a_str_reply,
                                               "Decree creation failed. Successful count of certificate signing is 0");
@@ -2048,7 +2049,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
 
             size_t l_l_addr_tokens_size = 0;
             char **l_l_addr_tokens = NULL;
-            dap_chain_ledger_addr_get_token_ticker_all(l_ledger, l_addr, &l_l_addr_tokens, &l_l_addr_tokens_size);
+            dap_ledger_addr_get_token_ticker_all(l_ledger, l_addr, &l_l_addr_tokens, &l_l_addr_tokens_size);
             if(l_l_addr_tokens_size > 0)
                 dap_string_append_printf(l_string_ret, "balance:\n");
             else
@@ -2056,7 +2057,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
 
             for(size_t i = 0; i < l_l_addr_tokens_size; i++) {
                 if(l_l_addr_tokens[i]) {
-                    uint256_t l_balance = dap_chain_ledger_calc_balance(l_ledger, l_addr, l_l_addr_tokens[i]);
+                    uint256_t l_balance = dap_ledger_calc_balance(l_ledger, l_addr, l_l_addr_tokens[i]);
                     char *l_balance_coins = dap_chain_balance_to_coins(l_balance);
                     char *l_balance_datoshi = dap_chain_balance_print(l_balance);
                     dap_string_append_printf(l_string_ret, "\t%s (%s) %s\n", l_balance_coins,
@@ -2642,12 +2643,12 @@ dap_list_t *s_tickers_list_created(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *
             case TX_ITEM_TYPE_IN:
                 l_parent_hash = ((dap_chain_tx_in_t*)l_item_in)->header.tx_prev_hash;
                 l_parrent_tx_out_idx = ((dap_chain_tx_in_t*)l_item_in)->header.tx_out_prev_idx;
-                l_tx_parent = dap_chain_ledger_tx_find_by_hash(a_net->pub.ledger, &((dap_chain_tx_in_t*)l_item_in)->header.tx_prev_hash);
+                l_tx_parent = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &((dap_chain_tx_in_t*)l_item_in)->header.tx_prev_hash);
                 break;
             case TX_ITEM_TYPE_IN_COND:
                 l_parent_hash = ((dap_chain_tx_in_cond_t*)l_item_in)->header.tx_prev_hash;
                 l_parrent_tx_out_idx = ((dap_chain_tx_in_cond_t*)l_item_in)->header.tx_out_prev_idx;
-                l_tx_parent = dap_chain_ledger_tx_find_by_hash(a_net->pub.ledger, &((dap_chain_tx_in_cond_t*)l_item_in)->header.tx_prev_hash);
+                l_tx_parent = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &((dap_chain_tx_in_cond_t*)l_item_in)->header.tx_prev_hash);
                 break;
         }
         if (!l_tx_parent) {
@@ -2659,7 +2660,7 @@ dap_list_t *s_tickers_list_created(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *
                 l_tx_parent, TX_ITEM_TYPE_OUT_ALL, l_parrent_tx_out_idx);
         switch(dap_chain_datum_tx_item_get_type(l_out_unknown)) {
             case TX_ITEM_TYPE_OUT:
-                l_current_token = dap_chain_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_parent_hash);
+                l_current_token = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_parent_hash);
                 l_tickers = dap_list_append(l_tickers, (void *)l_current_token);
                 break;
             case TX_ITEM_TYPE_OUT_EXT:
@@ -2668,7 +2669,7 @@ dap_list_t *s_tickers_list_created(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *
                 break;
             case TX_ITEM_TYPE_OUT_COND:
                 if(((dap_chain_tx_out_cond_t*)l_out_unknown)->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) {
-                    l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_parent_hash);
+                    l_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_parent_hash);
                 }
                 break;
         }
@@ -2714,7 +2715,7 @@ const char* s_tx_get_main_ticker(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *a_
 static bool dap_chain_mempool_find_addr_ledger(dap_ledger_t* a_ledger, dap_chain_hash_fast_t* a_tx_prev_hash, dap_chain_addr_t *a_addr)
 {
     dap_chain_datum_tx_t *l_tx;
-    l_tx = dap_chain_ledger_tx_find_by_hash (a_ledger,a_tx_prev_hash);
+    l_tx = dap_ledger_tx_find_by_hash (a_ledger,a_tx_prev_hash);
     dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL), *l_item;
     if(!l_list_out_items)
         return false;
@@ -3074,7 +3075,7 @@ int com_mempool_check(int a_argc, char **a_argv, char ** a_str_reply)
                     char l_atom_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
                     dap_chain_hash_fast_to_str(&l_atom_hash, l_atom_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
                     dap_string_append_printf(l_str_reply, "Atom hash is %s return code is %d (%s)\n",
-                                                            l_atom_hash_str, l_ret_code, dap_chain_ledger_tx_check_err_str(l_ret_code));
+                                                            l_atom_hash_str, l_ret_code, dap_ledger_tx_check_err_str(l_ret_code));
                 }
                 dap_chain_datum_dump(l_str_reply, l_datum, l_hash_out_type, l_net->pub.id);
                 if (!l_found_in_chains)
@@ -3238,7 +3239,7 @@ int com_mempool_proc_all(int argc, char ** argv, char ** a_str_reply) {
     }
 
 #ifdef DAP_TPS_TEST
-    dap_chain_ledger_set_tps_start_time(l_net->pub.ledger);
+    dap_ledger_set_tps_start_time(l_net->pub.ledger);
 #endif
     dap_chain_node_mempool_process_all(l_chain, true);
     dap_cli_server_cmd_set_reply_text(a_str_reply, "The entire mempool has been processed in %s.%s.",
@@ -3469,7 +3470,7 @@ static int s_parse_additional_token_decl_arg(int a_argc, char ** a_argv, char **
     a_params->ext.parsed_flags = l_flags;
     if (a_params->ext.delegated_token_from) {
         dap_chain_datum_token_t* l_delegated_token_from;
-        if (NULL == (l_delegated_token_from = dap_chain_ledger_token_ticker_check(a_params->net->pub.ledger, a_params->ext.delegated_token_from))) {
+        if (NULL == (l_delegated_token_from = dap_ledger_token_ticker_check(a_params->net->pub.ledger, a_params->ext.delegated_token_from))) {
             dap_cli_server_cmd_set_reply_text(a_str_reply, "To create a delegated token %s, can't find token by ticker %s", a_params->ticker, a_params->ext.delegated_token_from);
             return -91;
         }
@@ -3802,7 +3803,7 @@ int com_token_decl(int a_argc, char ** a_argv, char ** a_str_reply)
             }
 			if (l_params->ext.delegated_token_from){
 				dap_chain_datum_token_t *l_delegated_token_from;
-				if (NULL == (l_delegated_token_from = dap_chain_ledger_token_ticker_check(l_net->pub.ledger, l_params->ext.delegated_token_from))) {
+				if (NULL == (l_delegated_token_from = dap_ledger_token_ticker_check(l_net->pub.ledger, l_params->ext.delegated_token_from))) {
                     dap_cli_server_cmd_set_reply_text(a_str_reply,"To create a delegated token %s, can't find token by ticket %s", l_ticker, l_params->ext.delegated_token_from);
                     DAP_DEL_Z(l_params);
 					return -91;
@@ -5367,7 +5368,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, char **a_str_reply)
                 if (!dap_strcmp(l_native_token, l_main_token)) {
                     SUM_256_256(l_value_need_check, l_value_need, &l_value_need_check);
                     SUM_256_256(l_value_need_check, l_value_need_fee, &l_value_need_check);
-                    l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_json_item_token,
+                    l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_json_item_token,
                                                                                              l_addr_from, l_value_need_check, &l_value_transfer);
                     if(!l_list_used_out) {
                         log_it(L_WARNING, "Not enough funds in previous tx to transfer");
@@ -5379,7 +5380,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, char **a_str_reply)
                     }
                 } else {
                     //CHECK value need
-                    l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_json_item_token,
+                    l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_json_item_token,
                                                                                              l_addr_from, l_value_need, &l_value_transfer);
                     if(!l_list_used_out) {
                         log_it(L_WARNING, "Not enough funds in previous tx to transfer");
@@ -5390,7 +5391,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, char **a_str_reply)
                         continue;
                     }
                     //CHECK value fee
-                    l_list_used_out_fee = dap_chain_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_native_token,
+                    l_list_used_out_fee = dap_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_native_token,
                                                                                      l_addr_from, l_value_need_fee, &l_value_transfer_fee);
                     if(!l_list_used_out_fee) {
                         log_it(L_WARNING, "Not enough funds in previous tx to transfer");
@@ -5616,12 +5617,12 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply)
     }
     dap_chain_net_t * l_net = dap_chain_net_by_name(l_net_name);
     dap_ledger_t *l_ledger = l_net ? l_net->pub.ledger : NULL;
-    if(l_net == NULL || (l_ledger = dap_chain_ledger_by_net_name(l_net_name)) == NULL) {
+    if(l_net == NULL || (l_ledger = dap_ledger_by_net_name(l_net_name)) == NULL) {
         dap_cli_server_cmd_set_reply_text(a_str_reply, "not found net by name '%s'", l_net_name);
         return -7;
     }
 
-    if(!dap_chain_ledger_token_ticker_check(l_ledger, l_token_ticker)) {
+    if(!dap_ledger_token_ticker_check(l_ledger, l_token_ticker)) {
         dap_cli_server_cmd_set_reply_text(a_str_reply, "Ticker '%s' is not declared on network '%s'.",
                                           l_token_ticker, l_net_name);
         return -16;
@@ -5829,7 +5830,7 @@ int com_tx_verify(int a_argc, char **a_argv, char **a_str_reply)
         dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified tx not found");
         return -3;
     }
-    int l_ret = dap_chain_ledger_tx_add_check(l_net->pub.ledger, l_tx, l_tx_size, &l_tx_hash);
+    int l_ret = dap_ledger_tx_add_check(l_net->pub.ledger, l_tx, l_tx_size, &l_tx_hash);
     if (l_ret) {
         dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified tx verify fail with return code=%d", l_ret);
         return -4;
@@ -5997,7 +5998,7 @@ int com_tx_history(int a_argc, char ** a_argv, char **a_str_reply)
                         dap_hash_fast_t l_ttx_hash = {0};
                         dap_hash_fast(l_tx, l_datums[i]->header.data_size, &l_ttx_hash);
                         const char *l_token_ticker = NULL;
-                        if ((l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_ttx_hash))) {
+                        if ((l_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_ttx_hash))) {
                             dap_string_append_printf(l_tx_all_str, "\t\t↓↓↓ Ledger accepted ↓↓↓\n");
                             l_tx_ledger_accepted++;
                         } else {
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index a0f72850f3..349a3e485d 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -101,11 +101,11 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
                                           dap_chain_hash_fast_t *a_tx_hash)
 {
     const char *l_ticker = a_ledger
-            ? dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash)
+            ? dap_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash)
             : NULL;
     if (!l_ticker)
         return false;
-    dap_chain_datum_dump_tx(a_datum, l_ticker, a_str_out, a_hash_out_type, a_tx_hash, a_ledger->net_id);
+    dap_chain_datum_dump_tx(a_datum, l_ticker, a_str_out, a_hash_out_type, a_tx_hash, a_ledger->net->pub.id);
     dap_list_t *l_out_items = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_OUT_ALL, NULL);
     int l_out_idx = 0;
     dap_string_append_printf(a_str_out, "Spent OUTs:\r\n");
@@ -115,10 +115,9 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
         case TX_ITEM_TYPE_OUT:
         case TX_ITEM_TYPE_OUT_OLD:
         case TX_ITEM_TYPE_OUT_EXT:
-        case TX_ITEM_TYPE_OUT_COND_OLD:
         case TX_ITEM_TYPE_OUT_COND: {
             dap_hash_fast_t l_spender = { };
-            if (dap_chain_ledger_tx_hash_is_used_out_item(a_ledger, a_tx_hash, l_out_idx, &l_spender)) {
+            if (dap_ledger_tx_hash_is_used_out_item(a_ledger, a_tx_hash, l_out_idx, &l_spender)) {
                 char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' };
                 dap_hash_fast_to_str(&l_spender, l_hash_str, sizeof(l_hash_str));
                 dap_string_append_printf(a_str_out,
@@ -165,9 +164,9 @@ char* dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain,
                 ? dap_enc_base58_encode_hash_to_str(&l_atom_hash)
                 : dap_chain_hash_fast_to_str_new(&l_atom_hash);
         dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger;
-        const char *l_tx_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash);
+        const char *l_tx_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash);
         dap_string_append_printf(l_str_out, "%s TX with atom %s (ret_code %d - %s)\n", l_tx_token_ticker ? "ACCEPTED" : "DECLINED",
-                                                                    l_atom_hash_str, l_ret_code, dap_chain_ledger_tx_check_err_str(l_ret_code));
+                                                                    l_atom_hash_str, l_ret_code, dap_ledger_tx_check_err_str(l_ret_code));
         DAP_DELETE(l_atom_hash_str);
         dap_chain_datum_dump_tx(l_tx, l_tx_token_ticker, l_str_out, a_hash_out_type, a_tx_hash, a_chain->net_id);
     } else {
@@ -204,7 +203,7 @@ static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_tx_hash_process
         }
         l_tx_data->hash = *a_tx_hash;
         HASH_ADD(hh, *a_tx_data_ht, hash, sizeof(*a_tx_hash), l_tx_data);
-        const char *l_token_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash);
+        const char *l_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash);
         if (!l_token_ticker)
             l_declined = true;
     }
@@ -218,7 +217,7 @@ static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_tx_hash_process
     }
     dap_string_append_printf(a_str_out, "%s TX hash %s with atom %s (ret code %d - %s) \n\t%s", l_declined ? "DECLINED" : "ACCEPTED",
                                                                           l_tx_hash_str, l_atom_hash_str, a_ret_code,
-                                                                          dap_chain_ledger_tx_check_err_str(a_ret_code), l_time_str);
+                                                                          dap_ledger_tx_check_err_str(a_ret_code), l_time_str);
     DAP_DELETE(l_tx_hash_str);
     DAP_DELETE(l_atom_hash_str);
 }
@@ -279,7 +278,7 @@ char* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, const
 
         dap_hash_fast_t l_tx_hash;
         dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
-        const char *l_src_token = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash);
+        const char *l_src_token = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash);
 
         int l_src_subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED;
         for (dap_list_t *it = l_list_in_items; it; it = it->next) {
@@ -768,15 +767,15 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
         dap_string_t *l_str_ret = dap_string_new(NULL);
 
         char *l_str_out = NULL;
-        dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str);
+        dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net_str);
         if(l_is_all) {
-            size_t l_tx_count = dap_chain_ledger_count(l_ledger), l_tx_count_spent_count = 0;
+            size_t l_tx_count = dap_ledger_count(l_ledger), l_tx_count_spent_count = 0;
             if (!l_tx_count) {
-                dap_string_append_printf(l_str_ret, "Network ledger %s contains no transactions.\n", l_ledger->net_name);
+                dap_string_append_printf(l_str_ret, "Network ledger %s contains no transactions.\n", l_ledger->net->pub.name);
             } else {
                 dap_string_append_printf(l_str_ret, "There are %zu transactions in the network ledger %s:\n",
-                                         l_tx_count, l_ledger->net_name);
-                dap_list_t *l_txs_list = dap_chain_ledger_get_txs(l_ledger, l_tx_count, 1, true, l_unspent_flag);
+                                         l_tx_count, l_ledger->net->pub.name);
+                dap_list_t *l_txs_list = dap_ledger_get_txs(l_ledger, l_tx_count, 1, true, l_unspent_flag);
                 for (dap_list_t *iter = l_txs_list; iter; iter = dap_list_next(iter)) {
                     dap_chain_datum_tx_t *l_tx = iter->data;
                     dap_hash_fast_t l_tx_hash = { };
@@ -794,9 +793,9 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
                         l_str_out ? l_str_out : " empty");
                 DAP_DELETE(l_addr_str);
             } else if(l_tx_hash_str) {
-                dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &l_tx_hash);
+                dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_tx_hash);
                 if (!l_tx && !l_unspent_flag) {
-                    l_tx = dap_chain_ledger_tx_spent_find_by_hash(l_ledger, &l_tx_hash);
+                    l_tx = dap_ledger_tx_spent_find_by_hash(l_ledger, &l_tx_hash);
                 }
                 if(l_tx) {
                     size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
@@ -847,13 +846,13 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'list' requires key -net");
             return -1;
         }
-        dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str);
+        dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net_str);
         if (l_ledger == NULL){
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get ledger for net %s", l_net_str);
             return -2;
         }
         if (l_sub_cmd == SUB_CMD_LIST_LEDGER_THRESHOLD){
-            dap_string_t *l_str_ret = dap_chain_ledger_threshold_info(l_ledger);
+            dap_string_t *l_str_ret = dap_ledger_threshold_info(l_ledger);
             if (l_str_ret){
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str);
                 dap_string_free(l_str_ret, true);
@@ -862,7 +861,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
             return 0;
         }
         if (l_sub_cmd == SUB_CMD_LIST_LEDGER_THRESHOLD_WITH_HASH){
-            dap_string_t *l_str_ret = dap_chain_ledger_threshold_hash_info(l_ledger, &l_tx_threshold_hash);
+            dap_string_t *l_str_ret = dap_ledger_threshold_hash_info(l_ledger, &l_tx_threshold_hash);
             if (l_str_ret){
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str);
                 dap_string_free(l_str_ret, true);
@@ -871,7 +870,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
             return 0;
         }
         if (l_sub_cmd == SUB_CMD_LIST_LEDGER_BALANCE){
-            dap_string_t *l_str_ret = dap_chain_ledger_balance_info(l_ledger);
+            dap_string_t *l_str_ret = dap_ledger_balance_info(l_ledger);
             if (l_str_ret){
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str);
                 dap_string_free(l_str_ret, true);
@@ -880,7 +879,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
             return 0;
         }
         dap_string_t *l_str_ret = dap_string_new("");
-        dap_list_t *l_token_list = dap_chain_ledger_token_info(l_ledger);
+        dap_list_t *l_token_list = dap_ledger_token_info(l_ledger);
         dap_string_append_printf(l_str_ret, "Found %lu tokens in %s ledger\n", dap_list_length(l_token_list), l_net_str);
         for (dap_list_t *l_list = l_token_list; l_list; l_list = dap_list_next(l_list)) {
             dap_string_append(l_str_ret, (char *)l_list->data);
@@ -1062,7 +1061,7 @@ int com_token(int a_argc, char ** a_argv, char **a_str_reply)
                 // only selected net
                 if(l_net->pub.id.uint64 == l_chain_cur->net_id.uint64) {
                     long l_chain_datum = l_cur_datum;
-                    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_str);
+                    dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net_str);
                     char *l_datum_list_str = dap_db_history_filter(l_chain_cur, l_ledger, l_token_name_str, NULL,
                                                                    l_hash_out_type, l_page_start * l_page_size, (l_page_start+l_page)*l_page_size, &l_chain_datum, l_list_tx_hash_processd);
                     if(l_datum_list_str) {
@@ -1336,9 +1335,8 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply)
             if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &l_param_value_str)){
                 l_subtype = SUBTYPE_FEE;
                 if (!dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_addr", &l_param_addr_str)){
-                    if(!l_net->pub.decree->fee_addr)
-                    {
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Net fee add needed. Use -to_addr parameter");
+                    if (dap_chain_addr_is_blank(&l_net->pub.fee_addr)) {
+                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Use -to_addr parameter to set net fee");
                         return -111;
                     }
                 }else{
@@ -1473,7 +1471,7 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply)
         // Sign decree
         size_t l_total_signs_success = 0;
         if (l_certs_count)
-            l_datum_decree = dap_chain_datum_decree_in_cycle(l_certs, l_datum_decree, l_certs_count, &l_total_signs_success);
+            l_datum_decree = dap_chain_datum_decree_sign_in_cycle(l_certs, l_datum_decree, l_certs_count, &l_total_signs_success);
 
         if (!l_datum_decree || l_total_signs_success == 0){
             dap_cli_server_cmd_set_reply_text(a_str_reply,
@@ -1567,7 +1565,7 @@ int cmd_decree(int a_argc, char **a_argv, char ** a_str_reply)
                     // Sign decree
                     size_t l_total_signs_success = 0;
                     if (l_certs_count)
-                        l_datum_decree = dap_chain_datum_decree_in_cycle(l_certs, l_datum_decree, l_certs_count, &l_total_signs_success);
+                        l_datum_decree = dap_chain_datum_decree_sign_in_cycle(l_certs, l_datum_decree, l_certs_count, &l_total_signs_success);
 
                     if (!l_datum_decree || l_total_signs_success == 0){
                         dap_cli_server_cmd_set_reply_text(a_str_reply,
diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h
new file mode 100644
index 0000000000..2f1d084ca9
--- /dev/null
+++ b/modules/net/include/dap_chain_ledger.h
@@ -0,0 +1,357 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * Alexander Lysikov <alexander.lysikov@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2019
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+ DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ DAP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include <stdint.h>
+#include <stdbool.h>
+#include "dap_common.h"
+#include "dap_hash.h"
+#include "dap_list.h"
+#include "dap_math_ops.h"
+#include "dap_chain_common.h"
+#include "dap_chain_datum_token.h"
+#include "dap_chain_datum_tx.h"
+#include "dap_chain_datum_tx_in_ems.h"
+#include "dap_chain_datum_tx_items.h"
+#include "dap_chain_net.h"
+
+typedef struct dap_ledger {
+    dap_chain_net_t *net;
+    void *_internal;
+} dap_ledger_t;
+
+/**
+ * @brief Error codes for accepting a transaction to the ledger.
+ */
+typedef enum dap_ledger_tx_check{
+    DAP_LEDGER_TX_CHECK_OK = 0,
+    DAP_LEDGER_TX_CHECK_NULL_TX,
+    DAP_LEDGER_TX_CHECK_INVALID_TX_SIZE,
+    DAP_LEDGER_TX_ALREADY_CACHED,
+    DAP_LEDGER_TX_CHECK_INVALID_TX_SIGN,
+    DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED,
+    DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED,
+    DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND,
+    DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS,
+    DAP_LEDGER_TX_CHECK_TICKER_NOT_FOUND,
+    DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN,
+    DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS,
+    DAP_LEDGER_TX_CHECK_MULT256_OVERFLOW_EMS_LOCKED_X_RATE,
+    DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS,
+    DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX,
+    DAP_LEDGER_TX_CHECK_TOKEN_EMS_VALUE_EXEEDS_CUR_SUPPLY,
+    DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE,
+    DAP_LEDGER_TX_CHECK_STAKE_LOCK_TICKER_NOT_FOUND,
+    DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED,
+    DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED,
+    DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND,
+    DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND,
+    DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_MISSTYPED,
+    DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH,
+    DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX,
+    DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET,
+    DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE,
+    DAP_LEDGER_TX_CHECK_PREV_TICKER_NOT_FOUND,
+    DAP_LEDGER_TX_CHECK_PREV_TOKEN_NOT_FOUND,
+    DAP_LEDGER_PERMISSION_CHECK_FAILED,
+    DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS,
+    DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED,
+    DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL,
+    DAP_LEDGER_TX_CHECK_INVALID_TICKER,
+    DAP_LEDGER_TX_CHECK_MEMORY_PROBLEM,
+    /* add custom codes here */
+
+    DAP_LEDGER_TX_CHECK_UNKNOWN /* MAX */
+} dap_ledger_tx_check_t;
+
+typedef enum dap_ledger_emission_err{
+    DAP_LEDGER_EMISSION_ADD_OK = 0,
+    DAP_LEDGER_EMISSION_ADD_CHECK_EMS_IS_NULL,
+    DAP_LEDGER_EMISSION_ADD_CHECK_EMS_ALREADY_CACHED,
+    DAP_LEDGER_EMISSION_ADD_CHECK_THRESHOLD_OVERFLOW,
+    DAP_LEDGER_EMISSION_ADD_CHECK_VALUE_EXEEDS_CURRENT_SUPPLY,
+    DAP_LEDGER_EMISSION_ADD_CHECK_NOT_ENOUGH_VALID_SIGNS,
+    DAP_LEDGER_EMISSION_ADD_CHECK_CANT_FIND_DECLARATION_TOKEN,
+    DAP_LEDGER_EMISSION_ADD_CHECK_ZERO_VALUE,
+    DAP_LEDGER_EMISSION_ADD_TSD_CHECK_FAILED,
+    /* add custom codes here */
+    DAP_LEDGER_EMISSION_ADD_MEMORY_PROBLEM,
+    DAP_LEDGER_EMISSION_ADD_UNKNOWN /* MAX */
+} dap_ledger_emission_err_code_t;
+
+typedef enum dap_ledger_token_decl_add_err{
+    DAP_LEDGER_TOKEN_DECL_ADD_OK = 0,
+    DAP_LEDGER_TOKEN_DECL_ADD_ERR_LEDGER_IS_NULL,
+    DAP_LEDGER_TOKEN_DECL_ADD_ERR_DECL_DUPLICATE,
+    DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_CHECK,
+    DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOKEN_UPDATE_ABSENT_TOKEN,
+    DAP_LEDGER_TOKEN_DECL_ADD_ERR_NOT_ENOUGH_VALID_SIGN,
+    DAP_LEDGER_TOKEN_DECL_ADD_ERR_TOTAL_SIGNS_EXCEED_UNIQUE_SIGNS,
+    /* add custom codes here */
+
+    DAP_LEDGER_TOKEN_DECL_ADD_UNKNOWN /* MAX */
+} dap_ledger_token_decl_add_err_t;
+
+typedef bool (*dap_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner);
+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 struct dap_chain_net dap_chain_net_t;
+
+//Change this UUID to automatically reload ledger cache on next node startup
+#define DAP_LEDGER_CACHE_RELOAD_ONCE_UUID "0c92b759-a565-448f-b8bd-99103dacf7fc"
+
+// Checks the emission of the token, usualy on zero chain
+#define DAP_LEDGER_CHECK_TOKEN_EMISSION    0x0001
+
+// Check double spending in local cell
+#define DAP_LEDGER_CHECK_LOCAL_DS          0x0002
+
+// Check the double spending in all cells
+#define DAP_LEDGER_CHECK_CELLS_DS          0x0100
+
+#define DAP_LEDGER_CACHE_ENABLED           0x0200
+
+// Error code for no previous transaction (for stay in mempool)
+#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS  DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND
+// Error code for no emission for a transaction (for stay in mempoold)
+#define DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION  DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND
+// Error code for no decree for anchor (for stay in mempool)
+#define DAP_CHAIN_CS_VERIFY_CODE_NO_DECREE       -1113
+
+#define DAP_LEDGER_TOKENS_STR              "tokens"
+#define DAP_LEDGER_EMISSIONS_STR           "emissions"
+#define DAP_LEDGER_STAKE_LOCK_STR          "stake_lock"
+#define DAP_LEDGER_TXS_STR                 "txs"
+#define DAP_LEDGER_SPENT_TXS_STR           "spent_txs"
+#define DAP_LEDGER_BALANCES_STR            "balances"
+
+int dap_ledger_init();
+void dap_ledger_deinit();
+
+dap_ledger_t *dap_ledger_create(dap_chain_net_t *a_net, uint16_t a_flags);
+
+// Remove dap_ledger_t structure
+void dap_ledger_handle_free(dap_ledger_t *a_ledger);
+
+// Load ledger from mempool
+//int dap_ledger_load(const char *a_net_name, const char *a_chain_name);
+
+void dap_ledger_set_local_cell_id(dap_ledger_t *a_ledger, dap_chain_cell_id_t a_local_cell_id);
+
+/**
+ * @brief dap_chain_node_datum_tx_calc_hash
+ * @param a_tx
+ * @return
+ */
+DAP_STATIC_INLINE dap_chain_hash_fast_t* dap_chain_node_datum_tx_calc_hash(dap_chain_datum_tx_t *a_tx)
+{
+    dap_chain_hash_fast_t *tx_hash = DAP_NEW_Z(dap_chain_hash_fast_t);
+    if (!tx_hash) {
+        return NULL;
+    }
+    dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), tx_hash);
+    return tx_hash;
+}
+
+DAP_STATIC_INLINE char *dap_ledger_get_gdb_group(dap_ledger_t *a_ledger, const char *a_suffix)
+{
+    return a_ledger && a_ledger->net->pub.name && a_suffix
+            ? dap_strdup_printf("local.ledger-cache.%s.%s", a_ledger->net->pub.name, a_suffix)
+            : NULL;
+}
+
+/**
+ * Add new transaction to the cache
+ *
+ * return 1 OK, -1 error
+ */
+int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_from_threshold);
+int dap_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_hash_fast_t *a_tx_hash);
+
+
+int dap_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, size_t a_datum_size, dap_hash_fast_t *a_datum_hash);
+
+char* dap_ledger_tx_check_err_str(int a_code);
+
+/**
+ * Print list transaction from ledger
+ *
+ */
+
+char * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only);
+
+/**
+ * Check token ticker existance
+ *
+ */
+
+dap_chain_datum_token_t *dap_ledger_token_ticker_check(dap_ledger_t * a_ledger, const char *a_token_ticker);
+
+/**
+ * Add new token datum
+ *
+ */
+
+int dap_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size);
+int dap_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size);
+int dap_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size);
+char *dap_ledger_token_decl_add_err_code_to_str(int a_code);
+dap_list_t *dap_ledger_token_info(dap_ledger_t *a_ledger);
+
+// Get all token-declarations
+dap_list_t* dap_ledger_token_decl_all(dap_ledger_t *a_ledger);
+
+dap_string_t *dap_ledger_threshold_info(dap_ledger_t *a_ledger);
+dap_string_t *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_tx_treshold_hash);
+dap_string_t *dap_ledger_balance_info(dap_ledger_t *a_ledger);
+
+size_t dap_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker);
+size_t dap_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker);
+dap_list_t * dap_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const char * a_token_ticker);
+
+/**
+ * Add token emission datum
+ */
+int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size,
+                                        dap_hash_fast_t *a_emission_hash, bool a_from_threshold);
+int dap_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_hash_fast_t *a_token_emission_hash);
+char *dap_ledger_token_emission_err_code_to_str(int a_code);
+
+// Check if it addable
+int dap_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size, dap_chain_hash_fast_t *a_emission_hash);
+
+/* Add stake-lock item */
+int dap_ledger_emission_for_stake_lock_item_add(dap_ledger_t *a_ledger, const dap_chain_hash_fast_t *a_tx_hash);
+
+dap_chain_datum_token_emission_t *dap_ledger_token_emission_find(dap_ledger_t *a_ledger,
+        const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash);
+
+const char* dap_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,dap_chain_hash_fast_t *a_tx_hash);
+
+void dap_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr,
+        char *** a_tickers, size_t * a_tickers_size);
+
+void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr,
+        char *** a_tickers, size_t * a_tickers_size);
+
+bool dap_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx);
+
+// Checking a new transaction before adding to the cache
+int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash,
+                                    bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker);
+
+/**
+ * Delete all transactions from the cache
+ */
+void dap_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db);
+
+/**
+ * End of load mode with no chackes for incoming datums
+ */
+void dap_ledger_load_end(dap_ledger_t *a_ledger);
+
+/**
+ * Return number transactions from the cache
+ */
+unsigned dap_ledger_count(dap_ledger_t *a_ledger);
+uint64_t dap_ledger_count_from_to(dap_ledger_t * a_ledger, dap_time_t a_ts_from, dap_time_t a_ts_to);
+size_t dap_ledger_count_tps(dap_ledger_t *a_ledger, struct timespec *a_ts_from, struct timespec *a_ts_to);
+void dap_ledger_set_tps_start_time(dap_ledger_t *a_ledger);
+
+/**
+ * Check whether used 'out' items
+ */
+bool dap_ledger_tx_hash_is_used_out_item(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, int a_idx_out, dap_hash_fast_t *a_out_spender);
+
+/**
+ * Retun true if reward was collected before
+ */
+bool dap_ledger_is_used_reward(dap_ledger_t *a_ledger, dap_hash_fast_t *a_block_hash, dap_hash_fast_t *a_sign_pkey_hash);
+
+/**
+ * Calculate balance of addr
+ *
+ */
+uint256_t dap_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr,
+        const char *a_token_ticker);
+
+uint256_t dap_ledger_calc_balance_full(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr,
+            const char *a_token_ticker);
+
+/**
+ * Get transaction in the cache by hash
+ *
+ * return transaction, or NULL if transaction not found in the cache
+ */
+dap_chain_datum_tx_t* dap_ledger_tx_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash);
+dap_chain_datum_tx_t* dap_ledger_tx_spent_find_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash);
+dap_hash_fast_t *dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash);
+
+ // Get the transaction in the cache by the addr in out item
+dap_chain_datum_tx_t* dap_ledger_tx_find_by_addr(dap_ledger_t *a_ledger, const char * a_token,
+         const dap_chain_addr_t *a_addr, dap_chain_hash_fast_t *a_tx_first_hash);
+
+// Get the transaction in the cache by the public key that signed the transaction, starting with a_tx_first_hash
+const dap_chain_datum_tx_t* dap_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger,
+        char *a_public_key, size_t a_public_key_size, dap_chain_hash_fast_t *a_tx_first_hash);
+
+// Get the transaction in the cache with the out_cond item
+dap_chain_datum_tx_t* dap_ledger_tx_cache_find_out_cond(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type,
+                                                              dap_chain_hash_fast_t *a_tx_first_hash, dap_chain_tx_out_cond_t **a_out_cond,
+                                                              int *a_out_cond_idx, char *a_token_ticker);
+
+// Get all transactions from the cache with the specified out_cond items
+dap_list_t* dap_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, dap_chain_net_srv_uid_t a_srv_uid);
+
+// Get the value from all transactions in the cache with out_cond item
+uint256_t dap_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_addr_t *a_addr,
+                                                       dap_chain_tx_out_cond_t **tx_out_cond);
+
+// Get the list of 'out' items from previous transactions with summary value >= than a_value_need
+// Put this summary value to a_value_transfer
+dap_list_t *dap_ledger_get_list_tx_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from,
+                                                       uint256_t a_value_need, uint256_t *a_value_transfer);
+
+// Get the list of 'out_cond' items with summary value >= than a_value_need
+dap_list_t *dap_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker,  const dap_chain_addr_t *a_addr_from,
+        dap_chain_tx_out_cond_subtype_t a_subtype, uint256_t a_value_need, uint256_t *a_value_transfer);
+
+// Add new verificator callback with associated subtype. Returns 1 if callback replaced, overwise returns 0
+int dap_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype, dap_ledger_verificator_callback_t a_callback,
+                                     dap_ledger_updater_callback_t a_callback_added);
+
+// Getting a list of transactions from the ledger.
+dap_list_t * dap_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only);
+
+//bool dap_ledger_fee_verificator(dap_ledger_t* a_ledger, dap_chain_tx_out_cond_t* a_cond, dap_chain_datum_tx_t* a_tx, bool a_owner);
+
+void dap_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_ledger_tx_add_notify_t a_callback, void *a_arg);
+void dap_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_ledger_bridged_tx_notify_t a_callback, void *a_arg);
+
+
+bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger);
+void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_cache_tx_check_callback_t a_callback);
diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h
index 523b3e4717..b82409b423 100644
--- a/modules/net/include/dap_chain_net.h
+++ b/modules/net/include/dap_chain_net.h
@@ -37,7 +37,6 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_chain_common.h"
 #include "dap_chain.h"
 #include "dap_chain_node.h"
-#include "dap_chain_ledger.h"
 #include "dap_chain_net_decree.h"
 #include "dap_chain_net_tx.h"
 #include "dap_chain_datum_decree.h"
@@ -50,6 +49,7 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 
 struct dap_chain_node_info;
 typedef struct dap_chain_node_client dap_chain_node_client_t;
+typedef struct dap_ledger dap_ledger_t;
 
 typedef enum dap_chain_net_state{
     NET_STATE_OFFLINE = 0,
@@ -74,10 +74,15 @@ typedef struct dap_chain_net{
 
         bool mempool_autoproc;
 
-        dap_chain_t * chains; // double-linked list of chains
+        dap_chain_t *chains; // double-linked list of chains
         const char *native_ticker;
-        dap_ledger_t  *ledger;
+        dap_ledger_t *ledger;
         dap_chain_net_decree_t *decree;
+        // Net fee
+        uint256_t fee_value;
+        dap_chain_addr_t fee_addr;
+        // Block sign reward
+        uint256_t base_reward;
 
         pthread_mutex_t balancer_mutex;
         dap_list_t *link_list;
@@ -138,7 +143,7 @@ dap_chain_net_t * dap_chain_net_by_name( const char * a_name);
 dap_chain_net_t * dap_chain_net_by_id( dap_chain_net_id_t a_id);
 uint16_t dap_chain_net_get_acl_idx(dap_chain_net_t *a_net);
 dap_chain_net_id_t dap_chain_net_id_by_name( const char * a_name);
-dap_ledger_t * dap_chain_ledger_by_net_name( const char * a_net_name);
+dap_ledger_t * dap_ledger_by_net_name( const char * a_net_name);
 dap_string_t* dap_cli_list_net();
 
 dap_chain_t * dap_chain_net_get_chain_by_name( dap_chain_net_t * l_net, const char * a_name);
diff --git a/modules/net/include/dap_chain_net_decree.h b/modules/net/include/dap_chain_net_decree.h
index 255ab44326..4a1720c7df 100644
--- a/modules/net/include/dap_chain_net_decree.h
+++ b/modules/net/include/dap_chain_net_decree.h
@@ -29,7 +29,6 @@ typedef struct decree_params {
     dap_list_t *pkeys;
     uint16_t num_of_owners;
     uint16_t min_num_of_owners;
-    dap_chain_addr_t *fee_addr;
 }   dap_chain_net_decree_t;
 
 int dap_chain_net_decree_init(dap_chain_net_t *a_net);
diff --git a/modules/net/include/dap_chain_net_tx.h b/modules/net/include/dap_chain_net_tx.h
index 8fccb5f4e9..74aa1d9aeb 100644
--- a/modules/net/include/dap_chain_net_tx.h
+++ b/modules/net/include/dap_chain_net_tx.h
@@ -24,6 +24,7 @@
 #pragma once
 
 #include "dap_chain_net.h"
+#include "dap_chain_datum_tx_items.h"
 
 typedef enum dap_chain_net_tx_search_type {
     /// Search local, in memory, possible load data from drive to memory
@@ -88,4 +89,4 @@ void dap_chain_datum_tx_spends_item_free(dap_chain_datum_tx_spends_item_t * a_it
 void dap_chain_datum_tx_spends_items_free(dap_chain_datum_tx_spends_items_t * a_items);
 
 bool dap_chain_net_tx_get_fee(dap_chain_net_id_t a_net_id, uint256_t *a_value, dap_chain_addr_t *a_addr);
-bool dap_chain_net_tx_add_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, dap_chain_addr_t a_addr);
+bool dap_chain_net_tx_set_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, dap_chain_addr_t a_addr);
diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c
index 8f38736980..4950f4e3d5 100644
--- a/modules/net/srv/dap_chain_net_srv.c
+++ b/modules/net/srv/dap_chain_net_srv.c
@@ -93,8 +93,8 @@ static int s_str_to_price_unit(const char *a_price_unit_str, dap_chain_net_srv_p
  */
 int dap_chain_net_srv_init()
 {
-    dap_chain_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, s_pay_verificator_callback, NULL);
-    dap_chain_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE, s_fee_verificator_callback, NULL);
+    dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, s_pay_verificator_callback, NULL);
+    dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE, s_fee_verificator_callback, NULL);
     dap_stream_ch_chain_net_srv_init();
 
     dap_cli_server_cmd_add ("net_srv", s_cli_net_srv, "Network services managment",
@@ -661,12 +661,11 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply)
  * @param a_owner
  * @return
  */
-static bool s_fee_verificator_callback(dap_ledger_t *a_ledger, UNUSED_ARG dap_chain_tx_out_cond_t *a_cond,
-                                       dap_chain_datum_tx_t *a_tx_in, UNUSED_ARG bool a_owner)
+static bool s_fee_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t UNUSED_ARG *a_cond,
+                                       dap_chain_datum_tx_t *a_tx_in, bool UNUSED_ARG a_owner)
 {
-    dap_chain_net_t *l_net = dap_chain_net_by_name(a_ledger->net_name);
-    if (!l_net)
-        return false;
+    dap_chain_net_t *l_net = a_ledger->net;
+    assert(l_net);
     dap_chain_t *l_chain;
     DL_FOREACH(l_net->pub.chains, l_chain) {
         if (!l_chain->callback_block_find_by_tx_hash)
@@ -778,7 +777,7 @@ static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out
 
     // Check price is less than maximum
     dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0);
-    dap_chain_datum_tx_t *l_tx_prev = dap_chain_ledger_tx_find_by_hash(a_ledger , &l_tx_in_cond->header.tx_prev_hash);
+    dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash(a_ledger , &l_tx_in_cond->header.tx_prev_hash);
     dap_chain_tx_out_cond_t *l_prev_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_prev, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, NULL);
 
     uint256_t l_unit_price = {};
@@ -800,7 +799,7 @@ static bool s_pay_verificator_callback(dap_ledger_t * a_ledger, dap_chain_tx_out
     uint256_t l_value = l_receipt->receipt_info.value_datoshi;
     uint256_t l_cond_out_value = {};
     dap_chain_addr_t l_network_fee_addr = {};
-    dap_chain_net_tx_get_fee(a_ledger->net_id, NULL, &l_network_fee_addr);
+    dap_chain_net_tx_get_fee(a_ledger->net->pub.id, NULL, &l_network_fee_addr);
     int l_item_idx = 0;
     for (dap_list_t * l_list_tmp = l_list_out; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_item_idx++) {
         dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data;
@@ -1163,7 +1162,7 @@ dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,
 //        dap_chain_net_srv_parse_pricelist(l_srv, a_config_section);
         HASH_ADD(hh, s_srv_list, uid, sizeof(l_srv->uid), l_sdata);
         if (l_srv->pricelist)
-            dap_chain_ledger_tx_add_notify(l_srv->pricelist->net->pub.ledger, dap_stream_ch_chain_net_srv_tx_cond_added_cb, NULL);
+            dap_ledger_tx_add_notify(l_srv->pricelist->net->pub.ledger, dap_stream_ch_chain_net_srv_tx_cond_added_cb, NULL);
     }else{
         log_it(L_ERROR, "Already present service with 0x%016"DAP_UINT64_FORMAT_X, a_uid.uint64);
     }
diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c
index 07c316c94b..30a8335e8c 100644
--- a/modules/net/srv/dap_chain_net_srv_order.c
+++ b/modules/net/srv/dap_chain_net_srv_order.c
@@ -550,7 +550,7 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d
         DAP_DELETE(l_balance);
         if( a_order->price_unit.uint32 )
             dap_string_append_printf(a_str_out, "  price_unit:       %s\n", dap_chain_net_srv_price_unit_uid_to_str(a_order->price_unit) );
-        if(a_order->price_ticker)
+        if (*a_order->price_ticker)
             dap_string_append_printf(a_str_out, "  price_token:      %s\n",  a_order->price_ticker);
         if ( a_order->node_addr.uint64)
             dap_string_append_printf(a_str_out, "  node_addr:        "NODE_ADDR_FP_STR"\n", NODE_ADDR_FP_ARGS_S(a_order->node_addr) );
diff --git a/modules/service/datum/dap_chain_net_srv_datum.c b/modules/service/datum/dap_chain_net_srv_datum.c
index 87db2ea544..ef7885414f 100644
--- a/modules/service/datum/dap_chain_net_srv_datum.c
+++ b/modules/service/datum/dap_chain_net_srv_datum.c
@@ -248,7 +248,7 @@ void s_order_notficator(dap_store_obj_t *a_obj, void *a_arg)
     if (l_datum)
         l_tx_cond = (dap_chain_datum_tx_t *)l_datum->data;
     else
-        l_tx_cond = dap_chain_ledger_tx_find_by_hash(l_net->pub.ledger, &l_order->tx_cond_hash);
+        l_tx_cond = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_order->tx_cond_hash);
     if (!l_tx_cond) {
         log_it(L_DEBUG, "Invalid tx cond datum hash");
         return;
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 4e3d065313..7a7f365a73 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_lock.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c
@@ -22,16 +22,15 @@
     along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include "dap_chain_net_srv.h"
-#include "dap_chain_net_srv_stake_lock.h"
-#include "dap_chain_net_tx.h"
-#include "dap_chain_node_cli.h"
-#include "dap_chain_mempool.h"
-#include "dap_chain_wallet.h"
-#include "dap_chain_ledger.h"
 #include "dap_common.h"
 #include "dap_hash.h"
 #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_wallet.h"
+#include "dap_chain_mempool.h"
+#include "dap_chain_net_srv.h"
 
 static bool s_debug_more = false;
 
@@ -81,12 +80,12 @@ enum error_code {
     FEE_FORMAT_ERROR            = 43,
 };
 
-typedef struct dap_chain_ledger_token_emission_for_stake_lock_item {
+typedef struct dap_ledger_token_emission_for_stake_lock_item {
     dap_chain_hash_fast_t	datum_token_emission_for_stake_lock_hash;
     dap_chain_hash_fast_t	tx_used_out;
 //	const char 				datum_token_emission_hash[DAP_CHAIN_HASH_FAST_STR_SIZE];
     UT_hash_handle hh;
-} dap_chain_ledger_token_emission_for_stake_lock_item_t;
+} dap_ledger_token_emission_for_stake_lock_item_t;
 
 #define LOG_TAG		"dap_chain_net_stake_lock"
 #define MONTH_INDEX	8
@@ -115,7 +114,7 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_
  */
 int dap_chain_net_srv_stake_lock_init()
 {
-    dap_chain_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, s_stake_lock_callback_verificator, s_stake_lock_callback_updater);
+    dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK, s_stake_lock_callback_verificator, s_stake_lock_callback_updater);
     dap_cli_server_cmd_add("stake_lock", s_cli_stake_lock, "Stake lock service commands",
        "Command:"
                 "stake_lock hold\n"
@@ -200,7 +199,7 @@ static enum error_code s_cli_hold(int a_argc, char **a_argv, int a_arg_index, da
 
     l_ledger = l_net->pub.ledger;
 
-    if (NULL == dap_chain_ledger_token_ticker_check(l_ledger, l_ticker_str)) {
+    if (NULL == dap_ledger_token_ticker_check(l_ledger, l_ticker_str)) {
         dap_string_append_printf(output_line, "'%s'", l_ticker_str);
         return TOKEN_ERROR;
     }
@@ -214,7 +213,7 @@ static enum error_code s_cli_hold(int a_argc, char **a_argv, int a_arg_index, da
 
     dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker_str, l_ticker_str);
 
-    if (NULL == (l_delegated_token = dap_chain_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str))
+    if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str))
     ||	(l_delegated_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE)
     ||	!l_delegated_token->header_native_decl.tsd_total_size
     ||	NULL == (l_tsd = dap_tsd_find(l_delegated_token->data_n_tsd, l_delegated_token->header_native_decl.tsd_total_size,
@@ -399,7 +398,7 @@ static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, da
 
     l_ledger = l_net->pub.ledger;
 
-    l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &l_tx_hash);
+    l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_tx_hash);
 
     if (NULL == (l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_cond_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK,
                                                                  &l_prev_cond_idx)))
@@ -408,11 +407,11 @@ static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, da
     if (l_tx_out_cond->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK)
         return NO_VALID_SUBTYPE_ERROR;
 
-    if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, &l_tx_hash, l_prev_cond_idx, NULL)) {
+    if (dap_ledger_tx_hash_is_used_out_item(l_ledger, &l_tx_hash, l_prev_cond_idx, NULL)) {
         return IS_USED_OUT_ERROR;
     }
 
-    if (NULL == (l_ticker_str = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash)))
+    if (NULL == (l_ticker_str = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash)))
         return TX_TICKER_ERROR;
 
     if (l_tx_out_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_CREATE_BASE_TX ||
@@ -420,7 +419,7 @@ static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, da
 
         dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker_str, l_ticker_str);
 
-        if (NULL == (l_delegated_token = dap_chain_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str))
+        if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(l_ledger, l_delegated_ticker_str))
             ||	(l_delegated_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE)
             ||	!l_delegated_token->header_native_decl.tsd_total_size
             ||	NULL == (l_tsd = dap_tsd_find(l_delegated_token->data_n_tsd,
@@ -905,7 +904,7 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_
         return false;
     if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash))
         return false;
-    if (NULL == (l_prev_tx_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(
+    if (NULL == (l_prev_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(
                                                             a_ledger, &l_tx_in_cond->header.tx_prev_hash)))
         return false;
 
@@ -913,7 +912,7 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_
 
     if (a_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_CREATE_BASE_TX ||
             a_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_EMIT) {
-        if (NULL == (l_delegated_token = dap_chain_ledger_token_ticker_check(a_ledger, l_delegated_ticker_str))
+        if (NULL == (l_delegated_token = dap_ledger_token_ticker_check(a_ledger, l_delegated_ticker_str))
             ||	(l_delegated_token->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE)
             ||	!l_delegated_token->header_native_decl.tsd_total_size
             ||	NULL == (l_tsd = dap_tsd_find(l_delegated_token->data_n_tsd,
@@ -939,7 +938,7 @@ static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_
             l_burning_tx_hash = *(dap_hash_fast_t*)l_receipt->exts_n_signs;
             if (dap_hash_fast_is_blank(&l_burning_tx_hash))
                 return false;
-            l_burning_tx = dap_chain_ledger_tx_find_by_hash(a_ledger, &l_burning_tx_hash);
+            l_burning_tx = dap_ledger_tx_find_by_hash(a_ledger, &l_burning_tx_hash);
             if (!l_burning_tx) {
                 char l_burning_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' };
                 dap_hash_fast_to_str(&l_burning_tx_hash, l_burning_tx_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
@@ -1018,7 +1017,7 @@ static void s_stake_lock_callback_updater(dap_ledger_t *a_ledger, dap_chain_datu
     if (l_cond->subtype.srv_stake_lock.flags & DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_CREATE_BASE_TX) {
         dap_chain_hash_fast_t l_tx_cond_hash;
         dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_tx_cond_hash);
-        dap_chain_ledger_emission_for_stake_lock_item_add(a_ledger, &l_tx_cond_hash);
+        dap_ledger_emission_for_stake_lock_item_add(a_ledger, &l_tx_cond_hash);
     }
 }
 
@@ -1029,7 +1028,7 @@ static dap_chain_datum_t *s_stake_lock_datum_create(dap_chain_net_t *a_net, dap_
                                                     const char *a_delegated_ticker_str, uint256_t a_delegated_value)
 {
     dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_LOCK_ID };
-    dap_ledger_t * l_ledger = a_net ? dap_chain_ledger_by_net_name( a_net->pub.name ) : NULL;
+    dap_ledger_t * l_ledger = a_net ? dap_ledger_by_net_name( a_net->pub.name ) : NULL;
     // check valid param
     if (!a_net || !l_ledger || !a_key_from ||
         !a_key_from->priv_key_data || !a_key_from->priv_key_data_size || IS_ZERO_256(a_value))
@@ -1049,7 +1048,7 @@ static dap_chain_datum_t *s_stake_lock_datum_create(dap_chain_net_t *a_net, dap_
     if (l_main_native)
         SUM_256_256(l_value_need, l_total_fee, &l_value_need);
     else if (!IS_ZERO_256(l_total_fee)) {
-        l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_ticker,
+        l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_ticker,
                                                                     &l_addr, l_total_fee, &l_fee_transfer);
         if (!l_list_fee_out) {
             log_it(L_WARNING, "Not enough funds to pay fee");
@@ -1057,7 +1056,7 @@ static dap_chain_datum_t *s_stake_lock_datum_create(dap_chain_net_t *a_net, dap_
         }
     }
     // list of transaction with 'out' items
-    dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_main_ticker,
+    dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_main_ticker,
                                                                              &l_addr, l_value_need, &l_value_transfer);
     if(!l_list_used_out) {
         log_it( L_ERROR, "Nothing to transfer (not enough funds)");
@@ -1192,7 +1191,7 @@ dap_chain_datum_t *s_stake_unlock_datum_create(dap_chain_net_t *a_net, dap_enc_k
     SUM_256_256(l_net_fee, a_value_fee, &l_total_fee);
 
     if (!IS_ZERO_256(l_total_fee)) {
-        l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_ticker,
+        l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_ticker,
                                                                     &l_addr, l_total_fee, &l_fee_transfer);
         if (!l_list_fee_out) {
             log_it(L_WARNING, "Not enough funds to pay fee");
@@ -1200,7 +1199,7 @@ dap_chain_datum_t *s_stake_unlock_datum_create(dap_chain_net_t *a_net, dap_enc_k
         }
     }
     if (!IS_ZERO_256(a_delegated_value)) {
-        l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, a_delegated_ticker_str,
+        l_list_used_out = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, a_delegated_ticker_str,
                                                                                  &l_addr, a_delegated_value, &l_value_transfer);
         if(!l_list_used_out) {
             log_it( L_ERROR, "Nothing to transfer (not enough delegated tokens)");
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 9bb320251b..44ecfb56b8 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
@@ -63,7 +63,7 @@ static dap_chain_net_srv_stake_t *s_srv_stake = NULL;
  */
 int dap_chain_net_srv_stake_pos_delegate_init()
 {
-    dap_chain_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, s_stake_verificator_callback, s_stake_updater_callback);
+    dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, s_stake_verificator_callback, s_stake_updater_callback);
     dap_cli_server_cmd_add("srv_stake", s_cli_srv_stake, "Delegated stake service commands",
     "\t\t=== Commands for work with orders ===\n"
     "srv_stake order create -net <net_name> -value <value> -cert <priv_cert_name> \n"
@@ -361,9 +361,9 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net)
         log_it(L_ERROR, "Invalid arguments l_ledger in dap_chain_net_srv_stake_load_cache");
         return -1;
     }
-    if (!dap_chain_ledger_cache_enabled(l_ledger))
+    if (!dap_ledger_cache_enabled(l_ledger))
         return 0;
-    char *l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP);
+    char *l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP);
     size_t l_objs_count = 0;
     
     dap_store_obj_t *l_store_obj = dap_global_db_get_all_raw_sync(l_gdb_group, &l_objs_count);
@@ -385,14 +385,14 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net)
         HASH_ADD(hh, s_srv_stake->cache, tx_hash, sizeof(dap_hash_fast_t), l_cache);
     }
     dap_store_obj_free(l_store_obj, l_objs_count);
-    dap_chain_ledger_set_cache_tx_check_callback(l_ledger, s_stake_cache_check_tx);
+    dap_ledger_set_cache_tx_check_callback(l_ledger, s_stake_cache_check_tx);
     return 0;
 }
 
 void dap_chain_net_srv_stake_purge(dap_chain_net_t *a_net)
 {
     dap_ledger_t *l_ledger = a_net->pub.ledger;
-    char *l_gdb_group = dap_chain_ledger_get_gdb_group(l_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP);
+    char *l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP);
     dap_global_db_del(l_gdb_group, NULL, NULL, NULL);
     DAP_DELETE(l_gdb_group);
     s_stake_net_clear(a_net);
@@ -412,7 +412,7 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_chai
     const char *l_native_ticker = a_net->pub.native_ticker;
     char l_delegated_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
     dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker, l_native_ticker);
-    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_net->pub.name);
+    dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_net->pub.name);
     uint256_t l_value_transfer = {}, l_fee_transfer = {}; // how many coins to transfer
     // list of transaction with 'out' items to sell
     dap_chain_addr_t *l_owner_addr = (dap_chain_addr_t *)dap_chain_wallet_get_addr(a_wallet, a_net->pub.id);
@@ -421,14 +421,14 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_chai
     bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_net_fee_addr);
     if (l_net_fee_used)
         SUM_256_256(l_fee_total, l_net_fee, &l_fee_total);
-    dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_delegated_ticker,
+    dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_delegated_ticker,
                                                                              l_owner_addr, a_value, &l_value_transfer);
     if (!l_list_used_out) {
         log_it(L_WARNING, "Nothing to pay for delegate (not enough funds)");
         DAP_DELETE(l_owner_addr);
         return NULL;
     }
-    dap_list_t *l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
+    dap_list_t *l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
                                                                             l_owner_addr, l_fee_total, &l_fee_transfer);
     if (!l_list_fee_out) {
         log_it(L_WARNING, "Nothing to pay for fee (not enough funds)");
@@ -530,9 +530,9 @@ static char *s_stake_tx_put(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *a_net)
 
 dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t *a_net, dap_hash_fast_t *a_stake_tx_hash, dap_cert_t *a_cert)
 {
-    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_net->pub.name);
+    dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_net->pub.name);
 
-    dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_stake_tx_hash);
+    dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, a_stake_tx_hash);
     if (!l_cond_tx) {
         log_it(L_WARNING, "Requested conditional transaction not found");
         return NULL;
@@ -545,7 +545,7 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t
         return NULL;
     }
     dap_hash_fast_t l_spender_hash = { };
-    if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, a_stake_tx_hash, l_prev_cond_idx, &l_spender_hash)) {
+    if (dap_ledger_tx_hash_is_used_out_item(l_ledger, a_stake_tx_hash, l_prev_cond_idx, &l_spender_hash)) {
         char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
         dap_chain_hash_fast_to_str(&l_spender_hash, l_hash_str, sizeof(l_hash_str));
         log_it(L_WARNING, "Requested conditional transaction is already used out by %s", l_hash_str);
@@ -553,7 +553,7 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t
     }
     char l_delegated_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
     dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker, a_net->pub.native_ticker);
-    const char *l_tx_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, a_stake_tx_hash);
+    const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, a_stake_tx_hash);
     if (dap_strcmp(l_tx_ticker, l_delegated_ticker)) {
         log_it(L_WARNING, "Requested conditional transaction have another ticker (not %s)", l_delegated_ticker);
         return NULL;
@@ -698,9 +698,9 @@ static char *s_stake_decree_put(dap_chain_datum_decree_t *a_decree, dap_chain_ne
 
 static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_hash_fast_t *a_tx_hash, uint256_t a_fee, dap_enc_key_t *a_key)
 {
-    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_net->pub.name);
+    dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_net->pub.name);
 
-    dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_tx_hash);
+    dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, a_tx_hash);
     if (!l_cond_tx) {
         log_it(L_WARNING, "Requested conditional transaction not found");
         return NULL;
@@ -713,7 +713,7 @@ static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_h
         return NULL;
     }
     dap_hash_fast_t l_spender_hash = { };
-    if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, a_tx_hash, l_prev_cond_idx, &l_spender_hash)) {
+    if (dap_ledger_tx_hash_is_used_out_item(l_ledger, a_tx_hash, l_prev_cond_idx, &l_spender_hash)) {
         char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
         dap_chain_hash_fast_to_str(&l_spender_hash, l_hash_str, sizeof(l_hash_str));
         log_it(L_WARNING, "Requested conditional transaction is already used out by %s", l_hash_str);
@@ -733,7 +733,7 @@ static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_h
         return NULL;
     }
     const char *l_native_ticker = a_net->pub.native_ticker;
-    const char *l_delegated_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash);
+    const char *l_delegated_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash);
     uint256_t l_fee_transfer = {}; // how many coins to transfer
     // list of transaction with 'out' items to sell
     uint256_t l_net_fee, l_fee_total = a_fee;
@@ -741,7 +741,7 @@ static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_h
     bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_net_fee_addr);
     if (l_net_fee_used)
         SUM_256_256(l_fee_total, l_net_fee, &l_fee_total);
-    dap_list_t *l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
+    dap_list_t *l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
                                                                             &l_owner_addr, l_fee_total, &l_fee_transfer);
     if (!l_list_fee_out) {
         log_it(L_WARNING, "Nothing to pay for fee (not enough funds)");
@@ -802,10 +802,10 @@ static dap_chain_datum_tx_t *s_stake_tx_invalidate(dap_chain_net_t *a_net, dap_h
 
 static dap_chain_datum_decree_t *s_stake_decree_invalidate(dap_chain_net_t *a_net, dap_hash_fast_t *a_stake_tx_hash, dap_cert_t *a_cert)
 {
-    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_net->pub.name);
+    dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_net->pub.name);
 
     // add 'in' item to buy from conditional transaction
-    dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_stake_tx_hash);
+    dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, a_stake_tx_hash);
     if (!l_cond_tx) {
         log_it(L_WARNING, "Requested conditional transaction not found");
         return NULL;
@@ -1304,7 +1304,7 @@ static void s_get_tx_filter_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_
                                                                  &l_out_idx_tmp)))
     {
         dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_datum_hash);
-        if (!dap_chain_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_datum_hash, l_out_idx_tmp, NULL)) {
+        if (!dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_datum_hash, l_out_idx_tmp, NULL)) {
             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);
             if(!l_stake){
@@ -1335,8 +1335,8 @@ int dap_chain_net_srv_stake_check_validator(dap_chain_net_t * a_net, dap_hash_fa
     uint8_t l_test_data[1024] = {0};
     dap_chain_node_client_t *l_node_client = NULL;
     dap_chain_node_info_t *l_remote_node_info = NULL;
-    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_net->pub.name);
-    dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, a_tx_hash);
+    dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_net->pub.name);
+    dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_ledger, a_tx_hash);
     dap_chain_node_addr_t *l_signer_node_addr = NULL;
     int l_overall_correct = false;
 
@@ -1939,7 +1939,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply)
             if (l_tx_hash_str) {
                 l_final_tx_hash = DAP_NEW(dap_hash_fast_t);
                 dap_chain_hash_fast_from_str(l_tx_hash_str, l_final_tx_hash);
-                if(!dap_chain_ledger_tx_find_by_hash(l_net->pub.ledger, l_final_tx_hash)) {
+                if(!dap_ledger_tx_find_by_hash(l_net->pub.ledger, l_final_tx_hash)) {
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s is not found.", l_tx_hash_str);
                     return -20;
                 }
@@ -2182,14 +2182,14 @@ void dap_chain_net_srv_stake_get_fee_validators_str(dap_chain_net_t *a_net, dap_
 
 static void s_cache_data(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_addr_t *a_signing_addr)
 {
-    if (!dap_chain_ledger_cache_enabled(a_ledger))
+    if (!dap_ledger_cache_enabled(a_ledger))
         return;
     dap_chain_net_srv_stake_cache_data_t l_cache_data;
     dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_cache_data.tx_hash);
     char l_data_key[DAP_CHAIN_HASH_FAST_STR_SIZE];
     dap_chain_hash_fast_to_str(&l_cache_data.tx_hash, l_data_key, sizeof(l_data_key));
     l_cache_data.signing_addr = *a_signing_addr;
-    char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP);
+    char *l_gdb_group = dap_ledger_get_gdb_group(a_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP);
     if (dap_global_db_set(l_gdb_group, l_data_key, &l_cache_data, sizeof(l_cache_data), false, NULL, NULL))
         log_it(L_WARNING, "Stake service cache mismatch");
 }
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 1afa7e9519..62c029e9cb 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -82,7 +82,7 @@ static bool s_debug_more = true;
  */
 int dap_chain_net_srv_xchange_init()
 {
-    dap_chain_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, s_xchange_verificator_callback, NULL);
+    dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, s_xchange_verificator_callback, NULL);
     dap_cli_server_cmd_add("srv_xchange", s_cli_srv_xchange, "eXchange service commands",
 
     "srv_xchange order create -net <net_name> -token_sell <token_ticker> -token_buy <token_ticker> -w <wallet_name>"
@@ -171,7 +171,7 @@ static bool s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_
         return false;
     if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash))
         return false;
-    const char *l_sell_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_in_cond->header.tx_prev_hash);
+    const char *l_sell_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_ledger, &l_tx_in_cond->header.tx_prev_hash);
     if (!l_sell_ticker)
         return false;
     const char *l_buy_ticker = a_tx_out_cond->subtype.srv_xchange.buy_token;
@@ -183,7 +183,7 @@ static bool s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_
 
     dap_chain_addr_t l_service_fee_addr, *l_seller_addr = &a_tx_out_cond->subtype.srv_xchange.seller_addr;
     uint16_t l_service_fee_type;
-    dap_chain_net_t *l_net = dap_chain_net_by_name(a_ledger->net_name);
+    dap_chain_net_t *l_net = a_ledger->net;
     bool l_service_fee_used = s_srv_xchange_get_fee(l_net->pub.id, &l_service_fee_val, &l_service_fee_addr, &l_service_fee_type);
     const char *l_native_ticker = l_net->pub.native_ticker;
     const char *l_service_ticker = (l_service_fee_type == SERVICE_FEE_OWN_FIXED || l_service_fee_type == SERVICE_FEE_OWN_PERCENT) ?
@@ -374,7 +374,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_request(dap_chain_net_srv_xchan
     if (l_single_channel)
         SUM_256_256(l_value_need, l_total_fee, &l_value_need);
     else {
-        l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
+        l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
                                                                     l_seller_addr, l_total_fee, &l_fee_transfer);
         if (!l_list_fee_out) {
             log_it(L_WARNING, "Not enough funds to pay fee");
@@ -382,7 +382,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_request(dap_chain_net_srv_xchan
         }
     }
     // list of transaction with 'out' items to sell
-    dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_price->token_sell,
+    dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_price->token_sell,
                                                                              l_seller_addr, l_value_need, &l_value_transfer);
     if(!l_list_used_out) {
         DAP_DELETE(l_seller_addr);
@@ -533,7 +533,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
     if (l_pay_with_native)
         SUM_256_256(l_value_need, l_total_fee, &l_value_need);
     else {
-        l_list_fee_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
+        l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
                                                                     l_buyer_addr, l_total_fee, &l_fee_transfer);
         if (!l_list_fee_out) {
             log_it(L_WARNING, "Not enough funds to pay fee");
@@ -541,7 +541,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
         }
     }
     // list of transaction with 'out' items to sell
-    dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_price->token_buy,
+    dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_price->token_buy,
                                                                              l_buyer_addr, l_value_need, &l_value_transfer);
     if(!l_list_used_out) {
         DAP_DELETE(l_buyer_addr);
@@ -582,7 +582,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
         }
     }
     // add 'in' item to buy from conditional transaction
-    dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &a_price->tx_hash);
+    dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, &a_price->tx_hash);
     if (!l_cond_tx) {
         log_it(L_WARNING, "Requested conditional transaction not found");
         return NULL;
@@ -594,7 +594,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
         log_it(L_WARNING, "Requested transaction has no conditional output");
         return NULL;
     }
-    if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, &a_price->tx_hash, l_prev_cond_idx, NULL)) {
+    if (dap_ledger_tx_hash_is_used_out_item(l_ledger, &a_price->tx_hash, l_prev_cond_idx, NULL)) {
         log_it(L_WARNING, "Requested conditional transaction is already used out");
         return NULL;
     }
@@ -766,7 +766,7 @@ static bool s_xchange_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price,
     // create empty transaction
     dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
 
-    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_price->net->pub.name);
+    dap_ledger_t *l_ledger = dap_ledger_by_net_name(a_price->net->pub.name);
     dap_chain_addr_t *l_seller_addr = (dap_chain_addr_t *)dap_chain_wallet_get_addr(a_wallet, a_price->net->pub.id);
 
     // create and add reciept
@@ -780,18 +780,18 @@ static bool s_xchange_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price,
     DAP_DELETE(l_receipt);
 
     // add 'in' item to buy from conditional transaction
-    dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &a_price->tx_hash);
+    dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_ledger, &a_price->tx_hash);
     if (!l_cond_tx) {
         log_it(L_WARNING, "Requested conditional transaction not found");
         dap_chain_datum_tx_delete(l_tx);
         return false;
     }
-    const char *l_tx_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &a_price->tx_hash);
+    const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &a_price->tx_hash);
     bool l_single_channel = !dap_strcmp(l_tx_ticker, l_native_ticker);
     int l_prev_cond_idx = 0;
     dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_cond_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE,
                                                                              &l_prev_cond_idx);
-    if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, &a_price->tx_hash, l_prev_cond_idx, NULL)) {
+    if (dap_ledger_tx_hash_is_used_out_item(l_ledger, &a_price->tx_hash, l_prev_cond_idx, NULL)) {
         log_it(L_WARNING, "Requested conditional transaction is already used out");
         dap_chain_datum_tx_delete(l_tx);
         return false;
@@ -811,7 +811,7 @@ static bool s_xchange_tx_invalidate(dap_chain_net_srv_xchange_price_t *a_price,
     uint256_t l_total_fee = {};
     SUM_256_256(a_price->fee, l_net_fee, &l_total_fee);
     // list of transaction with 'out' items to get net fee
-    dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
+    dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_native_ticker,
                                                                              l_seller_addr, l_total_fee, &l_transfer_fee);
     if(!l_list_used_out) {
         dap_chain_datum_tx_delete(l_tx);
@@ -940,7 +940,7 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a
 
     dap_hash_fast_t l_tx_hash = {};
     dap_hash_fast(a_order, dap_chain_datum_tx_get_size(a_order), &l_tx_hash);
-    const char *l_token_sell = dap_chain_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx_hash);
+    const char *l_token_sell = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx_hash);
     strcpy(l_price->token_sell, l_token_sell);
 
 
@@ -948,7 +948,7 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a
     l_price->net = a_net;
     if (!IS_ZERO_256(l_price->datoshi_buy)) {
         l_price->rate = l_out_cond->subtype.srv_xchange.rate;
-        dap_hash_fast_t *l_final_hash = dap_chain_ledger_get_final_chain_tx_hash(a_net->pub.ledger,
+        dap_hash_fast_t *l_final_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger,
                                             DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_tx_hash);
         if (l_final_hash) {
             l_price->tx_hash = *l_final_hash;
@@ -1015,7 +1015,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, c
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'price create' requires parameter -token_sell");
                 return -5;
             }
-            if (!dap_chain_ledger_token_ticker_check(l_net->pub.ledger, l_token_sell_str)) {
+            if (!dap_ledger_token_ticker_check(l_net->pub.ledger, l_token_sell_str)) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_sell_str);
                 return -6;
             }
@@ -1024,7 +1024,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, c
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'price create' requires parameter -token_buy");
                 return -5;
             }
-            if (!dap_chain_ledger_token_ticker_check(l_net->pub.ledger, l_token_buy_str)) {
+            if (!dap_ledger_token_ticker_check(l_net->pub.ledger, l_token_buy_str)) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_buy_str);
                 return -6;
             }
@@ -1287,7 +1287,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, c
 
             dap_hash_fast_t l_tx_hash = {};
             dap_chain_hash_fast_from_str(l_order_hash_str, &l_tx_hash);
-            dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash);
+            dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash);
             if (!l_cond_tx) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nSpecified order not found", l_sign_str);
                 return -13;
@@ -1341,14 +1341,14 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, c
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified order not found");
                 return -13;
             }
-            dap_hash_fast_t *l_final_hash = dap_chain_ledger_get_final_chain_tx_hash(l_net->pub.ledger,
+            dap_hash_fast_t *l_final_hash = dap_ledger_get_final_chain_tx_hash(l_net->pub.ledger,
                                                  DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_order->tx_cond_hash);
             if (!l_final_hash) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified order have no active tx (copmleted)");
                 DAP_DELETE(l_order);
                 return -18;
             }
-            dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_hash(l_net->pub.ledger, l_final_hash);
+            dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, l_final_hash);
             if (!l_tx) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Internal error");
                 DAP_DELETE(l_order);
@@ -1441,7 +1441,7 @@ static int s_tx_check_for_open_close(dap_chain_net_t * a_net, dap_chain_datum_tx
     dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_out_cond_get(a_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE,
                                                                                &l_cond_idx);
     if (l_out_cond_item) {
-        if(dap_chain_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL))
+        if(dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL))
             return 2; // If its SRV_XCHANGE and spent its closed
         else
             return 1; // If its SRV_XCHANGE and not spent its open
@@ -1467,7 +1467,7 @@ static void s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_
 //                    dap_string_append_printf(l_reply_str, "Hash: %s\n", l_hash_str);
 
     // Get input token ticker
-    const char * l_tx_input_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(
+    const char * l_tx_input_ticker = dap_ledger_tx_get_token_ticker_by_hash(
                 a_net->pub.ledger, &l_tx_hash);
 
     // Find SRV_XCHANGE out_cond item
@@ -1477,7 +1477,7 @@ static void s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_
     bool l_is_cond_out = false;
     if ( l_out_cond_item && (l_out_cond_item->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE) )
     {
-        bool l_is_closed = dap_chain_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL);
+        bool l_is_closed = dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL);
 
         uint256_t l_value_from = l_out_cond_item->header.value;
         uint256_t l_rate = l_out_cond_item->subtype.srv_xchange.rate;
@@ -1543,7 +1543,7 @@ dap_chain_tx_out_cond_t *l_out_cond_item;
 
 
     for (l_tx_total = 0;
-            (l_datum_tx = dap_chain_ledger_tx_find_by_addr(a_net->pub.ledger, NULL, a_addr, &l_tx_first_hash));
+            (l_datum_tx = dap_ledger_tx_find_by_addr(a_net->pub.ledger, NULL, a_addr, &l_tx_first_hash));
                 l_tx_total++)
     {
         /* Check time range (if need ) */
@@ -1575,7 +1575,7 @@ dap_chain_tx_out_cond_t *l_out_cond_item;
 
             if (a_opt_status)                                                   /* 1 - closed, 2 - open  */
             {
-                l_rc = dap_chain_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_hash, l_item_idx, NULL);
+                l_rc = dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_hash, l_item_idx, NULL);
 
                 if ( a_opt_status )
                 {
@@ -1590,7 +1590,7 @@ dap_chain_tx_out_cond_t *l_out_cond_item;
             dap_string_append_printf(l_reply_str, "Hash: %s\n", l_hash_str);
 
 
-            const char *l_tx_input_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_hash);
+            const char *l_tx_input_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_hash);
 
             uint256_t l_rate = l_out_cond_item->subtype.srv_xchange.rate;
             uint256_t l_tx_input_values = dap_chain_net_get_tx_total_value(a_net, l_datum_tx);
@@ -1803,7 +1803,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
 //            dap_chain_net_srv_order_t *l_order = dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_str);
             dap_hash_fast_t l_tx_hash = {};
             dap_chain_hash_fast_from_str(l_order_hash_str, &l_tx_hash);
-            dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash);
+            dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash);
 
             if (l_cond_tx) {
                 dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(l_net, l_cond_tx, false);
@@ -1937,7 +1937,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
 //                    dap_string_append_printf(l_reply_str, "Hash: %s\n", l_hash_str);
 
                     // Get input token ticker
-                    const char * l_tx_input_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(
+                    const char * l_tx_input_ticker = dap_ledger_tx_get_token_ticker_by_hash(
                                 l_net->pub.ledger, &l_tx_hash);
 
                     // Find SRV_XCHANGE out_cond item
@@ -1950,7 +1950,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
                         char *l_rate_str = dap_chain_balance_to_coins(l_rate);
                         char *l_value_from_str = dap_chain_balance_to_coins(l_value_from);
 
-                        l_rc = dap_chain_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, &l_tx_hash, l_prev_cond_idx, NULL);
+                        l_rc = dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, &l_tx_hash, l_prev_cond_idx, NULL);
 
                         if ((l_opt_status == 1 && !l_rc) ||       /* Select close only */
                                 (l_opt_status == 2 &&  l_rc))     /* Select open only */
@@ -2009,7 +2009,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
                     dap_cli_server_cmd_set_reply_text(a_str_reply,"No argument '-token_from'");
                     return -5;
                 }
-                dap_chain_datum_token_t * l_token_from_datum = dap_chain_ledger_token_ticker_check( l_net->pub.ledger, l_token_from_str);
+                dap_chain_datum_token_t * l_token_from_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_from_str);
                 if(!l_token_from_datum){
                     dap_cli_server_cmd_set_reply_text(a_str_reply,"Can't find \"%s\" token in network \"%s\" for argument '-token_from' ", l_token_from_str, l_net->pub.name);
                     return -6;
@@ -2022,7 +2022,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
                     dap_cli_server_cmd_set_reply_text(a_str_reply,"No argument '-token_to'");
                     return -5;
                 }
-                dap_chain_datum_token_t * l_token_to_datum = dap_chain_ledger_token_ticker_check( l_net->pub.ledger, l_token_to_str);
+                dap_chain_datum_token_t * l_token_to_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_to_str);
                 if(!l_token_to_datum){
                     dap_cli_server_cmd_set_reply_text(a_str_reply,"Can't find \"%s\" token in network \"%s\" for argument '-token2' ", l_token_to_str, l_net->pub.name);
                     return -6;
@@ -2053,13 +2053,13 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
                     while(l_cur){
                         dap_chain_datum_tx_t * l_tx =(dap_chain_datum_tx_t *) l_cur->data;
                         if(l_tx){
+                            // TODO find another way to get current tx hash
                             dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx);
-
                             int l_cond_idx = 0;
                             dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE,
-                                                                                                       &l_cond_idx);
+                                                                                                    &l_cond_idx);
                             if (l_out_cond_item &&
-                                    dap_chain_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, l_tx_hash, l_cond_idx, NULL)) {
+                                    dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, l_tx_hash, l_cond_idx, NULL)) {
                                 uint256_t l_value_sell = l_out_cond_item->header.value;
                                 l_rate = l_out_cond_item->subtype.srv_xchange.rate;
                                     if (!IS_ZERO_256(l_value_sell)) {
@@ -2069,8 +2069,8 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
                                     }else{
                                         log_it(L_ERROR, "Sell value is 0 in avarage price calculation (summing)");
                                     }
-                                DAP_DEL_Z(l_tx_hash);
                             }
+                            DAP_DEL_Z(l_tx_hash);
                         }
                         l_cur = dap_list_next(l_cur);
                     }
@@ -2101,7 +2101,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
                             dap_hash_fast_t * l_tx_hash = &l_cur->tx_hash;
 
                             // Get input token ticker
-                            const char * l_tx_input_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(
+                            const char * l_tx_input_ticker = dap_ledger_tx_get_token_ticker_by_hash(
                                         l_net->pub.ledger, l_tx_hash);
 
                             // Check if output is spent
@@ -2173,7 +2173,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
                     dap_string_t *l_reply_str = dap_string_new("");
                     char ** l_tickers = NULL;
                     size_t l_tickers_count = 0;
-                    dap_chain_ledger_addr_get_token_ticker_all( l_net->pub.ledger,NULL,&l_tickers,&l_tickers_count);
+                    dap_ledger_addr_get_token_ticker_all( l_net->pub.ledger,NULL,&l_tickers,&l_tickers_count);
 
                     size_t l_pairs_count = 0;
                     if(l_tickers){
diff --git a/modules/test/CMakeLists.txt b/modules/test/CMakeLists.txt
deleted file mode 100644
index 0f12e79311..0000000000
--- a/modules/test/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-cmake_minimum_required(VERSION 3.10)
-if(TARGET dap_test)
-    return() # The project has already been built.
-endif()
-project(dap_test)
-
-add_library(${PROJECT_NAME} STATIC dap_test.h dap_test.c dap_test_generator.h dap_test_generator.c)
-
-target_include_directories(${PROJECT_NAME} INTERFACE .)
diff --git a/modules/test/dap_test.c b/modules/test/dap_test.c
deleted file mode 100644
index 55517435e1..0000000000
--- a/modules/test/dap_test.c
+++ /dev/null
@@ -1,112 +0,0 @@
-#include "dap_test.h"
-
-#include <sys/time.h>
-
-/*
- How to use benchmark_xxx() functions:
-
- void mytest_func()
- {
- // doing something ...
- }
-
- // Repeat mytest_func() 5 time
- int dt = benchmark_test_time(mytest_func, 5);
- // Display result, sample 'Encode and decode PASS. (4 msec.)'
- benchmark_mgs_time("Encode and decode", dt);
-
- // Repeat mytest_func() within 2 second
- float rate = benchmark_test_rate(mytest_func, 2);
- // Display result, sample 'Encode and decode PASS. (703 times/sec.)'
- benchmark_mgs_rate("Encode and decode", rate);
-
- */
-
-#define dap_pass_msg_benchmark(testname, benchmark_text) \
-    printf("\t%s%s PASS. %s%s\n", TEXT_COLOR_GRN, testname, benchmark_text, TEXT_COLOR_RESET); \
-    fflush(stdout); \
-
-/**
- * Display time in the format 'x.xx sec.' or 'xx msec.'
- */
-void benchmark_mgs_time(const char *test_name, int dt)
-{
-    char buf[120];
-    if(abs(dt) >= 1000) {
-        snprintf(buf, 120, "(%.3lf sec.)", dt * 1. / 1000);
-    }
-    else {
-
-        snprintf(buf, 120, "(%d msec.)", dt);
-    }
-    dap_pass_msg_benchmark(test_name, buf);
-}
-
-/**
- * Display rate in the format 'xx times/sec.'
- */
-void benchmark_mgs_rate(const char *test_name, float rate)
-{
-    char buf[120];
-    if(rate > 100) {
-        snprintf(buf, 120, "(%.0lf times/sec.)", rate);
-    }
-    else if(rate > 10) {
-        snprintf(buf, 120, "%.1lf times/sec.", rate);
-    }
-    else {
-        snprintf(buf, 120, "%.2lf times/sec.", rate);
-    }
-    dap_pass_msg_benchmark(test_name, buf);
-}
-
-/**
- * @return current time in milliseconds
- */
-int get_cur_time_msec(void)
-{
-    struct timespec time;
-    clock_gettime(CLOCK_MONOTONIC, &time);
-    int msec = time.tv_sec * 1000 + (time.tv_nsec + 500000) / 1000000;
-    return msec;
-}
-
-/**
- * Calculate the runtime of a function that repeat several times
- * @func_name function for repeats
- * @repeat how many times repeats
- * @return time in milliseconds
- */
-int benchmark_test_time(void (*func_name)(void), int repeat)
-{
-    int t1 = get_cur_time_msec();
-    for(int i = 0; i < repeat; i++)
-        func_name();
-    int t2 = get_cur_time_msec();
-    return t2 - t1;
-}
-
-/**
- * Calculate the rate of a function that repeat at a minimum specified number of seconds
- * @func_name function for repeats
- * @repeat how many times repeats
- * @return function rate, i.e. count per second
- */
-float benchmark_test_rate(void (*func_name)(void), float sec)
-{
-    if(sec < 0.1f) {
-        dap_test_msg("undefined times/sec.");
-        return 0;
-    }
-    int t1 = get_cur_time_msec();
-    int repeat = 0, dt;
-    do {
-        func_name();
-        dt = (get_cur_time_msec() - t1);
-        repeat++;
-    }
-    while(dt < sec * 1000);
-    float rate = repeat * 1000.f / dt;
-    return rate;
-}
-
diff --git a/modules/test/dap_test.h b/modules/test/dap_test.h
deleted file mode 100644
index 4a6445d82f..0000000000
--- a/modules/test/dap_test.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#pragma once
-#include <assert.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-#define TEXT_COLOR_RED   "\x1B[31m"
-#define TEXT_COLOR_GRN   "\x1B[32m"
-#define TEXT_COLOR_YEL   "\x1B[33m"
-#define TEXT_COLOR_BLU   "\x1B[34m"
-#define TEXT_COLOR_MAG   "\x1B[35m"
-#define TEXT_COLOR_CYN   "\x1B[36m"
-#define TEXT_COLOR_WHT   "\x1B[37m"
-#define TEXT_COLOR_RESET "\x1B[0m"
-
-/* Can be used like debug info during write test*/
-/**
- * @brief Can be used like debug info during write test
- */
-#define dap_test_msg(...) { \
-    printf("\t%s", TEXT_COLOR_WHT); \
-    printf(__VA_ARGS__); \
-    printf("%s\n", TEXT_COLOR_RESET); \
-    fflush(stdout); }
-
-#define dap_fail(msg) {\
-    printf("\t%s%s!%s\n", TEXT_COLOR_RED, msg, TEXT_COLOR_RESET); \
-    abort();}
-
-/* PIF - print if failed. For checking value in loop, for don't repeat output */
-/**
- * @brief PIF - print if failed. For checking value in loop, for don't repeat output
- */
-#define dap_assert_PIF(expr, msg) { \
-    if(expr) {} \
-    else { \
-    printf("\t%s%s FAILED!%s\n", TEXT_COLOR_RED, msg, TEXT_COLOR_RESET); \
-    abort(); } }
-
-/**
- * @brief
-*/
-#define dap_assert(expr, testname) { \
-    if(expr) { \
-        printf("\t%s%s PASS.%s\n", TEXT_COLOR_GRN, testname, TEXT_COLOR_RESET); \
-        fflush(stdout); \
-    } else { \
-    printf("\t%s%s FAILED!%s\n", TEXT_COLOR_RED, testname, TEXT_COLOR_RESET); \
-    abort(); } } \
-
-/**
- * @brief Display the name test
-*/
-#define dap_pass_msg(testname) { \
-    printf("\t%s%s PASS.%s\n", TEXT_COLOR_GRN, testname, TEXT_COLOR_RESET); \
-    fflush(stdout); } \
-
-/**
- * @brief Display the name of the test module
-*/
-#define dap_print_module_name(module_name) { \
-    printf("%s%s passing the tests... %s\n", TEXT_COLOR_CYN, module_name, TEXT_COLOR_RESET); \
-    fflush(stdout); }
-
-#define dap_str_equals(str1, str2) strcmp(str1, str2) == 0
-#define dap_strn_equals(str1, str2, count) strncmp(str1, str2, count) == 0
-int get_cur_time_msec(void);
-
-/*
- How to use benchmark_xxx() functions:
-
- void mytest_func()
- {
- // doing something ...
- }
-
- // Repeat mytest_func() 5 time
- int dt = benchmark_test_time(mytest_func, 5);
- // Display result, sample 'Encode and decode PASS. (4 msec.)'
- benchmark_mgs_time("Encode and decode", dt);
-
- // Repeat mytest_func() within 2 second
- float rate = benchmark_test_rate(mytest_func, 2);
- // Display result, sample 'Encode and decode PASS. (703 times/sec.)'
- benchmark_mgs_rate("Encode and decode", rate);
-
- */
-
-/**
- * Display time in the format 'x.xx sec.' or 'xx msec.'
- */
-void benchmark_mgs_time(const char *text, int dt);
-
-/**
- * Display rate in the format 'xx times/sec.'
- */
-void benchmark_mgs_rate(const char *test_name, float rate);
-/**
- * Calculate the runtime of a function that repeat several times
- * @func_name function for repeats
- * @repeat how many times repeats
- * @return time in milliseconds
- */
-int benchmark_test_time(void (*func_name)(void), int repeat);
-/**
- * Calculate the rate of a function that repeat at a minimum specified number of seconds
- * @func_name function for repeats
- * @repeat how many times repeats
- * @return function rate, i.e. count per second
- */
-float benchmark_test_rate(void (*func_name)(void), float sec);
diff --git a/modules/test/dap_test_generator.c b/modules/test/dap_test_generator.c
deleted file mode 100644
index 6a540f6928..0000000000
--- a/modules/test/dap_test_generator.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "dap_test_generator.h"
-
-#define BYTE_SIZE 255
-
-/**
- * @brief The function fills an array with random numbers
- * @param[out] array Takes a pointer to an array
- * @param[in] size Size of the array passed in the array parameter
- *
- * The function fills an array with random integer non-negative values
-*/
-void generate_random_byte_array(uint8_t* array, const size_t size) {
-    srand((uint32_t)time(NULL));
-    for(size_t i = 0; i < size; i++) {
-        array[i] = (uint8_t)rand() % BYTE_SIZE;
-    }
-
-    // Last byte not should be 0
-    if (array[size - 1] == 0)
-        array[size - 1] = 1;
-}
diff --git a/modules/test/dap_test_generator.h b/modules/test/dap_test_generator.h
deleted file mode 100644
index 4c74064744..0000000000
--- a/modules/test/dap_test_generator.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-#include <stdint.h>
-#include <stdlib.h>
-#include <time.h>
-
-void generate_random_byte_array(uint8_t* array, const size_t size);
-
diff --git a/modules/type/blocks/dap_chain_block.c b/modules/type/blocks/dap_chain_block.c
index 20420c7471..2b64edb253 100644
--- a/modules/type/blocks/dap_chain_block.c
+++ b/modules/type/blocks/dap_chain_block.c
@@ -91,10 +91,11 @@ dap_chain_block_t *dap_chain_block_new(dap_chain_hash_fast_t *a_prev_block, size
  * @param a_block_size
  * @return
  */
-size_t s_block_get_datum_offset (dap_chain_block_t * a_block, size_t a_block_size)
+size_t s_block_get_datum_offset(const dap_chain_block_t *a_block, size_t a_block_size)
 {
     if( a_block_size < sizeof(a_block->hdr) ){
         log_it(L_ERROR, "Can't get datum offset: corrupted block size %zu / header size %zu", a_block_size, sizeof (a_block->hdr));
+        return 0;
     }
     size_t l_offset = 0;
     dap_chain_block_meta_t * l_meta=NULL;
@@ -278,7 +279,7 @@ size_t dap_chain_block_datum_del_by_hash(dap_chain_block_t ** a_block_ptr, size_
  * @param a_block_size
  * @return
  */
-size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_block_size)
+size_t dap_chain_block_get_sign_offset(const dap_chain_block_t *a_block, size_t a_block_size)
 {
     assert(a_block);
     assert(a_block_size);
@@ -287,7 +288,7 @@ size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_bloc
         return 0;
     }
 
-    size_t l_offset = s_block_get_datum_offset(a_block,a_block_size);
+    size_t l_offset = s_block_get_datum_offset(a_block, a_block_size);
     dap_chain_datum_t * l_datum =(dap_chain_datum_t *) (a_block->meta_n_datum_n_sign + l_offset);
     // Pass all datums to the end
     for(size_t n=0; n<a_block->hdr.datum_count && l_offset< (a_block_size-sizeof (a_block->hdr)) ; n++){
@@ -296,12 +297,12 @@ size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_bloc
         // Check if size 0
         if(! l_datum_size){
             log_it(L_ERROR,"Datum size is 0, smth is corrupted in block");
-            return a_block_size;
+            return 0;
         }
         // Check if size of of block size
         if ( (l_datum_size+l_offset) > (a_block_size-sizeof (a_block->hdr)) ){
             log_it(L_ERROR,"Datum size is too big %zu thats with offset %zu is bigger than block size %zu", l_datum_size, l_offset, a_block_size);
-            return a_block_size;
+            return 0;
         }
         l_offset += l_datum_size;
         // Updae current datum pointer, if it was deleted - we also need to update it after realloc
@@ -309,7 +310,7 @@ size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_bloc
     }
     if (l_offset> (a_block_size-sizeof (a_block->hdr))){
         log_it(L_ERROR,"Offset %zd with block header %zu is bigger than block size %zu", l_offset,sizeof (a_block->hdr),a_block_size);
-        return a_block_size;
+        return 0;
     }
 
     return l_offset;
@@ -344,14 +345,13 @@ size_t dap_chain_block_sign_add(dap_chain_block_t **a_block_ptr, size_t a_block_
  * @param a_sign_num
  * @return
  */
-dap_sign_t *dap_chain_block_sign_get ( dap_chain_block_t * a_block, size_t a_block_size, uint16_t a_sign_num )
+dap_sign_t *dap_chain_block_sign_get(const dap_chain_block_t *a_block, size_t a_block_size, uint16_t a_sign_num)
 {
     assert(a_block);
     size_t l_offset = dap_chain_block_get_sign_offset(a_block, a_block_size);
     uint16_t l_sign_cur = 0;
     dap_sign_t *l_sign = (dap_sign_t *)(a_block->meta_n_datum_n_sign + l_offset);
     while (l_sign_cur < a_sign_num) {
-
         size_t l_sign_size = dap_sign_get_size(l_sign);
         if (!l_sign_size){
             log_it(L_ERROR, "Empty sign #%u",  l_sign_cur );
@@ -368,7 +368,7 @@ dap_sign_t *dap_chain_block_sign_get ( dap_chain_block_t * a_block, size_t a_blo
     return l_sign_cur == a_sign_num ? l_sign : NULL;
 }
 
-size_t dap_chain_block_get_signs_count(dap_chain_block_t * a_block, size_t a_block_size)
+size_t dap_chain_block_get_signs_count(const dap_chain_block_t * a_block, size_t a_block_size)
 {
     assert(a_block);
     assert(a_block_size);
@@ -390,6 +390,25 @@ size_t dap_chain_block_get_signs_count(dap_chain_block_t * a_block, size_t a_blo
     return l_sign_count;
 }
 
+bool dap_chain_block_sign_match_pkey(const dap_chain_block_t *a_block, size_t a_block_size, dap_pkey_t *a_sign_pkey)
+{
+    dap_return_val_if_fail(a_block && a_block_size, false);
+    uint16_t l_sign_count = 0;
+    size_t l_offset = dap_chain_block_get_sign_offset(a_block, a_block_size);
+    while (l_offset + sizeof(a_block->hdr) < a_block_size) {
+        dap_sign_t *l_sign = (dap_sign_t *)(a_block->meta_n_datum_n_sign + l_offset);
+        size_t l_sign_size = dap_sign_get_size(l_sign);
+        if (!l_sign_size) {
+            log_it(L_WARNING, "Empty sign #%hu", l_sign_count);
+            return false;
+        }
+        if (dap_pkey_match_sign(a_sign_pkey, l_sign))
+            return true;
+        l_offset += l_sign_size;
+    }
+    return false;
+}
+
 /**
  * @brief dap_chain_block_get_datums
  * @param a_block
@@ -397,7 +416,7 @@ size_t dap_chain_block_get_signs_count(dap_chain_block_t * a_block, size_t a_blo
  * @param a_datums_count
  * @return
  */
-dap_chain_datum_t** dap_chain_block_get_datums(dap_chain_block_t * a_block, size_t a_block_size,size_t * a_datums_count )
+dap_chain_datum_t** dap_chain_block_get_datums(const dap_chain_block_t *a_block, size_t a_block_size, size_t * a_datums_count )
 {
     assert(a_block);
     assert(a_block_size);
@@ -448,13 +467,14 @@ dap_chain_datum_t** dap_chain_block_get_datums(dap_chain_block_t * a_block, size
  * @param a_meta_count
  * @return
  */
-dap_chain_block_meta_t** dap_chain_block_get_meta(dap_chain_block_t * a_block, size_t a_block_size,size_t * a_meta_count )
+dap_chain_block_meta_t** dap_chain_block_get_meta(const dap_chain_block_t * a_block, size_t a_block_size,size_t * a_meta_count )
 {
+    if (a_meta_count)
+        *a_meta_count = 0;
     if( a_block_size < sizeof(a_block->hdr) ){
         log_it(L_ERROR,"Get meta: corrupted block size %zu thats smaller then block header size %zu", a_block_size, sizeof (a_block->hdr));
+        return NULL;
     }
-    if (a_meta_count)
-        *a_meta_count = 0;
     if (a_block->hdr.meta_count == 0) // no meta - nothing to return
         return NULL;
     size_t l_offset = 0;
@@ -482,6 +502,37 @@ dap_chain_block_meta_t** dap_chain_block_get_meta(dap_chain_block_t * a_block, s
     return l_ret;
 }
 
+dap_hash_fast_t *dap_chain_block_get_prev_hash(const dap_chain_block_t *a_block, size_t a_block_size)
+{
+    if( a_block_size < sizeof(a_block->hdr) ){
+        log_it(L_ERROR, "Get meta: corrupted block size %zu thats smaller then block header size %zu", a_block_size, sizeof (a_block->hdr));
+        return NULL;
+    }
+    if (a_block->hdr.meta_count == 0) // no meta - nothing to return
+        return NULL;
+
+    dap_chain_block_meta_t *l_meta = NULL;
+    for (size_t l_offset = 0, i = 0;
+         i < a_block->hdr.meta_count && l_offset + sizeof(a_block->hdr) + sizeof(dap_chain_block_meta_t) < a_block_size;
+         i++) {
+        l_meta = (dap_chain_block_meta_t *)(a_block->meta_n_datum_n_sign + l_offset);
+        l_offset += sizeof(l_meta->hdr) + l_meta->hdr.data_size;
+        if (l_offset + sizeof(a_block->hdr) > a_block_size) {
+            log_it(L_WARNING, "Get meta: corrupted block, can read only %zu from %hu metas", i, a_block->hdr.meta_count);
+            return NULL;
+        }
+        if (l_meta->hdr.type == DAP_CHAIN_BLOCK_META_PREV) {
+            if (l_meta->hdr.data_size != sizeof(dap_hash_t)) {
+                log_it(L_WARNING, "Get meta: corrupted block, incorrect size DAP_CHAIN_BLOCK_META_PREV %hu, must be %zu",
+                                                    l_meta->hdr.data_size, sizeof(dap_hash_t));
+                return NULL;
+            }
+            return (dap_hash_t *)l_meta->data;
+        }
+    }
+    return NULL;
+}
+
 /**
  * @brief dap_chain_block_meta_extract_generals
  * @param a_meta
diff --git a/modules/type/blocks/dap_chain_block_cache.c b/modules/type/blocks/dap_chain_block_cache.c
index 90a0d2467f..c5994830db 100644
--- a/modules/type/blocks/dap_chain_block_cache.c
+++ b/modules/type/blocks/dap_chain_block_cache.c
@@ -54,8 +54,7 @@ void dap_chain_block_cache_deinit()
  * @return
  */
 
-dap_chain_block_cache_t *dap_chain_block_cache_new(dap_chain_cs_blocks_t *a_blocks, dap_hash_fast_t *a_block_hash,
-                                                   dap_chain_block_t *a_block, size_t a_block_size)
+dap_chain_block_cache_t *dap_chain_block_cache_new(dap_hash_fast_t *a_block_hash, dap_chain_block_t *a_block, size_t a_block_size)
 {
     if (! a_block)
         return NULL;
@@ -67,7 +66,6 @@ dap_chain_block_cache_t *dap_chain_block_cache_new(dap_chain_cs_blocks_t *a_bloc
     }
     l_block_cache->block = a_block;
     l_block_cache->block_size= a_block_size;
-    l_block_cache->_inheritor = a_blocks;
     l_block_cache->ts_created = a_block->hdr.ts_created;
     l_block_cache->sign_count = dap_chain_block_get_signs_count(a_block, a_block_size);
     if (dap_chain_block_cache_update(l_block_cache, a_block_hash)) {
@@ -177,10 +175,10 @@ dap_list_t * dap_chain_block_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledg
 
         //Check whether used 'out' items
         dap_hash_fast_t *l_tx_hash = a_block_cache->datum_hash + i;
-        if (!dap_chain_ledger_tx_hash_is_used_out_item (a_ledger, l_tx_hash, l_out_idx_tmp, NULL)) {
+        if (!dap_ledger_tx_hash_is_used_out_item (a_ledger, l_tx_hash, l_out_idx_tmp, NULL)) {
             dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
             if (!l_item) {
-        log_it(L_CRITICAL, "Memory allocation error");
+                log_it(L_CRITICAL, "Memory allocation error");
                 if (l_list_used_out)
                     dap_list_free_full(l_list_used_out, NULL);
                 return NULL;
diff --git a/modules/type/blocks/dap_chain_block_chunk.c b/modules/type/blocks/dap_chain_block_chunk.c
index fd5578c968..0e9d2aa3cd 100644
--- a/modules/type/blocks/dap_chain_block_chunk.c
+++ b/modules/type/blocks/dap_chain_block_chunk.c
@@ -49,8 +49,7 @@ dap_chain_block_chunks_t * dap_chain_block_chunks_create(dap_chain_cs_blocks_t *
     for(size_t n=0; n< l_objs_count; n++){
         dap_hash_fast_t l_block_hash;
         dap_chain_hash_fast_from_str(l_objs[n].key, &l_block_hash);
-        dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_new(a_blocks, &l_block_hash,
-                                                                           (dap_chain_block_t*)l_objs[n].value, l_objs[n].value_len);
+        dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_new(&l_block_hash, (dap_chain_block_t *)l_objs[n].value, l_objs[n].value_len);
         dap_chain_block_chunks_add(l_ret, l_block_cache );
     }
     dap_global_db_objs_delete(l_objs,l_objs_count);
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index 1dc1d60663..88cb1a7ad1 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -98,8 +98,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain,
 static size_t s_callback_atom_get_static_hdr_size(void);
 
 static dap_chain_atom_iter_t *s_callback_atom_iter_create(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, bool a_with_treshold);
-static dap_chain_atom_iter_t* s_callback_atom_iter_create_from(dap_chain_t *  ,
-                                                                     dap_chain_atom_ptr_t , size_t);
+static dap_chain_atom_iter_t* s_callback_atom_iter_create_from(dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size);
 static dap_chain_atom_ptr_t s_callback_atom_iter_find_by_hash(dap_chain_atom_iter_t * a_atom_iter ,
                                                                        dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size);
 static dap_chain_datum_t *s_callback_datum_find_by_hash(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_datum_hash,
@@ -109,6 +108,7 @@ static dap_chain_atom_ptr_t s_callback_block_find_by_tx_hash(dap_chain_t * a_cha
 
 static dap_chain_datum_t** s_callback_atom_get_datums(dap_chain_atom_ptr_t a_atom, size_t a_atom_size, size_t * a_datums_count);
 static dap_time_t s_chain_callback_atom_get_timestamp(dap_chain_atom_ptr_t a_atom) { return ((dap_chain_block_t *)a_atom)->hdr.ts_created; }
+static uint256_t s_callback_calc_reward(dap_chain_t *a_chain, dap_hash_fast_t *a_block_hash, dap_pkey_t *a_block_sign_pkey);
 //    Get blocks
 static dap_chain_atom_ptr_t s_callback_atom_iter_get_first( dap_chain_atom_iter_t * a_atom_iter, size_t *a_atom_size ); //    Get the fisrt block
 static dap_chain_atom_ptr_t s_callback_atom_iter_get_next( dap_chain_atom_iter_t * a_atom_iter,size_t *a_atom_size );  //    Get the next block
@@ -117,7 +117,7 @@ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_links( dap_chain_atom_iter
 static dap_chain_atom_ptr_t *s_callback_atom_iter_get_lasts( dap_chain_atom_iter_t * a_atom_iter ,size_t *a_links_size,
                                                                   size_t ** a_lasts_size_ptr );  //    Get list of linked blocks
 //Get list of hashes
-static dap_list_t *s_block_parse_str_list(const char * a_hash_str,size_t * a_hash_size, dap_chain_t * a_chain, dap_cert_t * a_cert);
+static dap_list_t *s_block_parse_str_list(char *a_hash_str, size_t * a_hash_size, dap_chain_t * a_chain);
 
 // Delete iterator
 static void s_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_iter );                  //    Get the fisrt block
@@ -177,11 +177,24 @@ int dap_chain_cs_blocks_init()
             "block -net <net_name> -chain <chain_name> list [-from_hash <block_hash>] [-to_hash <block_hash>]"
             "[-from_dt <in YYMMDD>] [-to_dt <in YYMMDD>] [-cert <priv_cert_name> -unspent]\n"
                 "\t\t List blocks\n\n"
+
         "Commission collect:\n"
             "block -net <net_name> -chain <chain_name> fee collect\n"
             "-cert <priv_cert_name> -addr <addr> -hashes <hashes list> -fee <value>\n"
                 "\t\t Take the whole commission\n\n"
 
+        "Reward for block signs:\n"
+            "block -net <net_name> -chain <chain_name> reward set\n"
+            "-cert <poa_cert_name> -value <value>\n"
+                "\t\t Set base reward for sign for one block at one minute\n\n"
+
+            "block -net <net_name> -chain <chain_name> reward show\n"
+            "-cert <poa_cert_name> -value <value>\n"
+                "\t\t Show base reward for sign for one block at one minute\n\n"
+
+            "block -net <net_name> -chain <chain_name> reward collect\n"
+            "-cert <priv_cert_name> -addr <addr> -hashes <hashes list> -fee <value>\n"
+                "\t\t Take reward\n\n"
                                         );
     if( dap_chain_block_cache_init() ) {
         log_it(L_WARNING, "Can't init blocks cache");
@@ -238,6 +251,7 @@ static int s_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_c
     a_chain->callback_datum_find_by_hash = s_callback_datum_find_by_hash;
 
     a_chain->callback_block_find_by_tx_hash = s_callback_block_find_by_tx_hash;
+    a_chain->callback_calc_reward = s_callback_calc_reward;
 
     a_chain->callback_add_datums = s_callback_add_datums;
     a_chain->callback_purge = s_callback_cs_blocks_purge;
@@ -295,12 +309,12 @@ static int s_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_c
 }
 
 /**
- * @brief dap_chain_block_cs_cache_get_by_hash
+ * @brief dap_chain_block_cache_get_by_hash
  * @param a_blocks
  * @param a_block_hash
  * @return
  */
-dap_chain_block_cache_t * dap_chain_block_cs_cache_get_by_hash(dap_chain_cs_blocks_t * a_blocks,  dap_chain_hash_fast_t *a_block_hash)
+dap_chain_block_cache_t * dap_chain_block_cache_get_by_hash(dap_chain_cs_blocks_t * a_blocks,  dap_chain_hash_fast_t *a_block_hash)
 {
     dap_chain_block_cache_t * l_ret = NULL;
     pthread_rwlock_rdlock(& PVT(a_blocks)->rwlock);
@@ -309,6 +323,70 @@ dap_chain_block_cache_t * dap_chain_block_cs_cache_get_by_hash(dap_chain_cs_bloc
     return l_ret;
 }
 
+static char *s_blocks_decree_set_reward(dap_chain_net_t *a_net, dap_chain_t *a_chain, uint256_t a_value, dap_cert_t *a_cert)
+{
+    dap_return_val_if_fail(a_net && a_cert && a_cert->enc_key &&
+                           a_cert->enc_key->priv_key_data && a_cert->enc_key->priv_key_data_size, NULL);
+    dap_chain_t *l_chain_anchor = a_chain ? a_chain : dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR);
+    if (!l_chain_anchor) {
+        log_it(L_ERROR, "Can't find chain with anchor support");
+        return NULL;
+    }
+    dap_chain_t *l_chain_decree = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_DECREE);
+    if (!l_chain_decree) {
+        log_it(L_ERROR, "Can't find chain with decree support");
+        return NULL;
+    }
+    // Create decree
+    size_t l_tsd_total_size = sizeof(dap_tsd_t) + sizeof(uint256_t);
+    size_t l_decree_size = sizeof(dap_chain_datum_decree_t) + l_tsd_total_size;
+    dap_chain_datum_decree_t *l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, l_decree_size);
+    if (!l_decree) {
+        log_it(L_CRITICAL, "Memory allocation error");
+        return NULL;
+    }
+    // Fill the header
+    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;
+    l_decree->header.common_decree_params.chain_id = l_chain_anchor->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_REWARD;
+    l_decree->header.data_size = l_tsd_total_size;
+    // Fill a TSD section
+    dap_tsd_t *l_tsd = (dap_tsd_t *)l_decree->data_n_signs;
+    l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE;
+    l_tsd->size = sizeof(uint256_t);
+    *(uint256_t*)(l_tsd->data) = a_value;
+    // Sign it
+    dap_sign_t *l_sign = dap_cert_sign(a_cert, l_decree, l_decree_size, 0);
+    if (!l_sign) {
+        log_it(L_ERROR, "Decree signing failed");
+        DAP_DELETE(l_decree);
+        return NULL;
+    }
+    log_it(L_NOTICE, "<-- Signed with '%s'", a_cert->name);
+    size_t l_sign_size = dap_sign_get_size(l_sign);
+    l_decree_size += l_sign_size;
+    l_decree->header.signs_size = l_sign_size;
+    void *l_decree_rl = DAP_REALLOC(l_decree, l_decree_size);
+    if (!l_decree_rl) {
+        log_it(L_CRITICAL, "Memory reallocation error");
+        DAP_DELETE(l_decree);
+        return NULL;
+    } else
+        l_decree = l_decree_rl;
+    memcpy(l_decree->data_n_signs + l_tsd_total_size, l_sign, l_sign_size);
+    DAP_DELETE(l_sign);
+
+    dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_DECREE, l_decree, l_decree_size);
+    // Processing will be made according to autoprocess policy
+    char *l_ret = dap_chain_mempool_datum_add(l_datum, l_chain_decree, "hex");
+    DAP_DELETE(l_datum);
+    return l_ret;
+}
+
 /**
  * @brief s_cli_parse_cmd_hash
  * @param a_argv
@@ -384,7 +462,8 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
         SUBCMD_DUMP,
         SUBCMD_LIST,
         SUBCMD_FEE,
-        SUBCMD_DROP
+        SUBCMD_DROP,
+        SUBCMD_REWARD
     } l_subcmd={0};
 
     const char* l_subcmd_strs[]={
@@ -397,6 +476,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
         [SUBCMD_LIST]="list",
         [SUBCMD_FEE]="fee",
         [SUBCMD_DROP]="drop",
+        [SUBCMD_REWARD] = "reward",
         [SUBCMD_UNDEFINED]=NULL
     };
     const size_t l_subcmd_str_count=sizeof(l_subcmd_strs)/sizeof(*l_subcmd_strs);
@@ -437,7 +517,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
             l_subcmd_str_arg = l_subcmd_str_args[i];
         }
     }
-    int ret=-1000;
+    int ret = 0;
     // Do subcommand action
     switch ( l_subcmd ){
         // Flush memory for the new block
@@ -491,11 +571,9 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Error! Datum %s doesn't pass verifications, examine node log files",
                                                       l_subcmd_str_arg);
                     ret = -9;
-                } else {
+                } else
                    log_it(L_INFO, "Pass datum %s from mempool to block in the new forming round ",
                                                      l_subcmd_str_arg);
-                   ret = 0;
-                }
                 if (l_err)
                     break;
             }
@@ -518,7 +596,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
 					dap_chain_hash_fast_from_str( l_subcmd_str_arg, &l_block_hash); // Convert argument to hash
 					l_block = (dap_chain_block_t*) dap_chain_get_atom_by_hash( l_chain, &l_block_hash, &l_block_size);
 					if ( l_block){
-						dap_chain_block_cache_t *l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_block_hash);
+                        dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_block_hash);
 						if ( l_block_cache ){
 							dap_string_t * l_str_tmp = dap_string_new(NULL);
 							char buf[50];
@@ -598,7 +676,6 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
 							}
                             dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str);
                             dap_string_free(l_str_tmp, true);
-							ret=0;
 						}
 					}else {
 						dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find block %s ", l_subcmd_str_arg);
@@ -701,7 +778,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
                                 int l_out_idx_tmp = 0;
                                 if (NULL == dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE, &l_out_idx_tmp))
                                     continue;
-                                if (!dap_chain_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, l_block_cache->datum_hash + i, l_out_idx_tmp, NULL)) {
+                                if (!dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, l_block_cache->datum_hash + i, l_out_idx_tmp, NULL)) {
                                     fl_found = true;
                                     break;
                                 }
@@ -743,8 +820,10 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
                 dap_string_free(l_str_tmp, true);
 
         }break;
-        case SUBCMD_FEE:{
-            const char * str_tmp = NULL;
+
+        case SUBCMD_FEE:
+        case SUBCMD_REWARD: {
+            const char * l_fee_value_str = NULL;
             const char * l_cert_name = NULL;
             const char * l_addr_str = NULL;
             const char * l_hash_out_type = NULL;
@@ -755,12 +834,58 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
             dap_list_t              *l_block_list = NULL;
             dap_chain_addr_t        *l_addr = NULL;
 
-            //arg_index++;
+            if (l_subcmd == SUBCMD_FEE) {
+                if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "collect") >= 0) {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee' requires subcommand 'collect'");
+                    return -14;
+                }
+            } else { // l_sumcmd == SUBCMD_REWARD
+                if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "set") >= 0) {
+                    const char *l_value_str = NULL;
+                    dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-poa_cert", &l_cert_name);
+                    if(!l_cert_name) {
+                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block reward set' requires parameter '-poa_cert'");
+                        return -17;
+                    }
+                    dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name);
+                    if (!l_cert) {
+                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name);
+                        return -18;
+                    }
+                    if (!l_cert->enc_key || !l_cert->enc_key->priv_key_data || !l_cert->enc_key->priv_key_data_size) {
+                        dap_cli_server_cmd_set_reply_text(a_str_reply,
+                                "Certificate \"%s\" doesn't contains private key", l_cert_name);
+                        return -19;
+                    }
 
-            if(!dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "collect", NULL)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee' requires parameter 'collect'");
-                return -14;
+                    dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-value", &l_value_str);
+                    uint256_t l_value = dap_chain_balance_scan(l_value_str);
+                    if (!l_value_str || IS_ZERO_256(l_value)) {
+                        dap_cli_server_cmd_set_reply_text(a_str_reply,
+                                "Command 'block reward set' requires parameter '-value' to be valid 256-bit unsigned integer");
+                        return -20;
+                    }
+                    char *l_decree_hash_str = s_blocks_decree_set_reward(l_net, l_chain, l_value, l_cert);
+                    if (l_decree_hash_str) {
+                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Decree with hash %s created to set basic block sign reward", l_decree_hash_str);
+                        DAP_DELETE(l_decree_hash_str);
+                    } else {
+                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Basic block sign reward setting failed. Examine log file for details");
+                        return -21;
+                    }
+                    break;
+                } else if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "show") >= 0) {
+                    char *l_base_reward_str = dap_chain_balance_to_coins(l_net->pub.base_reward);
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Current base block reward is %s\n", l_base_reward_str);
+                    DAP_DEL_Z(l_base_reward_str);
+                    break;
+                } else if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "collect") == -1) {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block reward' requires subcommands 'set' or 'show' or 'collect'");
+                    return -14;
+                }
             }
+
+            // Fee or reward collect handler
             dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type);
             if(!l_hash_out_type)
                 l_hash_out_type = "hex";
@@ -774,124 +899,109 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply)
             // The address of the wallet to which the commission is received
             dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_str);
             dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-hashes", &l_hash_str);
-            dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &str_tmp);
+            dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &l_fee_value_str);
 
-            if(!l_addr_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-addr'");
+            if (!l_addr_str) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block %s collect' requires parameter '-addr'", l_subcmd_str);
                 return -16;
             }
             l_addr = dap_chain_addr_from_str(l_addr_str);
-
             if(!l_cert_name) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-cert'");
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block %s collect' requires parameter '-cert'", l_subcmd_str);
                 return -17;
             }
-            dap_cert_t * l_cert = dap_cert_find_by_name( l_cert_name );
-
-            if( l_cert == NULL ){
-                dap_cli_server_cmd_set_reply_text(a_str_reply,
-                        "Can't find \"%s\" certificate", l_cert_name );
+            dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name);
+            if (!l_cert) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name);
                 return -18;
             }
-
-            l_fee_value = dap_chain_balance_scan(str_tmp);
-            if(!str_tmp||IS_ZERO_256(l_fee_value)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-fee' to be valid uint256");
+            if (!l_cert->enc_key || !l_cert->enc_key->priv_key_data || !l_cert->enc_key->priv_key_data_size) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply,
+                        "Certificate \"%s\" doesn't contains private key", l_cert_name);
                 return -19;
             }
 
-            if( l_cert->enc_key == NULL ){
+            l_fee_value = dap_chain_balance_scan(l_fee_value_str);
+            if (!l_fee_value_str || IS_ZERO_256(l_fee_value)) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply,
-                        "Corrupted certificate \"%s\" without keys certificate", l_cert_name );
+                                                  "Command 'block %s collect' requires parameter '-fee' to be valid uint256", l_subcmd_str);
                 return -20;
             }
 
-            if(!l_hash_str){
+            if (!l_hash_str) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-hashes'");
                 return -21;
             }
-            l_block_list = s_block_parse_str_list(l_hash_str, &l_hashes_count,l_chain,l_cert);
-
-            if(!l_hashes_count){
+            // NOTE: This call will modify source string
+            l_block_list = s_block_parse_str_list((char *)l_hash_str, &l_hashes_count, l_chain);
+            if (!l_block_list || !l_hashes_count) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply,
                         "Block fee collection requires at least one hash to create a transaction");
                 return -22;
             }
 
-            char * l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_cert->enc_key,l_addr,l_block_list,l_fee_value,l_hash_out_type);
+            char *l_hash_tx = NULL;
+            if (l_subcmd == SUBCMD_FEE)
+                l_hash_tx = dap_chain_mempool_tx_coll_fee_create(l_blocks, l_cert->enc_key, l_addr, l_block_list, l_fee_value, l_hash_out_type);
+            else
+                l_hash_tx = dap_chain_mempool_tx_reward_create(l_blocks, l_cert->enc_key, l_addr, l_block_list, l_fee_value, l_hash_out_type);
             if (l_hash_tx) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Fee collect TX created succefully, hash=%s\n", l_hash_tx);
-                ret = 0;
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "TX for %s collection created succefully, hash=%s\n", l_subcmd_str, l_hash_tx);
+                DAP_DELETE(l_hash_tx);
+            } else {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create %s collect TX\n", l_subcmd_str);
+                ret = -24;
             }
-            else
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create fee collect TX\n");
-            ret = -24;
-
-            DAP_DELETE(l_hash_tx);
-            dap_list_free(l_block_list);
+            dap_list_free_full(l_block_list, NULL);
         }break;
+
+        default:
         case SUBCMD_UNDEFINED: {
             dap_cli_server_cmd_set_reply_text(a_str_reply,
                                               "Undefined block subcommand \"%s\" ",
                                               l_subcmd_str);
             ret=-11;
-        }
+        } break;
     }
     return ret;
 }
 
-static dap_list_t * s_block_parse_str_list(const char * a_hash_str,size_t * a_hash_size, dap_chain_t * a_chain, dap_cert_t *a_cert)
+static dap_list_t *s_block_parse_str_list(char *a_hash_str, size_t *a_hash_size, dap_chain_t *a_chain)
 {
     dap_list_t *l_block_list = NULL;
-    char * l_hashes_tmp_ptrs = NULL;
-    char * l_hashes_str_dup = dap_strdup(a_hash_str);
-    char *l_hashes_str = strtok_r(l_hashes_str_dup, ",", &l_hashes_tmp_ptrs);
-    dap_chain_hash_fast_t   l_hash_block;
-    dap_chain_block_t       *l_block;
-    dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
-
-    dap_pkey_t *l_pub_key = NULL;
-    if(a_cert) {
-        l_pub_key = dap_pkey_from_enc_key(a_cert->enc_key);
-    }
-    // First we just calc items
-    while(l_hashes_str) {
-        l_hashes_str = strtok_r(NULL, ",", &l_hashes_tmp_ptrs);
-        (*a_hash_size)++;
-    }
-    strcpy(l_hashes_str_dup, a_hash_str);
-    l_hashes_str = strtok_r(l_hashes_str_dup, ",", &l_hashes_tmp_ptrs);
-
+    dap_chain_hash_fast_t l_hash_block;
+    char *l_hashes_tmp_ptrs = NULL;
+    char *l_hashes_str = strtok_r(a_hash_str, ",", &l_hashes_tmp_ptrs);
     size_t l_hashes_pos = 0;
-    while(l_hashes_str) {
+    while (l_hashes_str) {
         l_hashes_str = dap_strstrip(l_hashes_str);
-        if(dap_chain_hash_fast_from_hex_str(l_hashes_str, &l_hash_block)!=0) {
-            log_it(L_WARNING,"Can't load hash %s",l_hashes_str);
-            *a_hash_size = 0;
-            DAP_DELETE(l_hashes_str_dup);
-            return NULL;
+        if (!l_hashes_str || dap_chain_hash_fast_from_str(l_hashes_str, &l_hash_block)) {
+            log_it(L_WARNING, "Can't convert string %s to hash", l_hashes_str ? l_hashes_str : "(null)");
+            l_hashes_pos = 0;
+            break;
         }
-        size_t l_block_size = 0;
-        l_block = (dap_chain_block_t*) dap_chain_get_atom_by_hash( a_chain, &l_hash_block, &l_block_size);
-        if(!l_block)
-        {
-            log_it(L_WARNING,"There aren't any block by this hash");
-            *a_hash_size = 0;
-            DAP_DELETE(l_hashes_str_dup);
-            return NULL;
+        dap_chain_block_t *l_block = (dap_chain_block_t *)dap_chain_get_atom_by_hash(a_chain, &l_hash_block, NULL);
+        if (!l_block) {
+            log_it(L_WARNING, "There is no block pointed by hash %s", l_hashes_str);
+            l_hashes_pos = 0;
+            break;
         }
-        dap_chain_block_cache_t *l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_hash_block);
-        //verification of signatures of all blocks
-        dap_sign_t * l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 0);
-        if(dap_pkey_compare_with_sign(l_pub_key, l_sign))
-            l_block_list = dap_list_append(l_block_list, l_block_cache);
-        else
-             log_it(L_WARNING,"Block %s signature does not match certificate key", l_block_cache->block_hash_str);
-
+        dap_hash_fast_t *l_block_hash_new = DAP_DUP(&l_hash_block);
+        if (!l_block_hash_new) {
+            log_it(L_CRITICAL, "Memory allocaton error");
+            l_hashes_pos = 0;
+            break;
+        }
+        l_block_list = dap_list_append(l_block_list, l_block_hash_new);
         l_hashes_str = strtok_r(NULL, ",", &l_hashes_tmp_ptrs);
         l_hashes_pos++;
     }
-    DAP_DELETE(l_hashes_str_dup);
+    if (a_hash_size)
+        *a_hash_size = l_hashes_pos;
+    if (!l_hashes_pos && l_block_list) {
+        dap_list_free_full(l_block_list, NULL);
+        l_block_list = NULL;
+    }
     return l_block_list;
 }
 
@@ -1023,7 +1133,7 @@ static void s_bft_consensus_setup(dap_chain_cs_blocks_t * a_blocks)
     // Compare all chunks with chain's tail
     for (dap_chain_block_chunk_t *l_chunk = PVT(a_blocks)->chunks->chunks_last ; l_chunk; l_chunk=l_chunk->prev ){
         size_t l_chunk_length = HASH_COUNT(l_chunk->block_cache_hash);
-        dap_chain_block_cache_t * l_block_cache_chunk_top_prev = dap_chain_block_cs_cache_get_by_hash(a_blocks,&l_chunk->block_cache_top->prev_hash);
+        dap_chain_block_cache_t * l_block_cache_chunk_top_prev = dap_chain_block_cache_get_by_hash(a_blocks,&l_chunk->block_cache_top->prev_hash);
         dap_chain_block_cache_t * l_block_cache= l_block_cache_chunk_top_prev;
         if ( l_block_cache ){ // we found prev block in main chain
             size_t l_tail_length = 0;
@@ -1103,7 +1213,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da
         pthread_rwlock_unlock(&PVT(l_blocks)->rwlock);
         return ATOM_PASS;
     } else {
-        l_block_cache = dap_chain_block_cache_new(l_blocks, &l_block_hash, l_block, l_block_size);
+        l_block_cache = dap_chain_block_cache_new(&l_block_hash, l_block, l_block_size);
         if (!l_block_cache) {
             log_it(L_DEBUG, "... corrupted block");
             pthread_rwlock_unlock(&PVT(l_blocks)->rwlock);
@@ -1169,6 +1279,11 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain,
         }
     }
 
+    if (l_block->hdr.ts_created > dap_time_now() + 60) {
+        log_it(L_WARNING, "Incorrect block timestamp");
+        return  ATOM_REJECT;
+    }
+
     size_t l_meta_count = 0;
     dap_chain_block_meta_t ** l_meta=  dap_chain_block_get_meta(l_block, a_atom_size, & l_meta_count);
     // Parse metadata
@@ -1187,7 +1302,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain,
                                         &l_is_genesis,
                                         &l_nonce,
                                         &l_nonce2 ) ;
-    DAP_DELETE(l_meta);
+    DAP_DEL_Z(l_meta);
 
     // 2nd level consensus
     if(l_blocks->callback_block_verify)
@@ -1268,7 +1383,7 @@ static dap_chain_atom_iter_t* s_callback_atom_iter_create_from(dap_chain_t * a_c
         dap_chain_atom_iter_t * l_atom_iter = s_callback_atom_iter_create(a_chain, a_chain->cells->id, 0);
         if (l_atom_iter){
             dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain);
-            l_atom_iter->cur_item = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_atom_hash);
+            l_atom_iter->cur_item = dap_chain_block_cache_get_by_hash(l_blocks, &l_atom_hash);
             l_atom_iter->cur = a_atom;
             l_atom_iter->cur_size = a_atom_size;
             return l_atom_iter;
@@ -1447,8 +1562,8 @@ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_links(dap_chain_atom_iter_
     *a_links_size = l_block_cache->links_hash_count;
     dap_chain_atom_ptr_t *l_ret = DAP_NEW_Z_SIZE(dap_chain_atom_ptr_t, l_block_cache->links_hash_count * sizeof(dap_chain_atom_ptr_t));
     for (size_t i = 0; i < l_block_cache->links_hash_count; ++i){
-        dap_chain_cs_blocks_t *l_cs_blocks = (dap_chain_cs_blocks_t *)l_block_cache->_inheritor;
-        dap_chain_block_cache_t *l_link = dap_chain_block_cs_cache_get_by_hash(l_cs_blocks, &l_block_cache->links_hash[i]);
+        dap_chain_cs_blocks_t *l_cs_blocks = DAP_CHAIN_CS_BLOCKS(a_atom_iter->chain);
+        dap_chain_block_cache_t *l_link = dap_chain_block_cache_get_by_hash(l_cs_blocks, &l_block_cache->links_hash[i]);
         assert(l_link);
         (*a_links_size_ptr)[i] = l_link->block_size;
         l_ret[i] = l_link->block;
@@ -1712,3 +1827,31 @@ static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, si
     pthread_rwlock_unlock(&PVT(l_blocks)->rwlock);
     return l_list;
 }
+
+static const dap_time_t s_block_timediff_unit = 60;
+
+static uint256_t s_callback_calc_reward(dap_chain_t *a_chain, dap_hash_fast_t *a_block_hash, dap_pkey_t *a_block_sign_pkey)
+{
+    uint256_t l_ret = uint256_0;
+    size_t l_block_size = 0;
+    const dap_chain_block_t *l_block = dap_chain_get_atom_by_hash(a_chain, a_block_hash, &l_block_size);
+    if (dap_chain_block_sign_match_pkey(l_block, l_block_size, a_block_sign_pkey)) {
+        dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id);
+        if (!l_net) {
+            log_it(L_ERROR, "Invalid chain object");
+            return l_ret;
+        }
+        size_t l_signs_count = dap_chain_block_get_signs_count(l_block, l_block_size);
+        DIV_256(l_net->pub.base_reward, GET_256_FROM_64(l_signs_count), &l_ret);
+        dap_time_t l_block_time = l_block->hdr.ts_created;
+        dap_hash_fast_t *l_prev_block_hash = dap_chain_block_get_prev_hash(l_block, l_block_size);
+        if (l_prev_block_hash) {
+            l_block = dap_chain_get_atom_by_hash(a_chain, l_prev_block_hash, &l_block_size);
+            assert(l_block);
+            dap_time_t l_time_diff = l_block_time - l_block->hdr.ts_created;
+            MULT_256_256(l_ret, GET_256_FROM_64(l_time_diff), &l_ret);
+            DIV_256(l_ret, GET_256_FROM_64(s_block_timediff_unit), &l_ret);
+        }
+    }
+    return l_ret;
+}
diff --git a/modules/type/blocks/include/dap_chain_block.h b/modules/type/blocks/include/dap_chain_block.h
index 9beab8cb37..6accd3802d 100644
--- a/modules/type/blocks/include/dap_chain_block.h
+++ b/modules/type/blocks/include/dap_chain_block.h
@@ -100,16 +100,18 @@ size_t dap_chain_block_datum_del_by_hash(dap_chain_block_t ** a_block_ptr, size_
 
 // Add sign in block
 size_t dap_chain_block_sign_add(dap_chain_block_t ** a_block_ptr, size_t a_block_size, dap_enc_key_t *a_key);
-dap_sign_t *dap_chain_block_sign_get ( dap_chain_block_t * a_block_ptr, size_t a_block_size, uint16_t a_sign_num );
+dap_sign_t *dap_chain_block_sign_get (const dap_chain_block_t *a_block_ptr, size_t a_block_size, uint16_t a_sign_num );
+bool dap_chain_block_sign_match_pkey(const dap_chain_block_t *a_block, size_t a_block_size, dap_pkey_t *a_sign_pkey);
+size_t dap_chain_block_get_signs_count(const dap_chain_block_t *a_block, size_t a_block_size);
+size_t dap_chain_block_get_sign_offset(const dap_chain_block_t *a_block, size_t a_block_size);
 
-size_t dap_chain_block_get_signs_count(dap_chain_block_t * a_block, size_t a_block_size);
-size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_block_size);
+dap_hash_fast_t *dap_chain_block_get_prev_hash(const dap_chain_block_t *a_block, size_t a_block_size);
 
 // Create and return datums list
-dap_chain_datum_t** dap_chain_block_get_datums(dap_chain_block_t * a_block, size_t a_block_size,size_t * a_datums_count );
+dap_chain_datum_t** dap_chain_block_get_datums(const dap_chain_block_t * a_block, size_t a_block_size,size_t * a_datums_count );
 
 // Create and return meta parameters  list
-dap_chain_block_meta_t** dap_chain_block_get_meta(dap_chain_block_t * a_block, size_t a_block_size,size_t * a_meta_count );
+dap_chain_block_meta_t** dap_chain_block_get_meta(const dap_chain_block_t *a_block, size_t a_block_size, size_t * a_meta_count );
 
 void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_meta_count,
                                     dap_chain_hash_fast_t * a_block_prev_hash,
diff --git a/modules/type/blocks/include/dap_chain_block_cache.h b/modules/type/blocks/include/dap_chain_block_cache.h
index b0cbfdac0c..22cb469d54 100644
--- a/modules/type/blocks/include/dap_chain_block_cache.h
+++ b/modules/type/blocks/include/dap_chain_block_cache.h
@@ -70,9 +70,6 @@ typedef struct dap_chain_block_cache {
     struct dap_chain_block_cache * prev;
     struct dap_chain_block_cache * next;
 
-    // Inhertied nested data
-    void * _inheritor;
-
     // uthash handle
     UT_hash_handle hh;
 } dap_chain_block_cache_t;
@@ -81,8 +78,7 @@ int dap_chain_block_cache_init();
 void dap_chain_block_cache_deinit();
 
 
-dap_chain_block_cache_t *dap_chain_block_cache_new(dap_chain_cs_blocks_t *a_blocks, dap_hash_fast_t *a_block_hash,
-                                                   dap_chain_block_t *a_block, size_t a_block_size);
+dap_chain_block_cache_t *dap_chain_block_cache_new(dap_hash_fast_t *a_block_hash, dap_chain_block_t *a_block, size_t a_block_size);
 dap_chain_block_cache_t *dap_chain_block_cache_dup(dap_chain_block_cache_t *a_block);
 int dap_chain_block_cache_update(dap_chain_block_cache_t *a_block_cache, dap_hash_fast_t *a_block_hash);
 void dap_chain_block_cache_delete(dap_chain_block_cache_t *a_block_cache);
diff --git a/modules/type/blocks/include/dap_chain_cs_blocks.h b/modules/type/blocks/include/dap_chain_cs_blocks.h
index 708dd05bba..4889dca957 100644
--- a/modules/type/blocks/include/dap_chain_cs_blocks.h
+++ b/modules/type/blocks/include/dap_chain_cs_blocks.h
@@ -66,4 +66,4 @@ typedef int (*dap_chain_blocks_block_callback_ptr_t)(dap_chain_cs_blocks_t *, da
 
 int dap_chain_cs_blocks_init();
 void dap_chain_cs_blocks_deinit();
-dap_chain_block_cache_t * dap_chain_block_cs_cache_get_by_hash(dap_chain_cs_blocks_t * a_blocks,  dap_chain_hash_fast_t *a_block_hash);
+dap_chain_block_cache_t *dap_chain_block_cache_get_by_hash(dap_chain_cs_blocks_t *a_blocks, dap_chain_hash_fast_t *a_block_hash);
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index 93c5224e6a..11382d550d 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -53,10 +53,10 @@
 #include "dap_chain_node_cli_cmd.h"
 #include "dap_chain_cell.h"
 #include "dap_chain_net.h"
+#include "dap_chain_ledger.h"
 
 #define LOG_TAG "dap_chain_cs_dag"
 
-
 typedef struct dap_chain_cs_dag_event_item {
     dap_chain_hash_fast_t hash;
     dap_chain_hash_fast_t datum_hash;
diff --git a/modules/wallet/dap_chain_wallet.c b/modules/wallet/dap_chain_wallet.c
index 2dfd5470fc..b6d6e01f88 100644
--- a/modules/wallet/dap_chain_wallet.c
+++ b/modules/wallet/dap_chain_wallet.c
@@ -58,6 +58,7 @@
 #include "dap_chain_wallet_internal.h"
 #include "dap_enc_key.h"
 #include "crc32c_adler.h"
+#include "dap_chain_ledger.h"
 
 #define LOG_TAG "dap_chain_wallet"
 
@@ -982,7 +983,7 @@ uint256_t dap_chain_wallet_get_balance (
     dap_chain_net_t *l_net = dap_chain_net_by_id(a_net_id);
     dap_chain_addr_t *l_addr = dap_chain_wallet_get_addr(a_wallet, a_net_id);
 
-    return  (l_net)  ? dap_chain_ledger_calc_balance(l_net->pub.ledger, l_addr, a_token_ticker) : uint256_0;
+    return  (l_net)  ? dap_ledger_calc_balance(l_net->pub.ledger, l_addr, a_token_ticker) : uint256_0;
 }
 
 /**
-- 
GitLab