From a3362a14e54ab16008d80d84fc3e1110d25956df Mon Sep 17 00:00:00 2001
From: Dmitriy Gerasimov <dm@cifercom.com>
Date: Mon, 15 Jan 2018 03:46:14 +0700
Subject: [PATCH] [+] Simple block mining function [+] Declarations for chain
 operations [+] Block cache [+] Block dump [*] Some internal fixes

---
 CMakeLists.txt              |  19 ++++---
 dap_chain.c                 |  25 ++++++++-
 dap_chain.h                 |  10 ++--
 dap_chain_block.c           |  55 ++++++++++++++++---
 dap_chain_block.h           |  20 +++++--
 dap_chain_block_cache.c     | 102 ++++++++++++++++++++++++++++++++++++
 dap_chain_block_cache.h     |  40 ++++++++++++++
 dap_chain_block_txs.h       |   2 +
 dap_chain_common.h          |  43 ++++++++++++++-
 dap_chain_mine.c            |  44 ++++++++++++++++
 dap_chain_mine.h            |  30 +++++++++++
 dap_chain_ops.c             |  19 +++++++
 dap_chain_ops.h             |   8 +++
 dap_chain_section.c         |   6 ++-
 dap_chain_section.h         |  21 ++++----
 dap_chain_section_coin.c    |  24 +++++++++
 dap_chain_section_coin.h    |  24 +++++++++
 dap_chain_section_tx_in.h   |   6 +--
 dap_chain_wallet.c          |   8 ++-
 dap_chain_wallet.h          |   4 +-
 dap_chain_wallet_internal.h |  25 +++++++++
 dap_hash.h                  |   2 +-
 dap_hash_keccak.h           |   2 +-
 dap_hash_slow.h             |   4 +-
 24 files changed, 498 insertions(+), 45 deletions(-)
 create mode 100644 dap_chain_block_cache.c
 create mode 100644 dap_chain_block_cache.h
 create mode 100644 dap_chain_mine.c
 create mode 100644 dap_chain_mine.h
 create mode 100644 dap_chain_ops.c
 create mode 100644 dap_chain_ops.h
 create mode 100644 dap_chain_section_coin.c
 create mode 100644 dap_chain_section_coin.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a01ff25cde..ec2db312c5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,14 +3,18 @@ project (dap-chain)
   
 set(DAP_CHAIN_SRCS 
 	dap_chain_common.c
+        dap_chain_mine.c
 	dap_chain_block.c 
-	dap_chain_block_txs.c 
+        dap_chain_block_cache.c
+        dap_chain_block_txs.c
 	dap_chain_section.c 
 	dap_chain_section_roots.c
-	dap_chain.c
-	dap_chain_coin.c  
-	dap_chain_srv.c  
         dap_chain_section_tx.c
+        dap_chain_section_coin.c
+        dap_chain.c
+        dap_chain_ops.c
+        dap_chain_coin.c
+	dap_chain_srv.c  
         dap_hash.c
         dap_hash_fusion.c
         dap_hash_keccak.c
@@ -19,8 +23,11 @@ set(DAP_CHAIN_SRCS
         )
 
 set(DAP_CHAIN_HEADERS
-	dap_chain_block.h
-	dap_chain.h
+        dap_chain_ops.h
+        dap_chain.h
+        dap_chain_mine.h
+        dap_chain_block.h
+        dap_chain_block_cache.h
         dap_chain_internal.h
         dap_chain_common.h
 	dap_chain_coin.h
diff --git a/dap_chain.c b/dap_chain.c
index d4452a10a9..377c127d9d 100644
--- a/dap_chain.c
+++ b/dap_chain.c
@@ -35,7 +35,7 @@
  */
 int dap_chain_init()
 {
-    log_it(L_INFO,"DapChain module init");
+
 }
 
 /**
@@ -43,7 +43,6 @@ int dap_chain_init()
  */
 void dap_chain_deinit()
 {
-    log_it(L_INFO,"DapChain module deinit");
 
 }
 
@@ -57,6 +56,9 @@ void dap_chain_deinit()
 dap_chain_t * dap_chain_open(const char * a_file_storage,const char * a_file_cache)
 {
     dap_chain_t * l_chain = DAP_NEW_Z(dap_chain_t);
+
+    l_chain->difficulty = 4;
+
     DAP_CHAIN_INTERNAL_LOCAL_NEW(l_chain);
 
     l_chain_internal->file_storage_type = 0x0000; // TODO compressed format
@@ -101,3 +103,22 @@ void dap_chain_info_dump_log(dap_chain_t * a_chain)
 {
 
 }
+
+dap_chain_block_cache_t* dap_chain_allocate_next_block(dap_chain_t * a_chain)
+{
+    dap_chain_block_t* l_block = NULL;
+    dap_chain_block_cache_t* l_block_cache = NULL;
+    if ( a_chain->block_last )
+        l_block = dap_chain_block_new( &a_chain->block_last->block_hash );
+    else
+        l_block = dap_chain_block_new( NULL );
+
+    if( l_block ){
+        l_block->header.difficulty = a_chain->difficulty;
+        l_block_cache = dap_chain_block_cache_new(l_block);
+        return l_block_cache;
+    }else{
+        log_it(L_ERROR, "Can't allocate next block!");
+        return NULL;
+    }
+}
diff --git a/dap_chain.h b/dap_chain.h
index 5e06a5d2d6..801595794c 100644
--- a/dap_chain.h
+++ b/dap_chain.h
@@ -24,11 +24,13 @@
 
 #pragma once
 #include "dap_chain_block.h"
+#include "dap_chain_block_cache.h"
 
 typedef struct dap_chain{
-    dap_chain_block_t * mapped_block_first; // Mapped area start
-    dap_chain_block_t * mapped_block_last; // Last block in mapped area
+    dap_chain_block_cache_t * block_first; // Mapped area start
+    dap_chain_block_cache_t * block_last; // Last block in mapped area
     uint64_t blocks_count;
+    uint64_t difficulty;
 
     void * _internal;
     void * _inhertor;
@@ -40,7 +42,9 @@ void dap_chain_deinit();
 dap_chain_t * dap_chain_open(const char * a_file_storage,const char * a_file_cache);
 void dap_chain_remap(dap_chain_t * a_chain, size_t a_offset);
 void dap_chain_save(dap_chain_t * a_chain);
-
 void dap_chain_info_dump_log(dap_chain_t * a_chain);
 
+dap_chain_block_cache_t* dap_chain_allocate_next_block(dap_chain_t * a_chain);
+
+
 void dap_chain_close(dap_chain_t * a_chain);
diff --git a/dap_chain_block.c b/dap_chain_block.c
index 09f95ad184..8d7e38d5a4 100644
--- a/dap_chain_block.c
+++ b/dap_chain_block.c
@@ -22,26 +22,69 @@
     along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-
+#include "string.h"
 #include "dap_common.h"
 
 #include "dap_chain_block.h"
 
 #define LOG_TAG "dap_chain_block"
 
+
 /**
- * @brief dap_chain_block_init
+ * @brief dap_chain_block_new
+ * @param a_prev_block
  * @return
  */
-int dap_chain_block_init()
+dap_chain_block_t * dap_chain_block_new(dap_chain_hash_t * a_prev_block )
 {
+    dap_chain_block_t * l_block = DAP_NEW_Z_SIZE (dap_chain_block_t,sizeof(l_block->header));
+    if( l_block == NULL){
+        log_it(L_CRITICAL, "Can't allocate memory for the new block");
+        return NULL;
+    }else{
+        l_block->header.signature = DAP_CHAIN_BLOCK_SIGNATURE;
+        l_block->header.version = 1;
+        if( a_prev_block ){
+            memcpy(&l_block->header.prev_block,a_prev_block,sizeof(l_block->header.prev_block));
+        }else{
+            log_it(L_INFO, "Genesis block produced");
+            memset(&l_block->header.prev_block,0xff,sizeof(l_block->header.prev_block));
+        }
 
+        l_block->header.size = sizeof(l_block->header);
+        return l_block;
+    }
 }
 
 /**
- * @brief dap_chain_block_deinit
+ * @brief dap_chain_block_create_section
+ * @param a_block
+ * @param a_section_type
+ * @param a_section_data_size
+ * @return
  */
-void dap_chain_block_deinit()
+dap_chain_section_t * dap_chain_block_create_section(dap_chain_block_t * a_block, uint32_t a_section_offset,
+                                                     uint16_t a_section_type, uint32_t a_section_data_size )
 {
-
+    if ( a_block) {
+        uint32_t l_sections_size = ( a_block->header.size - sizeof(a_block->header) );
+        if(   l_sections_size > a_section_offset ){
+            if( l_sections_size > (a_section_offset + a_section_data_size ) ) {
+                dap_chain_section_t * l_section = (dap_chain_section_t *) ( a_block->sections +a_section_offset) ;
+                l_section->type = a_section_type;
+                return l_section;
+            }else{
+                log_it(L_ERROR, "Section data size %lu is bigger then left for sections in block (%lu)"
+                       ,a_section_data_size,l_sections_size - a_section_offset );
+                return NULL;
+            }
+        }else{
+            log_it(L_ERROR, "Section offset %lu is bigger then section size %lu",a_section_offset,l_sections_size);
+            return NULL;
+        }
+    }else{
+        log_it(L_ERROR, "Block is NULL");
+        return NULL;
+    }
 }
+
diff --git a/dap_chain_block.h b/dap_chain_block.h
index 4e9ee859dc..b639db9860 100644
--- a/dap_chain_block.h
+++ b/dap_chain_block.h
@@ -27,6 +27,7 @@
 #include <stddef.h>
 #include "dap_common.h"
 #include "dap_math_ops.h"
+#include "dap_hash.h"
 #include "dap_chain_common.h"
 #include "dap_chain_section.h"
 #include "dap_chain_section_roots.h"
@@ -41,15 +42,28 @@ typedef struct  dap_chain_block{
      struct block_header{
         uint32_t signature; /// @param signature @brief Magic number, always equels to DAP_CHAIN_BLOCK_SIGNATURE
         int32_t version; /// @param version @brief block version (be carefull, signed value, as Bitcoin has)
+        uint32_t size; /// @param size of the whole block
         dap_chain_hash_t prev_block; /// @param prev_block Hash of the previous block
         uint64_t timestamp; /// @param timestamp @brief Block create time timestamp
         uint64_t difficulty; /// difficulty level
         uint64_t nonce; /// Nonce value to allow header variation for mining
         dap_chain_hash_t root_sections;/// @param root_main Main tree's root for all sections's hashes
     } DAP_ALIGN_PACKED header;
-    dap_chain_block_section_t section[];
+    uint8_t sections[]; // Sections
 } DAP_ALIGN_PACKED dap_chain_block_t;
 
-int dap_chain_block_init();
-void dap_chain_block_deinit();
+dap_chain_block_t * dap_chain_block_new(dap_chain_hash_t * a_prev_block );
 
+dap_chain_section_t * dap_chain_block_create_section(dap_chain_block_t * a_block, uint32_t a_section_offset
+                                                     , uint16_t a_section_type, uint32_t a_section_data_size );
+
+
+/**
+ * @brief dap_chain_block_calc_hash
+ * @param a_block
+ * @return
+ */
+static inline void dap_chain_block_hash_calc(dap_chain_block_t * a_block, dap_chain_hash_t * a_hash){
+    dap_hash(a_block,a_block->header.size,a_hash->data,
+             sizeof(a_hash->data),DAP_HASH_TYPE_SLOW_0);
+}
diff --git a/dap_chain_block_cache.c b/dap_chain_block_cache.c
new file mode 100644
index 0000000000..f3857d5d11
--- /dev/null
+++ b/dap_chain_block_cache.c
@@ -0,0 +1,102 @@
+#include <stdlib.h>
+#include <time.h>
+#include "dap_common.h"
+#include "dap_chain_block_cache.h"
+#include "dap_chain_section_coin.h"
+#include "dap_chain_section_tx.h"
+#include "dap_chain_section_tx_in.h"
+#include "dap_chain_section_tx_out.h"
+
+#define LOG_TAG "dap_chain_block_cache"
+
+dap_chain_block_cache_t * dap_chain_block_cache_new(dap_chain_block_t * a_block)
+{
+    dap_chain_block_cache_t * l_block_cache = DAP_NEW_Z(dap_chain_block_cache_t);
+    l_block_cache->block = a_block;
+    log_it(L_DEBUG,"Block cache created");
+    return l_block_cache;
+}
+
+/**
+ * @brief dap_chain_block_cache_delete
+ * @param a_block
+ */
+void dap_chain_block_cache_delete(dap_chain_block_cache_t * a_block_cache)
+{
+    DAP_DELETE(a_block_cache);
+    log_it(L_DEBUG,"Block cache deleted");
+}
+
+/**
+ * @brief dap_chain_block_cache_dump
+ * @param a_block_cache
+ */
+void dap_chain_block_cache_dump(dap_chain_block_cache_t * a_block_cache)
+{
+    if ( a_block_cache ) {
+        dap_chain_block_t * l_block = a_block_cache->block;
+        if( l_block ){
+            char * l_hash_str = dap_chain_hash_to_str(&a_block_cache->block_hash);
+            char * l_prev_hash_str = dap_chain_hash_to_str(&l_block->header.prev_block);
+            char * l_root_sections_str = dap_chain_hash_to_str(&l_block->header.root_sections);
+            log_it(L_INFO, "  **  block_hash        %s",l_hash_str);
+            log_it(L_INFO, "  **    version         %d",l_block->header.version);
+            log_it(L_INFO, "  **    timestamp       %s",  ctime(  (time_t*) &l_block->header.timestamp) );
+            log_it(L_INFO, "  **    difficulty      %llu",l_block->header.difficulty);
+            log_it(L_INFO, "  **    nonce           %llu",l_block->header.nonce);
+            log_it(L_INFO, "  **    prev_block      %s",l_prev_hash_str);
+            log_it(L_INFO, "  **    root_sections   %s",l_root_sections_str  );
+            log_it(L_INFO, "  **    size           %u",l_block->header.size);
+            log_it(L_INFO, "  **    sections[]");
+            DAP_DELETE(l_hash_str);
+            DAP_DELETE(l_prev_hash_str);
+
+            size_t i, l_sections_size = l_block->header.size - sizeof(l_block->header);
+            for( i = 0; i< l_sections_size; i++ ){
+                dap_chain_section_t * l_section = (dap_chain_section_t *) (l_block->sections + i);
+                switch ( l_section->type  ) {
+                    case DAP_CHAIN_SECTION_TX:{
+                        dap_chain_section_tx_t * l_tx = (dap_chain_section_tx_t *) l_section->data;
+                        log_it(L_INFO, "  **      tx");
+                        log_it(L_INFO, "  **          lock_time       %s", l_tx->header.lock_time?
+                                   ctime( (time_t *) &l_tx->header.lock_time ) : "0x0000000000000000" );
+                        log_it(L_INFO, "  **          tx_items_size   %u ",l_tx->header.tx_items_size);
+                        /*uint32_t l_data_offset;
+                        for ( l_data_offset = 0; l_data_offset < l_tx->header.tx_items_size; ++l_data_offset  ){
+
+                        }*/
+                        i += sizeof (l_tx->header);
+                        i += l_tx->header.tx_items_size ;
+                    }break;
+                    default:
+                        i = l_sections_size;
+                }
+            }
+        }else{
+            log_it(L_ERROR,"block in block cache for dump is NULL");
+        }
+    }else{
+        log_it(L_ERROR,"block cache for dump is NULL");
+    }
+
+}
+
+/**
+ * @brief dap_chain_block_cache_sections_size_grow
+ * @param a_block_cache
+ * @param a_sections_size_grow
+ */
+dap_chain_block_t* dap_chain_block_cache_sections_size_grow(dap_chain_block_cache_t * a_block_cache,size_t a_sections_size_grow )
+{
+    log_it(L_DEBUG,"Block section size reallocation: grow up +%lu",a_sections_size_grow);
+    a_block_cache->block->header.size += a_sections_size_grow;
+    a_block_cache->block=(dap_chain_block_t *) realloc(a_block_cache->block,a_block_cache->block->header.size );
+    if( a_block_cache->block ){
+        a_block_cache->sections_size += a_sections_size_grow;
+        return a_block_cache->block;
+    }else{
+        log_it(L_ERROR, "Can't reallocate block!");
+        return NULL;
+    }
+}
+
diff --git a/dap_chain_block_cache.h b/dap_chain_block_cache.h
new file mode 100644
index 0000000000..f258da4634
--- /dev/null
+++ b/dap_chain_block_cache.h
@@ -0,0 +1,40 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2018
+ * 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 "dap_chain_block.h"
+#include "dap_hash.h"
+
+typedef struct dap_chain_block_cache{
+    dap_chain_hash_t block_hash;
+    uint32_t sections_size;
+
+    uint64_t block_mine_time;
+    dap_chain_block_t * block;
+} dap_chain_block_cache_t;
+
+dap_chain_block_cache_t * dap_chain_block_cache_new(dap_chain_block_t * a_block);
+void dap_chain_block_cache_delete(dap_chain_block_cache_t * a_block_cache);
+dap_chain_block_t* dap_chain_block_cache_sections_size_grow(dap_chain_block_cache_t * a_block_cache,size_t a_sections_size_grow );
+
+void dap_chain_block_cache_dump(dap_chain_block_cache_t * a_block_cache);
diff --git a/dap_chain_block_txs.h b/dap_chain_block_txs.h
index 8bf7f08772..4de3c57d0f 100644
--- a/dap_chain_block_txs.h
+++ b/dap_chain_block_txs.h
@@ -22,3 +22,5 @@
     along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
+
+
diff --git a/dap_chain_common.h b/dap_chain_common.h
index 81a0699bca..0e3df1b819 100644
--- a/dap_chain_common.h
+++ b/dap_chain_common.h
@@ -24,6 +24,7 @@
 
 #pragma once
 #include <stdint.h>
+#include <stdio.h>
 
 #include "dap_common.h"
 #include "dap_math_ops.h"
@@ -33,7 +34,12 @@
 
 typedef union dap_chain_hash{
     uint8_t data[DAP_CHAIN_HASH_SIZE];
-} dap_chain_hash_t;
+} DAP_ALIGN_PACKED dap_chain_hash_t;
+
+typedef enum dap_chain_hash_kind {
+    HASH_GOLD = 0, HASH_SILVER, HASH_COPPER, HASH_USELESS = -1
+} dap_chain_hash_kind_t;
+
 
 typedef union dap_chain_sig_type{
     enum {
@@ -50,3 +56,38 @@ typedef struct dap_chain_addr{
     uint64_t checksum;
 } dap_chain_addr_t;
 
+/**
+ * @brief dap_chain_hash_to_str
+ * @param a_hash
+ * @return
+ */
+static inline char * dap_chain_hash_to_str(dap_chain_hash_t * a_hash)
+{
+    const size_t c_hash_str_size = sizeof(*a_hash)*2 +1 /*trailing zero*/ +2 /* heading 0x */  ;
+    char * ret = DAP_NEW_Z_SIZE(char, c_hash_str_size);
+    size_t i;
+    snprintf(ret,2,"0x");
+    for (i = 0; i< sizeof(a_hash->data); ++i)
+        snprintf(ret+i+2,2,"%02x",a_hash->data[i]);
+    return ret;
+}
+
+/**
+ * @brief dap_chain_hash_kind_check
+ * @param a_hash
+ * @details
+ */
+static inline dap_chain_hash_kind_t dap_chain_hash_kind_check(dap_chain_hash_t * a_hash, const uint8_t a_valuable_head  )
+{
+    register uint8_t i;
+    register uint8_t l_hash_first = a_hash->data[0];
+    register uint8_t * l_hash_data = a_hash->data;
+    for ( i = 1; i < a_valuable_head; ++i ){
+        if ( l_hash_data[i] != l_hash_first  )
+            return HASH_USELESS;
+    }
+    if( l_hash_first == 0 )
+        return HASH_GOLD;
+    else
+        return HASH_SILVER;
+}
diff --git a/dap_chain_mine.c b/dap_chain_mine.c
new file mode 100644
index 0000000000..a5ab4339cb
--- /dev/null
+++ b/dap_chain_mine.c
@@ -0,0 +1,44 @@
+#include <time.h>
+#include "dap_common.h"
+#include "dap_chain_block.h"
+#include "dap_chain_mine.h"
+
+#define LOG_TAG "dap_chain_mine"
+
+/**
+ * @brief dap_chain_mine_block
+ * @param a_block_cache
+ * @return
+ */
+int dap_chain_mine_block(dap_chain_block_cache_t * a_block_cache, bool a_mine_gold_only)
+{
+    dap_chain_hash_t l_hash;
+    dap_chain_block_t * l_block = a_block_cache->block;
+    dap_chain_hash_kind_t l_hash_kind;
+    uint64_t l_difficulty = l_block->header.difficulty;
+    time_t l_tm_start = time(NULL);
+    uint64_t l_hash_count = 0;
+    do{
+        l_block->header.nonce++;
+        log_it(L_DEBUG,"nonce %llu",l_block->header.nonce);
+        dap_chain_block_hash_calc(l_block,&l_hash);
+        l_hash_count++;
+        l_hash_kind = dap_chain_hash_kind_check(&l_hash,l_difficulty );
+        if(l_block->header.nonce = 0x0fffffffffffffff )
+            break;
+        if (a_mine_gold_only){
+            if (  l_hash_kind != HASH_GOLD ){
+                continue;
+            }
+        }
+    }while (  l_hash_kind == HASH_USELESS );
+    time_t l_tm_end = time(NULL);
+    if ( l_hash_kind == HASH_GOLD ){
+        log_it(L_INFO, " !!! Mined GOLD token !!!");
+    }else if ( l_hash_kind == HASH_SILVER ) {
+        log_it(L_INFO, " !!! Mined SILVER token !!!");
+    }
+    log_it(L_DEBUG, "Mining time: %lu seconds, %llu hashes, %llu H/s ", l_tm_end - l_tm_start,l_hash_count,
+            l_hash_count / (l_tm_end - l_tm_start));
+    return l_hash_kind != HASH_USELESS;
+}
diff --git a/dap_chain_mine.h b/dap_chain_mine.h
new file mode 100644
index 0000000000..cb5edfcc70
--- /dev/null
+++ b/dap_chain_mine.h
@@ -0,0 +1,30 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2018
+ * 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 "dap_chain_block_cache.h"
+
+
+int dap_chain_mine_block(dap_chain_block_cache_t * a_block_cache, bool a_mine_gold_only);
diff --git a/dap_chain_ops.c b/dap_chain_ops.c
new file mode 100644
index 0000000000..c31aba55d1
--- /dev/null
+++ b/dap_chain_ops.c
@@ -0,0 +1,19 @@
+#include "dap_chain_common.h"
+#include "dap_chain_ops.h"
+#include "dap_chain_block_txs.h"
+
+/**
+ * @brief dap_chain_op_tx_request
+ * @param a_wallet Sender's wallet
+ * @param a_wallet_key_idx Key index in the wallet
+ * @param a_chain_source Blockchain which token we send from
+ * @param a_value Amount of daptoshi's that we wish to send
+ * @param a_chain_tx_request Blockhain where we want to record our transaction request
+ * @param a_destination Destination address
+ */
+void dap_chain_op_tx_request(dap_chain_wallet_t * a_wallet, uint32_t a_wallet_key_idx,
+                             dap_chain_t * a_chain_source, uint64_t a_value, /// Token source and daptoshi's value
+                             dap_chain_t * a_chain_tx_request, dap_chain_addr_t a_destination ) ///  TX blockchain where to create new block
+{
+
+}
diff --git a/dap_chain_ops.h b/dap_chain_ops.h
new file mode 100644
index 0000000000..d6e984f0b2
--- /dev/null
+++ b/dap_chain_ops.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "dap_chain.h"
+#include "dap_chain_wallet.h"
+
+void dap_chain_op_tx_request(dap_chain_wallet_t * a_wallet, uint32_t a_wallet_key_idx, /// Sender's wallet and key index in it
+                             dap_chain_t * a_chain_source, uint64_t a_value, /// Token source and daptoshi's value
+                             dap_chain_t * a_chain_tx_request, dap_chain_addr_t a_destination ); ///  TX blockchain where to create new block
diff --git a/dap_chain_section.c b/dap_chain_section.c
index fd3af365e7..015682c8e1 100644
--- a/dap_chain_section.c
+++ b/dap_chain_section.c
@@ -23,5 +23,9 @@
 */
 
 #include "dap_common.h"
+#include "dap_chain_section.h"
+#include "dap_chain_section_tx.h"
+#include "dap_chain_section_roots.h"
+#include "dap_chain_section_coin.h"
 
-#define LOG_TAG "dap_chain_block_secion"
+#define LOG_TAG "dap_chain_secion"
diff --git a/dap_chain_section.h b/dap_chain_section.h
index 655c4a1053..2137d94f19 100644
--- a/dap_chain_section.h
+++ b/dap_chain_section.h
@@ -21,19 +21,16 @@
     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/>.
 */
-/**
-  * @struct dap_chain_block_section
-  * @brief section inside the block
-  */
 #pragma once
 #include <stdint.h>
 #include "dap_common.h"
 #include "dap_math_ops.h"
 #include "dap_chain_common.h"
 
-
 /// End section, means all the rest of the block is empty
 #define DAP_CHAIN_SECTION_END                 0x0000
+/// Section with additional roots, for example transaction roots
+#define DAP_CHAIN_SECTION_ROOTS 0x0001
 
 /// Transaction header section
 #define DAP_CHAIN_SECTION_TX                  0x0100
@@ -55,18 +52,18 @@
 /// Pub key section, with sign and address
 #define DAP_CHAIN_SECTION_PKEY                0x0c00
 
-/// Section with additional roots, for example transaction roots
-#define DAP_CHAIN_SECTION_ROOTS 0xf000
 
 /// Coin
-#define DAP_CHAIN_SECTION_COIN                0xffff
-
-
+#define DAP_CHAIN_SECTION_COIN                0xf000
 
+/**
+  * @struct dap_chain_block_section
+  * @brief section inside the block
+  */
 
-typedef struct dap_chain_block_section{
+typedef struct dap_chain_section{
     uint16_t type; // Section type
     uint8_t data[]; // data
-} DAP_ALIGN_PACKED dap_chain_block_section_t;
+} DAP_ALIGN_PACKED dap_chain_section_t;
 
 
diff --git a/dap_chain_section_coin.c b/dap_chain_section_coin.c
new file mode 100644
index 0000000000..3ceff1d00e
--- /dev/null
+++ b/dap_chain_section_coin.c
@@ -0,0 +1,24 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2018
+ * 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/>.
+*/
+#include "dap_chain_coin.h"
diff --git a/dap_chain_section_coin.h b/dap_chain_section_coin.h
new file mode 100644
index 0000000000..8bf7f08772
--- /dev/null
+++ b/dap_chain_section_coin.h
@@ -0,0 +1,24 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2018
+ * 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
diff --git a/dap_chain_section_tx_in.h b/dap_chain_section_tx_in.h
index 66bbefb5fe..18f0ee9578 100644
--- a/dap_chain_section_tx_in.h
+++ b/dap_chain_section_tx_in.h
@@ -35,9 +35,9 @@
 typedef struct dap_chain_tx_in{
     struct {
         dap_chain_tx_item_type_t type:8; /// @param    type            @brief Transaction item type
-        dap_chain_hash_t tx_prev_hash; /// @param tx_prev_hash    @brief Hash of the previous transaction
-        uint32_t tx_out_prev_idx; ///      @param   tx_prev_idx     @brief Previous tx_out index
-        dap_chain_sig_type_t sig_type:16; /// Signature type
+        dap_chain_hash_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
+        dap_chain_sig_type_t sig_type; /// Signature type
         uint32_t sig_size; /// Signature size
     } header; /// Only header's hash is used for verification
     uint32_t seq_no; /// Sequence number, out of the header so could be changed during reorganization
diff --git a/dap_chain_wallet.c b/dap_chain_wallet.c
index 85327756d9..0bacc35196 100644
--- a/dap_chain_wallet.c
+++ b/dap_chain_wallet.c
@@ -56,27 +56,31 @@ void dap_chain_wallet_close( dap_chain_wallet_t * a_wallet)
 /**
  * @brief dap_chain_wallet_get_pkey
  * @param a_wallet
+ * @param a_pkey_idx
  * @param a_pkey
  * @param a_pkey_size_max
  * @return 0 if everything is ok, negative value if error
  */
-int dap_chain_wallet_get_pkey( dap_chain_wallet_t * a_wallet, void * a_pkey, size_t a_pkey_size_max)
+int dap_chain_wallet_get_pkey( dap_chain_wallet_t * a_wallet,uint32_t a_pkey_idx, void * a_pkey, size_t a_pkey_size_max)
 {
+    DAP_CHAIN_WALLET_INTERNAL_LOCAL(a_wallet);
     return 0;
 }
 
 /**
  * @brief dap_chain_wallet_sign
  * @param a_wallet
+ * @param a_pkey_idx
  * @param a_data
  * @param a_data_size
  * @param a_sign
  * @param a_sign_size_max
  * @return 0 if everything is ok, negative value if error
  */
-int dap_chain_wallet_sign( dap_chain_wallet_t * a_wallet, const void * a_data, size_t a_data_size,
+int dap_chain_wallet_sign( dap_chain_wallet_t * a_wallet,uint32_t a_pkey_idx, const void * a_data, size_t a_data_size,
                            void * a_sign, size_t a_sign_size_max)
 {
+    DAP_CHAIN_WALLET_INTERNAL_LOCAL(a_wallet);
 
     return 0;
 }
diff --git a/dap_chain_wallet.h b/dap_chain_wallet.h
index c0ebad5cd0..e27f402465 100644
--- a/dap_chain_wallet.h
+++ b/dap_chain_wallet.h
@@ -32,7 +32,7 @@ typedef struct dap_chain_wallet{
 dap_chain_wallet_t * dap_chain_wallet_open(const char * a_file_name, dap_chain_sig_type_t a_sig_type); // Creates new one if not found
 void dap_chain_wallet_close( dap_chain_wallet_t * a_wallet);
 
-int dap_chain_wallet_get_pkey( dap_chain_wallet_t * a_wallet, void * a_pkey, size_t a_pkey_size_max);
+int dap_chain_wallet_get_pkey( dap_chain_wallet_t * a_wallet,uint32_t a_pkey_idx, void * a_pkey, size_t a_pkey_size_max);
 
-int dap_chain_wallet_sign( dap_chain_wallet_t * a_wallet, const void * a_data, size_t a_data_size, void * a_sign, size_t a_sign_size_max);
+int dap_chain_wallet_sign( dap_chain_wallet_t * a_wallet,uint32_t a_pkey_idx, const void * a_data, size_t a_data_size, void * a_sign, size_t a_sign_size_max);
 
diff --git a/dap_chain_wallet_internal.h b/dap_chain_wallet_internal.h
index 4a5950b4d1..fd51460603 100644
--- a/dap_chain_wallet_internal.h
+++ b/dap_chain_wallet_internal.h
@@ -24,14 +24,39 @@
 
 #pragma once
 
+#include "dap_enc_key.h"
 #include "dap_chain_common.h"
 
 #include "dap_chain_wallet.h"
 
+#define DAP_CHAIN_WALLET_FILE_SIGNATURE 0x1a167bef15feea18
+
+typedef struct dap_chain_wallet_key{
+    struct {
+        dap_chain_sig_type_t sig_type; /// Signature type
+        uint32_t key_size; /// Private key size
+    } header;
+    uint8_t key_raw[]; /// Raw data of the private key
+} DAP_ALIGN_PACKED dap_chain_wallet_key_t;
+
+
+typedef struct dap_chain_wallet_file
+{
+    struct {
+        uint64_t signature;
+        uint32_t version;
+        uint8_t type; /// Wallet storage type 0x00 - uncompressed and unencrypted
+        uint64_t keys_size;
+    } DAP_ALIGN_PACKED header;
+    uint8_t keys[];
+} DAP_ALIGN_PACKED dap_chain_wallet_file_t;
+
 typedef struct dap_chain_wallet_internal
 {
     dap_chain_addr_t addr;
     char * file_name;
+    size_t keys_count;
+    dap_enc_key_t ** keys;
 } dap_chain_wallet_internal_t;
 
 #define DAP_CHAIN_WALLET_INTERNAL(a) ((dap_chain_wallet_internal_t *) a->_internal  )
diff --git a/dap_hash.h b/dap_hash.h
index 5918195264..889a60f135 100644
--- a/dap_hash.h
+++ b/dap_hash.h
@@ -34,7 +34,7 @@ typedef enum dap_hash_type {
     DAP_HASH_TYPE_SLOW_0 = 1,
 } dap_hash_type_t;
 
-inline void dap_hash(void * a_data_in, size_t a_data_in_size,
+inline static void dap_hash(void * a_data_in, size_t a_data_in_size,
                      void * a_data_out, size_t a_data_out_size,
                      dap_hash_type_t a_type ){
     switch (a_type){
diff --git a/dap_hash_keccak.h b/dap_hash_keccak.h
index 890d9e0504..e5e13553b7 100644
--- a/dap_hash_keccak.h
+++ b/dap_hash_keccak.h
@@ -26,7 +26,7 @@
 #include "keccak.h"
 
 
-inline void dap_hash_keccak(const void * a_in, size_t a_in_size, void * a_out, size_t a_out_size)
+static inline void dap_hash_keccak(const void * a_in, size_t a_in_size, void * a_out, size_t a_out_size)
 {
     keccak((const uint8_t*) a_in,a_in_size, (uint8_t *) a_out,  a_out_size );
 }
diff --git a/dap_hash_slow.h b/dap_hash_slow.h
index 27d2604f89..320a09d512 100644
--- a/dap_hash_slow.h
+++ b/dap_hash_slow.h
@@ -34,10 +34,10 @@
  * @param a_in_length
  * @param a_out Must be allocated with enought space
  */
-inline void dap_hash_slow(const void *a_in, size_t a_in_length, char * a_out)
+static inline void dap_hash_slow(const void *a_in, size_t a_in_length, char * a_out)
 {
     cn_slow_hash(a_in,a_in_length,a_out);
 }
 
-inline size_t dap_hash_slow_size() { return DAP_HASH_SLOW_SIZE; }
+static inline size_t dap_hash_slow_size() { return DAP_HASH_SLOW_SIZE; }
 //cn_slow_hash(data, length, reinterpret_cast<char *>(&hash));
-- 
GitLab