|
|
|
@ -14,10 +14,10 @@ namespace xmreg
|
|
|
|
|
* into crypto::secret_key or crypto::public_key
|
|
|
|
|
* depending on the template argument.
|
|
|
|
|
*/
|
|
|
|
|
template <typename T>
|
|
|
|
|
bool
|
|
|
|
|
parse_str_secret_key(const string& key_str, T& secret_key)
|
|
|
|
|
{
|
|
|
|
|
template <typename T>
|
|
|
|
|
bool
|
|
|
|
|
parse_str_secret_key(const string& key_str, T& secret_key)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// hash and keys have same structure, so to parse string of
|
|
|
|
|
// a key, e.g., a view key, we can first parse it into the hash
|
|
|
|
@ -38,21 +38,21 @@ parse_str_secret_key(const string& key_str, T& secret_key)
|
|
|
|
|
copy(begin(hash_.data), end(hash_.data), secret_key.data);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// explicit instantiations of get template function
|
|
|
|
|
template bool parse_str_secret_key<crypto::secret_key>(const string& key_str, crypto::secret_key& secret_key);
|
|
|
|
|
template bool parse_str_secret_key<crypto::public_key>(const string& key_str, crypto::public_key& secret_key);
|
|
|
|
|
template bool parse_str_secret_key<crypto::hash>(const string& key_str, crypto::hash& secret_key);
|
|
|
|
|
template bool parse_str_secret_key<crypto::secret_key>(const string& key_str, crypto::secret_key& secret_key);
|
|
|
|
|
template bool parse_str_secret_key<crypto::public_key>(const string& key_str, crypto::public_key& secret_key);
|
|
|
|
|
template bool parse_str_secret_key<crypto::hash>(const string& key_str, crypto::hash& secret_key);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get transaction tx using given tx hash. Hash is represent as string here,
|
|
|
|
|
* so before we can tap into the blockchain, we need to pare it into
|
|
|
|
|
* crypto::hash object.
|
|
|
|
|
*/
|
|
|
|
|
bool
|
|
|
|
|
get_tx_pub_key_from_str_hash(Blockchain& core_storage, const string& hash_str, transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
bool
|
|
|
|
|
get_tx_pub_key_from_str_hash(Blockchain& core_storage, const string& hash_str, transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
crypto::hash tx_hash;
|
|
|
|
|
parse_hash256(hash_str, tx_hash);
|
|
|
|
|
|
|
|
|
@ -68,17 +68,17 @@ get_tx_pub_key_from_str_hash(Blockchain& core_storage, const string& hash_str, t
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Parse monero address in a string form into
|
|
|
|
|
* cryptonote::account_public_address object
|
|
|
|
|
*/
|
|
|
|
|
bool
|
|
|
|
|
parse_str_address(const string& address_str,
|
|
|
|
|
bool
|
|
|
|
|
parse_str_address(const string& address_str,
|
|
|
|
|
account_public_address& address,
|
|
|
|
|
bool testnet)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (!get_account_address_from_str(address, testnet, address_str))
|
|
|
|
|
{
|
|
|
|
@ -87,58 +87,58 @@ parse_str_address(const string& address_str,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return string representation of monero address
|
|
|
|
|
*/
|
|
|
|
|
string
|
|
|
|
|
print_address(const account_public_address& address, bool testnet)
|
|
|
|
|
{
|
|
|
|
|
string
|
|
|
|
|
print_address(const account_public_address& address, bool testnet)
|
|
|
|
|
{
|
|
|
|
|
return "<" + get_account_address_as_str(testnet, address) + ">";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string
|
|
|
|
|
print_sig (const signature& sig)
|
|
|
|
|
{
|
|
|
|
|
string
|
|
|
|
|
print_sig (const signature& sig)
|
|
|
|
|
{
|
|
|
|
|
stringstream ss;
|
|
|
|
|
|
|
|
|
|
ss << "c: <" << epee::string_tools::pod_to_hex(sig.c) << "> "
|
|
|
|
|
<< "r: <" << epee::string_tools::pod_to_hex(sig.r) << ">";
|
|
|
|
|
|
|
|
|
|
return ss.str();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if a character is a path seprator
|
|
|
|
|
*/
|
|
|
|
|
inline bool
|
|
|
|
|
is_separator(char c)
|
|
|
|
|
{
|
|
|
|
|
inline bool
|
|
|
|
|
is_separator(char c)
|
|
|
|
|
{
|
|
|
|
|
// default linux path separator
|
|
|
|
|
const char separator = PATH_SEPARARTOR;
|
|
|
|
|
|
|
|
|
|
return c == separator;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove trailinig path separator.
|
|
|
|
|
*/
|
|
|
|
|
string
|
|
|
|
|
remove_trailing_path_separator(const string& in_path)
|
|
|
|
|
{
|
|
|
|
|
string
|
|
|
|
|
remove_trailing_path_separator(const string& in_path)
|
|
|
|
|
{
|
|
|
|
|
string new_string = in_path;
|
|
|
|
|
if (!new_string.empty() && is_separator(new_string[new_string.size() - 1]))
|
|
|
|
|
new_string.erase(new_string.size() - 1);
|
|
|
|
|
return new_string;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bf::path
|
|
|
|
|
remove_trailing_path_separator(const bf::path& in_path)
|
|
|
|
|
{
|
|
|
|
|
bf::path
|
|
|
|
|
remove_trailing_path_separator(const bf::path& in_path)
|
|
|
|
|
{
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
|
|
|
|
|
string path_str = converter.to_bytes(in_path.native());
|
|
|
|
@ -146,7 +146,7 @@ remove_trailing_path_separator(const bf::path& in_path)
|
|
|
|
|
string path_str = in_path.native();
|
|
|
|
|
#endif
|
|
|
|
|
return bf::path(remove_trailing_path_separator(path_str));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//string
|
|
|
|
|
//timestamp_to_str(time_t timestamp, const char* format)
|
|
|
|
@ -155,9 +155,9 @@ remove_trailing_path_separator(const bf::path& in_path)
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string
|
|
|
|
|
timestamp_to_str_gm(time_t timestamp, const char* format)
|
|
|
|
|
{
|
|
|
|
|
string
|
|
|
|
|
timestamp_to_str_gm(time_t timestamp, const char* format)
|
|
|
|
|
{
|
|
|
|
|
const time_t* t = ×tamp;
|
|
|
|
|
|
|
|
|
|
const int TIME_LENGTH = 60;
|
|
|
|
@ -172,26 +172,26 @@ timestamp_to_str_gm(time_t timestamp, const char* format)
|
|
|
|
|
len = std::strftime(str_buff, TIME_LENGTH, format, &tmp);
|
|
|
|
|
|
|
|
|
|
return string(str_buff, len);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ostream&
|
|
|
|
|
operator<< (ostream& os, const account_public_address& addr)
|
|
|
|
|
{
|
|
|
|
|
ostream&
|
|
|
|
|
operator<< (ostream& os, const account_public_address& addr)
|
|
|
|
|
{
|
|
|
|
|
os << get_account_address_as_str(false, addr);
|
|
|
|
|
return os;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Generate key_image of foran ith output
|
|
|
|
|
*/
|
|
|
|
|
bool
|
|
|
|
|
generate_key_image(const crypto::key_derivation& derivation,
|
|
|
|
|
bool
|
|
|
|
|
generate_key_image(const crypto::key_derivation& derivation,
|
|
|
|
|
const std::size_t i,
|
|
|
|
|
const crypto::secret_key& sec_key,
|
|
|
|
|
const crypto::public_key& pub_key,
|
|
|
|
|
crypto::key_image& key_img)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
cryptonote::keypair in_ephemeral;
|
|
|
|
|
|
|
|
|
@ -230,12 +230,12 @@ generate_key_image(const crypto::key_derivation& derivation,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string
|
|
|
|
|
get_default_lmdb_folder(bool testnet)
|
|
|
|
|
{
|
|
|
|
|
string
|
|
|
|
|
get_default_lmdb_folder(bool testnet)
|
|
|
|
|
{
|
|
|
|
|
// default path to monero folder
|
|
|
|
|
// on linux this is /home/<username>/.bitmonero
|
|
|
|
|
string default_monero_dir = tools::get_default_data_dir();
|
|
|
|
@ -247,7 +247,7 @@ get_default_lmdb_folder(bool testnet)
|
|
|
|
|
// the default folder of the lmdb blockchain database
|
|
|
|
|
// is therefore as follows
|
|
|
|
|
return default_monero_dir + string("/lmdb");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -255,11 +255,11 @@ get_default_lmdb_folder(bool testnet)
|
|
|
|
|
*
|
|
|
|
|
* If not given, provide default path
|
|
|
|
|
*/
|
|
|
|
|
bool
|
|
|
|
|
get_blockchain_path(const boost::optional<string>& bc_path,
|
|
|
|
|
bool
|
|
|
|
|
get_blockchain_path(const boost::optional<string>& bc_path,
|
|
|
|
|
bf::path& blockchain_path,
|
|
|
|
|
bool testnet)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
// the default folder of the lmdb blockchain database
|
|
|
|
|
string default_lmdb_dir = xmreg::get_default_lmdb_folder(testnet);
|
|
|
|
|
|
|
|
|
@ -279,12 +279,12 @@ get_blockchain_path(const boost::optional<string>& bc_path,
|
|
|
|
|
blockchain_path = xmreg::remove_trailing_path_separator(blockchain_path);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
|
sum_money_in_outputs(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
uint64_t
|
|
|
|
|
sum_money_in_outputs(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
uint64_t sum_xmr {0};
|
|
|
|
|
|
|
|
|
|
for (const tx_out& txout: tx.vout)
|
|
|
|
@ -293,11 +293,11 @@ sum_money_in_outputs(const transaction& tx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sum_xmr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pair<uint64_t, uint64_t>
|
|
|
|
|
sum_money_in_outputs(const string& json_str)
|
|
|
|
|
{
|
|
|
|
|
pair<uint64_t, uint64_t>
|
|
|
|
|
sum_money_in_outputs(const string& json_str)
|
|
|
|
|
{
|
|
|
|
|
pair<uint64_t, uint64_t> sum_xmr {0, 0};
|
|
|
|
|
|
|
|
|
|
json j;
|
|
|
|
@ -320,11 +320,11 @@ sum_money_in_outputs(const string& json_str)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return sum_xmr;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pair<uint64_t, uint64_t>
|
|
|
|
|
sum_money_in_outputs(const json& _json)
|
|
|
|
|
{
|
|
|
|
|
pair<uint64_t, uint64_t>
|
|
|
|
|
sum_money_in_outputs(const json& _json)
|
|
|
|
|
{
|
|
|
|
|
pair<uint64_t, uint64_t> sum_xmr {0ULL, 0ULL};
|
|
|
|
|
|
|
|
|
|
for (const json& vout: _json["vout"])
|
|
|
|
@ -334,15 +334,15 @@ sum_money_in_outputs(const json& _json)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sum_xmr;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
array<uint64_t, 4>
|
|
|
|
|
summary_of_in_out_rct(
|
|
|
|
|
array<uint64_t, 4>
|
|
|
|
|
summary_of_in_out_rct(
|
|
|
|
|
const transaction& tx,
|
|
|
|
|
vector<pair<txout_to_key, uint64_t>>& output_pub_keys,
|
|
|
|
|
vector<txin_to_key>& input_key_imgs)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
uint64_t xmr_outputs {0};
|
|
|
|
|
uint64_t xmr_inputs {0};
|
|
|
|
@ -400,13 +400,13 @@ summary_of_in_out_rct(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return {xmr_outputs, xmr_inputs, mixin_no, num_nonrct_inputs};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// this version for mempool txs from json
|
|
|
|
|
array<uint64_t, 6>
|
|
|
|
|
summary_of_in_out_rct(const json& _json)
|
|
|
|
|
{
|
|
|
|
|
array<uint64_t, 6>
|
|
|
|
|
summary_of_in_out_rct(const json& _json)
|
|
|
|
|
{
|
|
|
|
|
uint64_t xmr_outputs {0};
|
|
|
|
|
uint64_t xmr_inputs {0};
|
|
|
|
|
uint64_t no_outputs {0};
|
|
|
|
@ -436,12 +436,12 @@ summary_of_in_out_rct(const json& _json)
|
|
|
|
|
mixin_no = _json["vin"].at(0)["key"]["key_offsets"].size() - 1;
|
|
|
|
|
|
|
|
|
|
return {xmr_outputs, xmr_inputs, no_outputs, no_inputs, mixin_no, num_nonrct_inputs};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
|
sum_money_in_inputs(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
uint64_t
|
|
|
|
|
sum_money_in_inputs(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
uint64_t sum_xmr {0};
|
|
|
|
|
|
|
|
|
|
size_t input_no = tx.vin.size();
|
|
|
|
@ -462,11 +462,11 @@ sum_money_in_inputs(const transaction& tx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sum_xmr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pair<uint64_t, uint64_t>
|
|
|
|
|
sum_money_in_inputs(const string& json_str)
|
|
|
|
|
{
|
|
|
|
|
pair<uint64_t, uint64_t>
|
|
|
|
|
sum_money_in_inputs(const string& json_str)
|
|
|
|
|
{
|
|
|
|
|
pair<uint64_t, uint64_t> sum_xmr {0, 0};
|
|
|
|
|
|
|
|
|
|
json j;
|
|
|
|
@ -487,12 +487,12 @@ sum_money_in_inputs(const string& json_str)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sum_xmr;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pair<uint64_t, uint64_t>
|
|
|
|
|
sum_money_in_inputs(const json& _json)
|
|
|
|
|
{
|
|
|
|
|
pair<uint64_t, uint64_t>
|
|
|
|
|
sum_money_in_inputs(const json& _json)
|
|
|
|
|
{
|
|
|
|
|
pair<uint64_t, uint64_t> sum_xmr {0, 0};
|
|
|
|
|
|
|
|
|
|
for (const json& vin: _json["vin"])
|
|
|
|
@ -502,11 +502,11 @@ sum_money_in_inputs(const json& _json)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sum_xmr;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
|
count_nonrct_inputs(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
uint64_t
|
|
|
|
|
count_nonrct_inputs(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
uint64_t num {0};
|
|
|
|
|
|
|
|
|
|
size_t input_no = tx.vin.size();
|
|
|
|
@ -528,11 +528,11 @@ count_nonrct_inputs(const transaction& tx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return num;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
|
count_nonrct_inputs(const string& json_str)
|
|
|
|
|
{
|
|
|
|
|
uint64_t
|
|
|
|
|
count_nonrct_inputs(const string& json_str)
|
|
|
|
|
{
|
|
|
|
|
uint64_t num {0};
|
|
|
|
|
|
|
|
|
|
json j;
|
|
|
|
@ -554,12 +554,12 @@ count_nonrct_inputs(const string& json_str)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return num;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
|
count_nonrct_inputs(const json& _json)
|
|
|
|
|
{
|
|
|
|
|
uint64_t
|
|
|
|
|
count_nonrct_inputs(const json& _json)
|
|
|
|
|
{
|
|
|
|
|
uint64_t num {0};
|
|
|
|
|
|
|
|
|
|
for (const json& vin: _json["vin"])
|
|
|
|
@ -570,23 +570,23 @@ count_nonrct_inputs(const json& _json)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return num;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
array<uint64_t, 2>
|
|
|
|
|
sum_money_in_tx(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
array<uint64_t, 2>
|
|
|
|
|
sum_money_in_tx(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
array<uint64_t, 2> sum_xmr;
|
|
|
|
|
|
|
|
|
|
sum_xmr[0] = sum_money_in_inputs(tx);
|
|
|
|
|
sum_xmr[1] = sum_money_in_outputs(tx);
|
|
|
|
|
|
|
|
|
|
return sum_xmr;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
array<uint64_t, 2>
|
|
|
|
|
sum_money_in_txs(const vector<transaction>& txs)
|
|
|
|
|
{
|
|
|
|
|
array<uint64_t, 2>
|
|
|
|
|
sum_money_in_txs(const vector<transaction>& txs)
|
|
|
|
|
{
|
|
|
|
|
array<uint64_t, 2> sum_xmr {0,0};
|
|
|
|
|
|
|
|
|
|
for (const transaction& tx: txs)
|
|
|
|
@ -596,12 +596,12 @@ sum_money_in_txs(const vector<transaction>& txs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sum_xmr;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
|
sum_fees_in_txs(const vector<transaction>& txs)
|
|
|
|
|
{
|
|
|
|
|
uint64_t
|
|
|
|
|
sum_fees_in_txs(const vector<transaction>& txs)
|
|
|
|
|
{
|
|
|
|
|
uint64_t fees_sum {0};
|
|
|
|
|
|
|
|
|
|
for (const transaction& tx: txs)
|
|
|
|
@ -610,13 +610,13 @@ sum_fees_in_txs(const vector<transaction>& txs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fees_sum;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vector<pair<txout_to_key, uint64_t>>
|
|
|
|
|
get_ouputs(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
vector<pair<txout_to_key, uint64_t>>
|
|
|
|
|
get_ouputs(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
vector<pair<txout_to_key, uint64_t>> outputs;
|
|
|
|
|
|
|
|
|
|
for (const tx_out& txout: tx.vout)
|
|
|
|
@ -637,11 +637,11 @@ get_ouputs(const transaction& tx)
|
|
|
|
|
|
|
|
|
|
return outputs;
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
vector<tuple<txout_to_key, uint64_t, uint64_t>>
|
|
|
|
|
get_ouputs_tuple(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
vector<tuple<txout_to_key, uint64_t, uint64_t>>
|
|
|
|
|
get_ouputs_tuple(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
vector<tuple<txout_to_key, uint64_t, uint64_t>> outputs;
|
|
|
|
|
|
|
|
|
|
for (uint64_t n = 0; n < tx.vout.size(); ++n)
|
|
|
|
@ -660,11 +660,11 @@ get_ouputs_tuple(const transaction& tx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return outputs;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
|
get_mixin_no(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
uint64_t
|
|
|
|
|
get_mixin_no(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
uint64_t mixin_no {0};
|
|
|
|
|
|
|
|
|
|
size_t input_no = tx.vin.size();
|
|
|
|
@ -692,10 +692,10 @@ get_mixin_no(const transaction& tx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mixin_no;
|
|
|
|
|
}
|
|
|
|
|
vector<uint64_t>
|
|
|
|
|
get_mixin_no(const string& json_str)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
vector<uint64_t>
|
|
|
|
|
get_mixin_no(const string& json_str)
|
|
|
|
|
{
|
|
|
|
|
vector<uint64_t> mixin_no;
|
|
|
|
|
|
|
|
|
|
json j;
|
|
|
|
@ -713,23 +713,23 @@ get_mixin_no(const string& json_str)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mixin_no;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vector<uint64_t>
|
|
|
|
|
get_mixin_no(const json& _json)
|
|
|
|
|
{
|
|
|
|
|
vector<uint64_t>
|
|
|
|
|
get_mixin_no(const json& _json)
|
|
|
|
|
{
|
|
|
|
|
vector<uint64_t> mixin_no;
|
|
|
|
|
|
|
|
|
|
mixin_no.push_back(_json["vin"].at(0)["key"]["key_offsets"].size());
|
|
|
|
|
|
|
|
|
|
return mixin_no;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vector<uint64_t>
|
|
|
|
|
get_mixin_no_in_txs(const vector<transaction>& txs)
|
|
|
|
|
{
|
|
|
|
|
vector<uint64_t>
|
|
|
|
|
get_mixin_no_in_txs(const vector<transaction>& txs)
|
|
|
|
|
{
|
|
|
|
|
vector<uint64_t> mixin_no;
|
|
|
|
|
|
|
|
|
|
for (const transaction& tx: txs)
|
|
|
|
@ -738,12 +738,12 @@ get_mixin_no_in_txs(const vector<transaction>& txs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mixin_no;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vector<txin_to_key>
|
|
|
|
|
get_key_images(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
vector<txin_to_key>
|
|
|
|
|
get_key_images(const transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
vector<txin_to_key> key_images;
|
|
|
|
|
|
|
|
|
|
size_t input_no = tx.vin.size();
|
|
|
|
@ -764,14 +764,14 @@ get_key_images(const transaction& tx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return key_images;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
get_payment_id(const vector<uint8_t>& extra,
|
|
|
|
|
bool
|
|
|
|
|
get_payment_id(const vector<uint8_t>& extra,
|
|
|
|
|
crypto::hash& payment_id,
|
|
|
|
|
crypto::hash8& payment_id8)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
payment_id = null_hash;
|
|
|
|
|
payment_id8 = null_hash8;
|
|
|
|
|
|
|
|
|
@ -798,21 +798,21 @@ get_payment_id(const vector<uint8_t>& extra,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
get_payment_id(const transaction& tx,
|
|
|
|
|
bool
|
|
|
|
|
get_payment_id(const transaction& tx,
|
|
|
|
|
crypto::hash& payment_id,
|
|
|
|
|
crypto::hash8& payment_id8)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
return get_payment_id(tx.extra, payment_id, payment_id8);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
array<size_t, 5>
|
|
|
|
|
timestamp_difference(uint64_t t1, uint64_t t2)
|
|
|
|
|
{
|
|
|
|
|
array<size_t, 5>
|
|
|
|
|
timestamp_difference(uint64_t t1, uint64_t t2)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
uint64_t timestamp_diff = t1 - t2;
|
|
|
|
|
|
|
|
|
@ -844,12 +844,12 @@ timestamp_difference(uint64_t t1, uint64_t t2)
|
|
|
|
|
time_diff_hours, time_diff_minutes,
|
|
|
|
|
time_diff_seconds};
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string
|
|
|
|
|
read(string filename)
|
|
|
|
|
{
|
|
|
|
|
string
|
|
|
|
|
read(string filename)
|
|
|
|
|
{
|
|
|
|
|
if (!bf::exists(bf::path(filename)))
|
|
|
|
|
{
|
|
|
|
|
cerr << "File does not exist: " << filename << endl;
|
|
|
|
@ -859,14 +859,14 @@ read(string filename)
|
|
|
|
|
std::ifstream t(filename);
|
|
|
|
|
return string(std::istreambuf_iterator<char>(t),
|
|
|
|
|
std::istreambuf_iterator<char>());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pair<string, double>
|
|
|
|
|
timestamps_time_scale(const vector<uint64_t>& timestamps,
|
|
|
|
|
pair<string, double>
|
|
|
|
|
timestamps_time_scale(const vector<uint64_t>& timestamps,
|
|
|
|
|
uint64_t timeN,
|
|
|
|
|
uint64_t resolution,
|
|
|
|
|
uint64_t time0)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
string empty_time = string(resolution, '_');
|
|
|
|
|
|
|
|
|
|
size_t time_axis_length = empty_time.size();
|
|
|
|
@ -891,26 +891,26 @@ timestamps_time_scale(const vector<uint64_t>& timestamps,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return make_pair(empty_time, scale);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// useful reference to get epoch time in correct timezon
|
|
|
|
|
// http://www.boost.org/doc/libs/1_41_0/doc/html/date_time/examples.html#date_time.examples.seconds_since_epoch
|
|
|
|
|
time_t
|
|
|
|
|
ptime_to_time_t(const pt::ptime& in_ptime)
|
|
|
|
|
{
|
|
|
|
|
time_t
|
|
|
|
|
ptime_to_time_t(const pt::ptime& in_ptime)
|
|
|
|
|
{
|
|
|
|
|
static pt::ptime epoch(gt::date(1970, 1, 1));
|
|
|
|
|
pt::time_duration::sec_type no_seconds = (in_ptime - epoch).total_seconds();
|
|
|
|
|
return time_t(no_seconds);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
decode_ringct(const rct::rctSig& rv,
|
|
|
|
|
bool
|
|
|
|
|
decode_ringct(const rct::rctSig& rv,
|
|
|
|
|
const crypto::public_key pub,
|
|
|
|
|
const crypto::secret_key &sec,
|
|
|
|
|
unsigned int i,
|
|
|
|
|
rct::key & mask,
|
|
|
|
|
uint64_t & amount)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
crypto::key_derivation derivation;
|
|
|
|
@ -953,11 +953,11 @@ decode_ringct(const rct::rctSig& rv,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
url_decode(const std::string& in, std::string& out)
|
|
|
|
|
{
|
|
|
|
|
bool
|
|
|
|
|
url_decode(const std::string& in, std::string& out)
|
|
|
|
|
{
|
|
|
|
|
out.clear();
|
|
|
|
|
out.reserve(in.size());
|
|
|
|
|
for (std::size_t i = 0; i < in.size(); ++i)
|
|
|
|
@ -993,11 +993,11 @@ url_decode(const std::string& in, std::string& out)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
map<std::string, std::string>
|
|
|
|
|
parse_crow_post_data(const string& req_body)
|
|
|
|
|
{
|
|
|
|
|
map<std::string, std::string>
|
|
|
|
|
parse_crow_post_data(const string& req_body)
|
|
|
|
|
{
|
|
|
|
|
map<std::string, std::string> body;
|
|
|
|
|
|
|
|
|
|
vector<string> vec;
|
|
|
|
@ -1020,15 +1020,15 @@ parse_crow_post_data(const string& req_body)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return body;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// from wallet2::decrypt
|
|
|
|
|
string
|
|
|
|
|
decrypt(const std::string &ciphertext,
|
|
|
|
|
string
|
|
|
|
|
decrypt(const std::string &ciphertext,
|
|
|
|
|
const crypto::secret_key &skey,
|
|
|
|
|
bool authenticated)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
const size_t prefix_size = sizeof(chacha8_iv)
|
|
|
|
|
+ (authenticated ? sizeof(crypto::signature) : 0);
|
|
|
|
@ -1071,13 +1071,13 @@ decrypt(const std::string &ciphertext,
|
|
|
|
|
key, iv, &plaintext[0]);
|
|
|
|
|
|
|
|
|
|
return plaintext;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// based on
|
|
|
|
|
// crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const
|
|
|
|
|
public_key
|
|
|
|
|
get_tx_pub_key_from_received_outs(const transaction &tx)
|
|
|
|
|
{
|
|
|
|
|
public_key
|
|
|
|
|
get_tx_pub_key_from_received_outs(const transaction &tx)
|
|
|
|
|
{
|
|
|
|
|
std::vector<tx_extra_field> tx_extra_fields;
|
|
|
|
|
|
|
|
|
|
if(!parse_tx_extra(tx.extra, tx_extra_fields))
|
|
|
|
@ -1115,20 +1115,20 @@ get_tx_pub_key_from_received_outs(const transaction &tx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null_pkey;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if given output (specified by output_index)
|
|
|
|
|
* belongs is ours based
|
|
|
|
|
* on our private view key and public spend key
|
|
|
|
|
*/
|
|
|
|
|
bool
|
|
|
|
|
is_output_ours(const size_t& output_index,
|
|
|
|
|
bool
|
|
|
|
|
is_output_ours(const size_t& output_index,
|
|
|
|
|
const transaction& tx,
|
|
|
|
|
const public_key& pub_tx_key,
|
|
|
|
|
const secret_key& private_view_key,
|
|
|
|
|
const public_key& public_spend_key)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
// public transaction key is combined with our viewkey
|
|
|
|
|
// to create, so called, derived key.
|
|
|
|
|
key_derivation derivation;
|
|
|
|
@ -1166,27 +1166,27 @@ is_output_ours(const size_t& output_index,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
get_real_output_for_key_image(const key_image& ki,
|
|
|
|
|
bool
|
|
|
|
|
get_real_output_for_key_image(const key_image& ki,
|
|
|
|
|
const transaction& tx,
|
|
|
|
|
const secret_key& private_view_key,
|
|
|
|
|
const public_key& public_spend_key,
|
|
|
|
|
uint64_t output_idx,
|
|
|
|
|
public_key output_pub_key)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
make_tx_from_json(const string& json_str, transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
bool
|
|
|
|
|
make_tx_from_json(const string& json_str, transaction& tx)
|
|
|
|
|
{
|
|
|
|
|
json j;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
@ -1448,12 +1448,12 @@ make_tx_from_json(const string& json_str, transaction& tx)
|
|
|
|
|
//cout << "From reconstructed tx: " << obj_to_json_str(tx) << endl;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string
|
|
|
|
|
make_printable(const string& in_s)
|
|
|
|
|
{
|
|
|
|
|
string
|
|
|
|
|
make_printable(const string& in_s)
|
|
|
|
|
{
|
|
|
|
|
string output;
|
|
|
|
|
|
|
|
|
|
for (char c: in_s)
|
|
|
|
@ -1486,13 +1486,13 @@ make_printable(const string& in_s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string
|
|
|
|
|
get_human_readable_timestamp(uint64_t ts)
|
|
|
|
|
{
|
|
|
|
|
string
|
|
|
|
|
get_human_readable_timestamp(uint64_t ts)
|
|
|
|
|
{
|
|
|
|
|
char buffer[64];
|
|
|
|
|
if (ts < 1234567890)
|
|
|
|
|
return "<unknown>";
|
|
|
|
@ -1506,11 +1506,11 @@ get_human_readable_timestamp(uint64_t ts)
|
|
|
|
|
strftime(buffer, sizeof(buffer), "%Y-%m-%d %I:%M:%S", &tm);
|
|
|
|
|
|
|
|
|
|
return std::string(buffer);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
pause_execution(uint64_t no_seconds, const string& text)
|
|
|
|
|
{
|
|
|
|
|
void
|
|
|
|
|
pause_execution(uint64_t no_seconds, const string& text)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
cout << "\nPausing " << text
|
|
|
|
|
<< " for " << no_seconds << " seconds: "
|
|
|
|
@ -1523,7 +1523,6 @@ pause_execution(uint64_t no_seconds, const string& text)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cout << endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|