From 067b6268e32e0663d07462128c06fed429fe8d0f Mon Sep 17 00:00:00 2001
From: Aleksey Feoktistov <aleksey@synestproject.com>
Date: Sun, 21 Nov 2021 19:08:14 +0500
Subject: [PATCH] [*] 256bit arithmetic for native 128

---
 dap-sdk/core/include/dap_math_ops.h           | 721 ++++++++++--------
 modules/common/dap_chain_common.c             |  15 +-
 modules/common/dap_chain_datum_tx.c           |  38 +
 modules/common/dap_chain_datum_tx_items.c     | 147 ++++
 modules/common/dap_chain_datum_tx_receipt.c   |  79 ++
 modules/common/include/dap_chain_common.h     |  14 +
 .../common/include/dap_chain_datum_token.h    |  29 +
 modules/common/include/dap_chain_datum_tx.h   |  15 +
 .../common/include/dap_chain_datum_tx_in.h    |   9 +
 .../common/include/dap_chain_datum_tx_items.h |  23 +
 .../common/include/dap_chain_datum_tx_out.h   |   9 +
 .../include/dap_chain_datum_tx_out_cond.h     |  48 ++
 .../include/dap_chain_datum_tx_out_ext.h      |  10 +
 .../include/dap_chain_datum_tx_receipt.h      |  22 +
 14 files changed, 874 insertions(+), 305 deletions(-)

diff --git a/dap-sdk/core/include/dap_math_ops.h b/dap-sdk/core/include/dap_math_ops.h
index fb2a1708b7..10794d37a8 100755
--- a/dap-sdk/core/include/dap_math_ops.h
+++ b/dap-sdk/core/include/dap_math_ops.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include <stdint.h>
 #include <stdio.h>
 #include "assert.h"
@@ -12,19 +13,23 @@
 
 #if __SIZEOF_INT128__ == 16
 
-#define DAP_GLOBAL_IS_INT128
+//#define DAP_GLOBAL_IS_INT128
+
+#endif
+
+
+#ifdef DAP_GLOBAL_IS_INT128
 typedef __int128 _dap_int128_t;
 
-#if !defined (int128_t)
+//#if !defined (int128_t)
 typedef __int128 int128_t;
-#endif
+//#endif
 
-#if !defined (uint128_t)
+//#if !defined (uint128_t)
 typedef unsigned __int128 uint128_t;
-#endif
-
+//#endif
 
