diff options
45 files changed, 3746 insertions, 157 deletions
diff --git a/.gitignore b/.gitignore index 0bd9ba3dd..d321aa43d 100644 --- a/.gitignore +++ b/.gitignore @@ -61,6 +61,7 @@ CMakeCache.txt CMakeFiles cmake_install.cmake install_manifest.txt +cmake-build-debug/ ### Linux ### *~ diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b27c10bd..a0508adfd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -868,5 +868,9 @@ option(INSTALL_VENDORED_LIBUNBOUND "Install libunbound binary built from source CHECK_C_COMPILER_FLAG(-std=c11 HAVE_C11) +include(CheckLibraryExists) +include(CheckFunctionExists) + check_library_exists(c memset_s "string.h" HAVE_MEMSET_S) check_library_exists(c explicit_bzero "strings.h" HAVE_EXPLICIT_BZERO) +check_function_exists(strptime HAVE_STRPTIME) @@ -163,25 +163,25 @@ sources are also used for statically-linked builds because distribution packages often include only shared library binaries (`.so`) but not static library archives (`.a`). -| Dep | Min. version | Vendored | Debian/Ubuntu pkg | Arch pkg | Optional | Purpose | -| -------------- | ------------- | ---------| ------------------ | -------------- | -------- | -------------- | -| GCC | 4.7.3 | NO | `build-essential` | `base-devel` | NO | | -| CMake | 3.0.0 | NO | `cmake` | `cmake` | NO | | -| pkg-config | any | NO | `pkg-config` | `base-devel` | NO | | -| Boost | 1.58 | NO | `libboost-all-dev` | `boost` | NO | C++ libraries | -| OpenSSL | basically any | NO | `libssl-dev` | `openssl` | NO | sha256 sum | -| libzmq | 3.0.0 | NO | `libzmq3-dev` | `zeromq` | NO | ZeroMQ library | -| libunbound | 1.4.16 | YES | `libunbound-dev` | `unbound` | NO | DNS resolver | -| libsodium | ? | NO | `libsodium-dev` | ? | NO | libsodium | -| libminiupnpc | 2.0 | YES | `libminiupnpc-dev` | `miniupnpc` | YES | NAT punching | -| libunwind | any | NO | `libunwind8-dev` | `libunwind` | YES | Stack traces | -| liblzma | any | NO | `liblzma-dev` | `xz` | YES | For libunwind | -| libreadline | 6.3.0 | NO | `libreadline6-dev` | `readline` | YES | Input editing | -| ldns | 1.6.17 | NO | `libldns-dev` | `ldns` | YES | SSL toolkit | -| expat | 1.1 | NO | `libexpat1-dev` | `expat` | YES | XML parsing | -| GTest | 1.5 | YES | `libgtest-dev`^ | `gtest` | YES | Test suite | -| Doxygen | any | NO | `doxygen` | `doxygen` | YES | Documentation | -| Graphviz | any | NO | `graphviz` | `graphviz` | YES | Documentation | +| Dep | Min. version | Vendored | Debian/Ubuntu pkg | Arch pkg | Fedora | Optional | Purpose | +| ------------ | ------------- | -------- | ------------------ | ------------ | ----------------- | -------- | -------------- | +| GCC | 4.7.3 | NO | `build-essential` | `base-devel` | `gcc` | NO | | +| CMake | 3.0.0 | NO | `cmake` | `cmake` | `cmake` | NO | | +| pkg-config | any | NO | `pkg-config` | `base-devel` | `pkgconf` | NO | | +| Boost | 1.58 | NO | `libboost-all-dev` | `boost` | `boost-devel` | NO | C++ libraries | +| OpenSSL | basically any | NO | `libssl-dev` | `openssl` | `openssl-devel` | NO | sha256 sum | +| libzmq | 3.0.0 | NO | `libzmq3-dev` | `zeromq` | `cppzmq-devel` | NO | ZeroMQ library | +| libunbound | 1.4.16 | YES | `libunbound-dev` | `unbound` | `unbound-devel` | NO | DNS resolver | +| libsodium | ? | NO | `libsodium-dev` | ? | `libsodium-devel` | NO | libsodium | +| libminiupnpc | 2.0 | YES | `libminiupnpc-dev` | `miniupnpc` | `miniupnpc-devel` | YES | NAT punching | +| libunwind | any | NO | `libunwind8-dev` | `libunwind` | `libunwind-devel` | YES | Stack traces | +| liblzma | any | NO | `liblzma-dev` | `xz` | `xz-devel` | YES | For libunwind | +| libreadline | 6.3.0 | NO | `libreadline6-dev` | `readline` | `readline-devel` | YES | Input editing | +| ldns | 1.6.17 | NO | `libldns-dev` | `ldns` | `ldns-devel` | YES | SSL toolkit | +| expat | 1.1 | NO | `libexpat1-dev` | `expat` | `expat-devel` | YES | XML parsing | +| GTest | 1.5 | YES | `libgtest-dev`^ | `gtest` | `gtest-devel` | YES | Test suite | +| Doxygen | any | NO | `doxygen` | `doxygen` | `doxygen` | YES | Documentation | +| Graphviz | any | NO | `graphviz` | `graphviz` | `graphviz` | YES | Documentation | [^] On Debian/Ubuntu `libgtest-dev` only includes sources and headers. You must diff --git a/cmake/FindReadline.cmake b/cmake/FindReadline.cmake index 7a11a270a..87f8ccace 100644 --- a/cmake/FindReadline.cmake +++ b/cmake/FindReadline.cmake @@ -15,8 +15,11 @@ # # READLINE_FOUND System has readline, include and lib dirs found # GNU_READLINE_FOUND Version of readline found is GNU readline, not libedit! +# LIBEDIT_FOUND Version of readline found is libedit, not GNU readline! # Readline_INCLUDE_DIR The readline include directories. # Readline_LIBRARY The readline library. +# GNU_READLINE_LIBRARY The GNU readline library or empty string. +# LIBEDIT_LIBRARY The libedit library or empty string. find_path(Readline_ROOT_DIR NAMES include/readline/readline.h @@ -63,7 +66,6 @@ check_function_exists(rl_copy_text HAVE_COPY_TEXT) check_function_exists(rl_filename_completion_function HAVE_COMPLETION_FUNCTION) if(NOT HAVE_COMPLETION_FUNCTION) - unset(READLINE_FOUND) set(CMAKE_REQUIRED_LIBRARIES ${Readline_LIBRARY} ${Termcap_LIBRARY}) check_function_exists(rl_copy_text HAVE_COPY_TEXT_TC) check_function_exists(rl_filename_completion_function HAVE_COMPLETION_FUNCTION_TC) @@ -74,8 +76,14 @@ if(NOT HAVE_COMPLETION_FUNCTION) endif(HAVE_COMPLETION_FUNCTION) endif(NOT HAVE_COMPLETION_FUNCTION) +set(LIBEDIT_LIBRARY "") +set(GNU_READLINE_LIBRARY "") + if(HAVE_COMPLETION_FUNCTION AND HAVE_COPY_TEXT) set(GNU_READLINE_FOUND TRUE) - set(READLINE_FOUND TRUE) + set(GNU_READLINE_LIBRARY ${Readline_LIBRARY}) +elseif(READLINE_FOUND AND NOT HAVE_COPY_TEXT) + set(LIBEDIT_FOUND TRUE) + set(LIBEDIT_LIBRARY ${Readline_LIBRARY}) endif(HAVE_COMPLETION_FUNCTION AND HAVE_COPY_TEXT) diff --git a/contrib/epee/include/storages/levin_abstract_invoke2.h b/contrib/epee/include/storages/levin_abstract_invoke2.h index 8ced9d689..b4f7abca8 100644 --- a/contrib/epee/include/storages/levin_abstract_invoke2.h +++ b/contrib/epee/include/storages/levin_abstract_invoke2.h @@ -60,8 +60,7 @@ namespace epee LOG_ERROR("Failed to load_from_binary on command " << command); return false; } - result_struct.load(stg_ret); - return true; + return result_struct.load(stg_ret); } template<class t_arg, class t_transport> @@ -105,9 +104,7 @@ namespace epee LOG_ERROR("Failed to load_from_binary on command " << command); return false; } - result_struct.load(stg_ret); - - return true; + return result_struct.load(stg_ret); } template<class t_result, class t_arg, class callback_t, class t_transport> @@ -133,7 +130,12 @@ namespace epee cb(LEVIN_ERROR_FORMAT, result_struct, context); return false; } - result_struct.load(stg_ret); + if (!result_struct.load(stg_ret)) + { + LOG_ERROR("Failed to load result struct on command " << command); + cb(LEVIN_ERROR_FORMAT, result_struct, context); + return false; + } cb(code, result_struct, context); return true; }, inv_timeout); @@ -176,7 +178,11 @@ namespace epee boost::value_initialized<t_in_type> in_struct; boost::value_initialized<t_out_type> out_struct; - static_cast<t_in_type&>(in_struct).load(strg); + if (!static_cast<t_in_type&>(in_struct).load(strg)) + { + LOG_ERROR("Failed to load in_struct in command " << command); + return -1; + } int res = cb(command, static_cast<t_in_type&>(in_struct), static_cast<t_out_type&>(out_struct), context); serialization::portable_storage strg_out; static_cast<t_out_type&>(out_struct).store(strg_out); @@ -200,7 +206,11 @@ namespace epee return -1; } boost::value_initialized<t_in_type> in_struct; - static_cast<t_in_type&>(in_struct).load(strg); + if (!static_cast<t_in_type&>(in_struct).load(strg)) + { + LOG_ERROR("Failed to load in_struct in notify " << command); + return -1; + } return cb(command, in_struct, context); } diff --git a/contrib/epee/include/storages/portable_storage_val_converters.h b/contrib/epee/include/storages/portable_storage_val_converters.h index 5d9664a65..36bb28627 100644 --- a/contrib/epee/include/storages/portable_storage_val_converters.h +++ b/contrib/epee/include/storages/portable_storage_val_converters.h @@ -150,8 +150,14 @@ POP_WARNINGS else if (boost::regex_match (from, boost::regex("\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\dZ"))) { // Convert to unix timestamp +#ifdef HAVE_STRPTIME struct tm tm; if (strptime(from.c_str(), "%Y-%m-%dT%H:%M:%S", &tm)) +#else + std::tm tm = {}; + std::istringstream ss(from); + if (ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S")) +#endif to = std::mktime(&tm); } else ASSERT_AND_THROW_WRONG_CONVERSION(); diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt index 9d104ceeb..538c7ce91 100644 --- a/contrib/epee/src/CMakeLists.txt +++ b/contrib/epee/src/CMakeLists.txt @@ -64,5 +64,5 @@ if (USE_READLINE AND GNU_READLINE_FOUND) PUBLIC easylogging PRIVATE - ${Readline_LIBRARY}) + ${GNU_READLINE_LIBRARY}) endif() diff --git a/contrib/epee/src/readline_buffer.cpp b/contrib/epee/src/readline_buffer.cpp index 00c2ddd62..076a63612 100644 --- a/contrib/epee/src/readline_buffer.cpp +++ b/contrib/epee/src/readline_buffer.cpp @@ -1,7 +1,6 @@ #include "readline_buffer.h" #include <readline/readline.h> #include <readline/history.h> -#include <sys/select.h> #include <unistd.h> #include <iostream> #include <boost/thread.hpp> diff --git a/external/miniupnpc/CMakeLists.txt b/external/miniupnpc/CMakeLists.txt index bc9685699..2df8d474b 100644 --- a/external/miniupnpc/CMakeLists.txt +++ b/external/miniupnpc/CMakeLists.txt @@ -73,6 +73,13 @@ if (CMAKE_COMPILER_IS_GNUC) endif () endif() +# always add -fPIC +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") +set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fPIC") +set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fPIC") +set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fPIC") +set (CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -fPIC") + configure_file (${CMAKE_CURRENT_SOURCE_DIR}/miniupnpcstrings.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/miniupnpcstrings.h) include_directories (${CMAKE_CURRENT_BINARY_DIR}) diff --git a/external/unbound/CMakeLists.txt b/external/unbound/CMakeLists.txt index 99ef62c5a..7d4da33e2 100644 --- a/external/unbound/CMakeLists.txt +++ b/external/unbound/CMakeLists.txt @@ -50,6 +50,7 @@ else() add_definitions(-D_GNU_SOURCE) endif() add_definitions(-std=c99) +add_definitions(-fPIC) option(USE_ECDSA "Use ECDSA algorithms" ON) option(USE_SHA2 "Enable SHA2 support" ON) diff --git a/src/common/apply_permutation.h b/src/common/apply_permutation.h index 4fd952686..8684f14ce 100644 --- a/src/common/apply_permutation.h +++ b/src/common/apply_permutation.h @@ -30,6 +30,8 @@ // This algorithm is adapted from Raymond Chen's code: // https://blogs.msdn.microsoft.com/oldnewthing/20170109-00/?p=95145 +#pragma once + #include <vector> #include <functional> #include "misc_log_ex.h" diff --git a/src/common/util.cpp b/src/common/util.cpp index a4a435104..bcea70558 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -34,6 +34,8 @@ #include <gnu/libc-version.h> #endif +#include "unbound.h" + #include "include_base_utils.h" #include "file_io_utils.h" #include "wipeable_string.h" @@ -453,8 +455,7 @@ std::string get_nix_version_display_string() // namespace fs = boost::filesystem; // Windows < Vista: C:\Documents and Settings\Username\Application Data\CRYPTONOTE_NAME // Windows >= Vista: C:\Users\Username\AppData\Roaming\CRYPTONOTE_NAME - // Mac: ~/Library/Application Support/CRYPTONOTE_NAME - // Unix: ~/.CRYPTONOTE_NAME + // Unix & Mac: ~/.CRYPTONOTE_NAME std::string config_folder; #ifdef WIN32 @@ -466,15 +467,8 @@ std::string get_nix_version_display_string() pathRet = "/"; else pathRet = pszHome; -#ifdef MAC_OSX - // Mac - pathRet /= "Library/Application Support"; - config_folder = (pathRet + "/" + CRYPTONOTE_NAME); -#else - // Unix config_folder = (pathRet + "/." + CRYPTONOTE_NAME); #endif -#endif return config_folder; } @@ -522,6 +516,18 @@ std::string get_nix_version_display_string() return std::error_code(code, std::system_category()); } + static bool unbound_built_with_threads() + { + ub_ctx *ctx = ub_ctx_create(); + if (!ctx) return false; // cheat a bit, should not happen unless OOM + ub_ctx_zone_add(ctx, "monero", "unbound"); // this calls ub_ctx_finalize first, then errors out with UB_SYNTAX + // if no threads, bails out early with UB_NOERROR, otherwise fails with UB_AFTERFINAL id already finalized + bool with_threads = ub_ctx_async(ctx, 1) != 0; // UB_AFTERFINAL is not defined in public headers, check any error + ub_ctx_delete(ctx); + MINFO("libunbound was built " << (with_threads ? "with" : "without") << " threads"); + return with_threads; + } + bool sanitize_locale() { // boost::filesystem throws for "invalid" locales, such as en_US.UTF-8, or kjsdkfs, @@ -564,6 +570,9 @@ std::string get_nix_version_display_string() OPENSSL_init_ssl(0, NULL); #endif + if (!unbound_built_with_threads()) + MCLOG_RED(el::Level::Warning, "global", "libunbound was not built with threads enabled - crashes may occur"); + return true; } void set_strict_default_file_permissions(bool strict) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 4af987c3b..69288a2b7 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -2933,7 +2933,7 @@ bool Blockchain::check_fee(size_t blob_size, uint64_t fee) const needed_fee += (blob_size % 1024) ? 1 : 0; needed_fee *= fee_per_kb; - if (fee < needed_fee * 0.98) // keep a little buffer on acceptance + if (fee < needed_fee - needed_fee / 50) // keep a little 2% buffer on acceptance - no integer overflow { MERROR_VER("transaction fee is not enough: " << print_money(fee) << ", minimum fee: " << print_money(needed_fee)); return false; diff --git a/src/cryptonote_protocol/cryptonote_protocol_defs.h b/src/cryptonote_protocol/cryptonote_protocol_defs.h index fc2f4c343..a1682ef8c 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_defs.h +++ b/src/cryptonote_protocol/cryptonote_protocol_defs.h @@ -271,7 +271,7 @@ namespace cryptonote { crypto::hash block_hash; uint64_t current_blockchain_height; - std::vector<size_t> missing_tx_indices; + std::vector<uint64_t> missing_tx_indices; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE_VAL_POD_AS_BLOB(block_hash) diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 5d25d1058..700eceff3 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -273,7 +273,7 @@ namespace cryptonote { if (version < hshd.top_version) MCLOG_RED(el::Level::Warning, "global", context << " peer claims higher version that we think (" << - (unsigned)hshd.top_version << " for " << (hshd.current_height - 1) << "instead of " << (unsigned)version << + (unsigned)hshd.top_version << " for " << (hshd.current_height - 1) << " instead of " << (unsigned)version << ") - we may be forked from the network and a software upgrade may be needed"); return false; } @@ -876,6 +876,8 @@ namespace cryptonote } context.m_remote_blockchain_height = arg.current_blockchain_height; + if (context.m_remote_blockchain_height > m_core.get_target_blockchain_height()) + m_core.set_target_blockchain_height(context.m_remote_blockchain_height); std::vector<crypto::hash> block_hashes; block_hashes.reserve(arg.blocks.size()); diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index 49d3bc836..237105d06 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -102,7 +102,7 @@ target_link_libraries(daemon ${Boost_SYSTEM_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${ZMQ_LIB} - ${Readline_LIBRARY} + ${GNU_READLINE_LIBRARY} ${EXTRA_LIBRARIES}) set_property(TARGET daemon PROPERTY diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 6ac47fcb2..a47e74c71 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -269,7 +269,7 @@ int main(int argc, char const * argv[]) } else { - std::cerr << "Unknown command" << std::endl; + std::cerr << "Unknown command: " << command.front() << std::endl; return 1; } } diff --git a/src/gen_multisig/CMakeLists.txt b/src/gen_multisig/CMakeLists.txt index ff3c46862..8c534d213 100644 --- a/src/gen_multisig/CMakeLists.txt +++ b/src/gen_multisig/CMakeLists.txt @@ -43,8 +43,8 @@ target_link_libraries(gen_multisig ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY} - ${Readline_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} + ${GNU_READLINE_LIBRARY} ${EXTRA_LIBRARIES}) add_dependencies(gen_multisig version) diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 269a9ba87..f8b96d7a4 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -1062,7 +1062,10 @@ namespace nodetool max_random_index = std::min<uint64_t>(local_peers_count -1, 20); random_index = get_random_index_with_fixed_probability(max_random_index); } else { - random_index = crypto::rand<size_t>() % m_peerlist.get_gray_peers_count(); + local_peers_count = m_peerlist.get_gray_peers_count(); + if (!local_peers_count) + return false; + random_index = crypto::rand<size_t>() % local_peers_count; } CHECK_AND_ASSERT_MES(random_index < local_peers_count, false, "random_starter_index < peers_local.size() failed!!"); diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index 24ab08778..3c34a5637 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -52,6 +52,13 @@ namespace rct { return proof; } + bool verBulletproof(const Bulletproof &proof) + { + try { return bulletproof_VERIFY(proof); } + // we can get deep throws from ge_frombytes_vartime if input isn't valid + catch (...) { return false; } + } + //Borromean (c.f. gmax/andytoshi's paper) boroSig genBorromean(const key64 x, const key64 P1, const key64 P2, const bits indices) { key64 L[2], alpha; @@ -645,7 +652,7 @@ namespace rct { rv.p.rangeSigs[i] = proveRange(rv.outPk[i].mask, outSk[i].mask, amounts[i]); #ifdef DBG if (bulletproof) - CHECK_AND_ASSERT_THROW_MES(bulletproof_VERIFY(rv.p.bulletproofs[i]), "bulletproof_VERIFY failed on newly created proof"); + CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs[i]), "verBulletproof failed on newly created proof"); else CHECK_AND_ASSERT_THROW_MES(verRange(rv.outPk[i].mask, rv.p.rangeSigs[i]), "verRange failed on newly created proof"); #endif @@ -725,7 +732,7 @@ namespace rct { rv.p.rangeSigs[i] = proveRange(rv.outPk[i].mask, outSk[i].mask, outamounts[i]); #ifdef DBG if (bulletproof) - CHECK_AND_ASSERT_THROW_MES(bulletproof_VERIFY(rv.p.bulletproofs[i]), "bulletproof_VERIFY failed on newly created proof"); + CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs[i]), "verBulletproof failed on newly created proof"); else CHECK_AND_ASSERT_THROW_MES(verRange(rv.outPk[i].mask, rv.p.rangeSigs[i]), "verRange failed on newly created proof"); #endif @@ -817,7 +824,7 @@ namespace rct { for (size_t i = 0; i < rv.outPk.size(); i++) { tpool.submit(&waiter, [&, i] { if (rv.p.rangeSigs.empty()) - results[i] = bulletproof_VERIFY(rv.p.bulletproofs[i]); + results[i] = verBulletproof(rv.p.bulletproofs[i]); else results[i] = verRange(rv.outPk[i].mask, rv.p.rangeSigs[i]); }); @@ -913,7 +920,7 @@ namespace rct { for (size_t i = 0; i < rv.outPk.size(); i++) { tpool.submit(&waiter, [&, i] { if (rv.p.rangeSigs.empty()) - results[i] = bulletproof_VERIFY(rv.p.bulletproofs[i]); + results[i] = verBulletproof(rv.p.bulletproofs[i]); else results[i] = verRange(rv.outPk[i].mask, rv.p.rangeSigs[i]); }); diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index bf4371a4e..82d73728c 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -77,17 +77,25 @@ namespace cryptonote CHAIN_HTTP_TO_MAP2(connection_context); //forward http requests to uri map BEGIN_URI_MAP2() + MAP_URI_AUTO_JON2("/get_height", on_get_height, COMMAND_RPC_GET_HEIGHT) MAP_URI_AUTO_JON2("/getheight", on_get_height, COMMAND_RPC_GET_HEIGHT) + MAP_URI_AUTO_BIN2("/get_blocks.bin", on_get_blocks, COMMAND_RPC_GET_BLOCKS_FAST) MAP_URI_AUTO_BIN2("/getblocks.bin", on_get_blocks, COMMAND_RPC_GET_BLOCKS_FAST) + MAP_URI_AUTO_BIN2("/get_blocks_by_height.bin", on_get_blocks_by_height, COMMAND_RPC_GET_BLOCKS_BY_HEIGHT) MAP_URI_AUTO_BIN2("/getblocks_by_height.bin", on_get_blocks_by_height, COMMAND_RPC_GET_BLOCKS_BY_HEIGHT) + MAP_URI_AUTO_BIN2("/get_hashes.bin", on_get_hashes, COMMAND_RPC_GET_HASHES_FAST) MAP_URI_AUTO_BIN2("/gethashes.bin", on_get_hashes, COMMAND_RPC_GET_HASHES_FAST) MAP_URI_AUTO_BIN2("/get_o_indexes.bin", on_get_indexes, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES) + MAP_URI_AUTO_BIN2("/get_random_outs.bin", on_get_random_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS) MAP_URI_AUTO_BIN2("/getrandom_outs.bin", on_get_random_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS) MAP_URI_AUTO_BIN2("/get_outs.bin", on_get_outs_bin, COMMAND_RPC_GET_OUTPUTS_BIN) + MAP_URI_AUTO_BIN2("/get_random_rctouts.bin", on_get_random_rct_outs, COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS) MAP_URI_AUTO_BIN2("/getrandom_rctouts.bin", on_get_random_rct_outs, COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS) + MAP_URI_AUTO_JON2("/get_transactions", on_get_transactions, COMMAND_RPC_GET_TRANSACTIONS) MAP_URI_AUTO_JON2("/gettransactions", on_get_transactions, COMMAND_RPC_GET_TRANSACTIONS) MAP_URI_AUTO_JON2("/get_alt_blocks_hashes", on_get_alt_blocks_hashes, COMMAND_RPC_GET_ALT_BLOCKS_HASHES) MAP_URI_AUTO_JON2("/is_key_image_spent", on_is_key_image_spent, COMMAND_RPC_IS_KEY_IMAGE_SPENT) + MAP_URI_AUTO_JON2("/send_raw_transaction", on_send_raw_tx, COMMAND_RPC_SEND_RAW_TX) MAP_URI_AUTO_JON2("/sendrawtransaction", on_send_raw_tx, COMMAND_RPC_SEND_RAW_TX) MAP_URI_AUTO_JON2_IF("/start_mining", on_start_mining, COMMAND_RPC_START_MINING, !m_restricted) MAP_URI_AUTO_JON2_IF("/stop_mining", on_stop_mining, COMMAND_RPC_STOP_MINING, !m_restricted) @@ -101,6 +109,7 @@ namespace cryptonote MAP_URI_AUTO_JON2("/get_transaction_pool_hashes.bin", on_get_transaction_pool_hashes, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES) MAP_URI_AUTO_JON2("/get_transaction_pool_stats", on_get_transaction_pool_stats, COMMAND_RPC_GET_TRANSACTION_POOL_STATS) MAP_URI_AUTO_JON2_IF("/stop_daemon", on_stop_daemon, COMMAND_RPC_STOP_DAEMON, !m_restricted) + MAP_URI_AUTO_JON2("/get_info", on_get_info, COMMAND_RPC_GET_INFO) MAP_URI_AUTO_JON2("/getinfo", on_get_info, COMMAND_RPC_GET_INFO) MAP_URI_AUTO_JON2("/get_limit", on_get_limit, COMMAND_RPC_GET_LIMIT) MAP_URI_AUTO_JON2_IF("/set_limit", on_set_limit, COMMAND_RPC_SET_LIMIT, !m_restricted) @@ -110,14 +119,23 @@ namespace cryptonote MAP_URI_AUTO_JON2("/get_outs", on_get_outs, COMMAND_RPC_GET_OUTPUTS) MAP_URI_AUTO_JON2_IF("/update", on_update, COMMAND_RPC_UPDATE, !m_restricted) BEGIN_JSON_RPC_MAP("/json_rpc") + MAP_JON_RPC("get_block_count", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT) MAP_JON_RPC("getblockcount", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT) + MAP_JON_RPC_WE("on_get_block_hash", on_getblockhash, COMMAND_RPC_GETBLOCKHASH) MAP_JON_RPC_WE("on_getblockhash", on_getblockhash, COMMAND_RPC_GETBLOCKHASH) + MAP_JON_RPC_WE("get_block_template", on_getblocktemplate, COMMAND_RPC_GETBLOCKTEMPLATE) MAP_JON_RPC_WE("getblocktemplate", on_getblocktemplate, COMMAND_RPC_GETBLOCKTEMPLATE) + MAP_JON_RPC_WE("submit_block", on_submitblock, COMMAND_RPC_SUBMITBLOCK) MAP_JON_RPC_WE("submitblock", on_submitblock, COMMAND_RPC_SUBMITBLOCK) + MAP_JON_RPC_WE("get_last_block_header", on_get_last_block_header, COMMAND_RPC_GET_LAST_BLOCK_HEADER) MAP_JON_RPC_WE("getlastblockheader", on_get_last_block_header, COMMAND_RPC_GET_LAST_BLOCK_HEADER) + MAP_JON_RPC_WE("get_block_header_by_hash", on_get_block_header_by_hash, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH) MAP_JON_RPC_WE("getblockheaderbyhash", on_get_block_header_by_hash, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH) + MAP_JON_RPC_WE("get_block_header_by_height", on_get_block_header_by_height, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT) MAP_JON_RPC_WE("getblockheaderbyheight", on_get_block_header_by_height, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT) + MAP_JON_RPC_WE("get_block_headers_range", on_get_block_headers_range, COMMAND_RPC_GET_BLOCK_HEADERS_RANGE) MAP_JON_RPC_WE("getblockheadersrange", on_get_block_headers_range, COMMAND_RPC_GET_BLOCK_HEADERS_RANGE) + MAP_JON_RPC_WE("get_block", on_get_block, COMMAND_RPC_GET_BLOCK) MAP_JON_RPC_WE("getblock", on_get_block, COMMAND_RPC_GET_BLOCK) MAP_JON_RPC_WE_IF("get_connections", on_get_connections, COMMAND_RPC_GET_CONNECTIONS, !m_restricted) MAP_JON_RPC_WE("get_info", on_get_info_json, COMMAND_RPC_GET_INFO) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index ad0bff077..00b553bad 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -1653,8 +1653,8 @@ namespace cryptonote struct response { std::string status; - uint64_t limit_up; - uint64_t limit_down; + int64_t limit_up; + int64_t limit_down; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(status) diff --git a/src/rpc/zmq_server.cpp b/src/rpc/zmq_server.cpp index afdff2328..6f06f4497 100644 --- a/src/rpc/zmq_server.cpp +++ b/src/rpc/zmq_server.cpp @@ -102,7 +102,7 @@ bool ZmqServer::addTCPSocket(std::string address, std::string port) rep_socket.reset(new zmq::socket_t(context, ZMQ_REP)); - rep_socket->setsockopt(ZMQ_RCVTIMEO, DEFAULT_RPC_RECV_TIMEOUT_MS); + rep_socket->setsockopt(ZMQ_RCVTIMEO, &DEFAULT_RPC_RECV_TIMEOUT_MS, sizeof(DEFAULT_RPC_RECV_TIMEOUT_MS)); std::string bind_address = addr_prefix + address + std::string(":") + port; rep_socket->bind(bind_address.c_str()); diff --git a/src/simplewallet/CMakeLists.txt b/src/simplewallet/CMakeLists.txt index beaacf0e9..f190ada8d 100644 --- a/src/simplewallet/CMakeLists.txt +++ b/src/simplewallet/CMakeLists.txt @@ -55,8 +55,8 @@ target_link_libraries(simplewallet ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY} - ${Readline_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} + ${GNU_READLINE_LIBRARY} ${EXTRA_LIBRARIES}) set_property(TARGET simplewallet PROPERTY diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index a4d6f0c2d..b6b6da441 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -122,7 +122,7 @@ namespace const command_line::arg_descriptor<std::string> arg_electrum_seed = {"electrum-seed", sw::tr("Specify Electrum seed for wallet recovery/creation"), ""}; const command_line::arg_descriptor<bool> arg_restore_deterministic_wallet = {"restore-deterministic-wallet", sw::tr("Recover wallet using Electrum-style mnemonic seed"), false}; const command_line::arg_descriptor<bool> arg_restore_multisig_wallet = {"restore-multisig-wallet", sw::tr("Recover multisig wallet using Electrum-style mnemonic seed"), false}; - const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", sw::tr("Create non-deterministic view and spend keys"), false}; + const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", sw::tr("Generate non-deterministic view and spend keys"), false}; const command_line::arg_descriptor<bool> arg_trusted_daemon = {"trusted-daemon", sw::tr("Enable commands which rely on a trusted daemon"), false}; const command_line::arg_descriptor<bool> arg_allow_mismatched_daemon_version = {"allow-mismatched-daemon-version", sw::tr("Allow communicating with a daemon that uses a different RPC version"), false}; const command_line::arg_descriptor<uint64_t> arg_restore_height = {"restore-height", sw::tr("Restore from specific blockchain height"), 0}; @@ -1690,6 +1690,16 @@ simple_wallet::simple_wallet() boost::bind(&simple_wallet::check_spend_proof, this, _1), tr("check_spend_proof <txid> <signature_file> [<message>]"), tr("Check a signature proving that the signer generated <txid>, optionally with a challenge string <message>.")); + m_cmd_binder.set_handler("get_reserve_proof", + boost::bind(&simple_wallet::get_reserve_proof, this, _1), + tr("get_reserve_proof (all|<amount>) [<message>]"), + tr("Generate a signature proving that you own at least this much, optionally with a challenge string <message>.\n" + "If 'all' is specified, you prove the entire sum of all of your existing accounts' balances.\n" + "Otherwise, you prove the reserve of the smallest possible amount above <amount> available in your current account.")); + m_cmd_binder.set_handler("check_reserve_proof", + boost::bind(&simple_wallet::check_reserve_proof, this, _1), + tr("check_reserve_proof <address> <signature_file> [<message>]"), + tr("Check a signature proving that the owner of <address> holds at least this much, optionally with a challenge string <message>.")); m_cmd_binder.set_handler("show_transfers", boost::bind(&simple_wallet::show_transfers, this, _1), tr("show_transfers [in|out|pending|failed|pool] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]"), @@ -1770,11 +1780,11 @@ simple_wallet::simple_wallet() tr("Turn this wallet into a multisig wallet, extra step for N-1/N wallets")); m_cmd_binder.set_handler("export_multisig_info", boost::bind(&simple_wallet::export_multisig, this, _1), - tr("export_multisig <filename>"), + tr("export_multisig_info <filename>"), tr("Export multisig info for other participants")); m_cmd_binder.set_handler("import_multisig_info", boost::bind(&simple_wallet::import_multisig, this, _1), - tr("import_multisig <filename> [<filename>...]"), + tr("import_multisig_info <filename> [<filename>...]"), tr("Import multisig info from other participants")); m_cmd_binder.set_handler("sign_multisig", boost::bind(&simple_wallet::sign_multisig, this, _1), @@ -1786,7 +1796,7 @@ simple_wallet::simple_wallet() tr("Submit a signed multisig transaction from a file")); m_cmd_binder.set_handler("export_raw_multisig_tx", boost::bind(&simple_wallet::export_raw_multisig, this, _1), - tr("export_raw_multisig <filename>"), + tr("export_raw_multisig_tx <filename>"), tr("Export a signed multisig transaction to a file")); m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), @@ -3832,7 +3842,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri else { if (nblocks[0].first > m_wallet->get_confirm_backlog_threshold()) - prompt << (boost::format(tr("There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No)")) % nblocks[0].first).str(); + prompt << (boost::format(tr("There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No): ")) % nblocks[0].first).str(); } } catch (const std::exception &e) @@ -4250,7 +4260,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a print_money(total_fee); } else { - prompt << boost::format(tr("Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No)")) % + prompt << boost::format(tr("Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): ")) % print_money(total_sent) % print_money(total_fee); } @@ -4455,7 +4465,7 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_) std::ostringstream prompt; if (!print_ring_members(ptx_vector, prompt)) return true; - prompt << boost::format(tr("Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No)")) % + prompt << boost::format(tr("Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): ")) % print_money(total_sent) % print_money(total_fee); std::string accepted = input_line(prompt.str()); @@ -4547,8 +4557,6 @@ bool simple_wallet::donate(const std::vector<std::string> &args_) fail_msg_writer() << tr("usage: donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]"); return true; } - // Hardcode Monero's donation address (see #1447) - const std::string address_str = "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A"; std::string amount_str; std::string payment_id_str; // get payment id and pop @@ -4564,11 +4572,11 @@ bool simple_wallet::donate(const std::vector<std::string> &args_) amount_str = local_args.back(); local_args.pop_back(); // push back address, amount, payment id - local_args.push_back(address_str); + local_args.push_back(MONERO_DONATION_ADDR); local_args.push_back(amount_str); if (!payment_id_str.empty()) local_args.push_back(payment_id_str); - message_writer() << tr("Donating ") << amount_str << " to The Monero Project (donate.getmonero.org/44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A)."; + message_writer() << tr("Donating ") << amount_str << " to The Monero Project (donate.getmonero.org/"<< MONERO_DONATION_ADDR <<")."; transfer_new(local_args); return true; } @@ -5137,6 +5145,110 @@ bool simple_wallet::check_spend_proof(const std::vector<std::string> &args) return true; } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::get_reserve_proof(const std::vector<std::string> &args) +{ + if(args.size() != 1 && args.size() != 2) { + fail_msg_writer() << tr("usage: get_reserve_proof (all|<amount>) [<message>]"); + return true; + } + + if (m_wallet->watch_only() || m_wallet->multisig()) + { + fail_msg_writer() << tr("The reserve proof can be generated only by a full wallet"); + return true; + } + + boost::optional<std::pair<uint32_t, uint64_t>> account_minreserve; + if (args[0] != "all") + { + account_minreserve = std::pair<uint32_t, uint64_t>(); + account_minreserve->first = m_current_subaddress_account; + if (!cryptonote::parse_amount(account_minreserve->second, args[0])) + { + fail_msg_writer() << tr("amount is wrong: ") << args[0]; + return true; + } + } + + if (!try_connect_to_daemon()) + { + fail_msg_writer() << tr("failed to connect to the daemon"); + return true; + } + + if (m_wallet->ask_password() && !get_and_verify_password()) { return true; } + + LOCK_IDLE_SCOPE(); + + try + { + const std::string sig_str = m_wallet->get_reserve_proof(account_minreserve, args.size() == 2 ? args[1] : ""); + const std::string filename = "monero_reserve_proof"; + if (epee::file_io_utils::save_string_to_file(filename, sig_str)) + success_msg_writer() << tr("signature file saved to: ") << filename; + else + fail_msg_writer() << tr("failed to save signature file"); + } + catch (const std::exception &e) + { + fail_msg_writer() << e.what(); + } + return true; +} +//---------------------------------------------------------------------------------------------------- +bool simple_wallet::check_reserve_proof(const std::vector<std::string> &args) +{ + if(args.size() != 2 && args.size() != 3) { + fail_msg_writer() << tr("usage: check_reserve_proof <address> <signature_file> [<message>]"); + return true; + } + + if (!try_connect_to_daemon()) + { + fail_msg_writer() << tr("failed to connect to the daemon"); + return true; + } + + cryptonote::address_parse_info info; + if(!cryptonote::get_account_address_from_str_or_url(info, m_wallet->testnet(), args[0], oa_prompter)) + { + fail_msg_writer() << tr("failed to parse address"); + return true; + } + if (info.is_subaddress) + { + fail_msg_writer() << tr("Address must not be a subaddress"); + return true; + } + + std::string sig_str; + if (!epee::file_io_utils::load_file_to_string(args[1], sig_str)) + { + fail_msg_writer() << tr("failed to load signature file"); + return true; + } + + LOCK_IDLE_SCOPE(); + + try + { + uint64_t total, spent; + if (m_wallet->check_reserve_proof(info.address, args.size() == 3 ? args[2] : "", sig_str, total, spent)) + { + success_msg_writer() << boost::format(tr("Good signature -- total: %s, spent: %s, unspent: %s")) % print_money(total) % print_money(spent) % print_money(total - spent); + } + else + { + fail_msg_writer() << tr("Bad signature"); + } + } + catch (const std::exception& e) + { + fail_msg_writer() << e.what(); + } + return true; +} +//---------------------------------------------------------------------------------------------------- static std::string get_human_readable_timestamp(uint64_t ts) { char buffer[64]; @@ -6636,7 +6748,8 @@ int main(int argc, char* argv[]) std::vector<std::string> command = command_line::get_arg(*vm, arg_command); if (!command.empty()) { - w.process_command(command); + if (!w.process_command(command)) + fail_msg_writer() << tr("Unknown command: ") << command.front(); w.stop(); w.deinit(); } diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 024077ca1..086076be0 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -49,6 +49,8 @@ #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "wallet.simplewallet" +// Hardcode Monero's donation address (see #1447) +constexpr const char MONERO_DONATION_ADDR[] = "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A"; /*! * \namespace cryptonote @@ -170,6 +172,8 @@ namespace cryptonote bool check_tx_proof(const std::vector<std::string> &args); bool get_spend_proof(const std::vector<std::string> &args); bool check_spend_proof(const std::vector<std::string> &args); + bool get_reserve_proof(const std::vector<std::string> &args); + bool check_reserve_proof(const std::vector<std::string> &args); bool show_transfers(const std::vector<std::string> &args); bool unspent_outputs(const std::vector<std::string> &args); bool rescan_blockchain(const std::vector<std::string> &args); diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index 2d664ba15..abecabbc3 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -126,6 +126,6 @@ if (BUILD_GUI_DEPS) endif() install(TARGETS wallet_merged ARCHIVE DESTINATION ${lib_folder}) - - add_subdirectory(api) endif() + +add_subdirectory(api) diff --git a/src/wallet/api/CMakeLists.txt b/src/wallet/api/CMakeLists.txt index 26127b75c..60d6970bd 100644 --- a/src/wallet/api/CMakeLists.txt +++ b/src/wallet/api/CMakeLists.txt @@ -78,6 +78,8 @@ target_link_libraries(wallet_api PRIVATE ${EXTRA_LIBRARIES}) +set_property(TARGET wallet_api PROPERTY EXCLUDE_FROM_ALL TRUE) +set_property(TARGET obj_wallet_api PROPERTY EXCLUDE_FROM_ALL TRUE) if(IOS) set(lib_folder lib-${ARCH}) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index fd0b65866..f96640d6e 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1576,6 +1576,55 @@ bool WalletImpl::checkSpendProof(const std::string &txid_str, const std::string } } +std::string WalletImpl::getReserveProof(bool all, uint32_t account_index, uint64_t amount, const std::string &message) const { + try + { + m_status = Status_Ok; + boost::optional<std::pair<uint32_t, uint64_t>> account_minreserve; + if (!all) + { + account_minreserve = std::make_pair(account_index, amount); + } + return m_wallet->get_reserve_proof(account_minreserve, message); + } + catch (const std::exception &e) + { + m_status = Status_Error; + m_errorString = e.what(); + return ""; + } +} + +bool WalletImpl::checkReserveProof(const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &total, uint64_t &spent) const { + cryptonote::address_parse_info info; + if (!cryptonote::get_account_address_from_str(info, m_wallet->testnet(), address)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse address"); + return false; + } + if (info.is_subaddress) + { + m_status = Status_Error; + m_errorString = tr("Address must not be a subaddress"); + return false; + } + + good = false; + try + { + m_status = Status_Ok; + good = m_wallet->check_reserve_proof(info.address, message, signature, total, spent); + return true; + } + catch (const std::exception &e) + { + m_status = Status_Error; + m_errorString = e.what(); + return false; + } +} + std::string WalletImpl::signMessage(const std::string &message) { return m_wallet->sign(message); diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 01359ffc6..0b9fc851b 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -142,6 +142,8 @@ public: virtual bool checkTxProof(const std::string &txid, const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &received, bool &in_pool, uint64_t &confirmations); virtual std::string getSpendProof(const std::string &txid, const std::string &message) const; virtual bool checkSpendProof(const std::string &txid, const std::string &message, const std::string &signature, bool &good) const; + virtual std::string getReserveProof(bool all, uint32_t account_index, uint64_t amount, const std::string &message) const; + virtual bool checkReserveProof(const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &total, uint64_t &spent) const; virtual std::string signMessage(const std::string &message); virtual bool verifySignedMessage(const std::string &message, const std::string &address, const std::string &signature) const; virtual void startRefresh(); diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index ab1a48d6e..acecbb9dd 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -706,6 +706,12 @@ struct Wallet virtual bool checkTxProof(const std::string &txid, const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &received, bool &in_pool, uint64_t &confirmations) = 0; virtual std::string getSpendProof(const std::string &txid, const std::string &message) const = 0; virtual bool checkSpendProof(const std::string &txid, const std::string &message, const std::string &signature, bool &good) const = 0; + /*! + * \brief getReserveProof - Generates a proof that proves the reserve of unspent funds + * Parameters `account_index` and `amount` are ignored when `all` is true + */ + virtual std::string getReserveProof(bool all, uint32_t account_index, uint64_t amount, const std::string &message) const = 0; + virtual bool checkReserveProof(const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &total, uint64_t &spent) const = 0; /* * \brief signMessage - sign a message with the spend private key diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 2c0aa36ef..0c2b7e984 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -357,7 +357,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, const bool deprecated_wallet = restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) || crypto::ElectrumWords::get_is_old_style_seed(field_seed)); THROW_WALLET_EXCEPTION_IF(deprecated_wallet, tools::error::wallet_internal_error, - tools::wallet2::tr("Cannot create deprecated wallets from JSON")); + tools::wallet2::tr("Cannot generate deprecated wallets from JSON")); wallet.reset(make_basic(vm, opts, password_prompter).release()); wallet->set_refresh_from_block_height(field_scan_from_height); @@ -544,8 +544,7 @@ crypto::hash8 get_short_payment_id(const tools::wallet2::pending_tx &ptx) { crypto::hash8 payment_id8 = null_hash8; std::vector<tx_extra_field> tx_extra_fields; - if(!parse_tx_extra(ptx.tx.extra, tx_extra_fields)) - return payment_id8; + parse_tx_extra(ptx.tx.extra, tx_extra_fields); // ok if partially parsed cryptonote::tx_extra_nonce extra_nonce; if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce)) { @@ -1460,14 +1459,12 @@ void wallet2::process_outgoing(const crypto::hash &txid, const cryptonote::trans entry.first->second.m_change = received; std::vector<tx_extra_field> tx_extra_fields; - if(parse_tx_extra(tx.extra, tx_extra_fields)) + parse_tx_extra(tx.extra, tx_extra_fields); // ok if partially parsed + tx_extra_nonce extra_nonce; + if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce)) { - tx_extra_nonce extra_nonce; - if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce)) - { - // we do not care about failure here - get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, entry.first->second.m_payment_id); - } + // we do not care about failure here + get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, entry.first->second.m_payment_id); } entry.first->second.m_subaddr_account = subaddr_account; entry.first->second.m_subaddr_indices = subaddr_indices; @@ -2983,6 +2980,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& cryptonote::block b; generate_genesis(b); m_blockchain.push_back(get_block_hash(b)); + add_subaddress_account(tr("Primary account")); if (!wallet_.empty()) store(); @@ -4239,8 +4237,7 @@ std::vector<std::vector<cryptonote::tx_destination_entry>> split_amounts( crypto::hash wallet2::get_payment_id(const pending_tx &ptx) const { std::vector<tx_extra_field> tx_extra_fields; - if(!parse_tx_extra(ptx.tx.extra, tx_extra_fields)) - return crypto::null_hash; + parse_tx_extra(ptx.tx.extra, tx_extra_fields); // ok if partially parsed tx_extra_nonce extra_nonce; crypto::hash payment_id = null_hash; if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce)) @@ -7947,6 +7944,251 @@ bool wallet2::check_tx_proof(const crypto::hash &txid, const cryptonote::account return false; } +std::string wallet2::get_reserve_proof(const boost::optional<std::pair<uint32_t, uint64_t>> &account_minreserve, const std::string &message) +{ + THROW_WALLET_EXCEPTION_IF(m_watch_only || m_multisig, error::wallet_internal_error, "Reserve proof can only be generated by a full wallet"); + THROW_WALLET_EXCEPTION_IF(balance_all() == 0, error::wallet_internal_error, "Zero balance"); + THROW_WALLET_EXCEPTION_IF(account_minreserve && balance(account_minreserve->first) < account_minreserve->second, error::wallet_internal_error, + "Not enough balance in this account for the requested minimum reserve amount"); + + // determine which outputs to include in the proof + std::vector<size_t> selected_transfers; + for (size_t i = 0; i < m_transfers.size(); ++i) + { + const transfer_details &td = m_transfers[i]; + if (!td.m_spent && (!account_minreserve || account_minreserve->first == td.m_subaddr_index.major)) + selected_transfers.push_back(i); + } + + if (account_minreserve) + { + // minimize the number of outputs included in the proof, by only picking the N largest outputs that can cover the requested min reserve amount + std::sort(selected_transfers.begin(), selected_transfers.end(), [&](const size_t a, const size_t b) + { return m_transfers[a].amount() > m_transfers[b].amount(); }); + while (selected_transfers.size() >= 2 && m_transfers[selected_transfers[1]].amount() >= account_minreserve->second) + selected_transfers.erase(selected_transfers.begin()); + size_t sz = 0; + uint64_t total = 0; + while (total < account_minreserve->second) + { + total += m_transfers[selected_transfers[sz]].amount(); + ++sz; + } + selected_transfers.resize(sz); + } + + // compute signature prefix hash + std::string prefix_data = message; + prefix_data.append((const char*)&m_account.get_keys().m_account_address, sizeof(cryptonote::account_public_address)); + for (size_t i = 0; i < selected_transfers.size(); ++i) + { + prefix_data.append((const char*)&m_transfers[selected_transfers[i]].m_key_image, sizeof(crypto::key_image)); + } + crypto::hash prefix_hash; + crypto::cn_fast_hash(prefix_data.data(), prefix_data.size(), prefix_hash); + + // generate proof entries + std::vector<reserve_proof_entry> proofs(selected_transfers.size()); + std::unordered_set<cryptonote::subaddress_index> subaddr_indices = { {0,0} }; + for (size_t i = 0; i < selected_transfers.size(); ++i) + { + const transfer_details &td = m_transfers[selected_transfers[i]]; + reserve_proof_entry& proof = proofs[i]; + proof.txid = td.m_txid; + proof.index_in_tx = td.m_internal_output_index; + proof.key_image = td.m_key_image; + subaddr_indices.insert(td.m_subaddr_index); + + // get tx pub key + const crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(td.m_tx, td.m_pk_index); + THROW_WALLET_EXCEPTION_IF(tx_pub_key == crypto::null_pkey, error::wallet_internal_error, "The tx public key isn't found"); + const std::vector<crypto::public_key> additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(td.m_tx); + + // determine which tx pub key was used for deriving the output key + const crypto::public_key *tx_pub_key_used = &tx_pub_key; + for (int i = 0; i < 2; ++i) + { + proof.shared_secret = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(*tx_pub_key_used), rct::sk2rct(m_account.get_keys().m_view_secret_key))); + crypto::key_derivation derivation; + THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(proof.shared_secret, rct::rct2sk(rct::I), derivation), + error::wallet_internal_error, "Failed to generate key derivation"); + crypto::public_key subaddress_spendkey; + THROW_WALLET_EXCEPTION_IF(!derive_subaddress_public_key(td.get_public_key(), derivation, proof.index_in_tx, subaddress_spendkey), + error::wallet_internal_error, "Failed to derive subaddress public key"); + if (m_subaddresses.count(subaddress_spendkey) == 1) + break; + THROW_WALLET_EXCEPTION_IF(additional_tx_pub_keys.empty(), error::wallet_internal_error, + "Normal tx pub key doesn't derive the expected output, while the additional tx pub keys are empty"); + THROW_WALLET_EXCEPTION_IF(i == 1, error::wallet_internal_error, + "Neither normal tx pub key nor additional tx pub key derive the expected output key"); + tx_pub_key_used = &additional_tx_pub_keys[proof.index_in_tx]; + } + + // generate signature for shared secret + crypto::generate_tx_proof(prefix_hash, m_account.get_keys().m_account_address.m_view_public_key, *tx_pub_key_used, boost::none, proof.shared_secret, m_account.get_keys().m_view_secret_key, proof.shared_secret_sig); + + // derive ephemeral secret key + crypto::key_image ki; + cryptonote::keypair ephemeral; + const bool r = cryptonote::generate_key_image_helper(m_account.get_keys(), m_subaddresses, td.get_public_key(), tx_pub_key, additional_tx_pub_keys, td.m_internal_output_index, ephemeral, ki); + THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key image"); + THROW_WALLET_EXCEPTION_IF(ephemeral.pub != td.get_public_key(), error::wallet_internal_error, "Derived public key doesn't agree with the stored one"); + + // generate signature for key image + const std::vector<const crypto::public_key*> pubs = { &ephemeral.pub }; + crypto::generate_ring_signature(prefix_hash, td.m_key_image, &pubs[0], 1, ephemeral.sec, 0, &proof.key_image_sig); + } + + // collect all subaddress spend keys that received those outputs and generate their signatures + std::unordered_map<crypto::public_key, crypto::signature> subaddr_spendkeys; + for (const cryptonote::subaddress_index &index : subaddr_indices) + { + crypto::secret_key subaddr_spend_skey = m_account.get_keys().m_spend_secret_key; + if (!index.is_zero()) + { + crypto::secret_key m = cryptonote::get_subaddress_secret_key(m_account.get_keys().m_view_secret_key, index); + crypto::secret_key tmp = subaddr_spend_skey; + sc_add((unsigned char*)&subaddr_spend_skey, (unsigned char*)&m, (unsigned char*)&tmp); + } + crypto::public_key subaddr_spend_pkey; + secret_key_to_public_key(subaddr_spend_skey, subaddr_spend_pkey); + crypto::generate_signature(prefix_hash, subaddr_spend_pkey, subaddr_spend_skey, subaddr_spendkeys[subaddr_spend_pkey]); + } + + // serialize & encode + std::ostringstream oss; + boost::archive::portable_binary_oarchive ar(oss); + ar << proofs << subaddr_spendkeys; + return "ReserveProofV1" + tools::base58::encode(oss.str()); +} + +bool wallet2::check_reserve_proof(const cryptonote::account_public_address &address, const std::string &message, const std::string &sig_str, uint64_t &total, uint64_t &spent) +{ + uint32_t rpc_version; + THROW_WALLET_EXCEPTION_IF(!check_connection(&rpc_version), error::wallet_internal_error, "Failed to connect to daemon: " + get_daemon_address()); + THROW_WALLET_EXCEPTION_IF(rpc_version < MAKE_CORE_RPC_VERSION(1, 0), error::wallet_internal_error, "Daemon RPC version is too old"); + + static constexpr char header[] = "ReserveProofV1"; + THROW_WALLET_EXCEPTION_IF(!boost::string_ref{sig_str}.starts_with(header), error::wallet_internal_error, + "Signature header check error"); + + std::string sig_decoded; + THROW_WALLET_EXCEPTION_IF(!tools::base58::decode(sig_str.substr(std::strlen(header)), sig_decoded), error::wallet_internal_error, + "Signature decoding error"); + + std::istringstream iss(sig_decoded); + boost::archive::portable_binary_iarchive ar(iss); + std::vector<reserve_proof_entry> proofs; + std::unordered_map<crypto::public_key, crypto::signature> subaddr_spendkeys; + ar >> proofs >> subaddr_spendkeys; + + THROW_WALLET_EXCEPTION_IF(subaddr_spendkeys.count(address.m_spend_public_key) == 0, error::wallet_internal_error, + "The given address isn't found in the proof"); + + // compute signature prefix hash + std::string prefix_data = message; + prefix_data.append((const char*)&address, sizeof(cryptonote::account_public_address)); + for (size_t i = 0; i < proofs.size(); ++i) + { + prefix_data.append((const char*)&proofs[i].key_image, sizeof(crypto::key_image)); + } + crypto::hash prefix_hash; + crypto::cn_fast_hash(prefix_data.data(), prefix_data.size(), prefix_hash); + + // fetch txes from daemon + COMMAND_RPC_GET_TRANSACTIONS::request gettx_req; + COMMAND_RPC_GET_TRANSACTIONS::response gettx_res; + for (size_t i = 0; i < proofs.size(); ++i) + gettx_req.txs_hashes.push_back(epee::string_tools::pod_to_hex(proofs[i].txid)); + m_daemon_rpc_mutex.lock(); + bool ok = net_utils::invoke_http_json("/gettransactions", gettx_req, gettx_res, m_http_client); + m_daemon_rpc_mutex.unlock(); + THROW_WALLET_EXCEPTION_IF(!ok || gettx_res.txs.size() != proofs.size(), + error::wallet_internal_error, "Failed to get transaction from daemon"); + + // check spent status + COMMAND_RPC_IS_KEY_IMAGE_SPENT::request kispent_req; + COMMAND_RPC_IS_KEY_IMAGE_SPENT::response kispent_res; + for (size_t i = 0; i < proofs.size(); ++i) + kispent_req.key_images.push_back(epee::string_tools::pod_to_hex(proofs[i].key_image)); + m_daemon_rpc_mutex.lock(); + ok = epee::net_utils::invoke_http_json("/is_key_image_spent", kispent_req, kispent_res, m_http_client, rpc_timeout); + m_daemon_rpc_mutex.unlock(); + THROW_WALLET_EXCEPTION_IF(!ok || kispent_res.spent_status.size() != proofs.size(), + error::wallet_internal_error, "Failed to get key image spent status from daemon"); + + total = spent = 0; + for (size_t i = 0; i < proofs.size(); ++i) + { + const reserve_proof_entry& proof = proofs[i]; + THROW_WALLET_EXCEPTION_IF(gettx_res.txs[i].in_pool, error::wallet_internal_error, "Tx is unconfirmed"); + + cryptonote::blobdata tx_data; + ok = string_tools::parse_hexstr_to_binbuff(gettx_res.txs[i].as_hex, tx_data); + THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to parse transaction from daemon"); + + crypto::hash tx_hash, tx_prefix_hash; + cryptonote::transaction tx; + THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(tx_data, tx, tx_hash, tx_prefix_hash), error::wallet_internal_error, + "Failed to validate transaction from daemon"); + THROW_WALLET_EXCEPTION_IF(tx_hash != proof.txid, error::wallet_internal_error, "Failed to get the right transaction from daemon"); + + THROW_WALLET_EXCEPTION_IF(proof.index_in_tx >= tx.vout.size(), error::wallet_internal_error, "index_in_tx is out of bound"); + + const cryptonote::txout_to_key* const out_key = boost::get<cryptonote::txout_to_key>(std::addressof(tx.vout[proof.index_in_tx].target)); + THROW_WALLET_EXCEPTION_IF(!out_key, error::wallet_internal_error, "Output key wasn't found") + + // get tx pub key + const crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx); + THROW_WALLET_EXCEPTION_IF(tx_pub_key == crypto::null_pkey, error::wallet_internal_error, "The tx public key isn't found"); + const std::vector<crypto::public_key> additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(tx); + + // check singature for shared secret + ok = crypto::check_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, boost::none, proof.shared_secret, proof.shared_secret_sig); + if (!ok && additional_tx_pub_keys.size() == tx.vout.size()) + ok = crypto::check_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[proof.index_in_tx], boost::none, proof.shared_secret, proof.shared_secret_sig); + if (!ok) + return false; + + // check signature for key image + const std::vector<const crypto::public_key*> pubs = { &out_key->key }; + ok = crypto::check_ring_signature(prefix_hash, proof.key_image, &pubs[0], 1, &proof.key_image_sig); + if (!ok) + return false; + + // check if the address really received the fund + crypto::key_derivation derivation; + THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(proof.shared_secret, rct::rct2sk(rct::I), derivation), error::wallet_internal_error, "Failed to generate key derivation"); + crypto::public_key subaddr_spendkey; + crypto::derive_subaddress_public_key(out_key->key, derivation, proof.index_in_tx, subaddr_spendkey); + THROW_WALLET_EXCEPTION_IF(subaddr_spendkeys.count(subaddr_spendkey) == 0, error::wallet_internal_error, + "The address doesn't seem to have received the fund"); + + // check amount + uint64_t amount = tx.vout[proof.index_in_tx].amount; + if (amount == 0) + { + // decode rct + crypto::secret_key shared_secret; + crypto::derivation_to_scalar(derivation, proof.index_in_tx, shared_secret); + rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[proof.index_in_tx]; + rct::ecdhDecode(ecdh_info, rct::sk2rct(shared_secret)); + amount = rct::h2d(ecdh_info.amount); + } + total += amount; + if (kispent_res.spent_status[i]) + spent += amount; + } + + // check signatures for all subaddress spend keys + for (const auto &i : subaddr_spendkeys) + { + if (!crypto::check_signature(prefix_hash, i.first, i.second)) + return false; + } + return true; +} + std::string wallet2::get_wallet_file() const { return m_wallet_file; @@ -8637,11 +8879,8 @@ size_t wallet2::import_outputs(const std::vector<tools::wallet2::transfer_detail // the hot wallet wouldn't have known about key images (except if we already exported them) cryptonote::keypair in_ephemeral; - std::vector<tx_extra_field> tx_extra_fields; THROW_WALLET_EXCEPTION_IF(td.m_tx.vout.empty(), error::wallet_internal_error, "tx with no outputs at index " + boost::lexical_cast<std::string>(i)); - THROW_WALLET_EXCEPTION_IF(!parse_tx_extra(td.m_tx.extra, tx_extra_fields), error::wallet_internal_error, - "Transaction extra has unsupported format at index " + boost::lexical_cast<std::string>(i)); crypto::public_key tx_pub_key = get_tx_pub_key_from_received_outs(td); const std::vector<crypto::public_key> additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(td.m_tx); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 2fbe05f89..04d789f18 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -433,6 +433,16 @@ namespace tools bool m_is_subaddress; }; + struct reserve_proof_entry + { + crypto::hash txid; + uint64_t index_in_tx; + crypto::public_key shared_secret; + crypto::key_image key_image; + crypto::signature shared_secret_sig; + crypto::signature key_image_sig; + }; + typedef std::tuple<uint64_t, crypto::public_key, rct::key> get_outs_entry; /*! @@ -836,6 +846,26 @@ namespace tools std::string get_spend_proof(const crypto::hash &txid, const std::string &message); bool check_spend_proof(const crypto::hash &txid, const std::string &message, const std::string &sig_str); + + /*! + * \brief Generates a proof that proves the reserve of unspent funds + * \param account_minreserve When specified, collect outputs only belonging to the given account and prove the smallest reserve above the given amount + * When unspecified, proves for all unspent outputs across all accounts + * \param message Arbitrary challenge message to be signed together + * \return Signature string + */ + std::string get_reserve_proof(const boost::optional<std::pair<uint32_t, uint64_t>> &account_minreserve, const std::string &message); + /*! + * \brief Verifies a proof of reserve + * \param address The signer's address + * \param message Challenge message used for signing + * \param sig_str Signature string + * \param total [OUT] the sum of funds included in the signature + * \param spent [OUT] the sum of spent funds included in the signature + * \return true if the signature verifies correctly + */ + bool check_reserve_proof(const cryptonote::account_public_address &address, const std::string &message, const std::string &sig_str, uint64_t &total, uint64_t &spent); + /*! * \brief GUI Address book get/store */ @@ -1119,6 +1149,7 @@ BOOST_CLASS_VERSION(tools::wallet2::pool_payment_details, 1) BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 7) BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 5) BOOST_CLASS_VERSION(tools::wallet2::address_book_row, 17) +BOOST_CLASS_VERSION(tools::wallet2::reserve_proof_entry, 0) BOOST_CLASS_VERSION(tools::wallet2::unsigned_tx_set, 0) BOOST_CLASS_VERSION(tools::wallet2::signed_tx_set, 0) BOOST_CLASS_VERSION(tools::wallet2::tx_construction_data, 2) @@ -1402,6 +1433,17 @@ namespace boost } template <class Archive> + inline void serialize(Archive& a, tools::wallet2::reserve_proof_entry& x, const boost::serialization::version_type ver) + { + a & x.txid; + a & x.index_in_tx; + a & x.shared_secret; + a & x.key_image; + a & x.shared_secret_sig; + a & x.key_image_sig; + } + + template <class Archive> inline void serialize(Archive &a, tools::wallet2::unsigned_tx_set &x, const boost::serialization::version_type ver) { a & x.txes; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index fc2c43c04..3bb69f2be 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -258,6 +258,7 @@ namespace tools entry.note = m_wallet->get_tx_note(pd.m_tx_hash); entry.type = "in"; entry.subaddr_index = pd.m_subaddr_index; + entry.address = m_wallet->get_subaddress_as_str(pd.m_subaddr_index); } //------------------------------------------------------------------------------------------------------------------------------ void wallet_rpc_server::fill_transfer_entry(tools::wallet_rpc::transfer_entry &entry, const crypto::hash &txid, const tools::wallet2::confirmed_transfer_details &pd) @@ -283,6 +284,7 @@ namespace tools entry.type = "out"; entry.subaddr_index = { pd.m_subaddr_account, 0 }; + entry.address = m_wallet->get_subaddress_as_str({pd.m_subaddr_account, 0}); } //------------------------------------------------------------------------------------------------------------------------------ void wallet_rpc_server::fill_transfer_entry(tools::wallet_rpc::transfer_entry &entry, const crypto::hash &txid, const tools::wallet2::unconfirmed_transfer_details &pd) @@ -301,6 +303,7 @@ namespace tools entry.note = m_wallet->get_tx_note(txid); entry.type = is_failed ? "failed" : "pending"; entry.subaddr_index = { pd.m_subaddr_account, 0 }; + entry.address = m_wallet->get_subaddress_as_str({pd.m_subaddr_account, 0}); } //------------------------------------------------------------------------------------------------------------------------------ void wallet_rpc_server::fill_transfer_entry(tools::wallet_rpc::transfer_entry &entry, const crypto::hash &payment_id, const tools::wallet2::pool_payment_details &ppd) @@ -319,6 +322,7 @@ namespace tools entry.double_spend_seen = ppd.m_double_spend_seen; entry.type = "pool"; entry.subaddr_index = pd.m_subaddr_index; + entry.address = m_wallet->get_subaddress_as_str(pd.m_subaddr_index); } //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_getbalance(const wallet_rpc::COMMAND_RPC_GET_BALANCE::request& req, wallet_rpc::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er) @@ -1721,6 +1725,66 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_get_reserve_proof(const wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::response& res, epee::json_rpc::error& er) + { + if (!m_wallet) return not_open(er); + + boost::optional<std::pair<uint32_t, uint64_t>> account_minreserve; + if (!req.all) + { + if (req.account_index >= m_wallet->get_num_subaddress_accounts()) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "Account index is out of bound"; + return false; + } + account_minreserve = std::make_pair(req.account_index, req.amount); + } + + try + { + res.signature = m_wallet->get_reserve_proof(account_minreserve, req.message); + } + catch (const std::exception &e) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = e.what(); + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_check_reserve_proof(const wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::response& res, epee::json_rpc::error& er) + { + if (!m_wallet) return not_open(er); + + cryptonote::address_parse_info info; + if (!get_account_address_from_str(info, m_wallet->testnet(), req.address)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + er.message = "Invalid address"; + return false; + } + if (info.is_subaddress) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "Address must not be a subaddress"; + return false; + } + + try + { + res.good = m_wallet->check_reserve_proof(info.address, req.message, req.signature, res.total, res.spent); + } + catch (const std::exception &e) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = e.what(); + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_get_transfers(const wallet_rpc::COMMAND_RPC_GET_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFERS::response& res, epee::json_rpc::error& er) { if (!m_wallet) return not_open(er); diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 88f2a85a4..a70d8626e 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -67,6 +67,8 @@ namespace tools BEGIN_URI_MAP2() BEGIN_JSON_RPC_MAP("/json_rpc") + MAP_JON_RPC_WE("get_balance", on_getbalance, wallet_rpc::COMMAND_RPC_GET_BALANCE) + MAP_JON_RPC_WE("get_address", on_getaddress, wallet_rpc::COMMAND_RPC_GET_ADDRESS) MAP_JON_RPC_WE("getbalance", on_getbalance, wallet_rpc::COMMAND_RPC_GET_BALANCE) MAP_JON_RPC_WE("getaddress", on_getaddress, wallet_rpc::COMMAND_RPC_GET_ADDRESS) MAP_JON_RPC_WE("create_address", on_create_address, wallet_rpc::COMMAND_RPC_CREATE_ADDRESS) @@ -78,6 +80,7 @@ namespace tools MAP_JON_RPC_WE("tag_accounts", on_tag_accounts, wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS) MAP_JON_RPC_WE("untag_accounts", on_untag_accounts, wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS) MAP_JON_RPC_WE("set_account_tag_description", on_set_account_tag_description, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION) + MAP_JON_RPC_WE("get_height", on_getheight, wallet_rpc::COMMAND_RPC_GET_HEIGHT) MAP_JON_RPC_WE("getheight", on_getheight, wallet_rpc::COMMAND_RPC_GET_HEIGHT) MAP_JON_RPC_WE("transfer", on_transfer, wallet_rpc::COMMAND_RPC_TRANSFER) MAP_JON_RPC_WE("transfer_split", on_transfer_split, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT) @@ -104,6 +107,8 @@ namespace tools MAP_JON_RPC_WE("check_tx_proof", on_check_tx_proof, wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF) MAP_JON_RPC_WE("get_spend_proof", on_get_spend_proof, wallet_rpc::COMMAND_RPC_GET_SPEND_PROOF) MAP_JON_RPC_WE("check_spend_proof", on_check_spend_proof, wallet_rpc::COMMAND_RPC_CHECK_SPEND_PROOF) + MAP_JON_RPC_WE("get_reserve_proof", on_get_reserve_proof, wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF) + MAP_JON_RPC_WE("check_reserve_proof", on_check_reserve_proof, wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF) MAP_JON_RPC_WE("get_transfers", on_get_transfers, wallet_rpc::COMMAND_RPC_GET_TRANSFERS) MAP_JON_RPC_WE("get_transfer_by_txid", on_get_transfer_by_txid, wallet_rpc::COMMAND_RPC_GET_TRANSFER_BY_TXID) MAP_JON_RPC_WE("sign", on_sign, wallet_rpc::COMMAND_RPC_SIGN) @@ -170,6 +175,8 @@ namespace tools bool on_check_tx_proof(const wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::response& res, epee::json_rpc::error& er); bool on_get_spend_proof(const wallet_rpc::COMMAND_RPC_GET_SPEND_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_SPEND_PROOF::response& res, epee::json_rpc::error& er); bool on_check_spend_proof(const wallet_rpc::COMMAND_RPC_CHECK_SPEND_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_SPEND_PROOF::response& res, epee::json_rpc::error& er); + bool on_get_reserve_proof(const wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::response& res, epee::json_rpc::error& er); + bool on_check_reserve_proof(const wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::response& res, epee::json_rpc::error& er); bool on_get_transfers(const wallet_rpc::COMMAND_RPC_GET_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFERS::response& res, epee::json_rpc::error& er); bool on_get_transfer_by_txid(const wallet_rpc::COMMAND_RPC_GET_TRANSFER_BY_TXID::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFER_BY_TXID::response& res, epee::json_rpc::error& er); bool on_sign(const wallet_rpc::COMMAND_RPC_SIGN::request& req, wallet_rpc::COMMAND_RPC_SIGN::response& res, epee::json_rpc::error& er); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index d797af5c1..ac25e8e84 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -1114,6 +1114,7 @@ namespace wallet_rpc std::string type; uint64_t unlock_time; cryptonote::subaddress_index subaddr_index; + std::string address; bool double_spend_seen; BEGIN_KV_SERIALIZE_MAP() @@ -1128,6 +1129,7 @@ namespace wallet_rpc KV_SERIALIZE(type); KV_SERIALIZE(unlock_time) KV_SERIALIZE(subaddr_index); + KV_SERIALIZE(address); KV_SERIALIZE(double_spend_seen) END_KV_SERIALIZE_MAP() }; @@ -1180,6 +1182,62 @@ namespace wallet_rpc }; }; + struct COMMAND_RPC_GET_RESERVE_PROOF + { + struct request + { + bool all; + uint32_t account_index; // ignored when `all` is true + uint64_t amount; // ignored when `all` is true + std::string message; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(all) + KV_SERIALIZE(account_index) + KV_SERIALIZE(amount) + KV_SERIALIZE(message) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string signature; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_RPC_CHECK_RESERVE_PROOF + { + struct request + { + std::string address; + std::string message; + std::string signature; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(message) + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + bool good; + uint64_t total; + uint64_t spent; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(good) + KV_SERIALIZE(total) + KV_SERIALIZE(spent) + END_KV_SERIALIZE_MAP() + }; + }; + struct COMMAND_RPC_GET_TRANSFERS { struct request diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index 2f3ce289d..51061dd6f 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -28,7 +28,10 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers +#include <boost/regex.hpp> + #include "common/util.h" +#include "common/command_line.h" #include "performance_tests.h" #include "performance_utils.h" @@ -47,6 +50,28 @@ #include "subaddress_expand.h" #include "sc_reduce32.h" #include "cn_fast_hash.h" +#include "rct_mlsag.h" + +namespace po = boost::program_options; + +std::string glob_to_regex(const std::string &val) +{ + std::string newval; + + bool escape = false; + for (char c: val) + { + if (c == '*') + newval += escape ? "*" : ".*"; + else if (c == '?') + newval += escape ? "?" : "."; + else if (c == '\\') + newval += '\\', escape = !escape; + else + newval += c; + } + return newval; +} int main(int argc, char** argv) { @@ -57,67 +82,92 @@ int main(int argc, char** argv) mlog_configure(mlog_get_default_log_path("performance_tests.log"), true); mlog_set_log_level(0); + po::options_description desc_options("Command line options"); + const command_line::arg_descriptor<std::string> arg_filter = { "filter", "Regular expression filter for which tests to run" }; + command_line::add_arg(desc_options, arg_filter, ""); + + po::variables_map vm; + bool r = command_line::handle_error_helper(desc_options, [&]() + { + po::store(po::parse_command_line(argc, argv, desc_options), vm); + po::notify(vm); + return true; + }); + if (!r) + return 1; + + const std::string filter = glob_to_regex(command_line::get_arg(vm, arg_filter)); + performance_timer timer; timer.start(); - TEST_PERFORMANCE3(test_construct_tx, 1, 1, false); - TEST_PERFORMANCE3(test_construct_tx, 1, 2, false); - TEST_PERFORMANCE3(test_construct_tx, 1, 10, false); - TEST_PERFORMANCE3(test_construct_tx, 1, 100, false); - TEST_PERFORMANCE3(test_construct_tx, 1, 1000, false); - - TEST_PERFORMANCE3(test_construct_tx, 2, 1, false); - TEST_PERFORMANCE3(test_construct_tx, 2, 2, false); - TEST_PERFORMANCE3(test_construct_tx, 2, 10, false); - TEST_PERFORMANCE3(test_construct_tx, 2, 100, false); - - TEST_PERFORMANCE3(test_construct_tx, 10, 1, false); - TEST_PERFORMANCE3(test_construct_tx, 10, 2, false); - TEST_PERFORMANCE3(test_construct_tx, 10, 10, false); - TEST_PERFORMANCE3(test_construct_tx, 10, 100, false); - - TEST_PERFORMANCE3(test_construct_tx, 100, 1, false); - TEST_PERFORMANCE3(test_construct_tx, 100, 2, false); - TEST_PERFORMANCE3(test_construct_tx, 100, 10, false); - TEST_PERFORMANCE3(test_construct_tx, 100, 100, false); - - TEST_PERFORMANCE3(test_construct_tx, 2, 1, true); - TEST_PERFORMANCE3(test_construct_tx, 2, 2, true); - TEST_PERFORMANCE3(test_construct_tx, 2, 10, true); - - TEST_PERFORMANCE3(test_construct_tx, 10, 1, true); - TEST_PERFORMANCE3(test_construct_tx, 10, 2, true); - TEST_PERFORMANCE3(test_construct_tx, 10, 10, true); - - TEST_PERFORMANCE3(test_construct_tx, 100, 1, true); - TEST_PERFORMANCE3(test_construct_tx, 100, 2, true); - TEST_PERFORMANCE3(test_construct_tx, 100, 10, true); - - TEST_PERFORMANCE2(test_check_tx_signature, 1, false); - TEST_PERFORMANCE2(test_check_tx_signature, 2, false); - TEST_PERFORMANCE2(test_check_tx_signature, 10, false); - TEST_PERFORMANCE2(test_check_tx_signature, 100, false); - - TEST_PERFORMANCE2(test_check_tx_signature, 2, true); - TEST_PERFORMANCE2(test_check_tx_signature, 10, true); - TEST_PERFORMANCE2(test_check_tx_signature, 100, true); - - TEST_PERFORMANCE0(test_is_out_to_acc); - TEST_PERFORMANCE0(test_is_out_to_acc_precomp); - TEST_PERFORMANCE0(test_generate_key_image_helper); - TEST_PERFORMANCE0(test_generate_key_derivation); - TEST_PERFORMANCE0(test_generate_key_image); - TEST_PERFORMANCE0(test_derive_public_key); - TEST_PERFORMANCE0(test_derive_secret_key); - TEST_PERFORMANCE0(test_ge_frombytes_vartime); - TEST_PERFORMANCE0(test_generate_keypair); - TEST_PERFORMANCE0(test_sc_reduce32); - - TEST_PERFORMANCE2(test_wallet2_expand_subaddresses, 50, 200); - - TEST_PERFORMANCE0(test_cn_slow_hash); - TEST_PERFORMANCE1(test_cn_fast_hash, 32); - TEST_PERFORMANCE1(test_cn_fast_hash, 16384); + TEST_PERFORMANCE3(filter, test_construct_tx, 1, 1, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 1, 2, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 1, 10, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 1, 100, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 1, 1000, false); + + TEST_PERFORMANCE3(filter, test_construct_tx, 2, 1, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 2, 2, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 2, 10, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 2, 100, false); + + TEST_PERFORMANCE3(filter, test_construct_tx, 10, 1, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 10, 2, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 10, 10, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 10, 100, false); + + TEST_PERFORMANCE3(filter, test_construct_tx, 100, 1, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 100, 2, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 100, 10, false); + TEST_PERFORMANCE3(filter, test_construct_tx, 100, 100, false); + + TEST_PERFORMANCE3(filter, test_construct_tx, 2, 1, true); + TEST_PERFORMANCE3(filter, test_construct_tx, 2, 2, true); + TEST_PERFORMANCE3(filter, test_construct_tx, 2, 10, true); + + TEST_PERFORMANCE3(filter, test_construct_tx, 10, 1, true); + TEST_PERFORMANCE3(filter, test_construct_tx, 10, 2, true); + TEST_PERFORMANCE3(filter, test_construct_tx, 10, 10, true); + + TEST_PERFORMANCE3(filter, test_construct_tx, 100, 1, true); + TEST_PERFORMANCE3(filter, test_construct_tx, 100, 2, true); + TEST_PERFORMANCE3(filter, test_construct_tx, 100, 10, true); + + TEST_PERFORMANCE2(filter, test_check_tx_signature, 1, false); + TEST_PERFORMANCE2(filter, test_check_tx_signature, 2, false); + TEST_PERFORMANCE2(filter, test_check_tx_signature, 10, false); + TEST_PERFORMANCE2(filter, test_check_tx_signature, 100, false); + + TEST_PERFORMANCE2(filter, test_check_tx_signature, 2, true); + TEST_PERFORMANCE2(filter, test_check_tx_signature, 10, true); + TEST_PERFORMANCE2(filter, test_check_tx_signature, 100, true); + + TEST_PERFORMANCE0(filter, test_is_out_to_acc); + TEST_PERFORMANCE0(filter, test_is_out_to_acc_precomp); + TEST_PERFORMANCE0(filter, test_generate_key_image_helper); + TEST_PERFORMANCE0(filter, test_generate_key_derivation); + TEST_PERFORMANCE0(filter, test_generate_key_image); + TEST_PERFORMANCE0(filter, test_derive_public_key); + TEST_PERFORMANCE0(filter, test_derive_secret_key); + TEST_PERFORMANCE0(filter, test_ge_frombytes_vartime); + TEST_PERFORMANCE0(filter, test_generate_keypair); + TEST_PERFORMANCE0(filter, test_sc_reduce32); + + TEST_PERFORMANCE2(filter, test_wallet2_expand_subaddresses, 50, 200); + + TEST_PERFORMANCE0(filter, test_cn_slow_hash); + TEST_PERFORMANCE1(filter, test_cn_fast_hash, 32); + TEST_PERFORMANCE1(filter, test_cn_fast_hash, 16384); + + TEST_PERFORMANCE3(test_ringct_mlsag, 1, 3, false); + TEST_PERFORMANCE3(test_ringct_mlsag, 1, 5, false); + TEST_PERFORMANCE3(test_ringct_mlsag, 1, 10, false); + TEST_PERFORMANCE3(test_ringct_mlsag, 1, 100, false); + TEST_PERFORMANCE3(test_ringct_mlsag, 1, 3, true); + TEST_PERFORMANCE3(test_ringct_mlsag, 1, 5, true); + TEST_PERFORMANCE3(test_ringct_mlsag, 1, 10, true); + TEST_PERFORMANCE3(test_ringct_mlsag, 1, 100, true); std::cout << "Tests finished. Elapsed time: " << timer.elapsed_ms() / 1000 << " sec" << std::endl; diff --git a/tests/performance_tests/performance_tests.h b/tests/performance_tests/performance_tests.h index a4d49fd82..589c34caf 100644 --- a/tests/performance_tests/performance_tests.h +++ b/tests/performance_tests/performance_tests.h @@ -34,6 +34,7 @@ #include <stdint.h> #include <boost/chrono.hpp> +#include <boost/regex.hpp> class performance_timer { @@ -122,8 +123,12 @@ private: }; template <typename T> -void run_test(const char* test_name) +void run_test(const std::string &filter, const char* test_name) { + boost::smatch match; + if (!filter.empty() && !boost::regex_match(std::string(test_name), match, boost::regex(filter))) + return; + test_runner<T> runner; if (runner.run()) { @@ -149,7 +154,7 @@ void run_test(const char* test_name) } #define QUOTEME(x) #x -#define TEST_PERFORMANCE0(test_class) run_test< test_class >(QUOTEME(test_class)) -#define TEST_PERFORMANCE1(test_class, a0) run_test< test_class<a0> >(QUOTEME(test_class<a0>)) -#define TEST_PERFORMANCE2(test_class, a0, a1) run_test< test_class<a0, a1> >(QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ">") -#define TEST_PERFORMANCE3(test_class, a0, a1, a2) run_test< test_class<a0, a1, a2> >(QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ", " QUOTEME(a2) ">") +#define TEST_PERFORMANCE0(filter, test_class) run_test< test_class >(filter, QUOTEME(test_class)) +#define TEST_PERFORMANCE1(filter, test_class, a0) run_test< test_class<a0> >(filter, QUOTEME(test_class<a0>)) +#define TEST_PERFORMANCE2(filter, test_class, a0, a1) run_test< test_class<a0, a1> >(filter, QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ">") +#define TEST_PERFORMANCE3(filter, test_class, a0, a1, a2) run_test< test_class<a0, a1, a2> >(filter, QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ", " QUOTEME(a2) ">") diff --git a/tests/performance_tests/rct_mlsag.h b/tests/performance_tests/rct_mlsag.h new file mode 100644 index 000000000..70fb36aec --- /dev/null +++ b/tests/performance_tests/rct_mlsag.h @@ -0,0 +1,87 @@ +// Copyright (c) 2014-2017, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#pragma once + +#include "ringct/rctSigs.h" +#include "cryptonote_basic/cryptonote_basic.h" + +#include "single_tx_test_base.h" + +template<size_t inputs, size_t ring_size, bool ver> +class test_ringct_mlsag : public single_tx_test_base +{ +public: + static const size_t cols = ring_size; + static const size_t rows = inputs; + static const size_t loop_count = 100; + + bool init() + { + if (!single_tx_test_base::init()) + return false; + + rct::keyV xtmp = rct::skvGen(rows); + rct::keyM xm = rct::keyMInit(rows, cols);// = [[None]*N] #just used to generate test public keys + sk = rct::skvGen(rows); + P = rct::keyMInit(rows, cols);// = keyM[[None]*N] #stores the public keys; + ind = 2; + for (size_t j = 0 ; j < rows ; j++) + { + for (size_t i = 0 ; i < cols ; i++) + { + xm[i][j] = rct::skGen(); + P[i][j] = rct::scalarmultBase(xm[i][j]); + } + } + for (size_t j = 0 ; j < rows ; j++) + { + sk[j] = xm[ind][j]; + } + IIccss = MLSAG_Gen(rct::identity(), P, sk, NULL, NULL, ind, rows); + + return true; + } + + bool test() + { + if (ver) + MLSAG_Ver(rct::identity(), P, IIccss, rows); + else + MLSAG_Gen(rct::identity(), P, sk, NULL, NULL, ind, rows); + return true; + } + +private: + rct::keyV sk; + rct::keyM P; + size_t ind; + rct::mgSig IIccss; +}; diff --git a/tests/unit_tests/address_from_url.cpp b/tests/unit_tests/address_from_url.cpp index 3630b59d3..f4ecbc295 100644 --- a/tests/unit_tests/address_from_url.cpp +++ b/tests/unit_tests/address_from_url.cpp @@ -32,6 +32,7 @@ #include "wallet/wallet2.h" #include "common/dns_utils.h" +#include "simplewallet/simplewallet.h" #include <string> TEST(AddressFromTXT, Success) @@ -83,7 +84,7 @@ TEST(AddressFromTXT, Failure) TEST(AddressFromURL, Success) { - const std::string addr = "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A"; + const std::string addr = MONERO_DONATION_ADDR; bool dnssec_result = false; diff --git a/tests/unit_tests/memwipe.cpp b/tests/unit_tests/memwipe.cpp index 59f50cef8..93dcc19f6 100644 --- a/tests/unit_tests/memwipe.cpp +++ b/tests/unit_tests/memwipe.cpp @@ -47,7 +47,7 @@ static void test(bool wipe) if ((intptr_t)quux == foop) { MDEBUG(std::hex << std::setw(8) << std::setfill('0') << *(uint32_t*)quux); - if (wipe) ASSERT_TRUE(memcmp(quux, "bar", 3)); + if (wipe) { ASSERT_TRUE(memcmp(quux, "bar", 3)); } } else MWARNING("We did not get the same location, cannot check"); free(quux); diff --git a/translations/monero.ts b/translations/monero.ts index 4393d3457..27f5e1c52 100644 --- a/translations/monero.ts +++ b/translations/monero.ts @@ -2367,7 +2367,7 @@ Outputs per *: </source> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> - <source>Create non-deterministic view and spend keys</source> + <source>Generate non-deterministic view and spend keys</source> <translation type="unfinished"></translation> </message> <message> @@ -2582,7 +2582,7 @@ Outputs per *: </source> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="356"/> - <source>Cannot create deprecated wallets from JSON</source> + <source>Cannot generate deprecated wallets from JSON</source> <translation type="unfinished"></translation> </message> <message> diff --git a/translations/monero_fr.ts b/translations/monero_fr.ts index 8ebba52cf..5cef15a92 100644 --- a/translations/monero_fr.ts +++ b/translations/monero_fr.ts @@ -2417,8 +2417,8 @@ Sorties par * : </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> - <source>Create non-deterministic view and spend keys</source> - <translation>Créer des clés d'audit et de dépense non déterministes</translation> + <source>Generate non-deterministic view and spend keys</source> + <translation>Générer des clés d'audit et de dépense non déterministes</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> @@ -2632,8 +2632,8 @@ Sorties par * : </translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="356"/> - <source>Cannot create deprecated wallets from JSON</source> - <translation>Impossible de créer un portefeuille obsolète à partir de JSON</translation> + <source>Cannot generate deprecated wallets from JSON</source> + <translation>Impossible de générer un portefeuille obsolète à partir de JSON</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="403"/> diff --git a/translations/monero_it.ts b/translations/monero_it.ts index 8ee3277fa..3674b2a32 100644 --- a/translations/monero_it.ts +++ b/translations/monero_it.ts @@ -2386,7 +2386,7 @@ Outputs per *: </source> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> - <source>Create non-deterministic view and spend keys</source> + <source>Generate non-deterministic view and spend keys</source> <translation>Crea chiavi di visualizzione e chiavi di spesa non-deterministiche</translation> </message> <message> @@ -2601,7 +2601,7 @@ Outputs per *: </source> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="356"/> - <source>Cannot create deprecated wallets from JSON</source> + <source>Cannot generate deprecated wallets from JSON</source> <translation>Impossibile creare portafogli disapprovati da JSON</translation> </message> <message> diff --git a/translations/monero_sv.ts b/translations/monero_sv.ts new file mode 100644 index 000000000..0090857c0 --- /dev/null +++ b/translations/monero_sv.ts @@ -0,0 +1,2783 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE TS []> +<TS version="2.1"> +<context> + <name>Monero::AddressBookImpl</name> + <message> + <location filename="../src/wallet/api/address_book.cpp" line="55"/> + <source>Invalid destination address</source> + <translation>Ogiltig måladress</translation> + </message> + <message> + <location filename="../src/wallet/api/address_book.cpp" line="65"/> + <source>Invalid payment ID. Short payment ID should only be used in an integrated address</source> + <translation>Ogiltigt betalnings-ID. Kort betalnings-ID ska endast användas i en integrerad adress</translation> + </message> + <message> + <location filename="../src/wallet/api/address_book.cpp" line="72"/> + <source>Invalid payment ID</source> + <translation>Ogiltigt betalnings-ID</translation> + </message> + <message> + <location filename="../src/wallet/api/address_book.cpp" line="79"/> + <source>Integrated address and long payment id can't be used at the same time</source> + <translation>Integrerad adress och långt betalnings-ID kan inte användas samtidigt</translation> + </message> +</context> +<context> + <name>Monero::PendingTransactionImpl</name> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="90"/> + <source>Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:</source> + <translation>Försöker spara transaktion till fil, men angiven fil finns redan. Avslutar för att inte riskera att skriva över någonting. Fil:</translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="97"/> + <source>Failed to write transaction(s) to file</source> + <translation>Det gick inte att skriva transaktioner till fil</translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="114"/> + <source>daemon is busy. Please try again later.</source> + <translation>daemonen är upptagen. Försök igen senare.</translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="117"/> + <source>no connection to daemon. Please make sure daemon is running.</source> + <translation>ingen anslutning till daemonen. Se till att daemonen körs.</translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="121"/> + <source>transaction %s was rejected by daemon with status: </source> + <translation>transaktionen %s avvisades av daemonen med status: </translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="126"/> + <source>. Reason: </source> + <translation>. Orsak: </translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="128"/> + <source>Unknown exception: </source> + <translation>Okänt undantag: </translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="131"/> + <source>Unhandled exception</source> + <translation>Ohanterat undantag</translation> + </message> +</context> +<context> + <name>Monero::UnsignedTransactionImpl</name> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="75"/> + <source>This is a watch only wallet</source> + <translation>Detta är en granskningsplånbok</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="85"/> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="92"/> + <source>Failed to sign transaction</source> + <translation>Det gick inte att signera transaktionen</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="135"/> + <source>Claimed change does not go to a paid address</source> + <translation>Begärd växel går inte till en betald adress</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="141"/> + <source>Claimed change is larger than payment to the change address</source> + <translation>Begärd växel är större än betalning till växeladressen</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="151"/> + <source>Change goes to more than one address</source> + <translation>Växel går till mer än en adress</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="164"/> + <source>sending %s to %s</source> + <translation>skickar %s till %s</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="170"/> + <source>with no destinations</source> + <translation>utan några mål</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="176"/> + <source>%s change to %s</source> + <translation>%s växel till %s</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="179"/> + <source>no change</source> + <translation>ingen växel</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="181"/> + <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min mixin %lu. %s</source> + <translation>Läste in %lu transaktioner, för %s, avgift %s, %s, %s, med minsta mixin %lu. %s</translation> + </message> +</context> +<context> + <name>Monero::WalletImpl</name> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="942"/> + <source>payment id has invalid format, expected 16 or 64 character hex string: </source> + <translation>betalnings-ID har ogiltigt format. En 16- eller 64-teckens hex-sträng förväntades: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="952"/> + <source>Failed to add short payment id: </source> + <translation>Det gick inte att lägga till kort betalnings-ID: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="978"/> + <location filename="../src/wallet/api/wallet.cpp" line="1072"/> + <source>daemon is busy. Please try again later.</source> + <translation>daemonen är upptagen. Försök igen senare.</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="981"/> + <location filename="../src/wallet/api/wallet.cpp" line="1075"/> + <source>no connection to daemon. Please make sure daemon is running.</source> + <translation>ingen anslutning till daemonen. Se till att daemonen körs.</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="984"/> + <location filename="../src/wallet/api/wallet.cpp" line="1078"/> + <source>RPC error: </source> + <translation>RPC-fel: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1081"/> + <source>failed to get random outputs to mix</source> + <translation>det gick inte att hämta slumpmässiga utgångar att mixa</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="994"/> + <location filename="../src/wallet/api/wallet.cpp" line="1088"/> + <source>not enough money to transfer, available only %s, sent amount %s</source> + <translation>inte tillräckligt med pengar för överföring, endast tillgängligt %s, skickat belopp %s</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="403"/> + <source>failed to parse address</source> + <translation>det gick inte att parsa adressen</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="415"/> + <source>failed to parse secret spend key</source> + <translation>det gick inte att parsa hemlig spendernyckel</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="425"/> + <source>No view key supplied, cancelled</source> + <translation>Ingen visningsnyckel angiven, avbruten</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="432"/> + <source>failed to parse secret view key</source> + <translation>det gick inte att parsa hemlig visningsnyckel</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="442"/> + <source>failed to verify secret spend key</source> + <translation>det gick inte att verifiera hemlig spendernyckel</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="447"/> + <source>spend key does not match address</source> + <translation>spendernyckel matchar inte adress</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="453"/> + <source>failed to verify secret view key</source> + <translation>det gick inte att verifiera hemlig visningsnyckel</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="458"/> + <source>view key does not match address</source> + <translation>visningsnyckel matchar inte adress</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="477"/> + <source>failed to generate new wallet: </source> + <translation>det gick inte att skapa ny plånbok: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="799"/> + <source>Failed to load unsigned transactions</source> + <translation>Det gick inte att läsa in osignerade transaktioner</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="820"/> + <source>Failed to load transaction from file</source> + <translation>Det gick inte att läsa in transaktion från fil</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="838"/> + <source>Wallet is view only</source> + <translation>Plånboken är endast för granskning</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="847"/> + <source>failed to save file </source> + <translation>det gick inte att spara fil </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="874"/> + <source>Failed to import key images: </source> + <translation>det gick inte att importera nyckelavbildningar: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="987"/> + <source>failed to get random outputs to mix: %s</source> + <translation>det gick inte att hitta slumpmässiga utgångar att mixa: %s</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1003"/> + <location filename="../src/wallet/api/wallet.cpp" line="1097"/> + <source>not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)</source> + <translation>ej tillräckligt med pengar för överföring, endast tillgängligt %s, transaktionsbelopp %s = %s + %s (avgift)</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1012"/> + <location filename="../src/wallet/api/wallet.cpp" line="1106"/> + <source>not enough outputs for specified mixin_count</source> + <translation>inte tillräckligt många utgångar för angiven mixin_count</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1014"/> + <location filename="../src/wallet/api/wallet.cpp" line="1108"/> + <source>output amount</source> + <translation>utgångens belopp</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1014"/> + <location filename="../src/wallet/api/wallet.cpp" line="1108"/> + <source>found outputs to mix</source> + <translation>hittade utgångar att mixa</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1019"/> + <location filename="../src/wallet/api/wallet.cpp" line="1113"/> + <source>transaction was not constructed</source> + <translation>transaktionen konstruerades inte</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1023"/> + <location filename="../src/wallet/api/wallet.cpp" line="1117"/> + <source>transaction %s was rejected by daemon with status: </source> + <translation>transaktionen %s avvisades av daemonen med status: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1030"/> + <location filename="../src/wallet/api/wallet.cpp" line="1124"/> + <source>one of destinations is zero</source> + <translation>ett av målen är noll</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1033"/> + <location filename="../src/wallet/api/wallet.cpp" line="1127"/> + <source>failed to find a suitable way to split transactions</source> + <translation>det gick inte att hitta ett lämpligt sätt att dela upp transaktioner</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1036"/> + <location filename="../src/wallet/api/wallet.cpp" line="1130"/> + <source>unknown transfer error: </source> + <translation>okänt överföringsfel: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1039"/> + <location filename="../src/wallet/api/wallet.cpp" line="1133"/> + <source>internal error: </source> + <translation>internt fel: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1042"/> + <location filename="../src/wallet/api/wallet.cpp" line="1136"/> + <source>unexpected error: </source> + <translation>oväntat fel: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1045"/> + <location filename="../src/wallet/api/wallet.cpp" line="1139"/> + <source>unknown error</source> + <translation>okänt fel</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1419"/> + <source>Rescan spent can only be used with a trusted daemon</source> + <translation>Genomsök efter spenderade kan endast användas med en betrodd daemon</translation> + </message> +</context> +<context> + <name>Monero::WalletManagerImpl</name> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="192"/> + <source>failed to parse txid</source> + <translation>det gick inte att parsa transaktions-id</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="199"/> + <location filename="../src/wallet/api/wallet_manager.cpp" line="206"/> + <source>failed to parse tx key</source> + <translation>det gick inte att parsa transaktionsnyckeln</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="217"/> + <source>failed to parse address</source> + <translation>det gick inte att parsa adressen</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="227"/> + <source>failed to get transaction from daemon</source> + <translation>det gick inte att hämta transaktion från daemon</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="238"/> + <source>failed to parse transaction from daemon</source> + <translation>det gick inte att parsa transaktion från daemonen</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="245"/> + <source>failed to validate transaction from daemon</source> + <translation>det gick inte att validera transaktion från daemon</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="250"/> + <source>failed to get the right transaction from daemon</source> + <translation>det gick inte att hämta rätt transaktion från daemonen</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="257"/> + <source>failed to generate key derivation from supplied parameters</source> + <translation>det gick inte att skapa nyckelhärledning från angivna parametrar</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="313"/> + <source>error: </source> + <translation>fel: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="319"/> + <source>received</source> + <translation>mottaget</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="319"/> + <source>in txid</source> + <translation>i transaktions-id</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet_manager.cpp" line="323"/> + <source>received nothing in txid</source> + <translation>tog emot ingenting i transaktions-id</translation> + </message> +</context> +<context> + <name>Wallet</name> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="212"/> + <source>Failed to parse address</source> + <translation>Det gick inte att parsa adressen</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="219"/> + <source>Failed to parse key</source> + <translation>Det gick inte att parsa nyckeln</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="227"/> + <source>failed to verify key</source> + <translation>det gick inte att verifiera nyckeln</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="237"/> + <source>key does not match address</source> + <translation>nyckeln matchar inte adressen</translation> + </message> +</context> +<context> + <name>command_line</name> + <message> + <location filename="../src/common/command_line.cpp" line="76"/> + <source>yes</source> + <translation>ja</translation> + </message> +</context> +<context> + <name>cryptonote::rpc_args</name> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="38"/> + <source>Specify ip to bind rpc server</source> + <translation>Ange IP-adress för att binda till RPC-server</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="39"/> + <source>Specify username[:password] required for RPC server</source> + <translation>Ange användarnamn[:lösenord] som krävs av RPC-servern</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="40"/> + <source>Confirm rpc-bind-ip value is NOT a loopback (local) IP</source> + <translation>Bekräftelsevärde för rpc-bind-ip är INTE ett lokalt (loopback) IP</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="66"/> + <source>Invalid IP address given for --</source> + <translation>Ogiltig IP-adress angiven för --</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="74"/> + <source> permits inbound unencrypted external connections. Consider SSH tunnel or SSL proxy instead. Override with --</source> + <translation> tillåter inkommande okrypterade externa anslutningar. Överväg att använda SSH-tunnel eller SSL-proxy istället. Åsidosätt med --</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="89"/> + <source>Username specified with --</source> + <translation>Användarnamn angivet med --</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="89"/> + <source> cannot be empty</source> + <translation> kan inte vara tomt</translation> + </message> +</context> +<context> + <name>cryptonote::simple_wallet</name> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="290"/> + <source>Commands: </source> + <translation>Kommandon: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1557"/> + <source>failed to read wallet password</source> + <translation>det gick inte att läsa lösenord för plånboken</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1325"/> + <source>invalid password</source> + <translation>ogiltigt lösenord</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="697"/> + <source>start_mining [<number_of_threads>] - Start mining in daemon</source> + <translation>start_mining [<antal_trådar>] - Starta brytning i daemonen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="698"/> + <source>Stop mining in daemon</source> + <translation>Avbryt brytning i daemonen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="699"/> + <source>Save current blockchain data</source> + <translation>Spara aktuella blockkedje-data</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="701"/> + <source>Show current wallet balance</source> + <translation>Visa aktuellt saldo för plånboken</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="704"/> + <source>Show blockchain height</source> + <translation>Visa blockkedjans höjd</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> + <source>Show current wallet public address</source> + <translation>Visa plånbokens aktuella öppna adress</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="744"/> + <source>Show this help</source> + <translation>Visa denna hjälp</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="788"/> + <source>set seed: needs an argument. available options: language</source> + <translation>set seed: behöver ett argument. tillgängliga alternativ: språk</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="811"/> + <source>set: unrecognized argument(s)</source> + <translation>set: okända argument</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1442"/> + <source>wallet file path not valid: </source> + <translation>ogiltig sökväg till plånbok: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="863"/> + <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> + <translation>Försöker skapa eller återställa plånbok, men angivna filer existerar. Avslutar för att inte riskera att skriva över någonting.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="416"/> + <source>usage: payment_id</source> + <translation>användning: payment_id</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="710"/> + <source>sweep_below <amount_threshold> [mixin] address [payment_id] - Send all unlocked outputs below the threshold to an address</source> + <translation>sweep_below <tröskelbelopp> [mixin] <adress> [<betalnings_ID>] - Skicka alla upplåsta utgångar under tröskelbeloppet till en adress</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="743"/> + <source>Generate a new random full size payment id - these will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids</source> + <translation>Skapa ett nytt slumpmässigt betalnings-ID av full storlek - dessa kommer att vara okrypterade på blockkedjan, se integrated_address för krypterade korta betalnings-ID</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="774"/> + <source>needs an argument</source> + <translation>kräver ett argument</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="797"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="798"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="801"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="805"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="809"/> + <source>0 or 1</source> + <translation>0 eller 1</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="800"/> + <source>integer >= 2</source> + <translation>heltal >= 2</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="803"/> + <source>0, 1, 2, 3, or 4</source> + <translation>0, 1, 2, 3 eller 4</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> + <source>unsigned integer</source> + <translation>positivt heltal</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="912"/> + <source>NOTE: the following 25 words can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. +</source> + <translation>OBSERVERA: följande 25 ord kan användas för att återfå tillgång till din plånbok. Skriv ner och spara dem på ett säkert ställe. Spara dem inte i din e-post eller på något lagringsutrymme som du inte har direkt kontroll över. +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="958"/> + <source>--restore-deterministic-wallet uses --generate-new-wallet, not --wallet-file</source> + <translation>--restore-deterministic-wallet använder --generate-new-wallet, inte --wallet-file</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="973"/> + <source>specify a recovery parameter with the --electrum-seed="words list here"</source> + <translation>ange en återställningsparameter med --electrum-seed="ordlista här"</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1123"/> + <source>specify a wallet path with --generate-new-wallet (not --wallet-file)</source> + <translation>ange sökväg till en plånbok med --generate-new-wallet (inte --wallet-file)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1261"/> + <source>wallet failed to connect to daemon: </source> + <translation>plånboken kunde inte ansluta till daemonen: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1269"/> + <source>Daemon uses a different RPC major version (%u) than the wallet (%u): %s. Either update one of them, or use --allow-mismatched-daemon-version.</source> + <translation>Daemonen använder en högre version av RPC (%u) än plånboken (%u): %s. Antingen uppdatera en av dem, eller använd --allow-mismatched-daemon-version.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1288"/> + <source>List of available languages for your wallet's seed:</source> + <translation>Lista över tillgängliga språk för din plånboks frö:</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1297"/> + <source>Enter the number corresponding to the language of your choice: </source> + <translation>Ange det tal som motsvarar det språk du vill använda: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1354"/> + <source>You had been using a deprecated version of the wallet. Please use the new seed that we provide. +</source> + <translation>Du hade använt en inaktuell version av plånboken. Använd det nya frö som vi tillhandahåller. +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1368"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1425"/> + <source>Generated new wallet: </source> + <translation>Ny plånbok skapad: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1374"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1430"/> + <source>failed to generate new wallet: </source> + <translation>det gick inte att skapa ny plånbok: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1457"/> + <source>Opened watch-only wallet</source> + <translation>Öppnade plånbok för granskning</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1457"/> + <source>Opened wallet</source> + <translation>Öppnade plånbok</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1466"/> + <source>You had been using a deprecated version of the wallet. Please proceed to upgrade your wallet. +</source> + <translation>Du hade använt en inaktuell version av plånboken. Fortsätt för att uppgradera din plånbok. +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1481"/> + <source>You had been using a deprecated version of the wallet. Your wallet file format is being upgraded now. +</source> + <translation>Du hade använt en inaktuell version av plånboken. Plånbokens filformat kommer nu att uppgraderas. +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1489"/> + <source>failed to load wallet: </source> + <translation>det gick inte att läsa in plånboken: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1497"/> + <source>Use the "help" command to see the list of available commands. +</source> + <translation>Använd kommandot "help" för att se en lista över tillgängliga kommandon. +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1541"/> + <source>Wallet data saved</source> + <translation>Plånboksdata sparades</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> + <source>Mining started in daemon</source> + <translation>Brytning startad i daemonen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1615"/> + <source>mining has NOT been started: </source> + <translation>brytning har INTE startats: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1634"/> + <source>Mining stopped in daemon</source> + <translation>Brytning stoppad i daemonen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1636"/> + <source>mining has NOT been stopped: </source> + <translation>brytning har INTE stoppats: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1655"/> + <source>Blockchain saved</source> + <translation>Blockkedjan sparad</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1670"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1687"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1699"/> + <source>Height </source> + <translation>Höjd </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1671"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1688"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1700"/> + <source>transaction </source> + <translation>transaktion </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1672"/> + <source>received </source> + <translation>mottaget </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1689"/> + <source>spent </source> + <translation>spenderad </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1701"/> + <source>unsupported transaction format</source> + <translation>transaktionsformatet stöds inte</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1718"/> + <source>Starting refresh...</source> + <translation>Startar uppdatering …</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1731"/> + <source>Refresh done, blocks received: </source> + <translation>Uppdatering färdig, mottagna block: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2186"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2701"/> + <source>payment id has invalid format, expected 16 or 64 character hex string: </source> + <translation>betalnings-ID har ogiltigt format. En 16- eller 64-teckens hex-sträng förväntades: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2201"/> + <source>bad locked_blocks parameter:</source> + <translation>dålig parameter för locked_blocks:</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2228"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2726"/> + <source>a single transaction cannot use more than one payment id: </source> + <translation>en enstaka transaktion kan inte använda mer än ett betalnings-ID: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2237"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2735"/> + <source>failed to set up payment id, though it was decoded correctly</source> + <translation>det gick inte att upprätta betalnings-ID, trots att det avkodades korrekt</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2262"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2533"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2794"/> + <source>transaction cancelled.</source> + <translation>transaktion avbröts.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2323"/> + <source>Sending %s. </source> + <translation>Skickar %s. </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2326"/> + <source>Your transaction needs to be split into %llu transactions. This will result in a transaction fee being applied to each transaction, for a total fee of %s</source> + <translation>Transaktionen behöver delas upp i %llu transaktioner. Detta kommer att göra att en transaktionsavgift läggs till varje transaktion, med ett totalt belopp på %s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2332"/> + <source>The transaction fee is %s</source> + <translation>Transaktionsavgiften är %s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2335"/> + <source>, of which %s is dust from change</source> + <translation>, varav %s är damm från växel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2336"/> + <source>.</source> + <translation>.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2336"/> + <source>A total of %s from dust change will be sent to dust address</source> + <translation>Ett total belopp på %s från växeldamm kommer att skickas till damm-adressen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2341"/> + <source>. +This transaction will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)</source> + <translation>. +Denna transaktion kommer att låsas upp vid block %llu, om ungefär %s dagar (förutsatt en blocktid på 2 minuter)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2367"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2544"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2805"/> + <source>Failed to write transaction(s) to file</source> + <translation>Det gick inte att skriva transaktioner till fil</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2371"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2548"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2809"/> + <source>Unsigned transaction(s) successfully written to file: </source> + <translation>Osignerade transaktioner skrevs till fil: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2583"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2844"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3157"/> + <source>Not enough money in unlocked balance</source> + <translation>Inte tillräckligt med pengar i upplåst saldo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2415"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2592"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> + <source>Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees</source> + <translation>Det gick inte att hitta något sätt att skapa transaktioner. Detta beror vanligtvis på damm som är så litet att det inte kan betala för sig självt i avgifter, eller ett försök att skicka mer pengar än upplåst saldo, eller att inte lämna tillräckligt för att täcka avgifterna</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2435"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2612"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2873"/> + <source>Reason: </source> + <translation>Orsak: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2624"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2885"/> + <source>failed to find a suitable way to split transactions</source> + <translation>det gick inte att hitta ett lämpligt sätt att dela upp transaktioner</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2503"/> + <source>No unmixable outputs found</source> + <translation>Inga omixbara utgångar kunde hittas</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2709"/> + <source>No address given</source> + <translation>Ingen adress har angivits</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2921"/> + <source>missing amount threshold</source> + <translation>beloppströskel saknas</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2926"/> + <source>invalid amount threshold</source> + <translation>ogiltig beloppströskel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3008"/> + <source>Claimed change does not go to a paid address</source> + <translation>Begärd växel går inte till en betald adress</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3013"/> + <source>Claimed change is larger than payment to the change address</source> + <translation>Begärd växel är större än betalning till växeladressen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3035"/> + <source>sending %s to %s</source> + <translation>skickar %s till %s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3041"/> + <source>with no destinations</source> + <translation>utan några mål</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3088"/> + <source>Failed to sign transaction</source> + <translation>Det gick inte att signera transaktionen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3094"/> + <source>Failed to sign transaction: </source> + <translation>Det gick inte att signera transaktion: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3120"/> + <source>Failed to load transaction from file</source> + <translation>Det gick inte att läsa in transaktion från fil</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3137"/> + <source>daemon is busy. Please try later</source> + <translation>daemonen är upptagen. Försök senare</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1745"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1995"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2395"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2572"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2833"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3146"/> + <source>RPC error: </source> + <translation>RPC-fel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="312"/> + <source>wallet is watch-only and has no spend key</source> + <translation>plånboken är enbart för granskning och har ingen spendernyckel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="390"/> + <source>Your original password was incorrect.</source> + <translation>Ditt ursprungliga lösenord var fel.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="404"/> + <source>Error with wallet rewrite: </source> + <translation>Fel vid återskrivning av plånbok: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="513"/> + <source>priority must be 0, 1, 2, 3, or 4 </source> + <translation>prioritet måste vara 0, 1, 2, 3 eller 4 </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="525"/> + <source>priority must be 0, 1, 2, 3,or 4</source> + <translation>prioritet måste vara 0, 1, 2, 3 eller 4</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="540"/> + <source>priority must be 0, 1, 2 3,or 4</source> + <translation>prioritet måste vara 0, 1, 2, 3 eller 4</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="623"/> + <source>invalid unit</source> + <translation>ogiltig enhet</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="641"/> + <source>invalid count: must be an unsigned integer</source> + <translation>ogiltigt värde för count: måste vara ett heltal utan tecken</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="659"/> + <source>invalid value</source> + <translation>ogiltigt värde</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="705"/> + <source>Same as transfer, but using an older transaction building algorithm</source> + <translation>Samma som transfer, men använder en äldre algoritm för att bygga transaktionen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="709"/> + <source>sweep_all [mixin] address [payment_id] - Send all unlocked balance to an address</source> + <translation>sweep_all [mixin] adress [betalnings_id] - Skicka allt upplåst saldo till en adress</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="711"/> + <source>donate [<mixin_count>] <amount> [payment_id] - Donate <amount> to the development team (donate.getmonero.org)</source> + <translation>donate [<mixin_antal>] <belopp> [<betalnings_id>] - Donera <belopp> till utvecklingsteamet (donate.getmonero.org)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="714"/> + <source>set_log <level>|<categories> - Change current log detail (level must be <0-4>)</source> + <translation>set_log <nivå>|<kategorier> - Ändra detaljnivån för aktuell logg (nivå måste vara 0-4)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="717"/> + <source>address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)] - Print all entries in the address book, optionally adding/deleting an entry to/from it</source> + <translation>address_book [(add (<adress> [pid <långt eller kort betalnings-ID>])|<integrerad adress> [<beskrivning eventuellt med blanktecken>])|(delete <index>)] - Skriv ut alla poster i adressboken, eventuellt lägg till/ta bort en post till/från den</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="729"/> + <source>show_transfers [in|out|pending|failed|pool] [<min_height> [<max_height>]] - Show incoming/outgoing transfers within an optional height range</source> + <translation>show_transfers [in|out|pending|failed|pool] [<min_höjd> [<max_höjd>]] - Visa inkommande/utgående överföringar inom ett valfritt höjdintervall</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="741"/> + <source>Show information about a transfer to/from this address</source> + <translation>Visa information om en överföring till/från denna adress</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="742"/> + <source>Change wallet password</source> + <translation>Ändra lösenord för plånbok</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="820"/> + <source>usage: set_log <log_level_number_0-4> | <categories></source> + <translation>användning: set_log <loggnivå_nummer_0-4> | <kategorier></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="886"/> + <source>(Y/Yes/N/No): </source> + <translation>(J/Ja/N/Nej): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1157"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1184"/> + <source>bad m_restore_height parameter: </source> + <translation>dålig parameter för m_restore_height: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1162"/> + <source>date format must be YYYY-MM-DD</source> + <translation>datumformat måste vara ÅÅÅÅ-MM-DD</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1175"/> + <source>Restore height is: </source> + <translation>Återställningshöjd är: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1176"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2348"/> + <source>Is this okay? (Y/Yes/N/No): </source> + <translation>Är detta okej? (J/Ja/N/Nej): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1212"/> + <source>Daemon is local, assuming trusted</source> + <translation>Daemonen är lokal, utgår från att den är betrodd</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1553"/> + <source>Password for new watch-only wallet</source> + <translation>Lösenord för ny granskningsplånbok</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1604"/> + <source>invalid arguments. Please use start_mining [<number_of_threads>] [do_bg_mining] [ignore_battery], <number_of_threads> should be from 1 to </source> + <translation>ogiltiga argument. Använd start_mining [<antal_trådar>] [do_bg_mining] [ignore_battery], <antal_trådar> ska vara från 1 till </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1755"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2457"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2634"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2895"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3205"/> + <source>internal error: </source> + <translation>internt fel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2000"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2462"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2900"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3210"/> + <source>unexpected error: </source> + <translation>oväntat fel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1765"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2005"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2467"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3215"/> + <source>unknown error</source> + <translation>okänt fel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1770"/> + <source>refresh failed: </source> + <translation>det gick inte att att uppdatera: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1770"/> + <source>Blocks received: </source> + <translation>Mottagna block: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1795"/> + <source>unlocked balance: </source> + <translation>upplåst saldo: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="808"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> + <source>amount</source> + <translation>belopp</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <source>spent</source> + <translation>spenderad</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <source>global index</source> + <translation>globalt index</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <source>tx id</source> + <translation>tx-ID</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1868"/> + <source>No incoming transfers</source> + <translation>Inga inkommande överföringar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1872"/> + <source>No incoming available transfers</source> + <translation>Inga inkommande tillgängliga överföringar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> + <source>No incoming unavailable transfers</source> + <translation>Inga inkommande otillgängliga överföringar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1887"/> + <source>expected at least one payment_id</source> + <translation>åtminstone ett payment_id förväntades</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> + <source>payment</source> + <translation>betalning</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> + <source>transaction</source> + <translation>transaktion</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> + <source>height</source> + <translation>höjd</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> + <source>unlock time</source> + <translation>upplåsningstid</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1908"/> + <source>No payments with id </source> + <translation>Inga betalningar med ID </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1960"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2026"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2280"/> + <source>failed to get blockchain height: </source> + <translation>det gick inte att hämta blockkedjans höjd: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2016"/> + <source>failed to connect to the daemon</source> + <translation>det gick inte att ansluta till daemonen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2034"/> + <source> +Transaction %llu/%llu: txid=%s</source> + <translation> +Transaktion %llu/%llu: txid=%s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2044"/> + <source> +Input %llu/%llu: amount=%s</source> + <translation> +Ingång %llu/%llu: belopp=%s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2060"/> + <source>failed to get output: </source> + <translation>det gick inte att hämta utgång: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2068"/> + <source>output key's originating block height shouldn't be higher than the blockchain height</source> + <translation>utgångsnyckelns ursprungsblockhöjd får inte vara högre än blockkedjans höjd</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2072"/> + <source> +Originating block heights: </source> + <translation> +Ursprungsblockhöjder: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2087"/> + <source> +|</source> + <translation> +|</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2087"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3915"/> + <source>| +</source> + <translation>| +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2104"/> + <source> +Warning: Some input keys being spent are from </source> + <translation> +Varning: Några ingångsnycklar som spenderas kommer från </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> + <source>, which can break the anonymity of ring signature. Make sure this is intentional!</source> + <translation>, vilket kan bryta ringsignaturens anonymitet. Se till att detta är avsiktligt!</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2152"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2937"/> + <source>wrong number of arguments</source> + <translation>fel antal argument</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2257"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2744"/> + <source>No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): </source> + <translation>Inget betalnings-ID har inkluderats med denna transaktion. Är detta okej? (J/Ja/N/Nej): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2298"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2762"/> + <source>No outputs found, or daemon is not ready</source> + <translation>Inga utgångar hittades, eller så är daemonen inte redo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2576"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2837"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3150"/> + <source>failed to get random outputs to mix: </source> + <translation>det gick inte att hitta slumpmässiga utgångar att mixa: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2518"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2779"/> + <source>Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> + <translation>Sveper upp %s i %llu transaktioner för en total avgift på %s. Är detta okej? (J/Ja/N/Nej): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2524"/> + <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> + <translation>Sveper upp %s för en total avgift på %s. Är detta okej? (J/Ja/N/Nej): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2969"/> + <source>Donating </source> + <translation>Donerar </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3053"/> + <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min mixin %lu. %sIs this okay? (Y/Yes/N/No): </source> + <translation>Läste in %lu transaktioner, för %s, avgift %s, %s, %s, med minsta mixin %lu. %sÄr detta okej? (J/Ja/N/Nej): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3077"/> + <source>This is a watch only wallet</source> + <translation>Detta är en granskningsplånbok</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4443"/> + <source>usage: show_transfer <txid></source> + <translation>användning: show_transfer <transaktions-ID></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4557"/> + <source>Transaction ID not found</source> + <translation>Transaktions-ID kunde inte hittas</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="237"/> + <source>true</source> + <translation>sant</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="266"/> + <source>failed to parse refresh type</source> + <translation>det gick inte att parsa uppdateringstyp</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="330"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="362"/> + <source>wallet is watch-only and has no seed</source> + <translation>plånboken är enbart för granskning och saknar frö</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="353"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="367"/> + <source>wallet is non-deterministic and has no seed</source> + <translation>plånboken är icke-deterministisk och saknar frö</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="450"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="467"/> + <source>wallet is watch-only and cannot transfer</source> + <translation>plånboken är enbart för granskning och kan inte göra överföringar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="480"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="496"/> + <source>mixin must be an integer >= 2</source> + <translation>mixin måste vara ett heltal >= 2</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="501"/> + <source>could not change default mixin</source> + <translation>det gick inte att ändra standardinställning för mixin</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="545"/> + <source>could not change default priority</source> + <translation>Det gick inte att ändra standardinställning för prioritet</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="700"/> + <source>Synchronize transactions and balance</source> + <translation>Synkronisera transaktioner och saldo</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="702"/> + <source>incoming_transfers [available|unavailable] - Show incoming transfers, all or filtered by availability</source> + <translation>incoming_transfers [available|unavailable] - Visa inkommande överföringar, alla eller filtrerade efter tillgänglighet</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="703"/> + <source>payments <PID_1> [<PID_2> ... <PID_N>] - Show payments for given payment ID[s]</source> + <translation>payments <B_ID_1> [<B_ID_2> … <B_ID_N>] - Visa betalningar för angivna betalnings-ID</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="706"/> + <source>transfer [<priority>] [<mixin_count>] <address> <amount> [<payment_id>] - Transfer <amount> to <address>. <priority> is the priority of the transaction. The higher the priority, the higher the fee of the transaction. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <mixin_count> is the number of extra inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> + <translation>transfer [<prioritet>] [<mixin_antal>] <adress> <belopp> [<betalnings_id>] - Överför <belopp> till <adress>. <prioritet> är transaktionens prioritet. Ju högre prioritet, desto högre transaktionsavgift. Giltiga värden i prioritetsordning (från lägsta till högsta) är: unimportant, normal, elevated, priority. Om det utelämnas kommer standardvärdet (se kommandot "set priority") att användas. <mixin_antal> är det antal extra ingångar som ska inkluderas för att uppnå ospårbarhet. Flera betalningar kan göras på en gång genom att lägga till <adress_2> <belopp_2> etcetera (före betalnings-ID, om det inkluderas)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="707"/> + <source>locked_transfer [<mixin_count>] <addr> <amount> <lockblocks>(Number of blocks to lock the transaction for, max 1000000) [<payment_id>]</source> + <translation>locked_transfer [<mixin_antal>] <adress> <belopp> <låsblock>(Antal block som transaktionen ska låsas för, max 1000000) [<betalnings_id>]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="708"/> + <source>Send all unmixable outputs to yourself with mixin 0</source> + <translation>Skicka alla omixbara utgångar till dig själv med mixin 0</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> + <source>Sign a transaction from a file</source> + <translation>Signera en transaktion från en fil</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="713"/> + <source>Submit a signed transaction from a file</source> + <translation>Skicka en signerad transaktion från en fil</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="716"/> + <source>integrated_address [PID] - Encode a payment ID into an integrated address for the current wallet public address (no argument uses a random payment ID), or decode an integrated address to standard address and payment ID</source> + <translation>integrated_address [PID] - Koda ett betalnings-ID till en integrerad adress för den aktuella plånbokens öppna adress (utan argument används ett slumpmässigt betalnings-ID), eller avkoda en integrerad adress till standardadress och betalnings-ID</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="718"/> + <source>Save wallet data</source> + <translation>Spara plånboksdata</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="719"/> + <source>Save a watch-only keys file</source> + <translation>Spara en fil med granskningsnycklar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="720"/> + <source>Display private view key</source> + <translation>Visa privat visningsnyckel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> + <source>Display private spend key</source> + <translation>Visa privat spendernyckel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="722"/> + <source>Display Electrum-style mnemonic seed</source> + <translation>Visa minnesfrö (Electrum-typ)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="723"/> + <source>Available options: seed language - set wallet seed language; always-confirm-transfers <1|0> - whether to confirm unsplit txes; print-ring-members <1|0> - whether to print detailed information about ring members during confirmation; store-tx-info <1|0> - whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference; default-mixin <n> - set default mixin (default is 4); auto-refresh <1|0> - whether to automatically sync new blocks from the daemon; refresh-type <full|optimize-coinbase|no-coinbase|default> - set wallet refresh behaviour; priority [0|1|2|3|4] - default/unimportant/normal/elevated/priority fee; confirm-missing-payment-id <1|0>; ask-password <1|0>; unit <monero|millinero|micronero|nanonero|piconero> - set default monero (sub-)unit; min-outputs-count [n] - try to keep at least that many outputs of value at least min-outputs-value; min-outputs-value [n] - try to keep at least min-outputs-count outputs of at least that value; merge-destinations <1|0> - whether to merge multiple payments to the same destination address</source> + <translation>Tillgängliga alternativ: seed language - ange språk för plånbokens frö; always-confirm-transfers <1|0> - huruvida ej delade transaktioner ska bekräftas; print-ring-members <1|0> - huruvida detaljerad information om ringmedlemmar ska skrivas ut vid bekräftelse; store-tx-info <1|0> - huruvida info om utgående transaktioner ska sparas (måladress, betalnings-ID, hemlig transaktionsnyckel) för framtida referens; default-mixin <n> - ange standardvärde för mixin (standard är 4); auto-refresh <1|0> - huruvida nya block från daemonen ska synkas automatiskt; refresh-type <full|optimize-coinbase|no-coinbase|default> - ange uppdateringsbeteende för plånbok; priority [0|1|2|3|4] - standard/oviktigt/normal/förhöjd/prioritetsavgift; confirm-missing-payment-id <1|0>; ask-password <1|0>; unit <monero|millinero|micronero|nanonero|piconero> - ange standardvärde för monero-(under-)enhet; min-outputs-count [n] - försök behålla åtminstone så många utgångar med ett värde på åtminstone min-outputs-value; min-outputs-value [n] - försök behålla åtminstone min-outputs-count utgångar av åtminstone detta värde; merge-destinations <1|0> - huruvida flera betalningar till samma måladress ska slås samman</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="724"/> + <source>Rescan blockchain for spent outputs</source> + <translation>Genomsök blockkedjan igen för spenderade utgångar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="725"/> + <source>Get transaction key (r) for a given <txid></source> + <translation>Hämta transaktionsnyckel (r) för ett givet <transaktions-ID></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="726"/> + <source>Check amount going to <address> in <txid></source> + <translation>Kontrollera belopp som går till <adress> i <transaktions-ID></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="727"/> + <source>Generate a signature to prove payment to <address> in <txid> using the transaction secret key (r) without revealing it</source> + <translation>Skapa en signatur för att bevisa betalning till <adress> i <transaktions-ID> genom att använda hemlig nyckel för transaktion (r) utan att avslöja den</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="728"/> + <source>Check tx proof for payment going to <address> in <txid></source> + <translation>Kontrollera transaktionsbevis för betalning som går till <adress> i <transaktions-ID></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="730"/> + <source>unspent_outputs [<min_amount> <max_amount>] - Show unspent outputs within an optional amount range</source> + <translation>unspent_outputs [<min_belopp> <max_belopp>] - Visa ej spenderade utgångar inom ett valfritt beloppsintervall</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="731"/> + <source>Rescan blockchain from scratch</source> + <translation>Genomsök blockkedjan från början</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="732"/> + <source>Set an arbitrary string note for a txid</source> + <translation>Ange en godtycklig sträng som anteckning för ett transaktions-ID</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="733"/> + <source>Get a string note for a txid</source> + <translation>Hämta en stränganteckning för ett transaktions-ID</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="734"/> + <source>Show wallet status information</source> + <translation>Visa statusinformation för plånbok</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="735"/> + <source>Sign the contents of a file</source> + <translation>Signera innehållet i en fil</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="736"/> + <source>Verify a signature on the contents of a file</source> + <translation>Verifera signaturen för innehållet i en fil</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="737"/> + <source>Export a signed set of key images</source> + <translation>Exportera en signerad uppsättning nyckelavbildningar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="738"/> + <source>Import signed key images list and verify their spent status</source> + <translation>Importera lista med signerade nyckelavbildningar och verifera deras spenderingsstatus</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="739"/> + <source>Export a set of outputs owned by this wallet</source> + <translation>Exportera en uppsättning utgångar som ägs av denna plånbok</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="740"/> + <source>Import set of outputs owned by this wallet</source> + <translation>Importera en uppsättning utgångar som ägs av denna plånbok</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="802"/> + <source>full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)</source> + <translation>full (långsammast, inga antaganden); optimize-coinbase (snabb, antar att hela coinbase-transaktionen betalas till en enda adress); no-coinbase (snabbast, antar att ingen coinbase-transaktion tas emot), default (samma som optimize-coinbase)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="806"/> + <source>monero, millinero, micronero, nanonero, piconero</source> + <translation>monero, millinero, micronero, nanonero, piconero</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="851"/> + <source>Wallet name not valid. Please try again or use Ctrl-C to quit.</source> + <translation>Plånbokens namn ej giltigt. Försök igen eller använd Ctrl-C för att avsluta.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="868"/> + <source>Wallet and key files found, loading...</source> + <translation>Plånbok och nyckelfil hittades, läser in …</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="874"/> + <source>Key file found but not wallet file. Regenerating...</source> + <translation>Nyckelfil hittades men inte plånboksfilen. Återskapar …</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> + <source>Key file not found. Failed to open wallet: </source> + <translation>Nyckelfilen kunde inte hittas. Det gick inte att öppna plånbok: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="894"/> + <source>Generating new wallet...</source> + <translation>Skapar ny plånbok …</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="937"/> + <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-json="jsonfilename" and --generate-from-keys="wallet_name"</source> + <translation>det går inte att ange mer än en av --generate-new-wallet="plånboksnamn", --wallet-file="plånboksnamn", --generate-from-view-key="plånboksnamn", --generate-from-json="json-filnamn" och --generate-from-keys="plånboksnamn"</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="953"/> + <source>can't specify both --restore-deterministic-wallet and --non-deterministic</source> + <translation>det går inte att ange både --restore-deterministic-wallet och --non-deterministic</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="982"/> + <source>Electrum-style word list failed verification</source> + <translation>det gick inte att verifiera ordlista av Electrum-typ</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="994"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1011"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1046"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1063"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1079"/> + <source>No data supplied, cancelled</source> + <translation>Ingen data angiven, avbryter</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1002"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1054"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2220"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2718"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3276"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3530"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4048"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4239"/> + <source>failed to parse address</source> + <translation>det gick inte att parsa adressen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1017"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1085"/> + <source>failed to parse view key secret key</source> + <translation>det gick inte att parsa hemlig visningsnyckel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1103"/> + <source>failed to verify view key secret key</source> + <translation>det gick inte att verifiera hemlig visningsnyckel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1031"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1107"/> + <source>view key does not match standard address</source> + <translation>visningsnyckel matchar inte standardadress</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1111"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1128"/> + <source>account creation failed</source> + <translation>det gick inte att skapa konto</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1069"/> + <source>failed to parse spend key secret key</source> + <translation>det gick inte att parsa spendernyckel hemlig nyckel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1095"/> + <source>failed to verify spend key secret key</source> + <translation>det gick inte att verifiera spendernyckel hemlig nyckel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1099"/> + <source>spend key does not match standard address</source> + <translation>spendernyckel matchar inte standardadress</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1199"/> + <source>failed to open account</source> + <translation>det gick inte att öppna konto</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1203"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1579"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1626"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3348"/> + <source>wallet is null</source> + <translation>plånbok är null</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1262"/> + <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or restart the wallet with the correct daemon address.</source> + <translation>Antingen har daemonen inte startat eller så angavs fel port. Se till att daemonen kör eller starta om plånboken med korrekt daemonadress.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1306"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1311"/> + <source>invalid language choice passed. Please try again. +</source> + <translation>ogiltigt språkval angavs. Försök igen. +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1370"/> + <source>View key: </source> + <translation>Visningsnyckel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1385"/> + <source>Your wallet has been generated! +To start synchronizing with the daemon, use the "refresh" command. +Use the "help" command to see the list of available commands. +Always use the "exit" command when closing monero-wallet-cli to save +your current session's state. Otherwise, you might need to synchronize +your wallet again (your wallet keys are NOT at risk in any case). +</source> + <translation>Din plånbok har skapats! +För att starta synkronisering med daemonen, använd kommandot "refresh". +Använd kommandot "help" för att se en lista över tillgängliga kommandon. +Använd alltid kommandot "exit" när du stänger monero-wallet-cli så att ditt aktuella sessionstillstånd sparas. Annars kan du bli tvungen att synkronisera +din plånbok igen (din plånboks nycklar är dock INTE hotade i vilket fall som helst). +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1492"/> + <source>You may want to remove the file "%s" and try again</source> + <translation>Du kan också vilja ta bort filen "%s" och försöka igen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1518"/> + <source>failed to deinitialize wallet</source> + <translation>det gick inte att avinitiera plånboken</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1570"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1968"/> + <source>this command requires a trusted daemon. Enable with --trusted-daemon</source> + <translation>detta kommando kräver en betrodd daemon. Aktivera med --trusted-daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1657"/> + <source>blockchain can't be saved: </source> + <translation>blockkedjan kan inte sparas: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1736"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1982"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2563"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2824"/> + <source>daemon is busy. Please try again later.</source> + <translation>daemonen är upptagen. Försök igen senare.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1740"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1986"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2390"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2567"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2828"/> + <source>no connection to daemon. Please make sure daemon is running.</source> + <translation>ingen anslutning till daemonen. Se till att daemonen körs.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1750"/> + <source>refresh error: </source> + <translation>fel vid uppdatering: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1794"/> + <source>Balance: </source> + <translation>Saldo: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> + <source>pubkey</source> + <translation>öppen nyckel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> + <source>key image</source> + <translation>nyckelavbildning</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> + <source>unlocked</source> + <translation>upplåst</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1846"/> + <source>ringct</source> + <translation>ringct</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> + <source>T</source> + <translation>S</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> + <source>F</source> + <translation>F</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> + <source>locked</source> + <translation>låst</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1857"/> + <source>RingCT</source> + <translation>RingCT</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1857"/> + <source>-</source> + <translation>-</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> + <source>payment ID has invalid format, expected 16 or 64 character hex string: </source> + <translation>betalnings-ID har ogiltigt format, en 16- eller 64-teckens hex-sträng förväntades: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1990"/> + <source>failed to get spent status</source> + <translation>det gick inte att hämta spenderingsstatus</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2105"/> + <source>the same transaction</source> + <translation>samma transaktion</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2105"/> + <source>blocks that are temporally very close</source> + <translation>block som ligger väldigt nära varandra i tiden</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2206"/> + <source>Locked blocks too high, max 1000000 (˜4 yrs)</source> + <translation>Låsta block för högt, max 1000000 (˜~4 år)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3258"/> + <source>usage: get_tx_proof <txid> <dest_address> [<tx_key>]</source> + <translation>användning: get_tx_proof <txid> <måladress> [<tx_key>]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3289"/> + <source>failed to parse tx_key</source> + <translation>det gick inte att parsa tx_nyckel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3298"/> + <source>Tx secret key was found for the given txid, but you've also provided another tx secret key which doesn't match the found one.</source> + <translation>Hemlig transaktionsnyckel hittades för det givna txid, men du har också angivit en annan hemlig transaktionsnyckel som inte matchar den hittade nyckeln.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3306"/> + <source>Tx secret key wasn't found in the wallet file. Provide it as the optional third parameter if you have it elsewhere.</source> + <translation>Den hemliga transaktionsnyckeln kunde inte hittas i plånboksfilen. Ange den som den valfria tredje parametern om du har den någon annanstans.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3330"/> + <source>Signature: </source> + <translation>Signatur: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3508"/> + <source>usage: check_tx_proof <txid> <address> <signature></source> + <translation>användning: check_tx_proof <txid> <adress> <signatur></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3539"/> + <source>Signature header check error</source> + <translation>Fel vid kontroll av signaturhuvud</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3550"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3560"/> + <source>Signature decoding error</source> + <translation>nFel vid avkodning av signatur</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3602"/> + <source>Tx pubkey was not found</source> + <translation>Transaktionens öppna nyckel kunde inte hittas</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3609"/> + <source>Good signature</source> + <translation>Bra signatur</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3613"/> + <source>Bad signature</source> + <translation>Dålig signatur</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3621"/> + <source>failed to generate key derivation</source> + <translation>det gick inte att skapa nyckelhärledning</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3994"/> + <source>usage: integrated_address [payment ID]</source> + <translation>användning: integrated_address [betalnings-ID]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4017"/> + <source>Integrated address: account %s, payment ID %s</source> + <translation>Integrerad adress: konto %s, betalnings-ID %s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4022"/> + <source>Standard address: </source> + <translation>Standardadress: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4027"/> + <source>failed to parse payment ID or address</source> + <translation>det gick inte att parsa betalnings-ID eller adress</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4038"/> + <source>usage: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</source> + <translation>användning: address_book [(add (<adress> [pid <långt eller kort betalnings-ID>])|<Integrerad adress> [<beskrivning eventuellt med blanktecken>])|(delete <index>)]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4070"/> + <source>failed to parse payment ID</source> + <translation>det gick inte att parsa betalnings-ID</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4088"/> + <source>failed to parse index</source> + <translation>det gick inte att parsa index</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4096"/> + <source>Address book is empty.</source> + <translation>Adressboken är tom.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4102"/> + <source>Index: </source> + <translation>Index: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4103"/> + <source>Address: </source> + <translation>Adress: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4104"/> + <source>Payment ID: </source> + <translation>Betalnings-ID: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4105"/> + <source>Description: </source> + <translation>Beskrivning: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4115"/> + <source>usage: set_tx_note [txid] free text note</source> + <translation>användning: set_tx_note [txid] fri textanteckning</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4143"/> + <source>usage: get_tx_note [txid]</source> + <translation>användning: get_tx_note [txid]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4193"/> + <source>usage: sign <filename></source> + <translation>användning: sign <filnamn></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4198"/> + <source>wallet is watch-only and cannot sign</source> + <translation>plånboken är enbart för granskning och kan inte signera</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4207"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4374"/> + <source>failed to read file </source> + <translation>det gick inte att läsa filen </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4219"/> + <source>usage: verify <filename> <address> <signature></source> + <translation>användning: verify <filnamn> <adress> <signatur></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4246"/> + <source>Bad signature from </source> + <translation>Dålig signatur från </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4250"/> + <source>Good signature from </source> + <translation>Bra signatur från </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4259"/> + <source>usage: export_key_images <filename></source> + <translation>användning: export_key_images <filnamn></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4264"/> + <source>wallet is watch-only and cannot export key images</source> + <translation>plånboken är enbart för granskning och kan inte exportera nyckelavbildningar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4274"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4346"/> + <source>failed to save file </source> + <translation>det gick inte att spara fil </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4285"/> + <source>Signed key images exported to </source> + <translation>Signerade nyckelavbildningar exporterades till </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4293"/> + <source>usage: import_key_images <filename></source> + <translation>användning: import_key_images <filnamn></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4323"/> + <source>usage: export_outputs <filename></source> + <translation>användning: export_outputs <filnamn></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4357"/> + <source>Outputs exported to </source> + <translation>Utgångar exporterades till </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4365"/> + <source>usage: import_outputs <filename></source> + <translation>användning: import_outputs <filnamn></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2246"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3818"/> + <source>amount is wrong: </source> + <translation>beloppet är fel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2247"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3819"/> + <source>expected number from 0 to </source> + <translation>förväntades: ett tal från 0 till </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2378"/> + <source>Money successfully sent, transaction </source> + <translation>Pengar skickades, transaktion </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3141"/> + <source>no connection to daemon. Please, make sure daemon is running.</source> + <translation>ingen anslutning till daemonen. Se till att daemonen körs.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2597"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2858"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3171"/> + <source>not enough outputs for specified mixin_count</source> + <translation>inte tillräckligt många utgångar för angiven mixin_count</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3174"/> + <source>output amount</source> + <translation>utgångens belopp</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3174"/> + <source>found outputs to mix</source> + <translation>hittade utgångar att mixa</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2428"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2605"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2866"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3179"/> + <source>transaction was not constructed</source> + <translation>transaktionen konstruerades inte</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2609"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> + <source>transaction %s was rejected by daemon with status: </source> + <translation>transaktionen %s avvisades av daemonen med status: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2443"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2620"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2881"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3191"/> + <source>one of destinations is zero</source> + <translation>ett av målen är noll</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> + <source>Failed to find a suitable way to split transactions</source> + <translation>Det gick inte att hitta ett passande sätt att dela upp transaktioner</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2452"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2629"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2890"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3200"/> + <source>unknown transfer error: </source> + <translation>okänt överföringsfel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2516"/> + <source>Sweeping </source> + <translation>Sveper upp </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2785"/> + <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No)</source> + <translation>Sveper upp %s för en total avgift på %s. Är detta okej? (J/Ja/N/Nej)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2816"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3129"/> + <source>Money successfully sent, transaction: </source> + <translation>Pengar skickades, transaktion: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3022"/> + <source>Change goes to more than one address</source> + <translation>Växel går till mer än en adress</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3047"/> + <source>%s change to %s</source> + <translation>%s växel till %s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3050"/> + <source>no change</source> + <translation>ingen växel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> + <source>Transaction successfully signed to file </source> + <translation>Transaktionen signerades till fil </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3226"/> + <source>usage: get_tx_key <txid></source> + <translation>användning: get_tx_key <transaktions-ID></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3266"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3354"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4122"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4150"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4450"/> + <source>failed to parse txid</source> + <translation>det gick inte att parsa transaktions-id</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3245"/> + <source>Tx key: </source> + <translation>Tx-nyckel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3250"/> + <source>no tx keys found for this txid</source> + <translation>inga tx-nycklar kunde hittas för detta txid</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3339"/> + <source>usage: check_tx_key <txid> <txkey> <address></source> + <translation>användning: check_tx_key <txid> <txnyckel> <adress></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3361"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3368"/> + <source>failed to parse tx key</source> + <translation>det gick inte att parsa transaktionsnyckeln</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3573"/> + <source>failed to get transaction from daemon</source> + <translation>det gick inte att hämta transaktion från daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3584"/> + <source>failed to parse transaction from daemon</source> + <translation>det gick inte att parsa transaktion från daemonen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3418"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3591"/> + <source>failed to validate transaction from daemon</source> + <translation>det gick inte att validera transaktion från daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3596"/> + <source>failed to get the right transaction from daemon</source> + <translation>det gick inte att hämta rätt transaktion från daemonen</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3385"/> + <source>failed to generate key derivation from supplied parameters</source> + <translation>det gick inte att skapa nyckelhärledning från angivna parametrar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3471"/> + <source>error: </source> + <translation>fel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3477"/> + <source>received</source> + <translation>mottaget</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3477"/> + <source>in txid</source> + <translation>i transaktions-id</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3481"/> + <source>received nothing in txid</source> + <translation>tog emot ingenting i transaktions-id</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3485"/> + <source>WARNING: this transaction is not yet included in the blockchain!</source> + <translation>VARNING: denna transaktion är ännu inte inkluderad i blockkedjan!</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3494"/> + <source>This transaction has %u confirmations</source> + <translation>Transaktionen har %u bekräftelser</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3498"/> + <source>WARNING: failed to determine number of confirmations!</source> + <translation>VARNING: det gick inte att avgöra antal bekräftelser!</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> + <source>usage: show_transfers [in|out|all|pending|failed] [<min_height> [<max_height>]]</source> + <translation>användning: show_transfers [in|out|all|pending|failed] [<min_höjd> [<max_höjd>]]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3700"/> + <source>bad min_height parameter:</source> + <translation>dålig parameter för min_height:</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3712"/> + <source>bad max_height parameter:</source> + <translation>dålig parameter för max_height:</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3760"/> + <source>in</source> + <translation>in</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> + <source>out</source> + <translation>ut</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> + <source>failed</source> + <translation>misslyckades</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3798"/> + <source>pending</source> + <translation>väntar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3809"/> + <source>usage: unspent_outputs [<min_amount> <max_amount>]</source> + <translation>användning: unspent_outputs [<min_belopp> <max_belopp>]</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3824"/> + <source><min_amount> should be smaller than <max_amount></source> + <translation><min_belopp> måste vara mindre än <max_belopp></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3856"/> + <source> +Amount: </source> + <translation> +Belopp: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3856"/> + <source>, number of keys: </source> + <translation>, antal nycklar: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3861"/> + <source> </source> + <translation></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3866"/> + <source> +Min block height: </source> + <translation> +Minblockhöjd: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3867"/> + <source> +Max block height: </source> + <translation> +Maxblockhöjd: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3868"/> + <source> +Min amount found: </source> + <translation> +Minbelopp funnet: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3869"/> + <source> +Max amount found: </source> + <translation> +Maxbelopp funnet: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3870"/> + <source> +Total count: </source> + <translation> +Totalt antal: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3910"/> + <source> +Bin size: </source> + <translation> +Storlek för binge: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3911"/> + <source> +Outputs per *: </source> + <translation> +Utgångar per *: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3913"/> + <source>count + ^ +</source> + <translation>antal + ^ +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3915"/> + <source> |</source> + <translation> |</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> + <source> +</source> + <translation> +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> + <source>+--> block height +</source> + <translation>+--> blockhöjd +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3918"/> + <source> ^</source> + <translation> ^</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3918"/> + <source>^ +</source> + <translation>^ +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3919"/> + <source> </source> + <translation></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3969"/> + <source>wallet</source> + <translation>plånbok</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4000"/> + <source>Random payment ID: </source> + <translation>Slumpmässigt betalnings-ID: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4001"/> + <source>Matching integrated address: </source> + <translation>Matchande integrerad adress: </translation> + </message> +</context> +<context> + <name>sw</name> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="116"/> + <source>Generate new wallet and save it to <arg></source> + <translation>Skapa ny plånbok och spara den till <arg></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="117"/> + <source>Generate incoming-only wallet from view key</source> + <translation>Skapa granskningsplånbok från visningsnyckel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="118"/> + <source>Generate wallet from private keys</source> + <translation>Skapa plånbok från privata nycklar</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="120"/> + <source>Specify Electrum seed for wallet recovery/creation</source> + <translation>Ange Electrum-frö för att återställa/skapa plånbok</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="121"/> + <source>Recover wallet using Electrum-style mnemonic seed</source> + <translation>Återställ plånbok genom användning av minnesfrö (Electrum-typ)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> + <source>Create non-deterministic view and spend keys</source> + <translation>Skapa non-deterministic visnings- och spendernyckel</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> + <source>Enable commands which rely on a trusted daemon</source> + <translation>Aktivera kommandon som kräver en betrodd daemon</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="124"/> + <source>Allow communicating with a daemon that uses a different RPC version</source> + <translation>Tillåt kommunikation med en daemon som använder en annan version av RPC</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> + <source>Restore from specific blockchain height</source> + <translation>Återställ från angiven blockkedjehöjd</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="136"/> + <source>daemon is busy. Please try again later.</source> + <translation>daemonen är upptagen. Försök igen senare.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="145"/> + <source>possibly lost connection to daemon</source> + <translation>anslutning till daemonen kan ha tappats</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="226"/> + <source>Error: </source> + <translation>Fel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4614"/> + <source>Failed to initialize wallet</source> + <translation>Det gick inte att initiera plånbok</translation> + </message> +</context> +<context> + <name>tools::dns_utils</name> + <message> + <location filename="../src/common/dns_utils.cpp" line="430"/> + <source>DNSSEC validation passed</source> + <translation>DNSSEC-validering godkänd</translation> + </message> + <message> + <location filename="../src/common/dns_utils.cpp" line="434"/> + <source>WARNING: DNSSEC validation was unsuccessful, this address may not be correct!</source> + <translation>VARNING: DNSSEC-verifiering misslyckades, denna adress kanske inte är korrekt!</translation> + </message> + <message> + <location filename="../src/common/dns_utils.cpp" line="437"/> + <source>For URL: </source> + <translation>För URL: </translation> + </message> + <message> + <location filename="../src/common/dns_utils.cpp" line="439"/> + <source> Monero Address = </source> + <translation> Monero-adress = </translation> + </message> + <message> + <location filename="../src/common/dns_utils.cpp" line="441"/> + <source>Is this OK? (Y/n) </source> + <translation>är det OK? (J/n) </translation> + </message> + <message> + <location filename="../src/common/dns_utils.cpp" line="451"/> + <source>you have cancelled the transfer request</source> + <translation>du har avbrutit överföringsbegäran</translation> + </message> +</context> +<context> + <name>tools::wallet2</name> + <message> + <location filename="../src/wallet/wallet2.cpp" line="106"/> + <source>Use daemon instance at <host>:<port></source> + <translation>Använd daemoninstans på <värddator>:<port></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="107"/> + <source>Use daemon instance at host <arg> instead of localhost</source> + <translation>Använd daemon-instansen på värddator <arg> istället för localhost</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="460"/> + <source>Wallet password</source> + <translation>Lösenord för plånboken</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="109"/> + <source>Wallet password file</source> + <translation>Lösenordsfil för plånboken</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="110"/> + <source>Use daemon instance at port <arg> instead of 18081</source> + <translation>Använd daemon-instansen på port <arg> istället för 18081</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="112"/> + <source>For testnet. Daemon must also be launched with --testnet flag</source> + <translation>För testnet. Daemonen måste också startas med flaggan --testnet</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="113"/> + <source>Restricts to view-only commands</source> + <translation>Begränsar till granskningskommandon</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="152"/> + <source>can't specify daemon host or port more than once</source> + <translation>det går inte ange värd eller port för daemonen mer än en gång</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="188"/> + <source>can't specify more than one of --password and --password-file</source> + <translation>det går inte att ange mer än en av --password och --password-file</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="204"/> + <source>the password file specified could not be read</source> + <translation>det gick inte att läsa angiven lösenordsfil</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="460"/> + <source>Enter new wallet password</source> + <translation>Ange nytt lösenord för plånboken</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="464"/> + <source>failed to read wallet password</source> + <translation>det gick inte att läsa lösenord för plånboken</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="227"/> + <source>Failed to load file </source> + <translation>Det gick inte att läsa in fil </translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="108"/> + <source>Wallet password (escape/quote as needed)</source> + <translation>Lösenord för plånboken (använd escape-sekvenser eller citattecken efter behov)</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="111"/> + <source>Specify username[:password] for daemon RPC client</source> + <translation>Ange användarnamn[:lösenord] för RPC-klient till daemonen</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="233"/> + <source>Failed to parse JSON</source> + <translation>Det gick inte att parsa JSON</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="240"/> + <source>Version %u too new, we can only grok up to %u</source> + <translation>Version %u är för ny, vi förstår bara upp till %u</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="258"/> + <source>failed to parse view key secret key</source> + <translation>det gick inte att parsa hemlig visningsnyckel</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="264"/> + <location filename="../src/wallet/wallet2.cpp" line="331"/> + <location filename="../src/wallet/wallet2.cpp" line="373"/> + <source>failed to verify view key secret key</source> + <translation>det gick inte att verifiera hemlig visningsnyckel</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="276"/> + <source>failed to parse spend key secret key</source> + <translation>det gick inte att parsa spendernyckel hemlig nyckel</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="282"/> + <location filename="../src/wallet/wallet2.cpp" line="343"/> + <location filename="../src/wallet/wallet2.cpp" line="394"/> + <source>failed to verify spend key secret key</source> + <translation>det gick inte att verifiera spendernyckel hemlig nyckel</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="295"/> + <source>Electrum-style word list failed verification</source> + <translation>det gick inte att verifiera ordlista av Electrum-typ</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="306"/> + <source>At least one of Electrum-style word list and private view key must be specified</source> + <translation>Åtminstone en av ordlista av Electrum-typ och privat visningsnyckel måste anges</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="311"/> + <source>Both Electrum-style word list and private key(s) specified</source> + <translation>Både ordlista av Electrum-typ och privat nyckel har angivits</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="324"/> + <source>invalid address</source> + <translation>ogiltig adress</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="335"/> + <source>view key does not match standard address</source> + <translation>visningsnyckel matchar inte standardadress</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="347"/> + <source>spend key does not match standard address</source> + <translation>spendernyckel matchar inte standardadress</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="356"/> + <source>Cannot create deprecated wallets from JSON</source> + <translation>Det går inte att skapa inaktuella plånböcker från JSON</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="403"/> + <source>failed to generate new wallet: </source> + <translation>det gick inte att skapa ny plånbok: </translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="5205"/> + <source>failed to read file </source> + <translation>det gick inte att läsa filen </translation> + </message> +</context> +<context> + <name>tools::wallet_rpc_server</name> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="151"/> + <source>Daemon is local, assuming trusted</source> + <translation>Daemonen är lokal, utgår från att den är betrodd</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="171"/> + <source>Cannot specify --</source> + <translation>Det går inte att ange --</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="171"/> + <source> and --</source> + <translation> och --</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="198"/> + <source>Failed to create file </source> + <translation>Det gick inte att skapa fil </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="198"/> + <source>. Check permissions or remove file</source> + <translation>. Kontrollera behörigheter eller ta bort filen</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="209"/> + <source>Error writing to file </source> + <translation>Fel vid skrivning till fil </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="212"/> + <source>RPC username/password is stored in file </source> + <translation>Användarnamn/lösenord för RPC har sparats i fil </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1748"/> + <source>Can't specify more than one of --wallet-file and --generate-from-json</source> + <translation>Det går inte att ange mer än en av --wallet-file och --generate-from-json</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1760"/> + <source>Must specify --wallet-file or --generate-from-json or --wallet-dir</source> + <translation>Måste ange --wallet-file eller --generate-from-json eller --wallet-dir</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1764"/> + <source>Loading wallet...</source> + <translation>Läser in plånbok …</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1789"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1814"/> + <source>Storing wallet...</source> + <translation>Sparar plånbok …</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1791"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1816"/> + <source>Stored ok</source> + <translation>Sparad ok</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1794"/> + <source>Loaded ok</source> + <translation>Inläst ok</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1798"/> + <source>Wallet initialization failed: </source> + <translation>Det gick inte att initiera plånbok: </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1805"/> + <source>Failed to initialize wallet rpc server</source> + <translation>Det gick inte att initiera RPC-servern för plånbok</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1809"/> + <source>Starting wallet rpc server</source> + <translation>Startar RPC-servern för plånbok</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1811"/> + <source>Stopped wallet rpc server</source> + <translation>Stoppade RPC-servern för plånbok</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1820"/> + <source>Failed to store wallet: </source> + <translation>Det gick inte att spara plånbok: </translation> + </message> +</context> +<context> + <name>wallet_args</name> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4580"/> + <source>Wallet options</source> + <translation>Alternativ för plånbok</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="59"/> + <source>Generate wallet from JSON format file</source> + <translation>Skapa plånbok från fil i JSON-format</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="63"/> + <source>Use wallet <arg></source> + <translation>Använd plånbok <arg></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="87"/> + <source>Max number of threads to use for a parallel job</source> + <translation>Max antal trådar att använda för ett parallellt jobb</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="88"/> + <source>Specify log file</source> + <translation>Ange loggfil</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="89"/> + <source>Config file</source> + <translation>Konfigurationsfil</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="98"/> + <source>General options</source> + <translation>Allmänna alternativ</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="128"/> + <source>Can't find config file </source> + <translation>Det gick inte att hitta konfigurationsfilen </translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="172"/> + <source>Logging to: </source> + <translation>Loggar till: </translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="173"/> + <source>Logging to %s</source> + <translation>Loggar till %s</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="153"/> + <source>Usage:</source> + <translation>Användning:</translation> + </message> +</context> +</TS> |