Skip to content
Snippets Groups Projects
dap_chain_node_cli_cmd.c 55 KiB
Newer Older
        n = (n_str) ? atoi(n_str) : 4;
    }
    else {
        argc_start = find_option_val(argv, argc_start, argc, "-c", &n_str);
        if(argc_start) {
            argc_host = argc_start + 1;
            n = (n_str) ? atoi(n_str) : 4;
        }
    }
    const char *addr = argv[argc_host];
    iputils_set_verbose();
    int res = (addr) ? ping_util(addr, n) : -EADDRNOTAVAIL;
    if(res >= 0) {
        if(str_reply)
            set_reply_text(str_reply, "ping %s time=%.1lf ms", addr, res * 1. / 1000);
    }
    else {
        if(str_reply) {
            switch (-res)
            {
            case EDESTADDRREQ:
                set_reply_text(str_reply, "ping %s error: %s", addr, "Destination address required");
                break;
            case EADDRNOTAVAIL:
                set_reply_text(str_reply, "ping %s error: %s", (addr) ? addr : "",
                        (addr) ? "Host not found" : "Host not defined");
                break;
            case EPFNOSUPPORT:
                set_reply_text(str_reply, "ping %s error: %s", addr, "Unknown protocol family");
                set_reply_text(str_reply, "ping %s error(%d)", addr, -res);
            }
        }
    }
    return res;
}

/**
 * Help command
 */
int com_help(int argc, const char ** argv, char **str_reply)
{
    if(argc > 1) {
        const COMMAND *cmd = find_command(argv[1]);
        if(cmd)
        {
            set_reply_text(str_reply, "%s:\n%s", cmd->doc, cmd->doc_ex);
            return 1;
        }
        set_reply_text(str_reply, "command \"%s\" not recognized", argv[1]);
        return -1;
    }
    else {
        // TODO Read list of commands & return it
    }
    if(str_reply)
        set_reply_text(str_reply, "command not defined, enter \"help <cmd name>\"");
    return -1;
}

/**
 * com_tx_create command
 *
 * Wallet info
 */
int com_tx_wallet(int argc, const char ** argv, char **str_reply)
{
    const char *c_wallets_path = "/opt/kelvin-node/etc";
    // Get address of wallet
    enum {
        CMD_NONE, CMD_WALLET_LIST, CMD_WALLET_INFO
    };
    int arg_index = 1;
    int cmd_num = CMD_NONE;
    const char *cmd_str = NULL;
    // find  add parameter ('alias' or 'handshake')
    if(find_option_val(argv, arg_index, min(argc, arg_index + 1), "list", NULL)) {
        cmd_num = CMD_WALLET_LIST;
    }
    else if(find_option_val(argv, arg_index, min(argc, arg_index + 1), "info", NULL)) {
        cmd_num = CMD_WALLET_INFO;
    }
    arg_index++;
    if(cmd_num == CMD_NONE) {
        set_reply_text(str_reply, "format of command: wallet [list | info -addr <addr> -w <wallet_name>]");
        return -1;
    }

    dap_chain_node_addr_t address;
    memset(&address, 0, sizeof(dap_chain_node_addr_t));
    const char *addr_str = NULL, *wallet_name = NULL;
    // find wallet addr
    find_option_val(argv, arg_index, argc, "-addr", &addr_str);
    find_option_val(argv, arg_index, argc, "-w", &wallet_name);

    GString *l_string_ret = g_string_new(NULL);
    switch (cmd_num) {
    // wallet list
    case CMD_WALLET_LIST: {
        GDir *l_dir = g_dir_open(c_wallets_path, 0, NULL);
        if(l_dir) {
            const char *l_file = NULL;
            do {
                l_file = g_dir_read_name(l_dir);
                int l_file_len = (l_file) ? strlen(l_file) : 0;
                if(l_file_len > 8 && !g_strcmp0(l_file + l_file_len - 8, ".dwallet")) {
                    char *l_file_path_tmp = g_strdup_printf("%s/%s", c_wallets_path, l_file);
                    dap_chain_wallet_t *l_wallet = dap_chain_wallet_open_file(l_file_path_tmp);
                    if(l_wallet) {
                        dap_chain_addr_t *l_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet);
                        char *l_addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) l_addr);
                        g_string_append_printf(l_string_ret, "\nwallet: %s\n", l_wallet->name);
                        g_string_append_printf(l_string_ret, "addr: %s\n", (l_addr_str) ? l_addr_str : "-");
                        DAP_DELETE(l_addr_str);
                        dap_chain_wallet_close(l_wallet);
                    }
                    g_free(l_file_path_tmp);
                }
            }
            while(l_file);
            g_dir_close(l_dir);
        }
    }
        break;

        // wallet info
    case CMD_WALLET_INFO: {
        dap_chain_wallet_t *l_wallet = NULL;
        if(wallet_name)
            l_wallet = dap_chain_wallet_open(wallet_name, c_wallets_path);
        if(l_wallet) {
            dap_chain_addr_t *l_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet);
            char *l_addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) l_addr);
            uint64_t balance = dap_chain_datum_tx_cache_calc_balance(l_addr);
            g_string_append_printf(l_string_ret, "\nwallet: %s\n", l_wallet->name);
            g_string_append_printf(l_string_ret, "addr: %s\n", (l_addr_str) ? l_addr_str : "-");
            g_string_append_printf(l_string_ret, "balance: %lld\n", balance);
            DAP_DELETE(l_addr_str);
            dap_chain_wallet_close(l_wallet);
        }
        else {
            g_string_free(l_string_ret, TRUE);
            set_reply_text(str_reply, "wallet not found");
            return -1;
        }
    }
        break;
    }

    char *l_str_ret_tmp = g_string_free(l_string_ret, FALSE);
    char *str_ret = strdup(l_str_ret_tmp);
    set_reply_text(str_reply, str_ret);
    g_free(l_str_ret_tmp);
    return 0;
}