-#else // __SIZEOF_INT128__ == 16
+#else //DAP_GLOBAL_IS_INT128
 
 typedef union uint128 {
     struct{
@@ -40,9 +45,9 @@ typedef union int128 {
     int32_t i32[4];
 } int128_t;
 
-typedef int128_t _dap_int128_t;
+#endif //DAP_GLOBAL_IS_INT128
 
-#endif // __SIZEOF_INT128__ == 16
+typedef int128_t _dap_int128_t;
 
 typedef struct uint256_t {
     uint128_t hi;
@@ -56,28 +61,35 @@ typedef struct uint512_t {
 
     } uint512_t;
 
-
-
-
-
 #endif //defined(__GNUC__) || defined (__clang__)
 
 ////////////////////////////////////////////////////////////////////////////////////////////////
 
 #ifndef DAP_GLOBAL_IS_INT128
 
+// uint128_t dap_uint128_substract(uint128_t a, uint128_t b);
+// uint128_t dap_uint128_add(uint128_t a, uint128_t b);
+// bool dap_uint128_check_equal(uint128_t a, uint128_t b);
 const  uint128_t two_power_64={ .hi = 1, .lo = 0};
 const  uint128_t lo_64={ .hi = 0, .lo = 0xffffffffffffffff};
 const  uint128_t hi_64={ .hi = 0xffffffffffffffff, .lo = 0};
-const  uint128_t zero_128={.hi=0,.lo=0};
+// const  uint128_t zero_128={.hi=0,.lo=0};
+#define zero_128 ((uint128_t){.hi=0,.lo=0})
 
-const  uint256_t zero_256={.hi=zero_128,.lo=zero_128};
+// const uint64_t lo_32=0xffffffff;
+// const uint64_t hi_32=0xffffffff00000000;
+// const uint64_t ones_64=0xffffffffffffffff;
 
-const uint64_t lo_32=0xffffffff;
-const uint64_t hi_32=0xffffffff00000000;
-const uint64_t ones_64=0xffffffffffffffff;
+#else // DAP_GLOBAL_IS_INT128
+#define zero_128 ((uint128_t)0)
+#endif // DAP_GLOBAL_IS_INT128
+
+//const uint256_t zero_256={.hi=zero_128,.lo=zero_128};
+#define zero_256 ((uint256_t){.hi=zero_128,.lo=zero_128})
+#define lo_32 ((uint64_t)0xffffffff)
+#define hi_32 ((uint64_t)0xffffffff00000000)
+#define ones_64 ((uint64_t)0xffffffffffffffff)
 
-#endif
 
 static inline bool EQUAL_128(uint128_t a_128_bit, uint128_t b_128_bit){
 #ifdef DAP_GLOBAL_IS_INT128
@@ -132,8 +144,8 @@ static inline uint256_t AND_256(uint256_t a_256_bit,uint256_t b_256_bit){
 
 #ifdef DAP_GLOBAL_IS_INT128
     uint256_t output = {};
-    output.hi= a_256_bit.hi | b_256_bit.hi;  
-    output.lo= a_256_bit.lo | b_256_bit.lo;
+    output.hi= a_256_bit.hi & b_256_bit.hi;  
+    output.lo= a_256_bit.lo & b_256_bit.lo;
     return output;
 
 #else 
@@ -256,11 +268,11 @@ static inline void LEFT_SHIFT_256(uint256_t a_256_bit,uint256_t* b_256_bit,int n
        b_256_bit->lo=a_256_bit.lo;
     } 
     if (n<128)
-    {   uint128_t shift_temp{.hi=0, .lo=0};
+    {   uint128_t shift_temp={.hi=0, .lo=0};
         LEFT_SHIFT_128(a_256_bit.lo,&shift_temp,n);
         b_256_bit->lo=shift_temp;   
-        uint128_t shift_temp_or_left{.hi=0, .lo=0};
-        uint128_t shift_temp_or_right{.hi=0, .lo=0};
+        uint128_t shift_temp_or_left={.hi=0, .lo=0};
+        uint128_t shift_temp_or_right={.hi=0, .lo=0};
         LEFT_SHIFT_128(a_256_bit.hi,&shift_temp_or_left,n);
         RIGHT_SHIFT_128(a_256_bit.lo,&shift_temp_or_right,128-n);
         b_256_bit->hi=OR_128(shift_temp_or_left,shift_temp_or_right);
@@ -272,20 +284,17 @@ static inline void RIGHT_SHIFT_256(uint256_t a_256_bit,uint256_t* b_256_bit,int
     assert (n <= 256);
 
 #ifdef DAP_GLOBAL_IS_INT128
-
-    if (n >= 128) 
-    {   
+    if (n >= 128) {   
         a_256_bit.lo=a_256_bit.hi;
         a_256_bit.hi=0;
         RIGHT_SHIFT_256(a_256_bit,b_256_bit,n-128);
     }
-    if (n == 0)
-    {
+    if (n == 0) {
        b_256_bit->hi=a_256_bit.hi;
        b_256_bit->lo=a_256_bit.lo;
     } 
-    else
-    {   uint64_t shift_temp;
+    else {
+        uint64_t shift_temp;
         shift_temp=a_256_bit.hi>>n;
         b_256_bit->hi=shift_temp;
         b_256_bit->lo=(a_256_bit.lo>>n)|(a_256_bit.hi<<(128-n));
@@ -304,11 +313,11 @@ static inline void RIGHT_SHIFT_256(uint256_t a_256_bit,uint256_t* b_256_bit,int
        b_256_bit->lo=a_256_bit.lo;
     } 
     if (n<128)
-    {   uint128_t shift_temp{.hi=0, .lo=0};
+    {   uint128_t shift_temp={.hi=0, .lo=0};
         RIGHT_SHIFT_128(a_256_bit.hi,&shift_temp,n);
         b_256_bit->hi=shift_temp;   
-        uint128_t shift_temp_or_left{.hi=0, .lo=0};
-        uint128_t shift_temp_or_right{.hi=0, .lo=0};
+        uint128_t shift_temp_or_left={.hi=0, .lo=0};
+        uint128_t shift_temp_or_right={.hi=0, .lo=0};
         RIGHT_SHIFT_128(a_256_bit.lo,&shift_temp_or_left,n);
         LEFT_SHIFT_128(a_256_bit.hi,&shift_temp_or_right,128-n);
         b_256_bit->lo=OR_128(shift_temp_or_left,shift_temp_or_right);
@@ -330,20 +339,20 @@ static inline void INCR_128(uint128_t *a_128_bit){
 #endif
 }
 
-//static inline void DECR_128(uint128_t* a_128_bit){
-//
-//#ifdef DAP_GLOBAL_IS_INT128
-//    *a_128_bit--;
-//
-//#else 
-//    a_128_bit->lo--;
-//    if(a_128_bit->hi == 0)
-//    {
-//        a_128_bit->hi--;
-//    }  
-//#endif
-//}
-//
+static inline void DECR_128(uint128_t* a_128_bit){
+
+#ifdef DAP_GLOBAL_IS_INT128
+   (*a_128_bit)--;
+
+#else 
+   a_128_bit->lo--;
+   if(a_128_bit->hi == 0)
+   {
+       a_128_bit->hi--;
+   }  
+#endif
+}
+
 static inline void INCR_256(uint256_t* a_256_bit){
 
 #ifdef DAP_GLOBAL_IS_INT128
@@ -362,29 +371,32 @@ static inline void INCR_256(uint256_t* a_256_bit){
 #endif
 }
 
-static inline int SUM_64_64(uint64_t a_64_bit,uint64_t b_64_bit,uint64_t* c_64_bit ) {
-
-int overflow_flag;
-*c_64_bit=a_64_bit+b_64_bit;
-overflow_flag=(*c_64_bit<a_64_bit);
-return overflow_flag;}
-
-
-
-static inline int OVERFLOW_SUM_64_64(uint64_t a_64_bit,uint64_t b_64_bit) {
+static inline int SUM_64_64(uint64_t a_64_bit,uint64_t b_64_bit,uint64_t* c_64_bit )
+{
+    int overflow_flag;
+    *c_64_bit=a_64_bit+b_64_bit;
+    overflow_flag=(*c_64_bit<a_64_bit);
+    return overflow_flag;
+}
 
-int overflow_flag;
-overflow_flag=(a_64_bit+b_64_bit<a_64_bit);
-return overflow_flag;}
+static inline int OVERFLOW_SUM_64_64(uint64_t a_64_bit,uint64_t b_64_bit)
+{
+    int overflow_flag;
+    overflow_flag=(a_64_bit+b_64_bit<a_64_bit);
+    return overflow_flag;
+}
 
-static inline int OVERFLOW_MULT_64_64(uint64_t a_64_bit,uint64_t b_64_bit) { return (a_64_bit>((uint64_t)-1)/b_64_bit); }
+static inline int OVERFLOW_MULT_64_64(uint64_t a_64_bit,uint64_t b_64_bit)
+{ 
+    return (a_64_bit>((uint64_t)-1)/b_64_bit);
+}
 
 static inline int MULT_64_64(uint64_t a_64_bit,uint64_t b_64_bit,uint64_t* c_64_bit ) {
-
-int overflow_flag;
-*c_64_bit=a_64_bit*b_64_bit;
-overflow_flag=OVERFLOW_MULT_64_64(a_64_bit, b_64_bit);
-return overflow_flag;}
+    int overflow_flag;
+    *c_64_bit=a_64_bit*b_64_bit;
+    overflow_flag=OVERFLOW_MULT_64_64(a_64_bit, b_64_bit);
+    return overflow_flag;
+}
 
 //
 //static inline void SUM_64_128(uint64_t a_64_bit,uint64_t b_64_bit,uint128_t* c_128_bit ) {
@@ -392,10 +404,16 @@ return overflow_flag;}
 //c_128_bit->lo=a_64_bit+b_64_bit;
 //c_128_bit->hi=(c_128_bit->lo<a_64_bit);}
 
-#ifndef DAP_GLOBAL_IS_INT128
+
 //Mixed precision: add a uint64_t into a uint128_t
-static inline int ADD_64_INTO_128(uint64_t a_64_bit,uint128_t* c_128_bit ) {
+static inline int ADD_64_INTO_128(uint64_t a_64_bit,uint128_t *c_128_bit )
+{
     int overflow_flag=0;
+#ifdef DAP_GLOBAL_IS_INT128
+    uint128_t temp=*c_128_bit;
+    *c_128_bit+=(uint128_t)a_64_bit;
+    overflow_flag=(*c_128_bit<temp);
+#else
     uint64_t overflow_64=0;
     uint64_t temp=0;
     temp=c_128_bit->lo;
@@ -403,10 +421,19 @@ static inline int ADD_64_INTO_128(uint64_t a_64_bit,uint128_t* c_128_bit ) {
     overflow_64=overflow_flag;
     temp=c_128_bit->hi;
     overflow_flag=SUM_64_64(overflow_64,temp,&c_128_bit->hi);
-    return overflow_flag;}
+#endif
+    return overflow_flag;
+}
 
-static inline int  SUM_128_128(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t* c_128_bit){
-    int overflow_flag;
+
+static inline int SUM_128_128(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t* c_128_bit)
+{
+    int overflow_flag=0;
+#ifdef DAP_GLOBAL_IS_INT128
+    *c_128_bit=a_128_bit+b_128_bit;
+    overflow_flag=(*c_128_bit<a_128_bit);
+    return overflow_flag;
+#else
     int overflow_flag_intermediate;
     overflow_flag=SUM_64_64(a_128_bit.lo,b_128_bit.lo,&c_128_bit->lo);
     uint64_t carry_in_64=overflow_flag;
@@ -415,46 +442,79 @@ static inline int  SUM_128_128(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t
     overflow_flag=SUM_64_64(carry_in_64,a_128_bit.hi,&intermediate_value);
     overflow_flag_intermediate=SUM_64_64(intermediate_value,b_128_bit.hi,&c_128_bit->hi);
     int return_overflow=overflow_flag|overflow_flag_intermediate;
-    return return_overflow;}
+    return return_overflow;
+#endif
+}
 
-static inline int SUBTRACT_128_128(uint128_t a_128_bit, uint128_t b_128_bit,uint128_t* c_128_bit)
+static inline int SUBTRACT_128_128(uint128_t a_128_bit, uint128_t b_128_bit, uint128_t* c_128_bit)
 {
+    int underflow_flag = 0;
+#ifdef DAP_GLOBAL_IS_INT128
+    *c_128_bit = a_128_bit - b_128_bit;
+    underflow_flag = (*c_128_bit < 0) ^ (a_128_bit < b_128_bit);
+#else
     c_128_bit->lo = a_128_bit.lo - b_128_bit.lo;
     uint64_t carry = (((c_128_bit->lo & b_128_bit.lo) & 1) + (b_128_bit.lo >> 1) + (c_128_bit->lo >> 1)) >> 63;
     c_128_bit->hi = a_128_bit.hi - (b_128_bit.hi + carry);
-    int underflow_flag=carry;
+    underflow_flag=carry;
+#endif
     return underflow_flag;
 }
 
-//static inline int SUBTRACT_256_256(uint256_t a_256_bit, uint256_t b_256_bit,uint256_t* c_256_bit){
-//
-//    if 
-//  int carry=0;
-//    carry=SUBTRACT_128_128(a_256_bit.lo, b_256_bit.lo,&c_256_bit->lo);
-//    uint64_t carry_64=carry;
-//    uint128_t carry_128{.hi=0,.lo=carry_64};
-//    uint128_t intermediate_val{.hi=0,.lo=0};
-//    int dummy_overflow=0;
-//    dummy_overflow=SUM_128_128(b_256_bit.hi,carry_128,&intermediate_val);
-//    carry=SUBTRACT_128_128(a_256_bit.hi, intermediate_val,&c_256_bit->hi );
-//    return carry;
-//}
+
+// static inline int SUBTRACT_256_256(uint256_t a_256_bit, uint256_t b_256_bit,uint256_t* c_256_bit){
+//     int carry=0;
+//     carry=SUBTRACT_128_128(a_256_bit.lo, b_256_bit.lo, &c_256_bit->lo);
+//     uint64_t carry_64=carry;
+//     uint128_t carry_128={.hi=0,.lo=carry_64};
+//     uint128_t intermediate_val={.hi=0,.lo=0};
+//     int dummy_overflow=0;
+//     dummy_overflow=SUM_128_128(b_256_bit.hi,carry_128,&intermediate_val);
+//     carry=SUBTRACT_128_128(a_256_bit.hi, intermediate_val,&c_256_bit->hi );
+//     return carry;
+// }
+
+
 //
 //Mixed precision: add a uint128_t into a uint256_t
 static inline int ADD_128_INTO_256(uint128_t a_128_bit,uint256_t* c_256_bit) {
     int overflow_flag=0;
+
+#ifdef DAP_GLOBAL_IS_INT128
+    uint128_t overflow_128=0;
+    uint128_t temp=0;
+#else
     uint128_t overflow_128={.hi=0,.lo=0};
     uint128_t temp={.hi=0,.lo=0};
+#endif
+
     temp=c_256_bit->lo;
     overflow_flag=SUM_128_128(a_128_bit,temp,&c_256_bit->lo);
+
+#ifdef DAP_GLOBAL_IS_INT128
+    overflow_128=overflow_flag;
+#else
     overflow_128.lo=overflow_flag;
+#endif
+
     temp=c_256_bit->hi;
     overflow_flag=SUM_128_128(overflow_128,temp,&c_256_bit->hi);
-    return overflow_flag;}
-
+    return overflow_flag;
+}
 
-static inline int  SUM_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* c_256_bit){
-    int overflow_flag;
+static inline int SUM_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* c_256_bit)
+{
+    int overflow_flag=0;
+#ifdef DAP_GLOBAL_IS_INT128
+    int overflow_flag_intermediate;
+    overflow_flag=SUM_128_128(a_256_bit.lo,b_256_bit.lo,&c_256_bit->lo);
+    uint128_t carry_in_128=overflow_flag;
+    uint128_t intermediate_value=0;
+    overflow_flag=0;
+    overflow_flag=SUM_128_128(carry_in_128,a_256_bit.hi,&intermediate_value);
+    overflow_flag_intermediate=SUM_128_128(intermediate_value,b_256_bit.hi,&c_256_bit->hi);
+    overflow_flag=overflow_flag||overflow_flag_intermediate;
+#else
     overflow_flag=SUM_128_128(a_256_bit.lo,b_256_bit.lo,&c_256_bit->lo);
     uint128_t carry_in_128;
     carry_in_128.hi=0;
@@ -464,16 +524,25 @@ static inline int  SUM_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t
     intermediate_value.lo=0;
     overflow_flag=0;
     overflow_flag=SUM_128_128(carry_in_128,a_256_bit.hi,&intermediate_value);
-    
     //we store overflow_flag in case there is already overflow
     int overflow_flag_bis=0; 
-    
     overflow_flag_bis=SUM_128_128(intermediate_value,b_256_bit.hi,&c_256_bit->hi);
     overflow_flag=overflow_flag||overflow_flag_bis;
-    return overflow_flag;}
+#endif
+    return overflow_flag;
+}
 
-static inline int  SUBTRACT_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* c_256_bit){
-    
+static inline int SUBTRACT_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* c_256_bit)
+{
+#ifdef DAP_GLOBAL_IS_INT128
+    int underflow_flag=0;
+    c_256_bit->lo = a_256_bit.lo - b_256_bit.lo;
+    uint64_t carry = (((c_256_bit->lo & b_256_bit.lo) & 1) + (b_256_bit.lo >> 1) + (c_256_bit->lo >> 1)) >> 127;
+    c_256_bit->hi = a_256_bit.hi - (b_256_bit.hi + carry);
+    underflow_flag=carry;
+    return underflow_flag;
+
+#else    
 //(u64 rd[4], const u64 ad[4], const u64 bd[4])
     uint64_t t, r, borrow;
 
@@ -504,8 +573,8 @@ static inline int  SUBTRACT_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint
     c_256_bit->hi.hi = r;
 
     return borrow;
-
-    }
+#endif
+}
 
 //Mixed precision: add a uint256_t into a uint512_t
 static inline int ADD_256_INTO_512(uint256_t a_256_bit,uint512_t* c_512_bit) {
@@ -514,14 +583,23 @@ static inline int ADD_256_INTO_512(uint256_t a_256_bit,uint512_t* c_512_bit) {
     uint256_t temp={.hi=zero_128,.lo=zero_128};
     temp=c_512_bit->lo;
     overflow_flag=SUM_256_256(a_256_bit,temp,&c_512_bit->lo);
+#ifdef DAP_GLOBAL_IS_INT128
+    overflow_256.lo=overflow_flag;
+#else
     overflow_256.lo.lo=overflow_flag;
+#endif
     temp=c_512_bit->hi;
     overflow_flag=SUM_256_256(overflow_256,temp,&c_512_bit->hi);
-    return overflow_flag;}
+    return overflow_flag;
+}
 
 
 static inline void MULT_64_128(uint64_t a_64_bit, uint64_t b_64_bit, uint128_t* c_128_bit)
 {
+#ifdef DAP_GLOBAL_IS_INT128
+    *c_128_bit = (uint128_t)a_64_bit;
+    *c_128_bit *= (uint128_t)b_64_bit;
+#else
     uint64_t a_64_bit_hi = (a_64_bit & 0xffffffff);
     uint64_t b_64_bit_hi = (b_64_bit & 0xffffffff);
     uint64_t prod_hi = (a_64_bit_hi * b_64_bit_hi);
@@ -539,20 +617,39 @@ static inline void MULT_64_128(uint64_t a_64_bit, uint64_t b_64_bit, uint128_t*
 
     c_128_bit->hi = (a_64_bit * b_64_bit) + w1 + prod_hi_shift_right;
     c_128_bit->lo = (prod_hi << 32) + w3;
+#endif
 }
 
 
 
 static inline void MULT_128_256(uint128_t a_128_bit,uint128_t b_128_bit,uint256_t* c_256_bit ) {
-
+#ifdef DAP_GLOBAL_IS_INT128
+    uint128_t a_128_bit_hi = (a_128_bit & 0xffffffffffffffff);
+    uint128_t b_128_bit_hi = (b_128_bit & 0xffffffffffffffff);
+    uint128_t prod_hi = (a_128_bit_hi * b_128_bit_hi);
+    uint128_t w3 = (prod_hi & 0xffffffffffffffff);
+    uint128_t prod_hi_shift_right = (prod_hi >> 64);
+
+    a_128_bit >>= 64;
+    prod_hi = (a_128_bit * b_128_bit_hi) + prod_hi_shift_right;
+    prod_hi_shift_right = (prod_hi & 0xffffffffffffffff);
+    uint64_t w1 = (prod_hi >> 64);
+
+    b_128_bit >>= 64;
+    prod_hi = (a_128_bit_hi * b_128_bit) + prod_hi_shift_right;
+    prod_hi_shift_right = (prod_hi >> 64);
+
+    c_256_bit->hi = (a_128_bit * b_128_bit) + w1 + prod_hi_shift_right;
+    c_256_bit->lo = (prod_hi << 64) + w3;
+#else
     //product of .hi terms - stored in .hi field of c_256_bit
     MULT_64_128(a_128_bit.hi,b_128_bit.hi, &c_256_bit->hi);
 
     //product of .lo terms - stored in .lo field of c_256_bit        
     MULT_64_128(a_128_bit.lo,b_128_bit.lo, &c_256_bit->lo);
 
-    uint128_t cross_product_one{.hi=0, .lo=0};
-    uint128_t cross_product_two{.hi=0, .lo=0};
+    uint128_t cross_product_one={.hi=0, .lo=0};
+    uint128_t cross_product_two={.hi=0, .lo=0};
     MULT_64_128(a_128_bit.hi, b_128_bit.lo, &cross_product_one);
     c_256_bit->lo.hi += cross_product_one.lo;
     if(c_256_bit->lo.hi < cross_product_one.lo)  // if overflow
@@ -576,82 +673,93 @@ static inline void MULT_128_256(uint128_t a_128_bit,uint128_t b_128_bit,uint256_
     {
         c_256_bit->hi.hi+=1;
     }
-} 
+#endif
+}
 
-static inline int MULT_128_128_NEW(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t* accum_128_bit){
-    int overflow=0; 
+// MULT_128_128_NEW
+static inline int MULT_128_128(uint128_t a_128_bit, uint128_t b_128_bit, uint128_t* c_128_bit){
+    int overflow_flag=0;
+
+#ifdef DAP_GLOBAL_IS_INT128
+    *c_128_bit=a_128_bit*b_128_bit;
+    overflow_flag=(a_128_bit>((uint128_t)-1)/b_128_bit);
+#else
     int equal_flag=0;
-    uint256_t full_product_256{.hi=zero_128, .lo=zero_128};
+    uint256_t full_product_256={.hi=zero_128, .lo=zero_128};
     MULT_128_256(a_128_bit,b_128_bit,&full_product_256);
-    *accum_128_bit=full_product_256.lo;
+    *c_128_bit=full_product_256.lo;
     equal_flag=EQUAL_128(full_product_256.hi,zero_128);
-    if (!equal_flag)
-    {
-        overflow=1;
+    if (!equal_flag) {
+        overflow_flag=1;
     }
-    return overflow;
+#endif
+    return overflow_flag;
 }
 
-static inline int MULT_128_128(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t* accum_128_bit) {    
-    uint64_t A=(b_128_bit.lo & lo_32)*(a_128_bit.hi & lo_32);
-    uint64_t B_32_64=((b_128_bit.lo & lo_32)*(a_128_bit.hi & hi_32))&hi_32;
-    uint64_t C_32_64=((b_128_bit.lo & hi_32)*(a_128_bit.hi & lo_32))&hi_32;
-    uint64_t E=(a_128_bit.lo & lo_32)*(b_128_bit.hi & lo_32);
-    uint64_t F_32_64=((a_128_bit.lo & lo_32)*(b_128_bit.hi & hi_32))&hi_32;
-    uint64_t G_32_64=((a_128_bit.lo & hi_32)*(b_128_bit.hi & lo_32))&hi_32;
 
-    //initialization of overflow counter
-    int overflow_ctr=0;
+// incorrect
+// static inline int MULT_128_128(uint128_t a_128_bit,uint128_t b_128_bit,uint128_t* accum_128_bit) {    
+//     uint64_t A=(b_128_bit.lo & lo_32)*(a_128_bit.hi & lo_32);
+//     uint64_t B_32_64=((b_128_bit.lo & lo_32)*(a_128_bit.hi & hi_32))&hi_32;
+//     uint64_t C_32_64=((b_128_bit.lo & hi_32)*(a_128_bit.hi & lo_32))&hi_32;
+//     uint64_t E=(a_128_bit.lo & lo_32)*(b_128_bit.hi & lo_32);
+//     uint64_t F_32_64=((a_128_bit.lo & lo_32)*(b_128_bit.hi & hi_32))&hi_32;
+//     uint64_t G_32_64=((a_128_bit.lo & hi_32)*(b_128_bit.hi & lo_32))&hi_32;
+
+//     //initialization of overflow counter
+//     int overflow_ctr=0;
 
-     //checking of overflow from ".hi terms"
-    int overflow_from_hi_calc=0;
-    overflow_from_hi_calc=(a_128_bit.hi*b_128_bit.hi>0);
-    overflow_ctr+=overflow_from_hi_calc;
+//      //checking of overflow from ".hi terms"
+//     int overflow_from_hi_calc=0;
+//     overflow_from_hi_calc=(a_128_bit.hi*b_128_bit.hi>0);
+//     overflow_ctr+=overflow_from_hi_calc;
     
-    //product of two ".lo" terms
-    MULT_64_128(a_128_bit.lo,b_128_bit.lo,accum_128_bit);   
+//     //product of two ".lo" terms
+//     MULT_64_128(a_128_bit.lo,b_128_bit.lo,accum_128_bit);   
 
-    int overflow=0;
-    uint64_t temp=0;
+//     int overflow=0;
+//     uint64_t temp=0;
 
-    overflow=SUM_64_64(A,temp,&accum_128_bit->hi); 
-    printf("accum_128_bit->hi after add in of A %" PRIu64 "\n",accum_128_bit->hi);
+//     overflow=SUM_64_64(A,temp,&accum_128_bit->hi); 
+//     printf("accum_128_bit->hi after add in of A %" PRIu64 "\n",accum_128_bit->hi);
  
-    overflow_ctr+=overflow;
-    temp=accum_128_bit->hi; 
-    overflow=0;
-
-    overflow=SUM_64_64(B_32_64,temp,&accum_128_bit->hi);  
-    overflow_ctr+=overflow;
-    temp=accum_128_bit->hi; 
-    overflow=0;
-
-    overflow=SUM_64_64(C_32_64,temp,&accum_128_bit->hi);  
-    overflow_ctr+=overflow;
-    temp=accum_128_bit->hi; 
-    overflow=0;
-
-    overflow=SUM_64_64(E,temp,&accum_128_bit->hi);  
-    overflow_ctr+=overflow;
-    temp=accum_128_bit->hi; 
-    overflow=0;
-
-    overflow=SUM_64_64(F_32_64,temp,&accum_128_bit->hi);  
-    overflow_ctr+=overflow;
-    temp=accum_128_bit->hi; 
-    overflow=0;
+//     overflow_ctr+=overflow;
+//     temp=accum_128_bit->hi; 
+//     overflow=0;
+
+//     overflow=SUM_64_64(B_32_64,temp,&accum_128_bit->hi);  
+//     overflow_ctr+=overflow;
+//     temp=accum_128_bit->hi; 
+//     overflow=0;
+
+//     overflow=SUM_64_64(C_32_64,temp,&accum_128_bit->hi);  
+//     overflow_ctr+=overflow;
+//     temp=accum_128_bit->hi; 
+//     overflow=0;
+
+//     overflow=SUM_64_64(E,temp,&accum_128_bit->hi);  
+//     overflow_ctr+=overflow;
+//     temp=accum_128_bit->hi; 
+//     overflow=0;
+
+//     overflow=SUM_64_64(F_32_64,temp,&accum_128_bit->hi);  
+//     overflow_ctr+=overflow;
+//     temp=accum_128_bit->hi; 
+//     overflow=0;
         
-    overflow=SUM_64_64(G_32_64,temp,&accum_128_bit->hi);  
-    overflow_ctr+=overflow;
-    temp=accum_128_bit->hi;  
-    overflow=0;
-
-    if(overflow_ctr>0){
-        overflow=1;}
-    else{overflow=0;}
+//     overflow=SUM_64_64(G_32_64,temp,&accum_128_bit->hi);  
+//     overflow_ctr+=overflow;
+//     temp=accum_128_bit->hi;  
+//     overflow=0;
+
+//     if(overflow_ctr>0){
+//         overflow=1;}
+//     else{overflow=0;}
     
-    return overflow;
-    }
+//     return overflow;
+// }
+
+
 
 static inline void MULT_256_512(uint256_t a_256_bit,uint256_t b_256_bit,uint512_t* c_512_bit) {
     int dummy_overflow;
@@ -662,12 +770,12 @@ static inline void MULT_256_512(uint256_t a_256_bit,uint256_t b_256_bit,uint512_
     MULT_128_256(a_256_bit.lo,b_256_bit.lo, &c_512_bit->lo);
 
     //cross product of .hi and .lo terms
-    uint256_t cross_product_first_term{ .hi = zero_128, .lo = zero_128};
-    uint256_t cross_product_second_term{ .hi = zero_128, .lo = zero_128};
-    uint256_t cross_product{ .hi = zero_128, .lo = zero_128};
-    uint256_t cross_product_shift_128{ .hi = zero_128, .lo = zero_128};
-    uint256_t c_512_bit_lo_copy{ .hi = zero_128, .lo = zero_128};
-    uint256_t c_512_bit_hi_copy{ .hi = zero_128, .lo = zero_128};
+    uint256_t cross_product_first_term={ .hi = zero_128, .lo = zero_128};
+    uint256_t cross_product_second_term={ .hi = zero_128, .lo = zero_128};
+    uint256_t cross_product={ .hi = zero_128, .lo = zero_128};
+    uint256_t cross_product_shift_128={ .hi = zero_128, .lo = zero_128};
+    uint256_t c_512_bit_lo_copy={ .hi = zero_128, .lo = zero_128};
+    uint256_t c_512_bit_hi_copy={ .hi = zero_128, .lo = zero_128};
     int overflow=0;
 
     MULT_128_256(a_256_bit.hi,b_256_bit.lo,&cross_product_first_term);
@@ -684,61 +792,70 @@ static inline void MULT_256_512(uint256_t a_256_bit,uint256_t b_256_bit,uint512_
     RIGHT_SHIFT_256(cross_product,&cross_product_shift_128,128);
     c_512_bit_hi_copy=c_512_bit->hi;    
     dummy_overflow=SUM_256_256(c_512_bit_hi_copy,cross_product_shift_128,&c_512_bit->hi);
-    }
+}
 
+static inline int MULT_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* accum_256_bit){
+    int overflow=0; 
+    int equal_flag=0;
+    uint512_t full_product_512={.hi=zero_256,.lo=zero_256,};
+    MULT_256_512(a_256_bit,b_256_bit,&full_product_512);
+    *accum_256_bit=full_product_512.lo;
+    equal_flag=EQUAL_256(full_product_512.hi,zero_256);
+    if (!equal_flag)
+    {
+        overflow=1;
+    }
+    return overflow;
+}
 
-static inline int MULT_256_256_NEW(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* accum_256_bit){
+// incorrect
+// static inline int MULT_256_256_NEW(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* accum_256_bit){
 
-    uint128_t two_0_coeff{.hi=0,.lo=0};
-    MULT_64_128(a_256_bit.lo.lo,b_256_bit.lo.lo,&two_0_coeff);
-    accum_256_bit->lo.lo=two_0_coeff.lo;
+//     uint128_t two_0_coeff={.hi=0,.lo=0};
+//     MULT_64_128(a_256_bit.lo.lo,b_256_bit.lo.lo,&two_0_coeff);
+//     accum_256_bit->lo.lo=two_0_coeff.lo;
     
-    uint128_t two_64_coeff{.hi=0,.lo=0};
-    uint128_t two_64_coeff_one{.hi=0,.lo=0};
-    MULT_64_128(a_256_bit.lo.hi,b_256_bit.lo.lo,&two_64_coeff_one);
-    uint128_t two_64_coeff_two{.hi=0,.lo=0};
-    MULT_64_128(a_256_bit.lo.lo,b_256_bit.lo.hi,&two_64_coeff_two);
-    uint128_t two_64_coeff_sum{.hi=0,.lo=0};
-    int dummy_overflow=0;
-    dummy_overflow=SUM_128_128(two_64_coeff_one,two_64_coeff_two,&two_64_coeff_sum);
-    if (two_64_coeff_sum.lo+two_0_coeff.hi<two_64_coeff_sum.lo){
+//     uint128_t two_64_coeff={.hi=0,.lo=0};
+//     uint128_t two_64_coeff_one={.hi=0,.lo=0};
+//     MULT_64_128(a_256_bit.lo.hi,b_256_bit.lo.lo,&two_64_coeff_one);
+//     uint128_t two_64_coeff_two={.hi=0,.lo=0};
+//     MULT_64_128(a_256_bit.lo.lo,b_256_bit.lo.hi,&two_64_coeff_two);
+//     uint128_t two_64_coeff_sum={.hi=0,.lo=0};
+//     int dummy_overflow=0;
+//     dummy_overflow=SUM_128_128(two_64_coeff_one,two_64_coeff_two,&two_64_coeff_sum);
+//     if (two_64_coeff_sum.lo+two_0_coeff.hi<two_64_coeff_sum.lo){
         
-        two_64_coeff.lo=two_64_coeff_sum.lo+two_0_coeff.hi;
-        two_64_coeff.hi=1+two_64_coeff_sum.hi;}
-    else{
-        two_64_coeff.lo=two_64_coeff_sum.lo+two_0_coeff.hi;
-        two_64_coeff.hi=two_64_coeff_sum.hi;
-    }
-    accum_256_bit->lo.hi=two_64_coeff.lo;
+//         two_64_coeff.lo=two_64_coeff_sum.lo+two_0_coeff.hi;
+//         two_64_coeff.hi=1+two_64_coeff_sum.hi;}
+//     else{
+//         two_64_coeff.lo=two_64_coeff_sum.lo+two_0_coeff.hi;
+//         two_64_coeff.hi=two_64_coeff_sum.hi;
+//     }
+//     accum_256_bit->lo.hi=two_64_coeff.lo;
     
 
-    uint128_t two_128_coeff{.hi=0,.lo=0};
-    uint128_t  two_128_coeff_one{.hi=0,.lo=0};
-    MULT_64_128(a_256_bit.lo.lo,b_256_bit.hi.lo,&two_128_coeff_one);
-    uint128_t  two_128_coeff_two{.hi=0,.lo=0};
-    MULT_64_128(a_256_bit.hi.lo,b_256_bit.lo.lo,&two_128_coeff_two);
-    uint128_t two_128_coeff_three{.hi=0,.lo=0};
-    MULT_64_128(a_256_bit.lo.hi,b_256_bit.lo.hi,&two_128_coeff_three);
-    uint128_t two_128_coeff_sum_one{.hi=0,.lo=0};
-    dummy_overflow=SUM_128_128(two_128_coeff_one,two_128_coeff_two,&two_128_coeff_sum_one);
-    uint128_t two_128_coeff_sum_two{.hi=0,.lo=0};
-    dummy_overflow=SUM_128_128(two_128_coeff_sum_one,two_128_coeff_three,&two_128_coeff_sum_two);
+//     uint128_t two_128_coeff={.hi=0,.lo=0};
+//     uint128_t two_128_coeff_one={.hi=0,.lo=0};
+//     MULT_64_128(a_256_bit.lo.lo,b_256_bit.hi.lo,&two_128_coeff_one);
+//     uint128_t two_128_coeff_two={.hi=0,.lo=0};
+//     MULT_64_128(a_256_bit.hi.lo,b_256_bit.lo.lo,&two_128_coeff_two);
+//     uint128_t two_128_coeff_three={.hi=0,.lo=0};
+//     MULT_64_128(a_256_bit.lo.hi,b_256_bit.lo.hi,&two_128_coeff_three);
+//     uint128_t two_128_coeff_sum_one={.hi=0,.lo=0};
+//     dummy_overflow=SUM_128_128(two_128_coeff_one,two_128_coeff_two,&two_128_coeff_sum_one);
+//     uint128_t two_128_coeff_sum_two={.hi=0,.lo=0};
+//     dummy_overflow=SUM_128_128(two_128_coeff_sum_one,two_128_coeff_three,&two_128_coeff_sum_two);
     
-    if (two_128_coeff_sum_two.lo+two_64_coeff.hi<two_128_coeff_sum_two.lo){
+//     if (two_128_coeff_sum_two.lo+two_64_coeff.hi<two_128_coeff_sum_two.lo){
         
-        two_128_coeff.lo=two_128_coeff_sum_two.lo+two_64_coeff.hi;
-        two_128_coeff.hi=1+two_128_coeff_sum_two.hi;}
-    else{
-        two_128_coeff.lo=two_128_coeff_sum_two.lo+two_64_coeff.hi;
-        two_128_coeff.hi=two_128_coeff_sum_two.hi;
-    }
-    accum_256_bit->hi.lo=two_128_coeff.lo;
-
+//         two_128_coeff.lo=two_128_coeff_sum_two.lo+two_64_coeff.hi;
+//         two_128_coeff.hi=1+two_128_coeff_sum_two.hi;}
+//     else{
+//         two_128_coeff.lo=two_128_coeff_sum_two.lo+two_64_coeff.hi;
+//         two_128_coeff.hi=two_128_coeff_sum_two.hi;
+//     }
+//     accum_256_bit->hi.lo=two_128_coeff.lo;
 
-
-//    
-//
-//    
 //    uint64_t two_192_coeff=0;
 //    uint64_t two_192_coeff_one=0;
 //    int overflow_two_192_coeff_one=0;
@@ -761,33 +878,24 @@ static inline int MULT_256_256_NEW(uint256_t a_256_bit,uint256_t b_256_bit,uint2
 //    overflow_two_192_coeff_sum_two=SUM_64_64(two_192_coeff_three,two_192_coeff_four,&two_192_coeff_sum_two);
 //    int overflow_two_192_coeff_sum=0;
 //    overflow_two_192_coeff_sum=SUM_64_64(two_192_coeff_sum_one,two_192_coeff_sum_two,&two_192_coeff);
-    
 
-    return 0;
-    
-}
+//     return 0;    
+// }
 
-static inline int MULT_256_256(uint256_t a_256_bit,uint256_t b_256_bit,uint256_t* accum_256_bit){
-    int overflow=0; 
-    int equal_flag=0;
-    uint512_t full_product_512{.hi=zero_256,.lo=zero_256,};
-    MULT_256_512(a_256_bit,b_256_bit,&full_product_512);
-    *accum_256_bit=full_product_512.lo;
-    equal_flag=EQUAL_256(full_product_512.hi,zero_256);
-    if (!equal_flag)
-    {
-        overflow=1;
-    }
-    return overflow;
-}
+//#ifndef DAP_GLOBAL_IS_INT128
 
-int compare128(uint128_t N1, uint128_t N2)
+static inline int compare128(uint128_t N1, uint128_t N2)
 {
+#ifdef DAP_GLOBAL_IS_INT128
+    return ( N1 > N2 ? 1 : 0 ) - ( N1 < N2 ? 1 : 0 );
+#else
     return    (((N1.hi > N2.hi) || ((N1.hi == N2.hi) && (N1.lo > N2.lo))) ? 1 : 0) 
          -    (((N1.hi < N2.hi) || ((N1.hi == N2.hi) && (N1.lo < N2.lo))) ? 1 : 0);
+#endif
 }
 
-size_t nlz64(uint64_t N)
+
+static inline int nlz64(uint64_t N)
 {
     uint64_t I;
     size_t C;
@@ -820,72 +928,81 @@ size_t nlz64(uint64_t N)
     return C;
 }
 
-size_t nlz128(uint128_t N)
+//static inline size_t nlz128(uint128_t N)
+static inline int nlz128(uint128_t N)
 {
+#ifdef DAP_GLOBAL_IS_INT128
+    return ( (N >> 64) == 0) ? nlz64((uint64_t)N) + 64 : nlz64((uint64_t)(N >> 64));
+#else
     return (N.hi == 0) ? nlz64(N.lo) + 64 : nlz64(N.hi);
+#endif
 }
 
-void shiftleft128(uint128_t N, unsigned S, uint128_t* A)
-{
-    uint64_t M1, M2;
-    S &= 127;
-
-    M1 = ((((S + 127) | S) & 64) >> 6) - 1llu;
-    M2 = (S >> 6) - 1llu;
-    S &= 63;
-    A->hi = (N.lo << S) & (~M2);
-    A->lo = (N.lo << S) & M2;
-    A->hi |= ((N.hi << S) | ((N.lo >> (64 - S)) & M1)) & M2;
-}
-
-void shiftright128(uint128_t N, unsigned S, uint128_t* A)
-{
-    uint64_t M1, M2;
-    S &= 127;
-
-    M1 = ((((S + 127) | S) & 64) >> 6) - 1llu;
-    M2 = (S >> 6) - 1llu;
-    S &= 63;
-    A->lo = (N.hi >> S) & (~M2);
-    A->hi = (N.hi >> S) & M2;
-    A->lo |= ((N.lo >> S) | ((N.hi << (64 - S)) & M1)) & M2;
-} 
-
-void sub128(uint128_t* Ans, uint128_t N, uint128_t M)
-{
-    Ans->lo = N.lo - M.lo;
-    uint64_t C = (((Ans->lo & M.lo) & 1) + (M.lo >> 1) + (Ans->lo >> 1)) >> 63;
-    Ans->hi = N.hi - (M.hi + C);
-}
-void bindivmod128(uint128_t M, uint128_t N, uint128_t* Q, uint128_t* R)
-{
-    Q->hi = Q->lo = 0;
-    size_t Shift = nlz128(N) - nlz128(M);
-    shiftleft128(N, Shift, &N);
-
-    do
-    {
-        shiftleft128(*Q, 1, Q);
-        if(compare128(M, N) >= 0)
-        {
-            sub128(&M, N, M);
-            Q->lo |= 1;
-        }
-
-        shiftright128(N, 1, &N);
-    }while(Shift-- != 0);
-
-    R->hi = M.hi;
-    R->lo = M.lo;
-}
+// void shiftleft128(uint128_t N, unsigned S, uint128_t* A)
+// {
+//     uint64_t M1, M2;
+//     S &= 127;
+
+//     M1 = ((((S + 127) | S) & 64) >> 6) - 1llu;
+//     M2 = (S >> 6) - 1llu;
+//     S &= 63;
+//     A->hi = (N.lo << S) & (~M2);
+//     A->lo = (N.lo << S) & M2;
+//     A->hi |= ((N.hi << S) | ((N.lo >> (64 - S)) & M1)) & M2;
+// }
+
+// void shiftright128(uint128_t N, unsigned S, uint128_t* A)
+// {
+//     uint64_t M1, M2;
+//     S &= 127;
+
+//     M1 = ((((S + 127) | S) & 64) >> 6) - 1llu;
+//     M2 = (S >> 6) - 1llu;
+//     S &= 63;
+//     A->lo = (N.hi >> S) & (~M2);
+//     A->hi = (N.hi >> S) & M2;
+//     A->lo |= ((N.lo >> S) | ((N.hi << (64 - S)) & M1)) & M2;
+// } 
+
+// void sub128(uint128_t* Ans, uint128_t N, uint128_t M)
+// {
+//     Ans->lo = N.lo - M.lo;
+//     uint64_t C = (((Ans->lo & M.lo) & 1) + (M.lo >> 1) + (Ans->lo >> 1)) >> 63;
+//     Ans->hi = N.hi - (M.hi + C);
+// }
+// void bindivmod128(uint128_t M, uint128_t N, uint128_t* Q, uint128_t* R)
+// {
+//     Q->hi = Q->lo = 0;
+//     size_t Shift = nlz128(N) - nlz128(M);
+//     shiftleft128(N, Shift, &N);
+
+//     do
+//     {
+//         shiftleft128(*Q, 1, Q);
+//         if(compare128(M, N) >= 0)
+//         {
+//             sub128(&M, N, M);
+//             Q->lo |= 1;
+//         }
+
+//         shiftright128(N, 1, &N);
+//     }while(Shift-- != 0);
+
+//     R->hi = M.hi;
+//     R->lo = M.lo;
+// }
 
-#else
+//#ifdef DAP_GLOBAL_IS_INT128
+//#else
 static inline uint128_t dap_uint128_substract(uint128_t a, uint128_t b)
 {
-    if (a < b) {
-        return 0;
-    }
-    return a - b;
+    // if (a < b) {
+    //     return 0;
+    // }
+    // return a - b;
+    uint128_t c = zero_128;
+    SUBTRACT_128_128(a, b, &c);
+    return c;
 }
 
 /**
@@ -896,11 +1013,14 @@ static inline uint128_t dap_uint128_substract(uint128_t a, uint128_t b)
  */
 static inline uint128_t dap_uint128_add(uint128_t a, uint128_t b)
 {
-    uint128_t l_ret = a + b;
-    if (l_ret < a || l_ret < b) {
-        return 0;
-    }
-    return l_ret;
+    // uint128_t l_ret = a + b;
+    // if (l_ret < a || l_ret < b) {
+    //     return 0;
+    // }
+    // return l_ret;
+    uint128_t c = zero_128;
+    SUM_128_128( a, b, &c);
+    return c;
 }
 
 /**
@@ -911,6 +1031,7 @@ static inline uint128_t dap_uint128_add(uint128_t a, uint128_t b)
  */
 static inline bool dap_uint128_check_equal(uint128_t a, uint128_t b)
 {
-    return a == b;
+    //return a == b;
+    return EQUAL_128(a, b);
 }
-#endif
+//#endif
diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c
index 3189c9ec51..91498d753a 100644
--- a/modules/common/dap_chain_common.c
+++ b/modules/common/dap_chain_common.c
@@ -421,25 +421,29 @@ uint128_t dap_chain_balance_scan(char *a_balance)
             return l_nul;
         }
         l_tmp = (l_tmp << 64) + c_pow10[i].u64[1] * l_digit;
-        l_ret = dap_uint128_add(l_ret, l_tmp);
+        // l_ret = dap_uint128_add(l_ret, l_tmp);
+        SUM_128_128(l_ret, l_tmp, &l_ret);
         if (l_ret == l_nul)
             return l_nul;
 #else
         uint128_t l_tmp;
         l_tmp.u64[0] = 0;
         l_tmp.u64[1] = c_pow10[i].u32[2] * l_digit;
-        l_ret = dap_uint128_add(l_ret, l_tmp);
+        // l_ret = dap_uint128_add(l_ret, l_tmp);
+        SUM_128_128(l_ret, l_tmp, &l_ret);
         if (l_ret.u64[0] == 0 && l_ret.u64[1] == 0)
             return l_nul;
         uint64_t l_mul = c_pow10[i].u32[3] * l_digit;
         l_tmp.u64[1] = l_mul << 32;
         l_tmp.u64[0] = l_mul >> 32;
-        l_ret = dap_uint128_add(l_ret, l_tmp);
+        // l_ret = dap_uint128_add(l_ret, l_tmp);
+        SUM_128_128(l_ret, l_tmp, &l_ret);
         if (l_ret.u64[0] == 0 && l_ret.u64[1] == 0)
             return l_nul;
         l_tmp.u64[1] = 0;
         l_tmp.u64[0] = c_pow10[i].u32[0] * l_digit;
-        l_ret = dap_uint128_add(l_ret, l_tmp);
+        //l_ret = dap_uint128_add(l_ret, l_tmp);
+        SUM_128_128(l_ret, l_tmp, &l_ret);
         if (l_ret.u64[0] == 0 && l_ret.u64[1] == 0)
             return l_nul;
         l_mul = c_pow10[i].u32[1] * l_digit;
@@ -448,7 +452,8 @@ uint128_t dap_chain_balance_scan(char *a_balance)
             return l_nul;
         }
         l_tmp.u64[0] = l_mul << 32;
-        l_ret = dap_uint128_add(l_ret, l_tmp);
+        //l_ret = dap_uint128_add(l_ret, l_tmp);
+        SUM_128_128(l_ret, l_tmp, &l_ret);
         if (l_ret.u64[0] == 0 && l_ret.u64[1] == 0)
             return l_nul;
 #endif
diff --git a/modules/common/dap_chain_datum_tx.c b/modules/common/dap_chain_datum_tx.c
index 6f48ec58ed..16370b884a 100644
--- a/modules/common/dap_chain_datum_tx.c
+++ b/modules/common/dap_chain_datum_tx.c
@@ -158,6 +158,18 @@ int dap_chain_datum_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain
     return -1;
 }
 
+// 256
+int dap_chain_datum_256_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint256_t a_value)
+{
+    dap_chain_256_tx_out_t *l_tx_out = dap_chain_datum_tx_item_256_out_create(a_addr, a_value);
+    if(l_tx_out) {
+        dap_chain_datum_tx_add_item(a_tx, (const uint8_t *)l_tx_out);
+        DAP_DELETE(l_tx_out);
+        return 1;
+    }
+    return -1;
+}
+
 /**
  * Create 'out_ext' item and insert to transaction
  *
@@ -174,6 +186,17 @@ int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_c
     return -1;
 }
 
+// 256
+int dap_chain_datum_256_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint256_t a_value, const char *a_token)
+{
+    dap_chain_256_tx_out_ext_t *l_tx_out = dap_chain_datum_tx_item_256_out_ext_create(a_addr, a_value, a_token);
+    if(l_tx_out) {
+        dap_chain_datum_tx_add_item(a_tx, (const uint8_t *)l_tx_out);
+        DAP_DELETE(l_tx_out);
+        return 1;
+    }
+    return -1;
+}
 /**
  * Create 'out_cond' item and insert to transaction
  *
@@ -192,6 +215,21 @@ int dap_chain_datum_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_enc_ke
     return -1;
 }
 
+// 256
+int dap_chain_datum_256_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
+        uint256_t a_value, uint256_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, const void *a_cond, size_t a_cond_size)
+{
+    dap_chain_256_tx_out_cond_t *l_tx_out = dap_chain_datum_tx_item_256_out_cond_create_srv_pay(
+                a_key, a_srv_uid,a_value, a_value_max_per_unit, a_unit, a_cond, a_cond_size );
+    if(l_tx_out) {
+        dap_chain_datum_tx_add_item(a_tx, (const uint8_t *) l_tx_out);
+        DAP_DELETE(l_tx_out);
+        return 1;
+    }
+    return -1;
+}
+
+
 /**
  * Sign a transaction (Add sign item to transaction)
  *
diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c
index 96f0ae56df..61ed72f059 100644
--- a/modules/common/dap_chain_datum_tx_items.c
+++ b/modules/common/dap_chain_datum_tx_items.c
@@ -58,6 +58,14 @@ static size_t dap_chain_tx_out_get_size(const dap_chain_tx_out_t *a_item)
     return size;
 }
 
+// 256
+static size_t dap_chain_256_tx_out_get_size(const dap_chain_256_tx_out_t *a_item)
+{
+    (void) a_item;
+    size_t size = sizeof(dap_chain_256_tx_out_t);
+    return size;
+}
+
 static size_t dap_chain_tx_out_ext_get_size(const dap_chain_tx_out_ext_t *a_item)
 {
     (void) a_item;
@@ -65,11 +73,25 @@ static size_t dap_chain_tx_out_ext_get_size(const dap_chain_tx_out_ext_t *a_item
     return size;
 }
 
+// 256
+static size_t dap_chain_256_tx_out_ext_get_size(const dap_chain_256_tx_out_ext_t *a_item)
+{
+    (void) a_item;
+    size_t size = sizeof(dap_chain_256_tx_out_ext_t);
+    return size;
+}
+
 static size_t dap_chain_tx_out_cond_get_size(const dap_chain_tx_out_cond_t *a_item)
 {
     return sizeof(dap_chain_tx_out_cond_t) + a_item->params_size;
 }
 
+// 256
+static size_t dap_chain_256_tx_out_cond_get_size(const dap_chain_256_tx_out_cond_t *a_item)
+{
+    return sizeof(dap_chain_256_tx_out_cond_t) + a_item->params_size;
+}
+
 static size_t dap_chain_tx_pkey_get_size(const dap_chain_tx_pkey_t *a_item)
 {
     size_t size = sizeof(dap_chain_tx_pkey_t) + a_item->header.sig_size;
@@ -117,9 +139,15 @@ size_t dap_chain_datum_item_tx_get_size(const uint8_t *a_item)
     case TX_ITEM_TYPE_OUT: // Transaction outputs
         size = dap_chain_tx_out_get_size((const dap_chain_tx_out_t*) a_item);
         break;
+    case TX_ITEM_TYPE_256_OUT: // 256
+        size = dap_chain_256_tx_out_get_size((const dap_chain_256_tx_out_t*) a_item);
+        break;
     case TX_ITEM_TYPE_OUT_EXT:
         size = dap_chain_tx_out_ext_get_size((const dap_chain_tx_out_ext_t*) a_item);
         break;
+    case TX_ITEM_TYPE_256_OUT_EXT: // 256
+        size = dap_chain_256_tx_out_ext_get_size((const dap_chain_256_tx_out_ext_t*) a_item);
+        break;
     case TX_ITEM_TYPE_RECEIPT: // Receipt
         size = dap_chain_datum_tx_receipt_get_size((const dap_chain_datum_tx_receipt_t*) a_item);
     case TX_ITEM_TYPE_IN_COND: // Transaction inputs with condition
@@ -128,6 +156,9 @@ size_t dap_chain_datum_item_tx_get_size(const uint8_t *a_item)
     case TX_ITEM_TYPE_OUT_COND: // Transaction output with condition
         size = dap_chain_tx_out_cond_get_size((const dap_chain_tx_out_cond_t*) a_item);
         break;
+    case TX_ITEM_TYPE_256_OUT_COND: // 256
+        size = dap_chain_256_tx_out_cond_get_size((const dap_chain_256_tx_out_cond_t*) a_item);
+        break;
     case TX_ITEM_TYPE_PKEY: // Transaction public keys
         size = dap_chain_tx_pkey_get_size((const dap_chain_tx_pkey_t*) a_item);
         break;
@@ -211,6 +242,18 @@ dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a
     return l_item;
 }
 
+//256
+dap_chain_256_tx_out_t* dap_chain_datum_tx_item_256_out_create(const dap_chain_addr_t *a_addr, uint256_t a_value)
+{
+    if(!a_addr)
+        return NULL;
+    dap_chain_256_tx_out_t *l_item = DAP_NEW_Z(dap_chain_256_tx_out_t);
+    l_item->header.type = TX_ITEM_TYPE_OUT;
+    l_item->header.value = a_value;
+    memcpy(&l_item->addr, a_addr, sizeof(dap_chain_addr_t));
+    return l_item;
+}
+
 dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_addr_t *a_addr, uint64_t a_value, const char *a_token)
 {
     if (!a_addr || !a_token)
@@ -223,6 +266,20 @@ dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_a
     return l_item;
 }
 
+//256
+dap_chain_256_tx_out_ext_t* dap_chain_datum_tx_item_256_out_ext_create(const dap_chain_addr_t *a_addr, uint256_t a_value, const char *a_token)
+{
+    if (!a_addr || !a_token)
+        return NULL;
+    dap_chain_256_tx_out_ext_t *l_item = DAP_NEW_Z(dap_chain_256_tx_out_ext_t);
+    l_item->header.type = TX_ITEM_TYPE_OUT_EXT;
+    l_item->header.value = a_value;
+    memcpy(&l_item->addr, a_addr, sizeof(dap_chain_addr_t));
+    strcpy(l_item->token, a_token);
+    return l_item;
+}
+
+
 /**
  * Create item dap_chain_tx_out_cond_t
  *
@@ -254,6 +311,34 @@ dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_pay(dap_enc
     return l_item;
 }
 
+// 256
+dap_chain_256_tx_out_cond_t* dap_chain_datum_tx_item_256_out_cond_create_srv_pay(dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
+        uint256_t a_value,uint256_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit,
+                                                                 const void *a_params, size_t a_params_size)
+{
+    if(!a_key || !a_params)
+        return NULL;
+    size_t l_pub_key_size = 0;
+    uint8_t *l_pub_key = dap_enc_key_serealize_pub_key(a_key, &l_pub_key_size);
+
+
+    dap_chain_256_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE(dap_chain_256_tx_out_cond_t, sizeof(dap_chain_256_tx_out_cond_t) + a_params_size);
+    if(l_item == NULL)
+        return NULL;
+
+    l_item->header.item_type = TX_ITEM_TYPE_OUT_COND;
+    l_item->header.value = a_value;
+    l_item->header.subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY; // By default creatre cond for service pay. Rework with smth more flexible
+    l_item->subtype.srv_pay.srv_uid = a_srv_uid;
+    l_item->subtype.srv_pay.unit = a_unit;
+    l_item->subtype.srv_pay.unit_price_max_datoshi = a_value_max_per_unit;
+    dap_hash_fast( l_pub_key, l_pub_key_size, & l_item->subtype.srv_pay.pkey_hash);
+    l_item->params_size = (uint32_t)a_params_size;
+    memcpy(l_item->params, a_params, a_params_size);
+    return l_item;
+}
+
+
 
 dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap_chain_net_srv_uid_t a_srv_uid, dap_chain_net_id_t a_net_id,
                                                                              const char *a_token, uint64_t a_value,
@@ -276,6 +361,28 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap
     return l_item;
 }
 
+// 256
+dap_chain_256_tx_out_cond_t *dap_chain_datum_tx_item_256_out_cond_create_srv_xchange(dap_chain_net_srv_uid_t a_srv_uid, dap_chain_net_id_t a_net_id,
+                                                                             const char *a_token, uint256_t a_value,
+                                                                             const void *a_params, uint32_t a_params_size)
+{
+    if (!a_token) {
+        return NULL;
+    }
+    dap_chain_256_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE(dap_chain_256_tx_out_cond_t, sizeof(dap_chain_256_tx_out_cond_t) + a_params_size);
+    l_item->header.item_type = TX_ITEM_TYPE_OUT_COND;
+    l_item->header.value = a_value;
+    l_item->header.subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE;
+    l_item->subtype.srv_xchange.srv_uid = a_srv_uid;
+    l_item->subtype.srv_xchange.net_id = a_net_id;
+    strcpy(l_item->subtype.srv_xchange.token, a_token);
+    l_item->params_size = a_params_size;
+    if (a_params_size) {
+        memcpy(l_item->params, a_params, a_params_size);
+    }
+    return l_item;
+}
+
 dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint64_t a_value, long double a_fee_value,
                                                                            dap_chain_addr_t *a_fee_addr, const void *a_params, uint32_t a_params_size)
 {
@@ -293,6 +400,25 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_c
     return l_item;
 }
 
+// 256
+dap_chain_256_tx_out_cond_t *dap_chain_datum_tx_item_256_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value, long double a_fee_value,
+                                                                           dap_chain_addr_t *a_fee_addr, const void *a_params, uint32_t a_params_size)
+{
+    dap_chain_256_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE(dap_chain_256_tx_out_cond_t, sizeof(dap_chain_256_tx_out_cond_t) + a_params_size);
+    l_item->header.item_type = TX_ITEM_TYPE_OUT_COND;
+    l_item->header.value = a_value;
+    l_item->header.subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE;
+    l_item->subtype.srv_stake.srv_uid = a_srv_uid;
+    l_item->subtype.srv_stake.fee_value = a_fee_value;
+    memcpy(&l_item->subtype.srv_stake.fee_addr, a_fee_addr, sizeof(dap_chain_addr_t));
+    l_item->params_size = a_params_size;
+    if (a_params_size) {
+        memcpy(l_item->params, a_params, a_params_size);
+    }
+    return l_item;
+}
+
+
 /**
  * Create item dap_chain_tx_sig_t
  *
@@ -414,3 +540,24 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_out_cond_get(dap_chain_datum_tx_t *a
     }
     return l_res;
 }
+
+// 256
+dap_chain_256_tx_out_cond_t *dap_chain_datum_256_tx_out_cond_get(dap_chain_datum_tx_t *a_tx, int *a_out_num)
+{
+    dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
+    int l_prev_cond_idx = l_list_out_items ? 0 : -1;
+    dap_chain_256_tx_out_cond_t *l_res = NULL;
+    for (dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_prev_cond_idx++) {
+        if (*(uint8_t *)l_list_tmp->data == TX_ITEM_TYPE_256_OUT_COND) {
+            l_res = l_list_tmp->data;
+            break;
+        }
+    }
+    dap_list_free(l_list_out_items);
+    if (a_out_num) {
+        *a_out_num = l_prev_cond_idx;
+    }
+    return l_res;
+}
+
+
diff --git a/modules/common/dap_chain_datum_tx_receipt.c b/modules/common/dap_chain_datum_tx_receipt.c
index d4428f85e5..6b484337f5 100644
--- a/modules/common/dap_chain_datum_tx_receipt.c
+++ b/modules/common/dap_chain_datum_tx_receipt.c
@@ -60,6 +60,27 @@ dap_chain_datum_tx_receipt_t * dap_chain_datum_tx_receipt_create( dap_chain_net_
     return  l_ret;
 }
 
+// 256
+dap_chain_datum_256_tx_receipt_t * dap_chain_datum_256_tx_receipt_create( dap_chain_net_srv_uid_t a_srv_uid,
+                                                                  dap_chain_net_srv_price_unit_uid_t a_units_type,
+                                                                    uint256_t a_units, uint256_t a_value_datoshi,
+                                                                  const void * a_ext, size_t a_ext_size)
+{
+    dap_chain_datum_256_tx_receipt_t * l_ret = DAP_NEW_Z_SIZE(dap_chain_datum_256_tx_receipt_t, dap_chain_datum_256_tx_receipt_get_size_hdr() +a_ext_size );
+    l_ret->type = TX_ITEM_TYPE_RECEIPT;
+    l_ret->receipt_info.units_type = a_units_type;
+    l_ret->receipt_info.srv_uid = a_srv_uid;
+    l_ret->receipt_info.units = a_units;
+    l_ret->receipt_info.value_datoshi = a_value_datoshi;
+    l_ret->size = dap_chain_datum_256_tx_receipt_get_size_hdr()+a_ext_size;
+
+    if( a_ext_size && a_ext){
+        l_ret->exts_size = a_ext_size;
+        memcpy(l_ret->exts_n_signs, a_ext, a_ext_size);
+    }
+    return  l_ret;
+}
+
 size_t dap_chain_datum_tx_receipt_sign_add(dap_chain_datum_tx_receipt_t ** a_receipt, size_t a_receipt_size, dap_enc_key_t *a_key )
 {
     dap_chain_datum_tx_receipt_t *l_receipt = *a_receipt;
@@ -83,6 +104,30 @@ size_t dap_chain_datum_tx_receipt_sign_add(dap_chain_datum_tx_receipt_t ** a_rec
     return a_receipt_size;
 }
 
+// 256
+size_t dap_chain_datum_256_tx_receipt_sign_add(dap_chain_datum_256_tx_receipt_t ** a_receipt, size_t a_receipt_size, dap_enc_key_t *a_key )
+{
+    dap_chain_datum_256_tx_receipt_t *l_receipt = *a_receipt;
+    if ( ! *a_receipt ){
+        log_it( L_ERROR, "NULL receipt, can't add sign");
+        return 0;
+    }
+    dap_sign_t * l_sign = dap_sign_create(a_key,&l_receipt->receipt_info,sizeof (l_receipt->receipt_info),0);
+    size_t l_sign_size = l_sign? dap_sign_get_size( l_sign ) : 0;
+    if ( ! l_sign || ! l_sign_size ){
+        log_it( L_ERROR, "Can't sign the receipt, may be smth with key?");
+        return 0;
+    }
+    l_receipt= (dap_chain_datum_256_tx_receipt_t*) DAP_REALLOC(l_receipt, a_receipt_size+l_sign_size);
+    memcpy(l_receipt->exts_n_signs + l_receipt->exts_size, l_sign, l_sign_size);
+    a_receipt_size += l_sign_size;
+    l_receipt->size = a_receipt_size;
+    l_receipt->exts_size += l_sign_size;
+    DAP_DELETE( l_sign );
+    *a_receipt = l_receipt;
+    return a_receipt_size;
+}
+
 /**
  * @brief dap_chain_datum_tx_receipt_sign_get
  * @param l_receipt
@@ -106,6 +151,24 @@ dap_sign_t* dap_chain_datum_tx_receipt_sign_get(dap_chain_datum_tx_receipt_t * l
     return l_sign;
 }
 
+// 256
+dap_sign_t* dap_chain_datum_256_tx_receipt_sign_get(dap_chain_datum_256_tx_receipt_t * l_receipt, size_t l_receipt_size, uint16_t a_sign_position)
+{
+    if ( !l_receipt ||  l_receipt_size != l_receipt->size || l_receipt_size <= sizeof (l_receipt->receipt_info)+1)
+        return NULL;
+    dap_sign_t * l_sign = (dap_sign_t *)l_receipt->exts_n_signs;//+l_receipt->exts_size);
+    for ( ; a_sign_position && l_receipt_size > (size_t) ( (byte_t *) l_sign - (byte_t *) l_receipt ) ; a_sign_position-- ){
+        l_sign =(dap_sign_t *) (((byte_t*) l_sign)+  dap_sign_get_size( l_sign ));
+    }
+    // not enough signs in receipt
+    if(a_sign_position>0)
+        return NULL;
+    // too big sign size
+    if((l_sign->header.sign_size + ((byte_t*) l_sign - (byte_t*) l_receipt->exts_n_signs)) >= l_receipt->exts_size)
+        return NULL;
+    return l_sign;
+}
+
 /**
  * @brief dap_chain_datum_tx_receipt_signs_count
  * @param a_receipt
@@ -126,3 +189,19 @@ uint16_t dap_chain_datum_tx_receipt_signs_count(dap_chain_datum_tx_receipt_t * a
         log_it(L_ERROR, "Receipt 0x%zu (size=%zu) is corrupted", (size_t)a_receipt, a_receipt_size);
     return l_ret;
 }
+
+// 256
+uint16_t dap_chain_datum_256_tx_receipt_signs_count(dap_chain_datum_256_tx_receipt_t * a_receipt, size_t a_receipt_size)
+{
+    uint16_t l_ret = 0;
+    if(!a_receipt)
+        return 0;
+    dap_sign_t *l_sign;
+    for (l_sign = (dap_sign_t *)a_receipt->exts_n_signs; a_receipt_size > (size_t) ( (byte_t *) l_sign - (byte_t *) a_receipt ) ;
+        l_sign =(dap_sign_t *) (((byte_t*) l_sign)+  dap_sign_get_size( l_sign )) ){
+        l_ret++;
+    }
+    if(a_receipt_size != (size_t) ((byte_t *) l_sign - (byte_t *) a_receipt) )
+        log_it(L_ERROR, "Receipt 0x%zu (size=%zu) is corrupted", (size_t)a_receipt, a_receipt_size);
+    return l_ret;
+}
diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h
index 807079680d..bf037687e6 100644
--- a/modules/common/include/dap_chain_common.h
+++ b/modules/common/include/dap_chain_common.h
@@ -191,14 +191,21 @@ typedef union {
 
 typedef enum dap_chain_tx_item_type {
     TX_ITEM_TYPE_IN = 0x00, /// @brief  Transaction: inputs
+
     TX_ITEM_TYPE_OUT = 0x10, /// @brief  Transaction: outputs
     TX_ITEM_TYPE_OUT_EXT = 0x11,
+    TX_ITEM_TYPE_256_OUT = 0x12, // 256
+    TX_ITEM_TYPE_256_OUT_EXT = 0x13, // 256
+
     TX_ITEM_TYPE_PKEY = 0x20,
     TX_ITEM_TYPE_SIG = 0x30,
     TX_ITEM_TYPE_TOKEN = 0x40,
     TX_ITEM_TYPE_TOKEN_EXT = 0x41,
     TX_ITEM_TYPE_IN_COND = 0x50, /// @brief  Transaction: conditon inputs
+
     TX_ITEM_TYPE_OUT_COND = 0x60, /// @brief  Transaction: conditon outputs
+    TX_ITEM_TYPE_256_OUT_COND = 0x61, // 256
+
     TX_ITEM_TYPE_RECEIPT = 0x70,
 
     TX_ITEM_TYPE_OUT_ALL = 0xfe,
@@ -213,6 +220,13 @@ typedef struct dap_chain_receipt{
     uint64_t value_datoshi; // Receipt value
 } dap_chain_receipt_info_t;
 
+// 256
+typedef struct dap_chain_256_receipt{
+    dap_chain_net_srv_uid_t srv_uid; // Service UID
+    dap_chain_net_srv_price_unit_uid_t units_type;
+    uint256_t units; // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT
+    uint256_t value_datoshi; // Receipt value
+} dap_chain_256_receipt_info_t;
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h
index d452fb9ac1..964c05723e 100644
--- a/modules/common/include/dap_chain_datum_token.h
+++ b/modules/common/include/dap_chain_datum_token.h
@@ -225,6 +225,35 @@ typedef struct dap_chain_datum_token_emission{
     } data;
 } DAP_ALIGN_PACKED dap_chain_datum_token_emission_t;
 
+// 256 Token emission
+typedef struct dap_chain_datum_256_token_emission{
+    struct  {
+        uint8_t version;
+        uint8_t type; // Emission Type
+        char ticker[DAP_CHAIN_TICKER_SIZE_MAX];
+        dap_chain_addr_t address; // Emission holder's address
+        uint256_t value;
+    } DAP_ALIGN_PACKED hdr;
+    union {
+        struct {
+            dap_chain_addr_t addr;
+            int flags;
+            uint64_t lock_time;
+        } DAP_ALIGN_PACKED type_presale;
+        struct {
+            uint256_t value_start;// Default value. Static if nothing else is defined
+            char value_change_algo_codename[32];
+        } DAP_ALIGN_PACKED type_atom_owner;
+        struct {
+            char codename[32];
+        } DAP_ALIGN_PACKED type_algo;
+        struct {
+            uint16_t signs_count;
+            byte_t  signs[];
+        } DAP_ALIGN_PACKED type_auth;// Signs if exists
+    } data;
+} DAP_ALIGN_PACKED dap_chain_datum_256_token_emission_t;
+
 // Different emissions type
 #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_UNDEFINED         0x00
 #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH              0x01
diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h
index 54885c4863..8c569f03ca 100644
--- a/modules/common/include/dap_chain_datum_tx.h
+++ b/modules/common/include/dap_chain_datum_tx.h
@@ -81,6 +81,10 @@ int dap_chain_datum_tx_add_item(dap_chain_datum_tx_t **a_tx, const uint8_t *a_it
  */
 uint64_t dap_chain_datum_tx_add_in_item_list(dap_chain_datum_tx_t **a_tx, dap_list_t *a_list_used_out);
 
+// 256
+uint256_t dap_chain_datum_256_tx_add_in_item_list(dap_chain_datum_tx_t **a_tx, dap_list_t *a_list_used_out);
+
+
 /**
  * Create 'in' item and insert to transaction
  *
@@ -106,6 +110,9 @@ int dap_chain_datum_tx_add_in_cond_item(dap_chain_datum_tx_t **a_tx, dap_chain_h
  */
 int dap_chain_datum_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint64_t a_value);
 
+// 256
+int dap_chain_datum_256_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr, uint256_t a_value);
+
 /**
  * Create 'out'_ext item and insert to transaction
  *
@@ -114,6 +121,10 @@ int dap_chain_datum_tx_add_out_item(dap_chain_datum_tx_t **a_tx, const dap_chain
 int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr,
                                         uint64_t a_value, const char *a_token);
 
+// 256
+int dap_chain_datum_256_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_chain_addr_t *a_addr,
+                                        uint256_t a_value, const char *a_token);
+
 /**
  * Create 'out_cond' item and insert to transaction
  *
@@ -122,6 +133,10 @@ int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_c
 int dap_chain_datum_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
         uint64_t a_value, uint64_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, const void *a_cond, size_t a_cond_size);
 
+//256
+int dap_chain_datum_256_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
+        uint256_t a_value, uint256_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, const void *a_cond, size_t a_cond_size);
+
 /**
 * Sign a transaction (Create sign item and insert to transaction)
  *
diff --git a/modules/common/include/dap_chain_datum_tx_in.h b/modules/common/include/dap_chain_datum_tx_in.h
index d52c76aac7..aabdc298bb 100644
--- a/modules/common/include/dap_chain_datum_tx_in.h
+++ b/modules/common/include/dap_chain_datum_tx_in.h
@@ -51,3 +51,12 @@ typedef struct list_used_item {
     uint64_t value;
 //dap_chain_tx_out_t *tx_out;
 } list_used_item_t;
+
+// 256
+typedef struct list_used_item_256 {
+    dap_chain_hash_fast_t tx_hash_fast;
+    uint32_t num_idx_out;
+    uint8_t padding[4];
+    uint256_t value;
+//dap_chain_tx_out_t *tx_out;
+} list_used_item_256_t;
diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h
index e194c7c336..70133b66a5 100644
--- a/modules/common/include/dap_chain_datum_tx_items.h
+++ b/modules/common/include/dap_chain_datum_tx_items.h
@@ -54,12 +54,15 @@ DAP_STATIC_INLINE const char * dap_chain_datum_tx_item_type_to_str(dap_chain_tx_
         case TX_ITEM_TYPE_IN: return "TX_ITEM_TYPE_IN";
         case TX_ITEM_TYPE_OUT: return "TX_ITEM_TYPE_OUT";
         case TX_ITEM_TYPE_OUT_EXT: return "TX_ITEM_TYPE_OUT_EXT";
+        case TX_ITEM_TYPE_256_OUT: return "TX_ITEM_TYPE_256_OUT"; //256
+        case TX_ITEM_TYPE_256_OUT_EXT: return "TX_ITEM_TYPE_256_OUT_EXT"; //256
         case TX_ITEM_TYPE_PKEY: return "TX_ITEM_TYPE_PKEY";
         case TX_ITEM_TYPE_SIG: return "TX_ITEM_TYPE_SIG";
         case TX_ITEM_TYPE_TOKEN: return "TX_ITEM_TYPE_TOKEN";
         case TX_ITEM_TYPE_TOKEN_EXT: return "TX_ITEM_TYPE_TOKEN_EXT";
         case TX_ITEM_TYPE_IN_COND: return "TX_ITEM_TYPE_IN_COND";
         case TX_ITEM_TYPE_OUT_COND: return "TX_ITEM_TYPE_OUT_COND";
+        case TX_ITEM_TYPE_256_OUT_COND: return "TX_ITEM_TYPE_256_OUT_COND"; //256
         case TX_ITEM_TYPE_RECEIPT: return "TX_ITEM_TYPE_RECEIPT";
         case TX_ITEM_TYPE_OUT_ALL: return "TX_ITEM_TYPE_OUT_ALL";
         case TX_ITEM_TYPE_ANY: return "TX_ITEM_TYPE_ANY";
@@ -99,6 +102,9 @@ dap_chain_tx_in_cond_t* dap_chain_datum_tx_item_in_cond_create(dap_chain_hash_fa
  */
 dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a_addr, uint64_t a_value);
 
+// 256
+dap_chain_256_tx_out_t* dap_chain_datum_tx_item_256_out_create(const dap_chain_addr_t *a_addr, uint256_t a_value);
+
 /**
  * Create item dap_chain_tx_out_ext_t
  *
@@ -106,6 +112,9 @@ dap_chain_tx_out_t* dap_chain_datum_tx_item_out_create(const dap_chain_addr_t *a
  */
 dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_addr_t *a_addr, uint64_t a_value, const char *a_token);
 
+// 256
+dap_chain_256_tx_out_ext_t* dap_chain_datum_tx_item_256_out_ext_create(const dap_chain_addr_t *a_addr, uint256_t a_value, const char *a_token);
+
 /**
  * Create item dap_chain_tx_out_cond_t
  *
@@ -114,6 +123,10 @@ dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_a
 dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_pay(dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
         uint64_t a_value, uint64_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit,
                                                                  const void *a_cond, size_t a_cond_size);
+// 256
+dap_chain_256_tx_out_cond_t* dap_chain_datum_tx_item_256_out_cond_create_srv_pay(dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
+        uint256_t a_value, uint256_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit,
+                                                                 const void *a_cond, size_t a_cond_size);
 /**
  * Create item dap_chain_tx_out_cond_t for eXchange service
  *
@@ -122,6 +135,11 @@ dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_pay(dap_enc
 dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap_chain_net_srv_uid_t a_srv_uid,
                                                                              dap_chain_net_id_t a_net_id, const char *a_token, uint64_t a_value,
                                                                              const void *a_params, uint32_t a_params_size);
+//256
+dap_chain_256_tx_out_cond_t* dap_chain_datum_tx_item_256_out_cond_create_srv_xchange(dap_chain_net_srv_uid_t a_srv_uid,
+                                                                             dap_chain_net_id_t a_net_id, const char *a_token, uint256_t a_value,
+                                                                             const void *a_params, uint32_t a_params_size);
+
 
 /**
  * Create item dap_chain_tx_out_cond_t for stake service
@@ -130,6 +148,10 @@ dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap
  */
 dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint64_t a_value, long double a_fee_value,
                                                                            dap_chain_addr_t *a_fee_addr, const void *a_params, uint32_t a_params_size);
+// 256
+dap_chain_256_tx_out_cond_t *dap_chain_datum_tx_item_256_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value, long double a_fee_value,
+                                                                           dap_chain_addr_t *a_fee_addr, const void *a_params, uint32_t a_params_size);
+
 /**
  * Create item dap_chain_tx_sig_t
  *
@@ -160,3 +182,4 @@ uint8_t* dap_chain_datum_tx_item_get( dap_chain_datum_tx_t *a_tx, int *a_item_id
 dap_list_t* dap_chain_datum_tx_items_get(dap_chain_datum_tx_t *a_tx, dap_chain_tx_item_type_t a_type, int *a_item_count);
 // Get conditional out item with it's idx
 dap_chain_tx_out_cond_t *dap_chain_datum_tx_out_cond_get(dap_chain_datum_tx_t *a_tx, int *a_out_num);
+dap_chain_256_tx_out_cond_t *dap_chain_datum_256_tx_out_cond_get(dap_chain_datum_tx_t *a_tx, int *a_out_num);
diff --git a/modules/common/include/dap_chain_datum_tx_out.h b/modules/common/include/dap_chain_datum_tx_out.h
index 24f8240a6f..e6bb99ccb1 100644
--- a/modules/common/include/dap_chain_datum_tx_out.h
+++ b/modules/common/include/dap_chain_datum_tx_out.h
@@ -39,3 +39,12 @@ typedef struct dap_chain_tx_out{
     } header; /// Only header's hash is used for verification
     dap_chain_addr_t addr; ////
 } DAP_ALIGN_PACKED dap_chain_tx_out_t;
+
+//256
+typedef struct dap_chain_256_tx_out{
+    struct {
+        dap_chain_tx_item_type_t type:8; ///           @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
+    dap_chain_addr_t addr; ////
+} DAP_ALIGN_PACKED dap_chain_256_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 b0b099572a..095708e4f3 100644
--- a/modules/common/include/dap_chain_datum_tx_out_cond.h
+++ b/modules/common/include/dap_chain_datum_tx_out_cond.h
@@ -94,3 +94,51 @@ typedef struct dap_chain_tx_out_cond {
     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_t;
+
+// 256
+typedef struct dap_chain_256_tx_out_cond {
+    struct {
+        /// Transaction item type
+        dap_chain_tx_item_type_t item_type :8;
+        /// Condition subtype
+        dap_chain_tx_out_cond_subtype_t subtype : 8;
+        /// Number of Datoshis ( DAP/10^9 ) to be reserver for service
+        uint256_t value;
+        /// When time expires this output could be used only by transaction owner
+        dap_chain_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
+            uint256_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
+            uint256_t value;
+        } srv_xchange;
+        struct {
+            // Service uid that only could be used for this outout
+            dap_chain_net_srv_uid_t srv_uid;
+            // 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_256_tx_out_cond_t;
+
diff --git a/modules/common/include/dap_chain_datum_tx_out_ext.h b/modules/common/include/dap_chain_datum_tx_out_ext.h
index 536012bbd6..1a310068cb 100644
--- a/modules/common/include/dap_chain_datum_tx_out_ext.h
+++ b/modules/common/include/dap_chain_datum_tx_out_ext.h
@@ -41,3 +41,13 @@ typedef struct dap_chain_tx_out_ext{
     dap_chain_addr_t addr;                 // Address to transfer to
     char token[DAP_CHAIN_TICKER_SIZE_MAX]; // Which token is transferred
 } DAP_ALIGN_PACKED dap_chain_tx_out_ext_t;
+
+// 256
+typedef struct dap_chain_256_tx_out_ext{
+    struct {
+        dap_chain_tx_item_type_t type : 8; // Transaction item type - should be TX_ITEM_TYPE_OUT_EXT
+        uint256_t value;                    // Number of Datoshis ( DAP/10^9 ) to be transfered
+    } header;                              // Only header's hash is used for verification
+    dap_chain_addr_t addr;                 // Address to transfer to
+    char token[DAP_CHAIN_TICKER_SIZE_MAX]; // Which token is transferred
+} DAP_ALIGN_PACKED dap_chain_256_tx_out_ext_t;
diff --git a/modules/common/include/dap_chain_datum_tx_receipt.h b/modules/common/include/dap_chain_datum_tx_receipt.h
index f873a4d927..7dfb587a47 100644
--- a/modules/common/include/dap_chain_datum_tx_receipt.h
+++ b/modules/common/include/dap_chain_datum_tx_receipt.h
@@ -39,6 +39,14 @@ typedef struct dap_chain_datum_tx_receipt {
     byte_t exts_n_signs[]; // Signatures, first from provider, second from client
 }DAP_ALIGN_PACKED dap_chain_datum_tx_receipt_t;
 
+// 256
+typedef struct dap_chain_datum_256_tx_receipt {
+    uint8_t type; //dap_chain_tx_item_type_t type :8; // Transaction item type
+    dap_chain_256_receipt_info_t receipt_info; // Receipt itself
+    uint16_t size;
+    uint16_t exts_size;
+    byte_t exts_n_signs[]; // Signatures, first from provider, second from client
+}DAP_ALIGN_PACKED dap_chain_datum_256_tx_receipt_t;
 
 #ifdef __cplusplus
 extern "C" {
@@ -57,6 +65,20 @@ static inline uint16_t dap_chain_datum_tx_receipt_get_size(const dap_chain_datum
     return l_receipt->size;
 }
 
+// 256
+static inline size_t dap_chain_datum_256_tx_receipt_get_size_hdr(){ return 1+sizeof (dap_chain_256_receipt_info_t)+sizeof (uint16_t) +sizeof (uint16_t); }
+
+dap_chain_datum_256_tx_receipt_t * dap_chain_datum_256_tx_receipt_create( dap_chain_net_srv_uid_t srv_uid,
+                                                                  dap_chain_net_srv_price_unit_uid_t units_type,
+                                                                    uint256_t units, uint256_t value_datoshi, const void * a_ext, size_t a_ext_size);
+size_t dap_chain_datum_256_tx_receipt_sign_add(dap_chain_datum_256_tx_receipt_t ** a_receipt, size_t a_receipt_size, dap_enc_key_t *a_key );
+dap_sign_t* dap_chain_datum_256_tx_receipt_sign_get(dap_chain_datum_256_tx_receipt_t * l_receipt, size_t l_receipt_size , uint16_t sign_position);
+uint16_t dap_chain_datum_256_tx_receipt_signs_count(dap_chain_datum_256_tx_receipt_t * l_receipt, size_t l_receipt_size);
+static inline uint16_t dap_chain_datum_256_tx_receipt_get_size(const dap_chain_datum_256_tx_receipt_t * l_receipt)
+{
+    return l_receipt->size;
+}
+
 
 #ifdef __cplusplus
 }
-- 
GitLab