mirror of
https://github.com/monero-project/monero.git
synced 2024-10-01 11:49:47 -04:00
Modifications to enable Offline Signing in monero-gui and possible other projects via UR or other mediums of
exchange. Added the following signatures in the mention files: wallet/wallet2.h + std::string export_key_images_string(bool all = false) const; + uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent); M bool wallet2::export_key_images(const std::string &filename, bool all) const wallet/api/pending_transaction.h + std::string commit_string() override; wallet/api/unsigned_transaction.h + std::string signAsString() override; wallet/api/wallet.h: + bool submitTransactionFromString(const std::string &fileName) override; + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) override; + std::string exportKeyImagesAsString(bool all = false) override; + bool importKeyImagesFromString(const std::string &data) override; + std::string exportOutputsAsString(bool all = false) override; + bool importOutputsFromString(const std::string &data) override; wallet/api/wallet2_api.h + virtual std::string commit_string() = 0; + virtual std::string signAsString() = 0; + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) = 0; + virtual bool submitTransactionFromString(const std::string &fileName) = 0; + virtual bool importKeyImagesFromString(const std::string &data) = 0; + virtual std::string exportOutputsAsString(bool all = false) = 0; + virtual bool importOutputsFromString(const std::string &data) = 0; + uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent); And the implementations in: wallet/wallet2.cpp wallet/api/pending_transaction.cpp wallet/api/unsigned_transaction.cpp wallet/api/wallet.cpp The method `bool wallet2::export_key_images(const std::string &filename, bool all) const` is modified to use `std::string export_key_images_string(bool all = false) const;` to get the string to write to the file. IMO that would be the perfect way to do it everywhere, but in the other methods it would require more modifications, so the other I duplicated and removed the part writing to the file and return instead a std::string, or use a std::string for the actual payload instead of a file path. One thing to mention is I remove in one or two log messages the filename, and the other is in `export_key_images` probably(almost sure) is now the performance messed up. This modifications was done to get all the necessary data for offline signing via UR or any other channel not using files as medium. IMO it had been better to not implement the filehandling direct in wallet2 or in the wallet api but rather in monero-wallet-cli and monero-gui itself, but it is like it is.
This commit is contained in:
parent
a1dc85c537
commit
84f402b47a
@ -162,6 +162,44 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite)
|
||||
return m_status == Status_Ok;
|
||||
}
|
||||
|
||||
std::string PendingTransactionImpl::commit_string()
|
||||
{
|
||||
|
||||
std::string tx;
|
||||
LOG_PRINT_L3("m_pending_tx size: " << m_pending_tx.size());
|
||||
|
||||
try {
|
||||
tx = m_wallet.m_wallet->dump_tx_to_str(m_pending_tx);
|
||||
m_status = Status_Ok;
|
||||
} catch (const tools::error::daemon_busy&) {
|
||||
// TODO: make it translatable with "tr"?
|
||||
m_errorString = tr("daemon is busy. Please try again later.");
|
||||
m_status = Status_Error;
|
||||
} catch (const tools::error::no_connection_to_daemon&) {
|
||||
m_errorString = tr("no connection to daemon. Please make sure daemon is running.");
|
||||
m_status = Status_Error;
|
||||
} catch (const tools::error::tx_rejected& e) {
|
||||
std::ostringstream writer(m_errorString);
|
||||
writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status();
|
||||
std::string reason = e.reason();
|
||||
m_status = Status_Error;
|
||||
m_errorString = writer.str();
|
||||
if (!reason.empty())
|
||||
m_errorString += string(tr(". Reason: ")) + reason;
|
||||
} catch (const std::exception &e) {
|
||||
m_errorString = string(tr("Unknown exception: ")) + e.what();
|
||||
m_status = Status_Error;
|
||||
} catch (...) {
|
||||
m_errorString = tr("Unhandled exception");
|
||||
LOG_ERROR(m_errorString);
|
||||
m_status = Status_Error;
|
||||
}
|
||||
m_wallet.startRefresh();
|
||||
if (m_status != Status_Ok)
|
||||
return "";
|
||||
return tx;
|
||||
}
|
||||
|
||||
uint64_t PendingTransactionImpl::amount() const
|
||||
{
|
||||
uint64_t result = 0;
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
~PendingTransactionImpl();
|
||||
int status() const override;
|
||||
std::string errorString() const override;
|
||||
std::string commit_string() override;
|
||||
bool commit(const std::string &filename = "", bool overwrite = false) override;
|
||||
uint64_t amount() const override;
|
||||
uint64_t dust() const override;
|
||||
|
@ -96,6 +96,28 @@ bool UnsignedTransactionImpl::sign(const std::string &signedFileName)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string UnsignedTransactionImpl::signAsString()
|
||||
{
|
||||
if(m_wallet.watchOnly())
|
||||
{
|
||||
m_errorString = tr("This is a watch only wallet");
|
||||
m_status = Status_Error;
|
||||
return "";
|
||||
}
|
||||
tools::wallet2::signed_tx_set signed_txes;
|
||||
std::vector<tools::wallet2::pending_tx> ptx;
|
||||
try
|
||||
{
|
||||
return m_wallet.m_wallet->sign_tx_dump_to_str(m_unsigned_tx_set, ptx, signed_txes);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
m_errorString = string(tr("Failed to sign transaction")) + e.what();
|
||||
m_status = Status_Error;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message)
|
||||
{
|
||||
|
@ -53,6 +53,7 @@ public:
|
||||
uint64_t txCount() const override;
|
||||
// sign txs and save to file
|
||||
bool sign(const std::string &signedFileName) override;
|
||||
std::string signAsString() override;
|
||||
std::string confirmationMessage() const override {return m_confirmationMessage;}
|
||||
uint64_t minMixinCount() const override;
|
||||
|
||||
|
@ -1134,6 +1134,27 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
|
||||
return transaction;
|
||||
}
|
||||
|
||||
UnsignedTransaction *WalletImpl::loadUnsignedTxFromString(const std::string &data) {
|
||||
clearStatus();
|
||||
UnsignedTransactionImpl * transaction = new UnsignedTransactionImpl(*this);
|
||||
if (checkBackgroundSync("cannot load tx") || !m_wallet->parse_unsigned_tx_from_str(data, transaction->m_unsigned_tx_set)){
|
||||
setStatusError(tr("Failed to load unsigned transactions"));
|
||||
transaction->m_status = UnsignedTransaction::Status::Status_Error;
|
||||
transaction->m_errorString = errorString();
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
||||
// Check tx data and construct confirmation message
|
||||
std::string extra_message;
|
||||
if (!std::get<2>(transaction->m_unsigned_tx_set.transfers).empty())
|
||||
extra_message = (boost::format("%u outputs to import. ") % (unsigned)std::get<2>(transaction->m_unsigned_tx_set.transfers).size()).str();
|
||||
transaction->checkLoadedTx([&transaction](){return transaction->m_unsigned_tx_set.txes.size();}, [&transaction](size_t n)->const tools::wallet2::tx_construction_data&{return transaction->m_unsigned_tx_set.txes[n];}, extra_message);
|
||||
setStatus(transaction->status(), transaction->errorString());
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
||||
bool WalletImpl::submitTransaction(const string &fileName) {
|
||||
clearStatus();
|
||||
if (checkBackgroundSync("cannot submit tx"))
|
||||
@ -1154,6 +1175,48 @@ bool WalletImpl::submitTransaction(const string &fileName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WalletImpl::submitTransactionFromString(const string &data) {
|
||||
clearStatus();
|
||||
if (checkBackgroundSync("cannot submit tx"))
|
||||
return false;
|
||||
std::unique_ptr<PendingTransactionImpl> transaction(new PendingTransactionImpl(*this));
|
||||
|
||||
bool r = m_wallet->parse_tx_from_str(data, transaction->m_pending_tx, NULL);
|
||||
if (!r) {
|
||||
setStatus(Status_Ok, tr("Failed to load transaction from string"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!transaction->commit()) {
|
||||
setStatusError(transaction->m_errorString);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string WalletImpl::exportKeyImagesAsString(bool all)
|
||||
{
|
||||
if (m_wallet->watch_only())
|
||||
{
|
||||
setStatusError(tr("Wallet is view only"));
|
||||
return "";
|
||||
}
|
||||
if (checkBackgroundSync("cannot export key images"))
|
||||
return "";
|
||||
|
||||
try
|
||||
{
|
||||
return m_wallet->export_key_images_string(all);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LOG_ERROR("Error exporting key images: " << e.what());
|
||||
setStatusError(e.what());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
bool WalletImpl::exportKeyImages(const string &filename, bool all)
|
||||
{
|
||||
if (m_wallet->watch_only())
|
||||
@ -1181,6 +1244,31 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WalletImpl::importKeyImagesFromString(const std::string &data)
|
||||
{
|
||||
if (checkBackgroundSync("cannot import key images"))
|
||||
return false;
|
||||
if (!trustedDaemon()) {
|
||||
setStatusError(tr("Key images can only be imported with a trusted daemon"));
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
uint64_t spent = 0, unspent = 0;
|
||||
uint64_t height = m_wallet->import_key_images_string(data, spent, unspent);
|
||||
LOG_PRINT_L2("Signed key images imported to height " << height << ", "
|
||||
<< print_money(spent) << " spent, " << print_money(unspent) << " unspent");
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LOG_ERROR("Error exporting key images: " << e.what());
|
||||
setStatusError(string(tr("Failed to import key images: ")) + e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WalletImpl::importKeyImages(const string &filename)
|
||||
{
|
||||
if (checkBackgroundSync("cannot import key images"))
|
||||
@ -1206,6 +1294,29 @@ bool WalletImpl::importKeyImages(const string &filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string WalletImpl::exportOutputsAsString(bool all)
|
||||
{
|
||||
if (checkBackgroundSync("cannot export outputs"))
|
||||
return "";
|
||||
if (m_wallet->key_on_device())
|
||||
{
|
||||
setStatusError(string(tr("Not supported on HW wallets.")));
|
||||
return "";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return m_wallet->export_outputs_to_str(all);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LOG_ERROR("Error exporting outputs: " << e.what());
|
||||
setStatusError(string(tr("Error exporting outputs: ")) + e.what());
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool WalletImpl::exportOutputs(const string &filename, bool all)
|
||||
{
|
||||
if (checkBackgroundSync("cannot export outputs"))
|
||||
@ -1238,6 +1349,32 @@ bool WalletImpl::exportOutputs(const string &filename, bool all)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WalletImpl::importOutputsFromString(const std::string &data)
|
||||
{
|
||||
if (checkBackgroundSync("cannot import outputs"))
|
||||
return false;
|
||||
if (m_wallet->key_on_device())
|
||||
{
|
||||
setStatusError(string(tr("Not supported on HW wallets.")));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
size_t n_outputs = m_wallet->import_outputs_from_str(data);
|
||||
LOG_PRINT_L2(std::to_string(n_outputs) << " outputs imported");
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LOG_ERROR("Failed to import outputs: " << e.what());
|
||||
setStatusError(string(tr("Failed to import outputs: ")) + e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WalletImpl::importOutputs(const string &filename)
|
||||
{
|
||||
if (checkBackgroundSync("cannot import outputs"))
|
||||
|
@ -166,10 +166,16 @@ public:
|
||||
std::set<uint32_t> subaddr_indices = {}) override;
|
||||
virtual PendingTransaction * createSweepUnmixableTransaction() override;
|
||||
bool submitTransaction(const std::string &fileName) override;
|
||||
bool submitTransactionFromString(const std::string &fileName) override;
|
||||
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
|
||||
virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) override;
|
||||
std::string exportKeyImagesAsString(bool all = false) override;
|
||||
bool exportKeyImages(const std::string &filename, bool all = false) override;
|
||||
bool importKeyImagesFromString(const std::string &data) override;
|
||||
bool importKeyImages(const std::string &filename) override;
|
||||
std::string exportOutputsAsString(bool all = false) override;
|
||||
bool exportOutputs(const std::string &filename, bool all = false) override;
|
||||
bool importOutputsFromString(const std::string &data) override;
|
||||
bool importOutputs(const std::string &filename) override;
|
||||
bool scanTransactions(const std::vector<std::string> &txids) override;
|
||||
|
||||
|
@ -89,6 +89,8 @@ struct PendingTransaction
|
||||
virtual ~PendingTransaction() = 0;
|
||||
virtual int status() const = 0;
|
||||
virtual std::string errorString() const = 0;
|
||||
// return string of transaction gives the same content which would be saved to file with commit(filename)
|
||||
virtual std::string commit_string() = 0;
|
||||
// commit transaction or save to file if filename is provided.
|
||||
virtual bool commit(const std::string &filename = "", bool overwrite = false) = 0;
|
||||
virtual uint64_t amount() const = 0;
|
||||
@ -161,6 +163,11 @@ struct UnsignedTransaction
|
||||
* return - true on success
|
||||
*/
|
||||
virtual bool sign(const std::string &signedFileName) = 0;
|
||||
/*!
|
||||
* @brief sign - Sign txs and return as string
|
||||
* return - true on success
|
||||
*/
|
||||
virtual std::string signAsString() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -895,11 +902,24 @@ struct Wallet
|
||||
*/
|
||||
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0;
|
||||
|
||||
/*!
|
||||
* \brief loadUnsignedTxFromString - creates transaction from unsigned tx string
|
||||
* \return - UnsignedTransaction object. caller is responsible to check UnsignedTransaction::status()
|
||||
* after object returned
|
||||
*/
|
||||
virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) = 0;
|
||||
|
||||
/*!
|
||||
* \brief submitTransaction - submits transaction in signed tx file
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool submitTransaction(const std::string &fileName) = 0;
|
||||
|
||||
/*!
|
||||
* \brief submitTransactionFromString - submits transaction in signed tx file
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool submitTransactionFromString(const std::string &fileName) = 0;
|
||||
|
||||
|
||||
/*!
|
||||
@ -916,6 +936,13 @@ struct Wallet
|
||||
virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations,
|
||||
PendingTransaction::Priority priority) const = 0;
|
||||
|
||||
/*!
|
||||
* \brief exportKeyImages - exports key images as string
|
||||
* \param all - export all key images or only those that have not yet been exported
|
||||
* \return - key images as std::string
|
||||
*/
|
||||
virtual std::string exportKeyImagesAsString(bool all = false) = 0;
|
||||
|
||||
/*!
|
||||
* \brief exportKeyImages - exports key images to file
|
||||
* \param filename
|
||||
@ -923,6 +950,13 @@ struct Wallet
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0;
|
||||
|
||||
/*!
|
||||
* \brief importKeyImagesFromString - imports key images from string for UR use.
|
||||
* \param data
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool importKeyImagesFromString(const std::string &data) = 0;
|
||||
|
||||
/*!
|
||||
* \brief importKeyImages - imports key images from file
|
||||
@ -932,12 +966,25 @@ struct Wallet
|
||||
virtual bool importKeyImages(const std::string &filename) = 0;
|
||||
|
||||
/*!
|
||||
* \brief importOutputs - exports outputs to file
|
||||
* \brief exportOutputsAsString - exports outputs to a string for UR
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual std::string exportOutputsAsString(bool all = false) = 0;
|
||||
|
||||
/*!
|
||||
* \brief exportOutputs - exports outputs to file
|
||||
* \param filename
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool exportOutputs(const std::string &filename, bool all = false) = 0;
|
||||
|
||||
/*!
|
||||
* \brief importOutputsFromString - imports outputs from string for UR
|
||||
* \param filename
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool importOutputsFromString(const std::string &data) = 0;
|
||||
|
||||
/*!
|
||||
* \brief importOutputs - imports outputs from file
|
||||
* \param filename
|
||||
|
@ -13262,9 +13262,8 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle
|
||||
return tx_pub_key;
|
||||
}
|
||||
|
||||
bool wallet2::export_key_images(const std::string &filename, bool all) const
|
||||
std::string wallet2::export_key_images_string(bool all) const
|
||||
{
|
||||
PERF_TIMER(export_key_images);
|
||||
std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> ski = export_key_images(all);
|
||||
std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC));
|
||||
const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
|
||||
@ -13287,8 +13286,13 @@ bool wallet2::export_key_images(const std::string &filename, bool all) const
|
||||
|
||||
// encrypt data, keep magic plaintext
|
||||
PERF_TIMER(export_key_images_encrypt);
|
||||
std::string ciphertext = encrypt_with_view_secret_key(data);
|
||||
return save_to_file(filename, magic + ciphertext);
|
||||
return magic + encrypt_with_view_secret_key(data);
|
||||
}
|
||||
|
||||
bool wallet2::export_key_images(const std::string &filename, bool all) const
|
||||
{
|
||||
PERF_TIMER(export_key_images);
|
||||
return save_to_file(filename, export_key_images_string(all));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@ -13353,10 +13357,16 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent
|
||||
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename);
|
||||
|
||||
return import_key_images_string(data, spent, unspent);
|
||||
}
|
||||
|
||||
uint64_t wallet2::import_key_images_string(const std::string &keyImages, uint64_t &spent, uint64_t &unspent)
|
||||
{
|
||||
std::string data = keyImages;
|
||||
const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC);
|
||||
if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen))
|
||||
{
|
||||
THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic in ") + filename);
|
||||
THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic"));
|
||||
}
|
||||
|
||||
try
|
||||
@ -13366,24 +13376,24 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + filename + ": " + e.what());
|
||||
THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt: ") + e.what());
|
||||
}
|
||||
|
||||
const size_t headerlen = 4 + 2 * sizeof(crypto::public_key);
|
||||
THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file ") + filename);
|
||||
THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size"));
|
||||
const uint32_t offset = (uint8_t)data[0] | (((uint8_t)data[1]) << 8) | (((uint8_t)data[2]) << 16) | (((uint8_t)data[3]) << 24);
|
||||
const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[4];
|
||||
const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[4 + sizeof(crypto::public_key)];
|
||||
const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
|
||||
if (public_spend_key != keys.m_spend_public_key || public_view_key != keys.m_view_public_key)
|
||||
{
|
||||
THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + filename + " are for a different account");
|
||||
THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images are from a different account" ));
|
||||
}
|
||||
THROW_WALLET_EXCEPTION_IF(offset > m_transfers.size(), error::wallet_internal_error, "Offset larger than known outputs");
|
||||
|
||||
const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature);
|
||||
THROW_WALLET_EXCEPTION_IF((data.size() - headerlen) % record_size,
|
||||
error::wallet_internal_error, std::string("Bad data size from file ") + filename);
|
||||
error::wallet_internal_error, std::string("Bad data size"));
|
||||
size_t nki = (data.size() - headerlen) / record_size;
|
||||
|
||||
std::vector<std::pair<crypto::key_image, crypto::signature>> ski;
|
||||
|
@ -1630,10 +1630,12 @@ private:
|
||||
void import_payments_out(const std::list<std::pair<crypto::hash,wallet2::confirmed_transfer_details>> &confirmed_payments);
|
||||
std::tuple<size_t, crypto::hash, std::vector<crypto::hash>> export_blockchain() const;
|
||||
void import_blockchain(const std::tuple<size_t, crypto::hash, std::vector<crypto::hash>> &bc);
|
||||
std::string export_key_images_string(bool all = false) const;
|
||||
bool export_key_images(const std::string &filename, bool all = false) const;
|
||||
std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> export_key_images(bool all = false) const;
|
||||
uint64_t import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, size_t offset, uint64_t &spent, uint64_t &unspent, bool check_spent = true);
|
||||
uint64_t import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent);
|
||||
uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent);
|
||||
bool import_key_images(std::vector<crypto::key_image> key_images, size_t offset=0, boost::optional<std::unordered_set<size_t>> selected_transfers=boost::none);
|
||||
bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false);
|
||||
crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const;
|
||||
|
Loading…
Reference in New Issue
Block a user