/**
 * com_tx_create command
 *
 * Create transaction
 */
int com_tx_create(int argc, const char ** argv, char **str_reply)
{
    int arg_index = 1;
    int cmd_num = 1;
    const char *value_str = NULL;
    const char *addr_base58_from = NULL;
    const char *addr_base58_to = NULL;
    const char *addr_base58_fee = NULL;
    const char *str_tmp = NULL;
    uint64_t value = 0;
    uint64_t value_fee = 0;
    find_option_val(argv, arg_index, argc, "from", &addr_base58_from);
    find_option_val(argv, arg_index, argc, "to", &addr_base58_to);
    if(find_option_val(argv, arg_index, argc, "fee", &addr_base58_fee)) {
        if(find_option_val(argv, arg_index, argc, "value_fee", &str_tmp)) {
            value_fee = strtoll(str_tmp, NULL, 10);
        }
    }
    if(find_option_val(argv, arg_index, argc, "value", &str_tmp)) {
        value = strtoll(str_tmp, NULL, 10);
    }
    if(!addr_base58_from) {
        set_reply_text(str_reply, "tx_create requires parameter 'from'");
        return -1;
    }
    if(!addr_base58_to) {
        set_reply_text(str_reply, "tx_create requires parameter 'to'");
        return -1;
    }
    if(!value) {
        set_reply_text(str_reply, "tx_create requires parameter 'value'");
        return -1;
    }
    if(addr_base58_fee && !value_fee) {
        set_reply_text(str_reply, "tx_create requires parameter 'value_fee' if 'fee' is specified");
        return -1;
    }

    const char *c_wallets_path = "/opt/kelvin-node/etc";
    const char *a_wallet_name_bliss = "w_bliss";
    const char *a_wallet_name_bliss2 = "w_bliss2";
    const char *a_wallet_name_picnic = "w_picnic";
    const char *a_wallet_name_tesla = "w_tesla";

    dap_chain_wallet_t *wallet_bliss = dap_chain_wallet_open(a_wallet_name_bliss, c_wallets_path);
    dap_chain_wallet_t *wallet_bliss2 = dap_chain_wallet_open(a_wallet_name_bliss2, c_wallets_path);
    dap_chain_wallet_t *wallet_picnic = dap_chain_wallet_open(a_wallet_name_picnic, c_wallets_path);
    dap_chain_wallet_t *wallet_tesla = dap_chain_wallet_open(a_wallet_name_tesla, c_wallets_path);
    dap_enc_key_t *l_key_bliss = dap_chain_wallet_get_key(wallet_bliss, 0);
    dap_enc_key_t *l_key_bliss2 = dap_chain_wallet_get_key(wallet_bliss2, 0);
    dap_enc_key_t *l_key_picnic = dap_chain_wallet_get_key(wallet_picnic, 0);
    dap_enc_key_t *l_key_tesla = dap_chain_wallet_get_key(wallet_tesla, 0);
            //"EXh66KVCxChbKHQcTWKYJXhua6HVZecpxuTTmWGuqm1V4vy5mVq52wD8rMQvfUnmJHsL4MuoJ7YVSFqn2RrdoN19mqHP1aQXSQPnXDR6oP9vsBPwYC9PhSvAxFystX";
            "EXh66KVCxChbKHQcSCRnMTByuFRDU2UsZUViPz2BoUAEYYWPfu8WhHhqX9HSyL3U3Q54JvJoKRZhRtumsAVNV6j8pzgtZDkkwzLgHBCAQHcG2FaSwCxESjkCYkgHUo";
            //"EXh66KVCxChbKHQcTeGf8TT7KhcCiiQ9TrPn6rcbNoNKuhAyJ4T9zr5yMfMCXGLVHmxVKZ6J4E9Zc7pNmAa4yrKNb3DkS34jxD6Q4MCXbHJMAPFEVtMoDdFMtCysE2";
            "EXh66KVCxChbKHQcSx27VwwbUnT2rRGNDBJm6zdC3DQw8XWtHqHrpoc9NEVd6Ub5rdFosQiXgWc5VhiNoySB6T4E49LMhMnLhr9sMSVqRr7Mix4bPrPEZXsYnNLzeX";
            //"EXh66KVCxChbKJLxZbyNJLxfF8CfGZmdenQWuqtr8MnXavhJaLo6vckjpYgpcevBo3zB65sAGQJT3ctYVwQnASc6sYyaawFHnacsrcP47PB4XfLYiEDZvwog4AVdbC";
            "EXh66KVCxChbKJLxXTwipYMooUpoGvpwpkcjpmGLbubwzqR2vVsH9HEgT2LcU2hDs2BTFkaNC8itE8nuCWxskVtRJG4iaubBDcRWAt2awtCVHAULffQGrwe8ocRCzS";
    char *addr_w_tesla =
            "EXh66KVCxChbTZ9umzb4Y6nJcMti8DPUdrsE1V4adjoKyPG3VvyrzHh6wrP6wGERLq9Qj5qK4hMEjd6uidcbsSSpzKQuADC2g1DzYkCCcitAs2Nsxk4dhespDdximc";

    dap_chain_wallet_t *l_wallet;
    dap_enc_key_t *l_key;
    if(!strcmp(addr_base58_from, addr_w_bliss)) {
        l_wallet = wallet_bliss;
        l_key = l_key_bliss;
    }
    else if(!strcmp(addr_base58_from, addr_w_bliss2)) {
        l_wallet = wallet_bliss2;
        l_key = l_key_bliss2;
    }
    else if(!strcmp(addr_base58_from, addr_w_picnic)) {
        l_wallet = wallet_picnic;
        l_key = l_key_picnic;
    }
    if(!l_wallet || !l_key) {
        set_reply_text(str_reply, "wallet for address 'from' does not exist");
        return -1;
    }

    dap_chain_addr_t *addr_from = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet);
    dap_chain_addr_t *addr_to = dap_chain_str_to_addr(addr_base58_to);
    dap_chain_addr_t *addr_fee = dap_chain_str_to_addr(addr_base58_fee);

    if(!addr_from) {
        set_reply_text(str_reply, "source address is invalid");
        return -1;
    }
    if(!addr_to) {
        set_reply_text(str_reply, "destination address is invalid");
        return -1;
    }
    if(addr_base58_fee && !addr_fee) {
        set_reply_text(str_reply, "fee address is invalid");
        return -1;
    }
    /*    dap_chain_addr_t *addr_b2 = (dap_chain_addr_t *) dap_chain_wallet_get_addr(wallet_bliss2);
     dap_chain_addr_t *addr_p = (dap_chain_addr_t *) dap_chain_wallet_get_addr(wallet_picnic);
     dap_chain_addr_t *addr_t = (dap_chain_addr_t *) dap_chain_wallet_get_addr(wallet_tesla);

     char *addr_str_b2 = dap_chain_addr_to_str((dap_chain_addr_t*) addr_b2);
     char *addr_str_p = dap_chain_addr_to_str((dap_chain_addr_t*) addr_p);
     char *addr_str_t = dap_chain_addr_to_str((dap_chain_addr_t*) addr_t);

     char *addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) addr_from);
     const dap_chain_addr_t *addr2 = dap_chain_str_to_addr(addr_str);
     char *addr_str2 = dap_chain_addr_to_str(addr2);
     int a1 = strcmp(addr_str, addr_str2);
     int a2 = strcmp(addr_str, addr_w_bliss);
     int a3 = strcmp(addr_str, addr_w_bliss2);*/

    static bool l_first_start = true;
    if(l_first_start)
    {
        const char *l_token_name = "KLVN";
        dap_enc_key_t *l_key = dap_chain_wallet_get_key(wallet_bliss, 0);
        const dap_chain_addr_t *l_addr = dap_chain_wallet_get_addr(wallet_bliss);
        dap_chain_node_datum_tx_cache_init(l_key, l_token_name, (dap_chain_addr_t*) l_addr, 1000);
        l_first_start = false;
    }
    GString *string_ret = g_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);

    uint64_t balance2 = dap_chain_datum_tx_cache_calc_balance(addr_to);
    uint64_t balance3 = dap_chain_datum_tx_cache_calc_balance(addr_fee);
    uint64_t balance1 = dap_chain_datum_tx_cache_calc_balance(addr_from);
    g_string_append_printf(string_ret, "transactions in cache=%d balance w_from=%lld w_to=%lld w_feee=%lld\n",
            dap_chain_node_datum_tx_cache_count(),
            balance1, balance2, balance3);

    int res = dap_chain_datum_tx_ctrl_create_transfer(l_key, addr_from, addr_to, addr_fee, value, value_fee);
    g_string_append_printf(string_ret, "transfer=%s\n", (res == 1) ? "Ok" : "False");

    if(1) {
        uint64_t balance1 = dap_chain_datum_tx_cache_calc_balance(addr_from);
        uint64_t balance2 = dap_chain_datum_tx_cache_calc_balance(addr_to);
        uint64_t balance3 = dap_chain_datum_tx_cache_calc_balance(addr_fee);
        g_string_append_printf(string_ret, "transactions in cache=%d balance w_from=%lld w_to=%lld w_feee=%lld\n",
                dap_chain_node_datum_tx_cache_count(),
                balance1, balance2, balance3);
    }

    char *str_ret_tmp = g_string_free(string_ret, FALSE);
    char *str_ret = strdup(str_ret_tmp);
    set_reply_text(str_reply, str_ret);
    DAP_DELETE(addr_to);
    DAP_DELETE(addr_fee);
    dap_chain_wallet_close(wallet_bliss);
    dap_chain_wallet_close(wallet_bliss2);
    dap_chain_wallet_close(wallet_picnic);
    dap_chain_wallet_close(wallet_tesla);
    return 0;
}

