From 6a5657cc18e13ce55070185d2dcc70895ad56088 Mon Sep 17 00:00:00 2001 From: Roman Khlopkov <roman.khlopkov@demlabs.net> Date: Tue, 29 Mar 2022 19:50:45 +0300 Subject: [PATCH] [+] Base TX creation separated from emission --- dap-sdk/crypto/include/dap_enc_base58.h | 1 - dap-sdk/crypto/src/dap_enc_base58.c | 28 --- dap-sdk/crypto/src/dap_hash.c | 40 +++- modules/mempool/dap_chain_mempool.c | 57 +++++ modules/mempool/include/dap_chain_mempool.h | 5 + modules/net/dap_chain_node_cli.c | 5 +- modules/net/dap_chain_node_cli_cmd.c | 217 ++++++++------------ modules/net/dap_chain_node_cli_cmd_tx.c | 6 +- modules/type/blocks/dap_chain_cs_blocks.c | 4 +- 9 files changed, 194 insertions(+), 169 deletions(-) diff --git a/dap-sdk/crypto/include/dap_enc_base58.h b/dap-sdk/crypto/include/dap_enc_base58.h index 8652d7bfd0..8392fb617e 100755 --- a/dap-sdk/crypto/include/dap_enc_base58.h +++ b/dap-sdk/crypto/include/dap_enc_base58.h @@ -47,7 +47,6 @@ char* dap_enc_base58_encode_hash_to_str(dap_chain_hash_fast_t *a_in_hash); char* dap_enc_base58_from_hex_str_to_str(const char *a_in_str); // convert from "Bura1HFrKsqbdytEXQVrxpbovtvLhR1VbrJs65JBx3gc" to "0xA21F1E865B6740A28E8708798ECF25D2C0AA596DF5EB1FD724186B6AD7FF2199" char* dap_enc_base58_to_hex_str_from_str(const char *a_in_str); -int dap_enc_base58_hex_to_hash(const char * a_hex_str, dap_chain_hash_fast_t * a_datum_hash); #ifdef __cplusplus } diff --git a/dap-sdk/crypto/src/dap_enc_base58.c b/dap-sdk/crypto/src/dap_enc_base58.c index 0614fa39ef..12054863ab 100755 --- a/dap-sdk/crypto/src/dap_enc_base58.c +++ b/dap-sdk/crypto/src/dap_enc_base58.c @@ -226,34 +226,6 @@ char* dap_enc_base58_encode_hash_to_str(dap_chain_hash_fast_t *a_in_hash) return dap_enc_base58_encode_to_str(a_in_hash->raw, sizeof(dap_chain_hash_fast_t)); } -/** - * @brief dap_enc_base58_hex_to_hash - * @param a_hex_str - * @param a_datum_hash - * @return - */ -int dap_enc_base58_hex_to_hash(const char * a_hex_str, dap_chain_hash_fast_t * a_datum_hash) -{ - assert(a_datum_hash); - - if (a_hex_str){ - char* l_datum_base58 = dap_enc_base58_from_hex_str_to_str(a_hex_str); - void * l_decoded = DAP_NEW_Z_SIZE(void,strlen(l_datum_base58)); - size_t l_decoded_size; - if (( l_decoded_size = dap_enc_base58_decode(l_datum_base58, l_decoded))!= sizeof (*a_datum_hash) ){ - memcpy( a_datum_hash, l_decoded, l_decoded_size); - return 0; - }else{ - log_it(L_ERROR,"Wrong hash format: can't parse \"%s\", decoded size %zd when expected %zd", a_hex_str, l_decoded_size, - sizeof (*a_datum_hash)); - return -1; - } - - }else - return -1; -} - - // convert from "0xA21F1E865B6740A28E8708798ECF25D2C0AA596DF5EB1FD724186B6AD7FF2199" to "Bura1HFrKsqbdytEXQVrxpbovtvLhR1VbrJs65JBx3gc" char* dap_enc_base58_from_hex_str_to_str(const char *a_in_str) { diff --git a/dap-sdk/crypto/src/dap_hash.c b/dap-sdk/crypto/src/dap_hash.c index 7a62574684..944c0fea81 100755 --- a/dap-sdk/crypto/src/dap_hash.c +++ b/dap-sdk/crypto/src/dap_hash.c @@ -25,6 +25,7 @@ #include <stdlib.h> #include "dap_common.h" #include "dap_hash.h" +#include "dap_enc_base58.h" #include "KeccakHash.h" #include "SimpleFIPS202.h" @@ -37,17 +38,17 @@ * @param a_hash * @return */ -int dap_chain_hash_fast_from_str( const char * a_hash_str, dap_chain_hash_fast_t * a_hash) +int dap_chain_hash_fast_from_hex_str( const char *a_hex_str, dap_chain_hash_fast_t *a_hash) { const size_t c_hash_str_size = sizeof(*a_hash) * 2 + 1 /*trailing zero*/+ 2 /* heading 0x */; - size_t l_hash_str_len = strlen( a_hash_str); + size_t l_hash_str_len = strlen(a_hex_str); if ( l_hash_str_len + 1 == c_hash_str_size ){ for(size_t l_offset = 2; l_offset < l_hash_str_len; l_offset += 2) { char l_byte; - if(dap_sscanf(a_hash_str + l_offset, "%02hhx", &l_byte) != 1) { - if(dap_sscanf(a_hash_str + l_offset, "%02hhx", &l_byte) != 1) { + if(dap_sscanf(a_hex_str + l_offset, "%02hhx", &l_byte) != 1) { + if(dap_sscanf(a_hex_str + l_offset, "%02hhx", &l_byte) != 1) { log_it(L_ERROR, "dap_chain_str_to_hash_fast parse error: offset=%zu, hash_str_len=%zu, str=\"%2s\"", - l_offset, l_hash_str_len, a_hash_str + l_offset); + l_offset, l_hash_str_len, a_hex_str + l_offset); return -10 * ((int) l_offset); // Wrong char } } @@ -58,3 +59,32 @@ int dap_chain_hash_fast_from_str( const char * a_hash_str, dap_chain_hash_fast_t return -1; } + +/** + * @brief dap_chain_hash_fast_from_base58_str + * @param a_base58_str + * @param a_datum_hash + * @return + */ +int dap_chain_hash_fast_from_base58_str(const char *a_base58_str, dap_chain_hash_fast_t *a_hash) +{ + if (!a_hash) + return -1; + if (!a_base58_str) + return -2; + size_t l_hash_len = dap_strlen(a_base58_str); + if (l_hash_len > DAP_ENC_BASE58_ENCODE_SIZE(sizeof(dap_hash_fast_t))) + return -3; + // from base58 to binary + byte_t l_out[DAP_ENC_BASE58_DECODE_SIZE(DAP_ENC_BASE58_ENCODE_SIZE(sizeof(dap_hash_fast_t)))]; + size_t l_out_size = dap_enc_base58_decode(a_in_str, l_out); + if (l_out_size != sizeof(dap_hash_fast_t)) + return -4; + memcpy(a_hash, l_out, sizeof(dap_hash_fast_t)); + return 0; +} + +int dap_chain_hash_fast_from_str( const char *a_hash_str, dap_chain_hash_fast_t *a_hash) +{ + return dap_chain_hash_fast_from_hex_str(a_hash_str, a_hash) && dap_chain_hash_fast_from_base58_str(a_hash_str, a_hash); +} diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index ee705f2552..c392357992 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -587,6 +587,63 @@ dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond(dap_chain_net_t * a_net, return l_key_hash; } +dap_chain_hash_fast_t *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_emission_hash, + dap_chain_id_t a_emission_chain_id, uint256_t a_emission_value, + dap_chain_addr_t *a_addr_to, dap_cert_t *a_certs, size_t a_certs_count) +{ + char *l_gdb_group_mempool_base_tx = dap_chain_net_get_gdb_group_mempool(a_chain); + // create first transaction (with tx_token) + dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); + l_tx->header.ts_created = time(NULL); + dap_chain_hash_fast_t l_tx_prev_hash = { 0 }; + // create items + + dap_chain_tx_token_t *l_tx_token = dap_chain_datum_tx_item_token_create(a_emission_chain_id, a_emission_hash, l_ticker); + dap_chain_tx_in_t *l_in = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, 0); + dap_chain_tx_out_t *l_out = dap_chain_datum_tx_item_out_create(a_addr_to, a_emission_value); + + // pack items to transaction + dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_tx_token); + dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_in); + dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_out); + + if (a_certs){ + // Sign all that we have with certs + for(size_t i = 0; i < a_certs_count; i++) { + if(dap_chain_datum_tx_add_sign_item(&l_tx, a_certs[i]->enc_key) < 0) { + dap_chain_node_cli_set_reply_text(a_str_reply, "No private key for certificate=%s", + a_certs[i]->name); + DAP_DELETE(l_addr); + return NULL; + } + } + } + + DAP_DEL_Z(l_tx_token); + DAP_DEL_Z(l_in); + DAP_DEL_Z(l_out); + + size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); + + // Pack transaction into the datum + dap_chain_datum_t * l_datum_tx = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size); + size_t l_datum_tx_size = dap_chain_datum_size(l_datum_tx); + DAP_DEL_Z(l_tx); + // calc datum hash + dap_chain_hash_fast_t *l_datum_tx_hash = DAP_NEW(dap_hash_fast_t); + dap_hash_fast(l_datum_tx, l_datum_tx_size, l_datum_tx_hash); + char *l_tx_hash_str = dap_chain_hash_fast_to_str_new(l_datum_tx_hash); + // Add to mempool tx token + bool l_placed = dap_chain_global_db_gr_set(l_tx_hash_str, l_datum_tx, + l_datum_tx_size, l_gdb_group_mempool_base_tx); + DAP_DEL_Z(l_tx_hash_str); + DAP_DELETE(l_datum_tx); + if (!l_placed) { + return NULL; + } + return l_datum_tx_hash; +} + uint8_t* dap_datum_mempool_serialize(dap_datum_mempool_t *datum_mempool, size_t *size) { size_t a_request_size = 2 * sizeof(uint16_t), shift_size = 0; diff --git a/modules/mempool/include/dap_chain_mempool.h b/modules/mempool/include/dap_chain_mempool.h index 9cc95a0723..c9db3876ff 100644 --- a/modules/mempool/include/dap_chain_mempool.h +++ b/modules/mempool/include/dap_chain_mempool.h @@ -5,6 +5,7 @@ #include "dap_chain_net.h" #include "dap_chain_ledger.h" #include "dap_http.h" +#include "dap_cert.h" /* // datum mempool structure typedef struct dap_datum_mempool { @@ -65,3 +66,7 @@ int dap_chain_mempool_tx_create_massive(dap_chain_t * a_chain, dap_enc_key_t *a_ const dap_chain_addr_t* a_addr_fee, const char a_token_ticker[DAP_CHAIN_TICKER_SIZE_MAX], uint256_t a_value, uint256_t a_value_fee, size_t a_tx_num); + +dap_chain_hash_fast_t *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_emission_hash, + dap_chain_id_t a_emission_chain_id, uint256_t a_emission_value, + dap_chain_addr_t *a_addr_to, dap_cert_t *a_certs, size_t a_certs_count); diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index c8da12bf8b..943ee15f77 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -1046,7 +1046,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config) ); dap_chain_node_cli_cmd_item_create ("token_emit", com_token_emit, "Token emission", - "token_emit -net <net name> -chain_emission <chain for emission> -chain_base_tx <chain for base tx> -addr <addr> -token <token ticker> -certs <cert> -emission_value <val>\n"); + "token_emit {sign | -token <token ticker> -emission_value <val>} -net <net name> [-chain_emission <chain for emission>] [-chain_base_tx <chain for base tx> -addr <addr>] -certs <cert list>\n"); dap_chain_node_cli_cmd_item_create ("mempool_list", com_mempool_list, "List mempool entries for selected chain network", "mempool_list -net <net name>\n"); @@ -1071,7 +1071,8 @@ int dap_chain_node_cli_init(dap_config_t * g_config) // Transaction commands dap_chain_node_cli_cmd_item_create ("tx_create", com_tx_create, "Make transaction", - "tx_create -net <net name> -chain <chain name> -from_wallet <name> -to_addr <addr> -token <token ticker> -value <value> [-fee <addr> -value_fee <val>]\n" ); + "tx_create -net <net name> -chain <chain name> {-from_wallet <name> -token <token ticker> -value <value> -to_addr <addr> | -from_emission <emission_hash>}" + "[-fee <addr> -value_fee <val>]\n" ); dap_chain_node_cli_cmd_item_create ("tx_cond_create", com_tx_cond_create, "Make cond transaction", "tx_cond_create -net <net name> -token <token ticker> -wallet <from wallet> -cert <public cert>" "-value <value datoshi> -unit <mb | kb | b | sec | day> -srv_uid <numeric uid>\n" ); diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 8e4c92971c..5bff985b8f 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -1855,30 +1855,30 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply) dap_string_append_printf(l_string_ret, "addr: %s\n", (l_addr_str) ? l_addr_str : "-"); dap_string_append_printf(l_string_ret, "network: %s\n", (l_net_name ) ? l_net_name : "-"); - size_t l_addr_tokens_size = 0; - char **l_addr_tokens = NULL; - dap_chain_ledger_addr_get_token_ticker_all_fast(l_ledger, l_addr, &l_addr_tokens, &l_addr_tokens_size); - if(l_addr_tokens_size > 0) + size_t l_l_addr_tokens_size = 0; + char **l_l_addr_tokens = NULL; + dap_chain_ledger_addr_get_token_ticker_all_fast(l_ledger, l_addr, &l_l_addr_tokens, &l_l_addr_tokens_size); + if(l_l_addr_tokens_size > 0) dap_string_append_printf(l_string_ret, "balance:\n"); else dap_string_append_printf(l_string_ret, "balance: 0"); - for(size_t i = 0; i < l_addr_tokens_size; i++) { - if(l_addr_tokens[i]) { - uint256_t l_balance = dap_chain_ledger_calc_balance(l_ledger, l_addr, l_addr_tokens[i]); + for(size_t i = 0; i < l_l_addr_tokens_size; i++) { + if(l_l_addr_tokens[i]) { + uint256_t l_balance = dap_chain_ledger_calc_balance(l_ledger, l_addr, l_l_addr_tokens[i]); char *l_balance_coins = dap_chain_balance_to_coins(l_balance); char *l_balance_datoshi = dap_chain_balance_print(l_balance); dap_string_append_printf(l_string_ret, "\t%s (%s) %s\n", l_balance_coins, - l_balance_datoshi, l_addr_tokens[i]); - if(i < l_addr_tokens_size - 1) + l_balance_datoshi, l_l_addr_tokens[i]); + if(i < l_l_addr_tokens_size - 1) dap_string_append_printf(l_string_ret, "\n"); DAP_DELETE(l_balance_coins); DAP_DELETE(l_balance_datoshi); } - DAP_DELETE(l_addr_tokens[i]); + DAP_DELETE(l_l_addr_tokens[i]); } - DAP_DELETE(l_addr_tokens); + DAP_DELETE(l_l_addr_tokens); DAP_DELETE(l_addr_str); if(l_wallet) dap_chain_wallet_close(l_wallet); @@ -2986,8 +2986,8 @@ int com_token_decl(int a_argc, char ** a_argv, char ** a_str_reply) }else if ( strcmp( a_argv[l_arg_index],"-tx_receiver_allowed" )==0){ const char *a_tx_receiver_allowed_base58 = NULL; dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "-tx_receiver_allowed", &a_tx_receiver_allowed_base58); - dap_chain_addr_t *addr_to = dap_chain_addr_from_str(a_tx_receiver_allowed_base58); - dap_tsd_t * l_tsd = dap_tsd_create(DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD, addr_to, sizeof(dap_chain_addr_t)); + dap_chain_addr_t *l_addr_to = dap_chain_addr_from_str(a_tx_receiver_allowed_base58); + dap_tsd_t * l_tsd = dap_tsd_create(DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD, l_addr_to, sizeof(dap_chain_addr_t)); l_tsd_list = dap_list_append( l_tsd_list, l_tsd); //dap_tsd_t * l_tsd = dap_tsd_create_string(DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD, a_tx_receiver_allowed_base58); l_tsd_total_size+= dap_tsd_size( l_tsd); @@ -3408,9 +3408,10 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) dap_hash_fast(l_datum_emission, l_datum_emission_size, &l_emission_hash); // Calc token's hash dap_hash_fast(l_emission, l_emission_size, &l_token_emission_hash); - l_emission_hash_str = dap_chain_hash_fast_to_str_new(&l_emission_hash); - l_emission_hash_str_base58 = dap_enc_base58_encode_hash_to_str(&l_emission_hash); + bool l_hex_format = dap_strcmp(l_hash_out_type, "hex"); + l_emission_hash_str = l_hex_format ? dap_chain_hash_fast_to_str_new(&l_emission_hash) + : dap_enc_base58_encode_hash_to_str(&l_emission_hash); // Delete token emission DAP_DEL_Z(l_emission); @@ -3420,81 +3421,28 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) l_datum_emission_size, l_gdb_group_mempool_emission); str_reply_tmp = dap_strdup_printf("Datum %s with 256bit emission is%s placed in datum pool", - dap_strcmp(l_hash_out_type, "hex") ? l_emission_hash_str_base58 : l_emission_hash_str, - l_placed ? "" : " not"); - DAP_DELETE((char *)l_emission_hash_str); - DAP_DEL_Z(l_emission_hash_str_base58); + l_emission_hash_str, l_placed ? "" : " not"); + DAP_DEL_Z(l_emission_hash_str); if (!l_placed) { DAP_DEL_Z(l_datum_emission); + DAP_DEL_Z(l_certs); return -1; } if(l_chain_base_tx) { - char *l_gdb_group_mempool_base_tx = dap_chain_net_get_gdb_group_mempool(l_chain_base_tx); - // create first transaction (with tx_token) - dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); - l_tx->header.ts_created = time(NULL); - dap_chain_hash_fast_t l_tx_prev_hash = { 0 }; - // create items - - dap_chain_tx_token_t *l_tx_token = dap_chain_datum_tx_item_token_create(l_chain_emission->id, &l_token_emission_hash, l_ticker); - dap_chain_tx_in_t *l_in = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, 0); - dap_chain_tx_out_t *l_out = dap_chain_datum_tx_item_out_create(l_addr, l_emission_value); - - // pack items to transaction - dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_tx_token); - dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_in); - dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_out); - - if (l_certs){ - // Sign all that we have with certs - for(size_t i = 0; i < l_certs_size; i++) { - if(dap_chain_datum_tx_add_sign_item(&l_tx, l_certs[i]->enc_key) < 0) { - dap_chain_node_cli_set_reply_text(a_str_reply, "No private key for certificate=%s", - l_certs[i]->name); - DAP_DELETE(l_addr); - return -3; - } - } - } - - if (l_certs) - DAP_DEL_Z(l_certs); - - DAP_DEL_Z(l_tx_token); - DAP_DEL_Z(l_in); - DAP_DEL_Z(l_out); - - size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); - - // Pack transaction into the datum - dap_chain_datum_t * l_datum_tx = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size); - size_t l_datum_tx_size = dap_chain_datum_size(l_datum_tx); - - // calc datum hash - dap_chain_hash_fast_t l_datum_tx_hash; - dap_hash_fast(l_datum_tx, l_datum_tx_size, &l_datum_tx_hash); - char * l_tx_hash_str = dap_chain_hash_fast_to_str_new(&l_datum_tx_hash); - char * l_tx_hash_str_base58 = dap_enc_base58_encode_hash_to_str(&l_datum_tx_hash); - DAP_DEL_Z(l_tx); - - // Add to mempool tx token - bool l_placed = dap_chain_global_db_gr_set(dap_strdup(l_tx_hash_str), l_datum_tx, - l_datum_tx_size, l_gdb_group_mempool_base_tx); - dap_chain_node_cli_set_reply_text(a_str_reply, "%s\nDatum %s with 256bit TX is%s placed in datum pool ", - str_reply_tmp, - dap_strcmp(l_hash_out_type, "hex") ? l_tx_hash_str_base58 : l_tx_hash_str, - l_placed ? "" : " not"); - DAP_DEL_Z(l_tx_hash_str); + dap_chain_hash_fast_t *l_datum_tx_hash = dap_chain_mempool_base_tx_create(l_chain_base_tx, &l_emission_hash, + l_chain_emission->id, l_emission_value, + l_addr, l_certs, l_certs_size); + char *l_tx_hash_str = l_hex_format ? dap_chain_hash_fast_to_str_new(l_datum_tx_hash) + : dap_enc_base58_encode_hash_to_str(l_datum_tx_hash); + = dap_enc_base58_encode_hash_to_str(l_datum_tx_hash); + dap_chain_node_cli_set_reply_text(a_str_reply, "%s\nDatum %s with 256bit TX is%s placed in datum pool", + str_reply_tmp, l_tx_hash_str, l_placed ? "" : " not"); DAP_DEL_Z(l_tx_hash_str_base58); DAP_DELETE(str_reply_tmp); - DAP_DELETE(l_addr); - if (!l_placed) { - DAP_DELETE(l_datum_tx); - return -2; - } } - + DAP_DELETE(l_addr); + DAP_DEL_Z(l_certs); return 0; } @@ -3880,11 +3828,14 @@ int com_tx_create(int argc, char ** argv, char **str_reply) const char * l_net_name = NULL; const char * l_chain_name = NULL; const char * l_tx_num_str = NULL; + const char *l_emission_hash_str = NULL; + dap_chain_hash_fast_t l_emission_hash = {}; size_t l_tx_num = 0; uint256_t l_value = {}; uint256_t l_value_fee = {}; dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-from_wallet", &l_from_wallet_name); + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-from_emission", &l_emission_hash_str); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-to_addr", &addr_base58_to); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-token", &l_token_ticker); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-net", &l_net_name); @@ -3902,39 +3853,43 @@ int com_tx_create(int argc, char ** argv, char **str_reply) if(dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-value", &str_tmp)) { l_value = dap_chain_balance_scan(str_tmp); } - if(!l_from_wallet_name) { - dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-from_wallet'"); + if(!l_from_wallet_name && !l_emission_hash_str) { + dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires one of parameters '-from_wallet' or '-from_emission'"); return -1; } if(!addr_base58_to) { dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-to_addr'"); - return -1; + return -2; } - if(IS_ZERO_256(l_value)) { - dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-value'"); - return -1; + if (l_emission_hash_str) { + if (dap_chain_hash_fast_from_str(l_emission_hash_str, &l_emission_hash)) { + dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-emission_hash' " + "to be valid string containing hash in hex or base58 format"); + return -3; + } + } else { + if(IS_ZERO_256(l_value)) { + dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-value' to be valid uint256 value"); + return -4; + } } if(addr_base58_fee && IS_ZERO_256(l_value_fee)) { dap_chain_node_cli_set_reply_text(str_reply, - "tx_create requires parameter '-value_fee' if '-fee' is specified"); - return -1; + "tx_create requires parameter '-value_fee' to be valid uint256 value if '-fee' is specified"); + return -5; } if(!l_net_name) { dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-net'"); - return -1; + return -6; } dap_chain_net_t * l_net = dap_chain_net_by_name(l_net_name); dap_ledger_t *l_ledger = l_net ? l_net->pub.ledger : NULL; if(l_net == NULL || (l_ledger = dap_chain_ledger_by_net_name(l_net_name)) == NULL) { dap_chain_node_cli_set_reply_text(str_reply, "not found net by name '%s'", l_net_name); - return -1; + return -7; } - /* if(!l_chain_name) { - dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-chain'"); - return -1; - }*/ dap_chain_t * l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_name); if(!l_chain) { l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_TX); @@ -3942,7 +3897,32 @@ int com_tx_create(int argc, char ** argv, char **str_reply) if(!l_chain) { dap_chain_node_cli_set_reply_text(str_reply, "not found chain name '%s', try use parameter '-chain'", l_chain_name); - return -1; + return -8; + } + + dap_chain_addr_t *l_addr_to = dap_chain_addr_from_str(addr_base58_to); + if(!l_addr_to) { + dap_chain_node_cli_set_reply_text(str_reply, "destination address is invalid"); + return -11; + } + + dap_string_t *string_ret = dap_string_new(NULL); + int res = 0; + if (l_emission_hash_str) { + dap_hash_fast_t *l_tx_hash = dap_chain_mempool_base_tx_create(l_chain, &l_emission_hash, l_addr_to); + if (l_tx_hash){ + char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_chain_hash_fast_to_str(l_tx_hash,l_tx_hash_str,sizeof (l_tx_hash_str)-1); + dap_string_append_printf(string_ret, "transfer=Ok\ntx_hash=%s\n",l_tx_hash_str); + DAP_DELETE(l_tx_hash); + }else{ + dap_string_append_printf(string_ret, "transfer=False\n"); + res = -15; + } + dap_chain_node_cli_set_reply_text(str_reply, string_ret->str); + dap_string_free(string_ret, false); + DAP_DELETE(l_addr_to); + return res; } const char *c_wallets_path = dap_chain_wallet_get_path(g_config); @@ -3950,49 +3930,36 @@ int com_tx_create(int argc, char ** argv, char **str_reply) if(!l_wallet) { dap_chain_node_cli_set_reply_text(str_reply, "wallet %s does not exist", l_from_wallet_name); - return -1; + return -9; } const dap_chain_addr_t *addr_from = (const dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id); - dap_chain_addr_t *addr_to = dap_chain_addr_from_str(addr_base58_to); + dap_chain_addr_t *addr_fee = dap_chain_addr_from_str(addr_base58_fee); if(!addr_from) { dap_chain_node_cli_set_reply_text(str_reply, "source address is invalid"); - return -1; - } - if(!addr_to) { - dap_chain_node_cli_set_reply_text(str_reply, "destination address is invalid"); - return -1; + return -10; } if(addr_base58_fee && !addr_fee) { dap_chain_node_cli_set_reply_text(str_reply, "fee address is invalid"); - return -1; + return -12; } - - // // Check, if network ID is same as ID in destination wallet address. If not - operation is cancelled. - // - - if (addr_to->net_id.uint64 != l_net->pub.id.uint64) - { + if (l_addr_to->net_id.uint64 != l_net->pub.id.uint64) { dap_chain_node_cli_set_reply_text(str_reply, "destination wallet network ID=0x%llx and network ID=0x%llx is not equal. Please, change network name or wallet address", - addr_to->net_id.uint64, l_net->pub.id.uint64); - return -1; + l_addr_to->net_id.uint64, l_net->pub.id.uint64); + return -13; } - dap_string_t *string_ret = dap_string_new(NULL); - //g_string_printf(string_ret, "from=%s\nto=%s\nval=%lld\nfee=%s\nval_fee=%lld\n\n", - // addr_base58_from, addr_base58_to, value, addr_base58_fee, value_fee); - int res = 0; if(l_tx_num){ res = dap_chain_mempool_tx_create_massive(l_chain, dap_chain_wallet_get_key(l_wallet, 0), addr_from, - addr_to, addr_fee, + l_addr_to, addr_fee, l_token_ticker, l_value, l_value_fee, l_tx_num); dap_string_append_printf(string_ret, "transfer=%s\n", (res == 0) ? "Ok" : (res == -2) ? "False, not enough funds for transfer" : "False"); }else{ - dap_hash_fast_t * l_tx_hash = dap_chain_mempool_tx_create(l_chain, dap_chain_wallet_get_key(l_wallet, 0), addr_from, addr_to, + dap_hash_fast_t * l_tx_hash = dap_chain_mempool_tx_create(l_chain, dap_chain_wallet_get_key(l_wallet, 0), addr_from, l_addr_to, addr_fee, l_token_ticker, l_value, l_value_fee); if (l_tx_hash){ @@ -4002,7 +3969,7 @@ int com_tx_create(int argc, char ** argv, char **str_reply) DAP_DELETE(l_tx_hash); }else{ dap_string_append_printf(string_ret, "transfer=False\n"); - res = -1; + res = -14; } } @@ -4010,7 +3977,7 @@ int com_tx_create(int argc, char ** argv, char **str_reply) dap_chain_node_cli_set_reply_text(str_reply, string_ret->str); dap_string_free(string_ret, false); - DAP_DELETE(addr_to); + DAP_DELETE(l_addr_to); DAP_DELETE(addr_fee); dap_chain_wallet_close(l_wallet); return res; @@ -4047,13 +4014,9 @@ int com_tx_verify(int a_argc, char **a_argv, char **a_str_reply) *a_str_reply = NULL; } dap_hash_fast_t l_tx_hash; - char *l_hex_str_from58 = NULL; - if (dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash) < 0) { - l_hex_str_from58 = dap_enc_base58_to_hex_str_from_str(l_tx_hash_str); - if (!l_hex_str_from58) { - dap_chain_node_cli_set_reply_text(a_str_reply, "Invalid tx hash format, need hex or base58"); - return -3; - } + if (dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash)) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Invalid tx hash format, need hex or base58"); + return -3; } size_t l_tx_size = 0; char *l_gdb_group = dap_chain_net_get_gdb_group_mempool(l_chain); diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index e0b93b3f27..880710d272 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -1316,8 +1316,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) //const char *l_chain_group = dap_chain_gdb_get_group(l_chain); dap_chain_hash_fast_t l_tx_hash; if(l_tx_hash_str) { - if (dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash) && - dap_enc_base58_hex_to_hash(l_tx_hash_str, &l_tx_hash)) { + if (dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash)) { l_tx_hash_str = NULL; dap_chain_node_cli_set_reply_text(a_str_reply, "tx hash not recognized"); return -1; @@ -1458,8 +1457,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply) return -2; } dap_chain_hash_fast_t *l_tx_hash = DAP_NEW(dap_chain_hash_fast_t); - if (dap_chain_hash_fast_from_str(l_tx_hash_str, l_tx_hash) && - dap_enc_base58_hex_to_hash(l_tx_hash_str, l_tx_hash)) { + if (dap_chain_hash_fast_from_str(l_tx_hash_str, l_tx_hash)) { dap_chain_node_cli_set_reply_text(a_str_reply, "Can't get hash_fast from %s", l_tx_hash_str); return -4; } diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 106ee3bee2..1d03a0911f 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -277,7 +277,7 @@ static int s_cli_parse_cmd_hash(char ** a_argv, int a_arg_index, int a_argc, cha const char *l_datum_hash_str = NULL; dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, a_param, &l_datum_hash_str); - return dap_enc_base58_hex_to_hash(l_datum_hash_str, a_datum_hash); + return dap_chain_hash_fast_from_str(l_datum_hash_str, a_datum_hash); } /** @@ -455,7 +455,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) dap_chain_block_t * l_block; size_t l_block_size = 0; dap_chain_hash_fast_t l_block_hash={0}; - dap_enc_base58_hex_to_hash( l_subcmd_str_arg, &l_block_hash); // Convert argument to hash + dap_chain_hash_fast_from_str( l_subcmd_str_arg, &l_block_hash); // Convert argument to hash l_block = (dap_chain_block_t*) dap_chain_get_atom_by_hash( l_chain, &l_block_hash, &l_block_size); if ( l_block){ dap_chain_block_cache_t *l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_block_hash); -- GitLab