/**
 * com_tx_create command
 *
 * Signing transaction
 */
int com_tx_create0(int argc, const char ** argv, char **str_reply)
{
    // create wallet
    const char *a_wallets_path = "/opt/kelvin-node/etc";
    const char *a_wallet_name_bliss = "w_bliss";
    const char *a_wallet_name_bliss2 = "w_bliss2";
    const char *a_wallet_name_picnic = "w_picnic";
    const char *a_wallet_name_tesla = "w_tesla";

    dap_chain_net_id_t a_net_id = { 0x1 };
    dap_chain_sign_type_t a_sig_type = { SIG_TYPE_TESLA };
    //dap_chain_sign_type_t a_sig_type = { SIG_TYPE_PICNIC };
    //dap_chain_sign_type_t a_sig_type = { SIG_TYPE_BLISS };
    const char * a_wallet_name = a_wallet_name_tesla;
    dap_chain_wallet_t *wallet0 = dap_chain_wallet_create(a_wallet_name, a_wallets_path, a_net_id, a_sig_type);

    dap_chain_wallet_t *wallet_bliss = dap_chain_wallet_open(a_wallet_name_bliss, a_wallets_path);
    dap_chain_wallet_t *wallet_bliss2 = dap_chain_wallet_open(a_wallet_name_bliss2, a_wallets_path);
    dap_chain_wallet_t *wallet_picnic = dap_chain_wallet_open(a_wallet_name_picnic, a_wallets_path);
    dap_chain_wallet_t *wallet_tesla = dap_chain_wallet_open(a_wallet_name_tesla, a_wallets_path);
    dap_enc_key_t *l_key_bliss = dap_chain_wallet_get_key(wallet_bliss, 0);
    dap_enc_key_t *l_key_bliss2 = dap_chain_wallet_get_key(wallet_bliss2, 0);
    dap_enc_key_t *l_key_picnic = dap_chain_wallet_get_key(wallet_picnic, 0);
    dap_enc_key_t *l_key_tesla = dap_chain_wallet_get_key(wallet_tesla, 0);
    /*/ debug - test check signing
     {


     int a_data_size = 50;
     char *a_data = "DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify";

     dap_enc_key_t *l_key0 = dap_enc_key_new_generate(DAP_ENC_KEY_TYPE_SIG_BLISS, NULL, 0, NULL, 0, 0);
     dap_enc_key_t *l_key1 = dap_enc_key_new_generate(DAP_ENC_KEY_TYPE_SIG_TESLA, NULL, 0, NULL, 0, 0);
     dap_enc_key_t *l_key2 = dap_enc_key_new_generate(DAP_ENC_KEY_TYPE_SIG_PICNIC, NULL, 0, NULL, 0, 0);
     dap_enc_key_t *l_key = dap_chain_wallet_get_key(wallet, 0);

     size_t l_buflen_out;
     char *l_data;
     l_data = dap_enc_key_serealize_pub_key(l_key0, &l_buflen_out);
     dap_enc_key_deserealize_pub_key(l_key0, l_data, l_buflen_out);
     l_data = dap_enc_key_serealize_pub_key(l_key1, &l_buflen_out);
     dap_enc_key_deserealize_pub_key(l_key1, l_data, l_buflen_out);
     l_data = dap_enc_key_serealize_pub_key(l_key2, &l_buflen_out);
     dap_enc_key_deserealize_pub_key(l_key2, l_data, l_buflen_out);
     l_data = dap_enc_key_serealize_pub_key(l_key, &l_buflen_out);
     dap_enc_key_deserealize_pub_key(l_key, l_data, l_buflen_out);

     dap_chain_sign_t *l_chain_sign;
     l_chain_sign = dap_chain_sign_create(l_key0, a_data, a_data_size, 0);
     int l_size0 = dap_chain_sign_get_size(l_chain_sign);
     int l_verify0 = dap_chain_sign_verify(l_chain_sign, a_data, a_data_size);
     DAP_DELETE(l_chain_sign);
     l_chain_sign = dap_chain_sign_create(l_key1, a_data, a_data_size, 0);
     int l_size1 = dap_chain_sign_get_size(l_chain_sign);
     int l_verify1 = dap_chain_sign_verify(l_chain_sign, a_data, a_data_size);
     DAP_DELETE(l_chain_sign);
     l_chain_sign = dap_chain_sign_create(l_key2, a_data, a_data_size, 0);
     int l_size2 = dap_chain_sign_get_size(l_chain_sign);
     int l_verify2 = dap_chain_sign_verify(l_chain_sign, a_data, a_data_size);
     DAP_DELETE(l_chain_sign);
     l_chain_sign = dap_chain_sign_create(l_key, a_data, a_data_size, 0);
     int l_size = dap_chain_sign_get_size(l_chain_sign);
     int l_verify = dap_chain_sign_verify(l_chain_sign, a_data, a_data_size);
     DAP_DELETE(l_chain_sign);
     printf("verify=%d/%d %d/%d %d/%d %d/%d\n", l_size0, l_verify0, l_size1, l_verify1, l_size2, l_verify2, l_size,
     l_verify);

     dap_enc_key_delete(l_key0);
     dap_enc_key_delete(l_key1);
     dap_enc_key_delete(l_key2);
     }*/
    static bool l_first_start = true;
    if(l_first_start)
    {
        const char *l_token_name = "KLVN";
        dap_enc_key_t *l_key = dap_chain_wallet_get_key(wallet_bliss, 0);
        const dap_chain_addr_t *l_addr = dap_chain_wallet_get_addr(wallet_bliss);
        dap_chain_node_datum_tx_cache_init(l_key, l_token_name, (dap_chain_addr_t*) l_addr, 1000);
        l_first_start = false;
    }
    int res;
    // transfer from 1st transaction to addr_w_bliss
    /*    dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
     dap_chain_hash_fast_t l_tx_prev_hash = { 0 };
     uint32_t l_tx_out_prev_idx = 0;
     dap_chain_tx_in_t *l_tx_item_in = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, l_tx_out_prev_idx);
     res = dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *) l_tx_item_in);
     res = dap_chain_datum_tx_add_sign_item(&l_tx, l_key);
     res = dap_chain_node_datum_tx_cache_add(l_tx);
     DAP_DELETE(l_tx);*/

    char *addr_w_bliss =
            "EXh66KVCxChbKHQcTWKYJXhua6HVZecpxuTTmWGuqm1V4vy5mVq52wD8rMQvfUnmJHsL4MuoJ7YVSFqn2RrdoN19mqHP1aQXSQPnXDR6oP9vsBPwYC9PhSvAxFystX";
    char *addr_w_bliss2 =
            "EXh66KVCxChbKHQcTeGf8TT7KhcCiiQ9TrPn6rcbNoNKuhAyJ4T9zr5yMfMCXGLVHmxVKZ6J4E9Zc7pNmAa4yrKNb3DkS34jxD6Q4MCXbHJMAPFEVtMoDdFMtCysE2";
    char *addr_w_picnic =
            "EXh66KVCxChbKJLxZbyNJLxfF8CfGZmdenQWuqtr8MnXavhJaLo6vckjpYgpcevBo3zB65sAGQJT3ctYVwQnASc6sYyaawFHnacsrcP47PB4XfLYiEDZvwog4AVdbC";

    dap_chain_addr_t *addr_1 = (dap_chain_addr_t *) dap_chain_wallet_get_addr(wallet_bliss);
    dap_chain_addr_t *addr_2 = dap_chain_str_to_addr(addr_w_bliss2);
    dap_chain_addr_t *addr_3 = dap_chain_str_to_addr(addr_w_picnic);

    //char *addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) addr_from);
    //const dap_chain_addr_t *addr2 = dap_chain_str_to_addr(addr_str);
    //char *addr_str2 = dap_chain_addr_to_str(addr2);
    //int a = strcmp(addr_str,addr_str2);

    uint64_t balance1 = dap_chain_datum_tx_cache_calc_balance(addr_1);
    uint64_t balance2 = dap_chain_datum_tx_cache_calc_balance(addr_2);
    uint64_t balance3 = dap_chain_datum_tx_cache_calc_balance(addr_3);
    printf("transactions in cache=%d balance %lld %lld %lld\n", dap_chain_node_datum_tx_cache_count(),
            balance1, balance2, balance3);

    res = dap_chain_datum_tx_ctrl_create_transfer(l_key_bliss, addr_1, addr_2, addr_3, 100, 2);
    printf("transfer=%d\n", res);
    balance1 = dap_chain_datum_tx_cache_calc_balance(addr_1);
    balance2 = dap_chain_datum_tx_cache_calc_balance(addr_2);
    balance3 = dap_chain_datum_tx_cache_calc_balance(addr_3);
    printf("transactions in cache=%d balance %lld %lld %lld\n", dap_chain_node_datum_tx_cache_count(),
            balance1, balance2, balance3);

    res = dap_chain_datum_tx_ctrl_create_transfer(l_key_bliss2, addr_2, addr_3, addr_3, 200, 2);
    printf("transfer=%d\n", res);
    balance1 = dap_chain_datum_tx_cache_calc_balance(addr_1);
    balance2 = dap_chain_datum_tx_cache_calc_balance(addr_2);
    balance3 = dap_chain_datum_tx_cache_calc_balance(addr_3);
    printf("transactions in cache=%d balance %lld %lld %lld\n", dap_chain_node_datum_tx_cache_count(),
            balance1, balance2, balance3);

    dap_chain_wallet_close(wallet_bliss);
    dap_chain_wallet_close(wallet_bliss2);
    dap_chain_wallet_close(wallet_picnic);
    dap_chain_wallet_close(wallet_tesla);
    set_reply_text(str_reply, "com_tx_create ok");

    /*/dap_chain_datum_tx_vefify(l_tx);

     char *addr_w_tesla = "ad8VdHszE1zxS2SDFsvTsmQVBh1G7exkvPy6DiUtjzpgiGY82iMaWeP83K6Euh9fih2G3WN1E6SpfWdCfxA7yjyTu3yrw";
     char *addr_w_picnic =
     "ad8VdHszE1zx5WVKbKugtuBAimU3QT5FCnWMKKaYpMmeRwTwTNULiM7eyYiBskEG9LSN5NCp5roadQtCXe4caJqKPcWiB";
     char *addr_w_bliss = "ad8VdHszE1zx5UAFyPFYryPdMiXPMeQDL5gy6jUztE6NJsTN4idtU4xtKHkknXBYfoXQUJDUYHkL5B2QDgyisdQ715hnF";
     const dap_chain_addr_t *addr = dap_chain_wallet_get_addr(wallet);


     dap_chain_datum_tx_t *l_tx_tmp = dap_chain_node_datum_tx_cache_find_by_pkey(l_key->pub_key_data,
     l_key->pub_key_data_size, NULL);

     char *addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) addr);
     const dap_chain_addr_t *addr2 = dap_chain_str_to_addr(addr_str);
     char *addr_str2 = dap_chain_addr_to_str(addr2);
     free(addr_str);
     free(addr_str2);

     if(wallet) {
     if(dap_chain_wallet_get_certs_number(wallet) > 0) {
     dap_chain_pkey_t *pk0 = dap_chain_wallet_get_pkey(wallet, 0);
     dap_enc_key_t *a_key = dap_chain_wallet_get_key(wallet, 0);
     //dap_enc_key_t *a_key1 = dap_chain_wallet_get_key(wallet, 0);
     //dap_enc_key_t *a_key2 = dap_chain_wallet_get_key(wallet2, 0);

     int res = dap_chain_datum_tx_add_item(&l_tx, l_tx_item_in);
     int res1 = dap_chain_datum_tx_add_sign(&l_tx, a_key);
     int res2 = dap_chain_datum_tx_add_sign(&l_tx, a_key);
     int res3 = dap_chain_datum_tx_verify_sign(l_tx);
     res3 = 0;
     }
     dap_chain_wallet_close(wallet);
     DAP_DELETE(l_tx);
     }
     set_reply_text(str_reply, "com_tx_create ok");
     return 0;*/
}

/**
 * tx_verify command
 *
 * Verifing transaction
 */
int com_tx_verify(int argc, const char ** argv, char **str_reply)
{
    if(argc > 1) {
        const COMMAND *cmd = find_command(argv[1]);
        if(cmd)
        {
            if(str_reply)
                *str_reply = g_strdup(cmd->doc);
            return 1;
        }
        if(str_reply)
            set_reply_text(str_reply, "command \"%s\" not recognized", argv[1]);
        set_reply_text(str_reply, "command not defined, enter \"help <cmd name>\"");