diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 715c3ade1a..c31ec2d2b6 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -1,1023 +1,1040 @@
 // Copyright (c) 2011-2016 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "guiutil.h"
 
 #include "bitcoinaddressvalidator.h"
 #include "bitcoinunits.h"
 #include "dstencode.h"
 #include "qvalidatedlineedit.h"
 #include "walletmodel.h"
 
 #include "cashaddr.h"
 #include "config.h"
 #include "dstencode.h"
 #include "fs.h"
 #include "init.h"
 #include "policy/policy.h"
 #include "primitives/transaction.h"
 #include "protocol.h"
 #include "script/script.h"
 #include "script/standard.h"
 #include "util.h"
 #include "utilstrencodings.h"
 
 #ifdef WIN32
 #ifdef _WIN32_WINNT
 #undef _WIN32_WINNT
 #endif
 #define _WIN32_WINNT 0x0501
 #ifdef _WIN32_IE
 #undef _WIN32_IE
 #endif
 #define _WIN32_IE 0x0501
 #define WIN32_LEAN_AND_MEAN 1
 #ifndef NOMINMAX
 #define NOMINMAX
 #endif
 #include "shellapi.h"
 #include "shlobj.h"
 #include "shlwapi.h"
 #endif
 
 #include <boost/filesystem/fstream.hpp>
 #if BOOST_FILESYSTEM_VERSION >= 3
 #include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
 #endif
 #include <boost/scoped_array.hpp>
 
 #include <QAbstractItemView>
 #include <QApplication>
 #include <QClipboard>
 #include <QDateTime>
 #include <QDesktopServices>
 #include <QDesktopWidget>
 #include <QDoubleValidator>
 #include <QFileDialog>
 #include <QFont>
 #include <QLineEdit>
 #include <QMouseEvent>
 #include <QSettings>
 #include <QTextDocument> // for Qt::mightBeRichText
 #include <QThread>
 
 #if QT_VERSION < 0x050000
 #include <QUrl>
 #else
 #include <QUrlQuery>
 #endif
 
 #if QT_VERSION >= 0x50200
 #include <QFontDatabase>
 #endif
 
 #if BOOST_FILESYSTEM_VERSION >= 3
 static fs::detail::utf8_codecvt_facet utf8;
 #endif
 
 #if defined(Q_OS_MAC)
 // These Mac includes must be done in the global namespace
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreServices/CoreServices.h>
 
 extern double NSAppKitVersionNumber;
 #if !defined(NSAppKitVersionNumber10_8)
 #define NSAppKitVersionNumber10_8 1187
 #endif
 #if !defined(NSAppKitVersionNumber10_9)
 #define NSAppKitVersionNumber10_9 1265
 #endif
 #endif
 
 namespace GUIUtil {
 
 QString dateTimeStr(const QDateTime &date) {
     return date.date().toString(Qt::SystemLocaleShortDate) + QString(" ") +
            date.toString("hh:mm");
 }
 
 QString dateTimeStr(qint64 nTime) {
     return dateTimeStr(QDateTime::fromTime_t((qint32)nTime));
 }
 
 QFont fixedPitchFont() {
 #if QT_VERSION >= 0x50200
     return QFontDatabase::systemFont(QFontDatabase::FixedFont);
 #else
     QFont font("Monospace");
 #if QT_VERSION >= 0x040800
     font.setStyleHint(QFont::Monospace);
 #else
     font.setStyleHint(QFont::TypeWriter);
 #endif
     return font;
 #endif
 }
 
 static std::string MakeAddrInvalid(std::string addr) {
     if (addr.size() < 2) {
         return "";
     }
 
     // Checksum is at the end of the address. Swapping chars to make it invalid.
     std::swap(addr[addr.size() - 1], addr[addr.size() - 2]);
     if (!IsValidDestinationString(addr)) {
         return addr;
     }
     return "";
 }
 
 std::string DummyAddress(const Config &config) {
     // Just some dummy data to generate an convincing random-looking (but
     // consistent) address
     static const std::vector<uint8_t> dummydata = {
         0xeb, 0x15, 0x23, 0x1d, 0xfc, 0xeb, 0x60, 0x92, 0x58, 0x86,
         0xb6, 0x7d, 0x06, 0x52, 0x99, 0x92, 0x59, 0x15, 0xae, 0xb1};
 
     const CTxDestination dstKey = CKeyID(uint160(dummydata));
     return MakeAddrInvalid(EncodeDestination(dstKey, config));
 }
 
+// Addresses are stored in the database with the encoding that the client was
+// configured with at the time of creation.
+//
+// This converts to clients current configuration.
+QString convertToConfiguredAddressFormat(const Config &config,
+                                         const QString &addr) {
+    if (!IsValidDestinationString(addr.toStdString(),
+                                  config.GetChainParams())) {
+        // We have something sketchy as input. Do not try to convert.
+        return addr;
+    }
+    CTxDestination dst =
+        DecodeDestination(addr.toStdString(), config.GetChainParams());
+    return QString::fromStdString(EncodeDestination(dst, config));
+}
+
 void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) {
     parent->setFocusProxy(widget);
 
     widget->setFont(fixedPitchFont());
 #if QT_VERSION >= 0x040700
     // We don't want translators to use own addresses in translations
     // and this is the only place, where this address is supplied.
     widget->setPlaceholderText(
         QObject::tr("Enter a Bitcoin address (e.g. %1)")
             .arg(QString::fromStdString(DummyAddress(GetConfig()))));
 #endif
     widget->setValidator(
         new BitcoinAddressEntryValidator(Params().CashAddrPrefix(), parent));
     widget->setCheckValidator(new BitcoinAddressCheckValidator(parent));
 }
 
 void setupAmountWidget(QLineEdit *widget, QWidget *parent) {
     QDoubleValidator *amountValidator = new QDoubleValidator(parent);
     amountValidator->setDecimals(8);
     amountValidator->setBottom(0.0);
     widget->setValidator(amountValidator);
     widget->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 }
 
 QString bitcoinURIScheme(const CChainParams &params, bool useCashAddr) {
     if (!useCashAddr) {
         return "bitcoincash";
     }
     return QString::fromStdString(params.CashAddrPrefix());
 }
 
-QString bitcoinURIScheme(const Config &cfg) {
-    return bitcoinURIScheme(cfg.GetChainParams(), cfg.UseCashAddrEncoding());
+QString bitcoinURIScheme(const Config &config) {
+    return bitcoinURIScheme(config.GetChainParams(),
+                            config.UseCashAddrEncoding());
 }
 
 static bool IsCashAddrEncoded(const QUrl &uri) {
     const std::string addr = (uri.scheme() + ":" + uri.path()).toStdString();
     auto decoded = cashaddr::Decode(addr, "");
     return !decoded.first.empty();
 }
 
 bool parseBitcoinURI(const QString &scheme, const QUrl &uri,
                      SendCoinsRecipient *out) {
     // return if URI has wrong scheme.
     if (!uri.isValid() || uri.scheme() != scheme) {
         return false;
     }
 
     SendCoinsRecipient rv;
     if (IsCashAddrEncoded(uri)) {
         rv.address = uri.scheme() + ":" + uri.path();
     } else {
         // strip out uri scheme for base58 encoded addresses
         rv.address = uri.path();
     }
     // Trim any following forward slash which may have been added by the OS
     if (rv.address.endsWith("/")) {
         rv.address.truncate(rv.address.length() - 1);
     }
     rv.amount = Amount(0);
 
 #if QT_VERSION < 0x050000
     QList<QPair<QString, QString>> items = uri.queryItems();
 #else
     QUrlQuery uriQuery(uri);
     QList<QPair<QString, QString>> items = uriQuery.queryItems();
 #endif
     for (QList<QPair<QString, QString>>::iterator i = items.begin();
          i != items.end(); i++) {
         bool fShouldReturnFalse = false;
         if (i->first.startsWith("req-")) {
             i->first.remove(0, 4);
             fShouldReturnFalse = true;
         }
 
         if (i->first == "label") {
             rv.label = i->second;
             fShouldReturnFalse = false;
         }
         if (i->first == "message") {
             rv.message = i->second;
             fShouldReturnFalse = false;
         } else if (i->first == "amount") {
             if (!i->second.isEmpty()) {
                 if (!BitcoinUnits::parse(BitcoinUnits::BCH, i->second,
                                          &rv.amount)) {
                     return false;
                 }
             }
             fShouldReturnFalse = false;
         }
 
         if (fShouldReturnFalse) {
             return false;
         }
     }
     if (out) {
         *out = rv;
     }
     return true;
 }
 
 bool parseBitcoinURI(const QString &scheme, QString uri,
                      SendCoinsRecipient *out) {
     //
     //    Cannot handle this later, because bitcoincash://
     //    will cause Qt to see the part after // as host,
     //    which will lower-case it (and thus invalidate the address).
     if (uri.startsWith(scheme + "://", Qt::CaseInsensitive)) {
         uri.replace(0, scheme.length() + 3, scheme + ":");
     }
     QUrl uriInstance(uri);
     return parseBitcoinURI(scheme, uriInstance, out);
 }
 
-QString formatBitcoinURI(const Config &cfg, const SendCoinsRecipient &info) {
+QString formatBitcoinURI(const Config &config, const SendCoinsRecipient &info) {
     QString ret = info.address;
-    if (!cfg.UseCashAddrEncoding()) {
+    if (!config.UseCashAddrEncoding()) {
         // prefix address with uri scheme for base58 encoded addresses.
-        ret = (bitcoinURIScheme(cfg) + ":%1").arg(ret);
+        ret = (bitcoinURIScheme(config) + ":%1").arg(ret);
     }
     int paramCount = 0;
 
     if (info.amount != Amount(0)) {
         ret +=
             QString("?amount=%1")
                 .arg(BitcoinUnits::format(BitcoinUnits::BCH, info.amount, false,
                                           BitcoinUnits::separatorNever));
         paramCount++;
     }
 
     if (!info.label.isEmpty()) {
         QString lbl(QUrl::toPercentEncoding(info.label));
         ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl);
         paramCount++;
     }
 
     if (!info.message.isEmpty()) {
         QString msg(QUrl::toPercentEncoding(info.message));
         ret +=
             QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg);
         paramCount++;
     }
 
     return ret;
 }
 
 bool isDust(const QString &address, const Amount amount) {
     CTxDestination dest = DecodeDestination(address.toStdString());
     CScript script = GetScriptForDestination(dest);
     CTxOut txOut(amount, script);
     return txOut.IsDust(dustRelayFee);
 }
 
 QString HtmlEscape(const QString &str, bool fMultiLine) {
 #if QT_VERSION < 0x050000
     QString escaped = Qt::escape(str);
 #else
     QString escaped = str.toHtmlEscaped();
 #endif
     if (fMultiLine) {
         escaped = escaped.replace("\n", "<br>\n");
     }
     return escaped;
 }
 
 QString HtmlEscape(const std::string &str, bool fMultiLine) {
     return HtmlEscape(QString::fromStdString(str), fMultiLine);
 }
 
 void copyEntryData(QAbstractItemView *view, int column, int role) {
     if (!view || !view->selectionModel()) return;
     QModelIndexList selection = view->selectionModel()->selectedRows(column);
 
     if (!selection.isEmpty()) {
         // Copy first item
         setClipboard(selection.at(0).data(role).toString());
     }
 }
 
 QList<QModelIndex> getEntryData(QAbstractItemView *view, int column) {
     if (!view || !view->selectionModel()) return QList<QModelIndex>();
     return view->selectionModel()->selectedRows(column);
 }
 
 QString getSaveFileName(QWidget *parent, const QString &caption,
                         const QString &dir, const QString &filter,
                         QString *selectedSuffixOut) {
     QString selectedFilter;
     QString myDir;
     // Default to user documents location
     if (dir.isEmpty()) {
 #if QT_VERSION < 0x050000
         myDir = QDesktopServices::storageLocation(
             QDesktopServices::DocumentsLocation);
 #else
         myDir =
             QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
 #endif
     } else {
         myDir = dir;
     }
     /* Directly convert path to native OS path separators */
     QString result = QDir::toNativeSeparators(QFileDialog::getSaveFileName(
         parent, caption, myDir, filter, &selectedFilter));
 
     /* Extract first suffix from filter pattern "Description (*.foo)" or
      * "Description (*.foo *.bar ...) */
     QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
     QString selectedSuffix;
     if (filter_re.exactMatch(selectedFilter)) {
         selectedSuffix = filter_re.cap(1);
     }
 
     /* Add suffix if needed */
     QFileInfo info(result);
     if (!result.isEmpty()) {
         if (info.suffix().isEmpty() && !selectedSuffix.isEmpty()) {
             /* No suffix specified, add selected suffix */
             if (!result.endsWith(".")) result.append(".");
             result.append(selectedSuffix);
         }
     }
 
     /* Return selected suffix if asked to */
     if (selectedSuffixOut) {
         *selectedSuffixOut = selectedSuffix;
     }
     return result;
 }
 
 QString getOpenFileName(QWidget *parent, const QString &caption,
                         const QString &dir, const QString &filter,
                         QString *selectedSuffixOut) {
     QString selectedFilter;
     QString myDir;
     if (dir.isEmpty()) // Default to user documents location
     {
 #if QT_VERSION < 0x050000
         myDir = QDesktopServices::storageLocation(
             QDesktopServices::DocumentsLocation);
 #else
         myDir =
             QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
 #endif
     } else {
         myDir = dir;
     }
     /* Directly convert path to native OS path separators */
     QString result = QDir::toNativeSeparators(QFileDialog::getOpenFileName(
         parent, caption, myDir, filter, &selectedFilter));
 
     if (selectedSuffixOut) {
         /* Extract first suffix from filter pattern "Description (*.foo)" or
          * "Description (*.foo *.bar ...) */
         QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
         QString selectedSuffix;
         if (filter_re.exactMatch(selectedFilter)) {
             selectedSuffix = filter_re.cap(1);
         }
         *selectedSuffixOut = selectedSuffix;
     }
     return result;
 }
 
 Qt::ConnectionType blockingGUIThreadConnection() {
     if (QThread::currentThread() != qApp->thread()) {
         return Qt::BlockingQueuedConnection;
     } else {
         return Qt::DirectConnection;
     }
 }
 
 bool checkPoint(const QPoint &p, const QWidget *w) {
     QWidget *atW = QApplication::widgetAt(w->mapToGlobal(p));
     if (!atW) return false;
     return atW->topLevelWidget() == w;
 }
 
 bool isObscured(QWidget *w) {
     return !(checkPoint(QPoint(0, 0), w) &&
              checkPoint(QPoint(w->width() - 1, 0), w) &&
              checkPoint(QPoint(0, w->height() - 1), w) &&
              checkPoint(QPoint(w->width() - 1, w->height() - 1), w) &&
              checkPoint(QPoint(w->width() / 2, w->height() / 2), w));
 }
 
 void openDebugLogfile() {
     fs::path pathDebug = GetDataDir() / "debug.log";
 
     /* Open debug.log with the associated application */
     if (fs::exists(pathDebug))
         QDesktopServices::openUrl(
             QUrl::fromLocalFile(boostPathToQString(pathDebug)));
 }
 
 void SubstituteFonts(const QString &language) {
 #if defined(Q_OS_MAC)
 // Background:
 // OSX's default font changed in 10.9 and Qt is unable to find it with its
 // usual fallback methods when building against the 10.7 sdk or lower.
 // The 10.8 SDK added a function to let it find the correct fallback font.
 // If this fallback is not properly loaded, some characters may fail to
 // render correctly.
 //
 // The same thing happened with 10.10. .Helvetica Neue DeskInterface is now
 // default.
 //
 // Solution: If building with the 10.7 SDK or lower and the user's platform
 // is 10.9 or higher at runtime, substitute the correct font. This needs to
 // happen before the QApplication is created.
 #if defined(MAC_OS_X_VERSION_MAX_ALLOWED) &&                                   \
     MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
     if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_8) {
         if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9)
             /* On a 10.9 - 10.9.x system */
             QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande");
         else {
             /* 10.10 or later system */
             if (language == "zh_CN" || language == "zh_TW" ||
                 language == "zh_HK") // traditional or simplified Chinese
                 QFont::insertSubstitution(".Helvetica Neue DeskInterface",
                                           "Heiti SC");
             else if (language == "ja") // Japanesee
                 QFont::insertSubstitution(".Helvetica Neue DeskInterface",
                                           "Songti SC");
             else
                 QFont::insertSubstitution(".Helvetica Neue DeskInterface",
                                           "Lucida Grande");
         }
     }
 #endif
 #endif
 }
 
 ToolTipToRichTextFilter::ToolTipToRichTextFilter(int _size_threshold,
                                                  QObject *parent)
     : QObject(parent), size_threshold(_size_threshold) {}
 
 bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt) {
     if (evt->type() == QEvent::ToolTipChange) {
         QWidget *widget = static_cast<QWidget *>(obj);
         QString tooltip = widget->toolTip();
         if (tooltip.size() > size_threshold && !tooltip.startsWith("<qt") &&
             !Qt::mightBeRichText(tooltip)) {
             // Envelop with <qt></qt> to make sure Qt detects this as rich text
             // Escape the current message as HTML and replace \n by <br>
             tooltip = "<qt>" + HtmlEscape(tooltip, true) + "</qt>";
             widget->setToolTip(tooltip);
             return true;
         }
     }
     return QObject::eventFilter(obj, evt);
 }
 
 void TableViewLastColumnResizingFixer::connectViewHeadersSignals() {
     connect(tableView->horizontalHeader(),
             SIGNAL(sectionResized(int, int, int)), this,
             SLOT(on_sectionResized(int, int, int)));
     connect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this,
             SLOT(on_geometriesChanged()));
 }
 
 // We need to disconnect these while handling the resize events, otherwise we
 // can enter infinite loops.
 void TableViewLastColumnResizingFixer::disconnectViewHeadersSignals() {
     disconnect(tableView->horizontalHeader(),
                SIGNAL(sectionResized(int, int, int)), this,
                SLOT(on_sectionResized(int, int, int)));
     disconnect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this,
                SLOT(on_geometriesChanged()));
 }
 
 // Setup the resize mode, handles compatibility for Qt5 and below as the method
 // signatures changed.
 // Refactored here for readability.
 void TableViewLastColumnResizingFixer::setViewHeaderResizeMode(
     int logicalIndex, QHeaderView::ResizeMode resizeMode) {
 #if QT_VERSION < 0x050000
     tableView->horizontalHeader()->setResizeMode(logicalIndex, resizeMode);
 #else
     tableView->horizontalHeader()->setSectionResizeMode(logicalIndex,
                                                         resizeMode);
 #endif
 }
 
 void TableViewLastColumnResizingFixer::resizeColumn(int nColumnIndex,
                                                     int width) {
     tableView->setColumnWidth(nColumnIndex, width);
     tableView->horizontalHeader()->resizeSection(nColumnIndex, width);
 }
 
 int TableViewLastColumnResizingFixer::getColumnsWidth() {
     int nColumnsWidthSum = 0;
     for (int i = 0; i < columnCount; i++) {
         nColumnsWidthSum += tableView->horizontalHeader()->sectionSize(i);
     }
     return nColumnsWidthSum;
 }
 
 int TableViewLastColumnResizingFixer::getAvailableWidthForColumn(int column) {
     int nResult = lastColumnMinimumWidth;
     int nTableWidth = tableView->horizontalHeader()->width();
 
     if (nTableWidth > 0) {
         int nOtherColsWidth =
             getColumnsWidth() -
             tableView->horizontalHeader()->sectionSize(column);
         nResult = std::max(nResult, nTableWidth - nOtherColsWidth);
     }
 
     return nResult;
 }
 
 // Make sure we don't make the columns wider than the table's viewport width.
 void TableViewLastColumnResizingFixer::adjustTableColumnsWidth() {
     disconnectViewHeadersSignals();
     resizeColumn(lastColumnIndex, getAvailableWidthForColumn(lastColumnIndex));
     connectViewHeadersSignals();
 
     int nTableWidth = tableView->horizontalHeader()->width();
     int nColsWidth = getColumnsWidth();
     if (nColsWidth > nTableWidth) {
         resizeColumn(secondToLastColumnIndex,
                      getAvailableWidthForColumn(secondToLastColumnIndex));
     }
 }
 
 // Make column use all the space available, useful during window resizing.
 void TableViewLastColumnResizingFixer::stretchColumnWidth(int column) {
     disconnectViewHeadersSignals();
     resizeColumn(column, getAvailableWidthForColumn(column));
     connectViewHeadersSignals();
 }
 
 // When a section is resized this is a slot-proxy for ajustAmountColumnWidth().
 void TableViewLastColumnResizingFixer::on_sectionResized(int logicalIndex,
                                                          int oldSize,
                                                          int newSize) {
     adjustTableColumnsWidth();
     int remainingWidth = getAvailableWidthForColumn(logicalIndex);
     if (newSize > remainingWidth) {
         resizeColumn(logicalIndex, remainingWidth);
     }
 }
 
 // When the table's geometry is ready, we manually perform the stretch of the
 // "Message" column,
 // as the "Stretch" resize mode does not allow for interactive resizing.
 void TableViewLastColumnResizingFixer::on_geometriesChanged() {
     if ((getColumnsWidth() - this->tableView->horizontalHeader()->width()) !=
         0) {
         disconnectViewHeadersSignals();
         resizeColumn(secondToLastColumnIndex,
                      getAvailableWidthForColumn(secondToLastColumnIndex));
         connectViewHeadersSignals();
     }
 }
 
 /**
  * Initializes all internal variables and prepares the
  * the resize modes of the last 2 columns of the table and
  */
 TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(
     QTableView *table, int lastColMinimumWidth, int allColsMinimumWidth,
     QObject *parent)
     : QObject(parent), tableView(table),
       lastColumnMinimumWidth(lastColMinimumWidth),
       allColumnsMinimumWidth(allColsMinimumWidth) {
     columnCount = tableView->horizontalHeader()->count();
     lastColumnIndex = columnCount - 1;
     secondToLastColumnIndex = columnCount - 2;
     tableView->horizontalHeader()->setMinimumSectionSize(
         allColumnsMinimumWidth);
     setViewHeaderResizeMode(secondToLastColumnIndex, QHeaderView::Interactive);
     setViewHeaderResizeMode(lastColumnIndex, QHeaderView::Interactive);
 }
 
 #ifdef WIN32
 static fs::path StartupShortcutPath() {
     std::string chain = ChainNameFromCommandLine();
     if (chain == CBaseChainParams::MAIN)
         return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk";
     // Remove this special case when CBaseChainParams::TESTNET = "testnet4"
     if (chain == CBaseChainParams::TESTNET)
         return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk";
     return GetSpecialFolderPath(CSIDL_STARTUP) /
            strprintf("Bitcoin (%s).lnk", chain);
 }
 
 bool GetStartOnSystemStartup() {
     // check for Bitcoin*.lnk
     return fs::exists(StartupShortcutPath());
 }
 
 bool SetStartOnSystemStartup(bool fAutoStart) {
     // If the shortcut exists already, remove it for updating
     fs::remove(StartupShortcutPath());
 
     if (fAutoStart) {
         CoInitialize(nullptr);
 
         // Get a pointer to the IShellLink interface.
         IShellLink *psl = nullptr;
         HRESULT hres =
             CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
                              IID_IShellLink, reinterpret_cast<void **>(&psl));
 
         if (SUCCEEDED(hres)) {
             // Get the current executable path
             TCHAR pszExePath[MAX_PATH];
             GetModuleFileName(nullptr, pszExePath, sizeof(pszExePath));
 
             // Start client minimized
             QString strArgs = "-min";
             // Set -testnet /-regtest options
             strArgs += QString::fromStdString(strprintf(
                 " -testnet=%d -regtest=%d", GetBoolArg("-testnet", false),
                 GetBoolArg("-regtest", false)));
 
 #ifdef UNICODE
             boost::scoped_array<TCHAR> args(new TCHAR[strArgs.length() + 1]);
             // Convert the QString to TCHAR*
             strArgs.toWCharArray(args.get());
             // Add missing '\0'-termination to string
             args[strArgs.length()] = '\0';
 #endif
 
             // Set the path to the shortcut target
             psl->SetPath(pszExePath);
             PathRemoveFileSpec(pszExePath);
             psl->SetWorkingDirectory(pszExePath);
             psl->SetShowCmd(SW_SHOWMINNOACTIVE);
 #ifndef UNICODE
             psl->SetArguments(strArgs.toStdString().c_str());
 #else
             psl->SetArguments(args.get());
 #endif
 
             // Query IShellLink for the IPersistFile interface for
             // saving the shortcut in persistent storage.
             IPersistFile *ppf = nullptr;
             hres = psl->QueryInterface(IID_IPersistFile,
                                        reinterpret_cast<void **>(&ppf));
             if (SUCCEEDED(hres)) {
                 WCHAR pwsz[MAX_PATH];
                 // Ensure that the string is ANSI.
                 MultiByteToWideChar(CP_ACP, 0,
                                     StartupShortcutPath().string().c_str(), -1,
                                     pwsz, MAX_PATH);
                 // Save the link by calling IPersistFile::Save.
                 hres = ppf->Save(pwsz, TRUE);
                 ppf->Release();
                 psl->Release();
                 CoUninitialize();
                 return true;
             }
             psl->Release();
         }
         CoUninitialize();
         return false;
     }
     return true;
 }
 #elif defined(Q_OS_LINUX)
 
 // Follow the Desktop Application Autostart Spec:
 // http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
 
 static fs::path GetAutostartDir() {
     char *pszConfigHome = getenv("XDG_CONFIG_HOME");
     if (pszConfigHome) return fs::path(pszConfigHome) / "autostart";
     char *pszHome = getenv("HOME");
     if (pszHome) return fs::path(pszHome) / ".config" / "autostart";
     return fs::path();
 }
 
 static fs::path GetAutostartFilePath() {
     std::string chain = ChainNameFromCommandLine();
     if (chain == CBaseChainParams::MAIN)
         return GetAutostartDir() / "bitcoin.desktop";
     return GetAutostartDir() / strprintf("bitcoin-%s.lnk", chain);
 }
 
 bool GetStartOnSystemStartup() {
     fs::ifstream optionFile(GetAutostartFilePath());
     if (!optionFile.good()) return false;
     // Scan through file for "Hidden=true":
     std::string line;
     while (!optionFile.eof()) {
         getline(optionFile, line);
         if (line.find("Hidden") != std::string::npos &&
             line.find("true") != std::string::npos)
             return false;
     }
     optionFile.close();
 
     return true;
 }
 
 bool SetStartOnSystemStartup(bool fAutoStart) {
     if (!fAutoStart)
         fs::remove(GetAutostartFilePath());
     else {
         char pszExePath[MAX_PATH + 1];
         memset(pszExePath, 0, sizeof(pszExePath));
         if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath) - 1) ==
             -1)
             return false;
 
         fs::create_directories(GetAutostartDir());
 
         fs::ofstream optionFile(GetAutostartFilePath(),
                                 std::ios_base::out | std::ios_base::trunc);
         if (!optionFile.good()) return false;
         std::string chain = ChainNameFromCommandLine();
         // Write a bitcoin.desktop file to the autostart directory:
         optionFile << "[Desktop Entry]\n";
         optionFile << "Type=Application\n";
         if (chain == CBaseChainParams::MAIN)
             optionFile << "Name=Bitcoin\n";
         else
             optionFile << strprintf("Name=Bitcoin (%s)\n", chain);
         optionFile << "Exec=" << pszExePath
                    << strprintf(" -min -testnet=%d -regtest=%d\n",
                                 GetBoolArg("-testnet", false),
                                 GetBoolArg("-regtest", false));
         optionFile << "Terminal=false\n";
         optionFile << "Hidden=false\n";
         optionFile.close();
     }
     return true;
 }
 
 #elif defined(Q_OS_MAC)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 // based on:
 // https://github.com/Mozketo/LaunchAtLoginController/blob/master/LaunchAtLoginController.m
 
 // NB: caller must release returned ref if it's not NULL
 LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list,
                                               CFURLRef findUrl);
 LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list,
                                               CFURLRef findUrl) {
     LSSharedFileListItemRef foundItem = nullptr;
     // loop through the list of startup items and try to find the bitcoin app
     CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(list, nullptr);
     for (int i = 0; !foundItem && i < CFArrayGetCount(listSnapshot); ++i) {
         LSSharedFileListItemRef item =
             (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i);
         UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction |
                                  kLSSharedFileListDoNotMountVolumes;
         CFURLRef currentItemURL = nullptr;
 
 #if defined(MAC_OS_X_VERSION_MAX_ALLOWED) &&                                   \
     MAC_OS_X_VERSION_MAX_ALLOWED >= 10100
         if (&LSSharedFileListItemCopyResolvedURL)
             currentItemURL = LSSharedFileListItemCopyResolvedURL(
                 item, resolutionFlags, nullptr);
 #if defined(MAC_OS_X_VERSION_MIN_REQUIRED) &&                                  \
     MAC_OS_X_VERSION_MIN_REQUIRED < 10100
         else
             LSSharedFileListItemResolve(item, resolutionFlags, &currentItemURL,
                                         nullptr);
 #endif
 #else
         LSSharedFileListItemResolve(item, resolutionFlags, &currentItemURL,
                                     nullptr);
 #endif
 
         if (currentItemURL && CFEqual(currentItemURL, findUrl)) {
             // found
             CFRetain(foundItem = item);
         }
         if (currentItemURL) {
             CFRelease(currentItemURL);
         }
     }
     CFRelease(listSnapshot);
     return foundItem;
 }
 
 bool GetStartOnSystemStartup() {
     CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
     LSSharedFileListRef loginItems = LSSharedFileListCreate(
         nullptr, kLSSharedFileListSessionLoginItems, nullptr);
     LSSharedFileListItemRef foundItem =
         findStartupItemInList(loginItems, bitcoinAppUrl);
     // findStartupItemInList retains the item it returned, need to release
     if (foundItem) {
         CFRelease(foundItem);
     }
     CFRelease(loginItems);
     CFRelease(bitcoinAppUrl);
     return foundItem;
 }
 
 bool SetStartOnSystemStartup(bool fAutoStart) {
     CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
     LSSharedFileListRef loginItems = LSSharedFileListCreate(
         nullptr, kLSSharedFileListSessionLoginItems, nullptr);
     LSSharedFileListItemRef foundItem =
         findStartupItemInList(loginItems, bitcoinAppUrl);
 
     if (fAutoStart && !foundItem) {
         // add bitcoin app to startup item list
         LSSharedFileListInsertItemURL(loginItems,
                                       kLSSharedFileListItemBeforeFirst, nullptr,
                                       nullptr, bitcoinAppUrl, nullptr, nullptr);
     } else if (!fAutoStart && foundItem) {
         // remove item
         LSSharedFileListItemRemove(loginItems, foundItem);
     }
     // findStartupItemInList retains the item it returned, need to release
     if (foundItem) {
         CFRelease(foundItem);
     }
     CFRelease(loginItems);
     CFRelease(bitcoinAppUrl);
     return true;
 }
 #pragma GCC diagnostic pop
 #else
 
 bool GetStartOnSystemStartup() {
     return false;
 }
 bool SetStartOnSystemStartup(bool fAutoStart) {
     return false;
 }
 
 #endif
 
 void saveWindowGeometry(const QString &strSetting, QWidget *parent) {
     QSettings settings;
     settings.setValue(strSetting + "Pos", parent->pos());
     settings.setValue(strSetting + "Size", parent->size());
 }
 
 void restoreWindowGeometry(const QString &strSetting, const QSize &defaultSize,
                            QWidget *parent) {
     QSettings settings;
     QPoint pos = settings.value(strSetting + "Pos").toPoint();
     QSize size = settings.value(strSetting + "Size", defaultSize).toSize();
 
     if (!pos.x() && !pos.y()) {
         QRect screen = QApplication::desktop()->screenGeometry();
         pos.setX((screen.width() - size.width()) / 2);
         pos.setY((screen.height() - size.height()) / 2);
     }
 
     parent->resize(size);
     parent->move(pos);
 }
 
 void setClipboard(const QString &str) {
     QApplication::clipboard()->setText(str, QClipboard::Clipboard);
     QApplication::clipboard()->setText(str, QClipboard::Selection);
 }
 
 #if BOOST_FILESYSTEM_VERSION >= 3
 fs::path qstringToBoostPath(const QString &path) {
     return fs::path(path.toStdString(), utf8);
 }
 
 QString boostPathToQString(const fs::path &path) {
     return QString::fromStdString(path.string(utf8));
 }
 #else
 #warning Conversion between boost path and QString can use invalid character encoding with boost_filesystem v2 and older
 fs::path qstringToBoostPath(const QString &path) {
     return fs::path(path.toStdString());
 }
 
 QString boostPathToQString(const fs::path &path) {
     return QString::fromStdString(path.string());
 }
 #endif
 
 QString formatDurationStr(int secs) {
     QStringList strList;
     int days = secs / 86400;
     int hours = (secs % 86400) / 3600;
     int mins = (secs % 3600) / 60;
     int seconds = secs % 60;
 
     if (days) strList.append(QString(QObject::tr("%1 d")).arg(days));
     if (hours) strList.append(QString(QObject::tr("%1 h")).arg(hours));
     if (mins) strList.append(QString(QObject::tr("%1 m")).arg(mins));
     if (seconds || (!days && !hours && !mins))
         strList.append(QString(QObject::tr("%1 s")).arg(seconds));
 
     return strList.join(" ");
 }
 
 QString formatServicesStr(quint64 mask) {
     QStringList strList;
 
     // Just scan the last 8 bits for now.
     for (int i = 0; i < 8; i++) {
         uint64_t check = 1 << i;
         if (mask & check) {
             switch (check) {
                 case NODE_NETWORK:
                     strList.append("NETWORK");
                     break;
                 case NODE_GETUTXO:
                     strList.append("GETUTXO");
                     break;
                 case NODE_BLOOM:
                     strList.append("BLOOM");
                     break;
                 case NODE_XTHIN:
                     strList.append("XTHIN");
                     break;
                 case NODE_BITCOIN_CASH:
                     strList.append("CASH");
                     break;
                 default:
                     strList.append(QString("%1[%2]").arg("UNKNOWN").arg(check));
             }
         }
     }
 
     if (strList.size())
         return strList.join(" & ");
     else
         return QObject::tr("None");
 }
 
 QString formatPingTime(double dPingTime) {
     return (dPingTime == std::numeric_limits<int64_t>::max() / 1e6 ||
             dPingTime == 0)
                ? QObject::tr("N/A")
                : QString(QObject::tr("%1 ms"))
                      .arg(QString::number((int)(dPingTime * 1000), 10));
 }
 
 QString formatTimeOffset(int64_t nTimeOffset) {
     return QString(QObject::tr("%1 s"))
         .arg(QString::number((int)nTimeOffset, 10));
 }
 
 QString formatNiceTimeOffset(qint64 secs) {
     // Represent time from last generated block in human readable text
     QString timeBehindText;
     const int HOUR_IN_SECONDS = 60 * 60;
     const int DAY_IN_SECONDS = 24 * 60 * 60;
     const int WEEK_IN_SECONDS = 7 * 24 * 60 * 60;
     // Average length of year in Gregorian calendar
     const int YEAR_IN_SECONDS = 31556952;
     if (secs < 60) {
         timeBehindText = QObject::tr("%n second(s)", "", secs);
     } else if (secs < 2 * HOUR_IN_SECONDS) {
         timeBehindText = QObject::tr("%n minute(s)", "", secs / 60);
     } else if (secs < 2 * DAY_IN_SECONDS) {
         timeBehindText = QObject::tr("%n hour(s)", "", secs / HOUR_IN_SECONDS);
     } else if (secs < 2 * WEEK_IN_SECONDS) {
         timeBehindText = QObject::tr("%n day(s)", "", secs / DAY_IN_SECONDS);
     } else if (secs < YEAR_IN_SECONDS) {
         timeBehindText = QObject::tr("%n week(s)", "", secs / WEEK_IN_SECONDS);
     } else {
         qint64 years = secs / YEAR_IN_SECONDS;
         qint64 remainder = secs % YEAR_IN_SECONDS;
         timeBehindText = QObject::tr("%1 and %2")
                              .arg(QObject::tr("%n year(s)", "", years))
                              .arg(QObject::tr("%n week(s)", "",
                                               remainder / WEEK_IN_SECONDS));
     }
     return timeBehindText;
 }
 
 void ClickableLabel::mouseReleaseEvent(QMouseEvent *event) {
     Q_EMIT clicked(event->pos());
 }
 
 void ClickableProgressBar::mouseReleaseEvent(QMouseEvent *event) {
     Q_EMIT clicked(event->pos());
 }
 
 } // namespace GUIUtil
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index cd6f7be8c5..6f1ec209c4 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -1,276 +1,280 @@
 // Copyright (c) 2011-2016 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #ifndef BITCOIN_QT_GUIUTIL_H
 #define BITCOIN_QT_GUIUTIL_H
 
 #include "amount.h"
 #include "fs.h"
 
 #include <QEvent>
 #include <QHeaderView>
 #include <QLabel>
 #include <QMessageBox>
 #include <QObject>
 #include <QProgressBar>
 #include <QString>
 #include <QTableView>
 
 class QValidatedLineEdit;
 class SendCoinsRecipient;
 class CChainParams;
 class Config;
 
 QT_BEGIN_NAMESPACE
 class QAbstractItemView;
 class QDateTime;
 class QFont;
 class QLineEdit;
 class QUrl;
 class QWidget;
 QT_END_NAMESPACE
 
 /** Utility functions used by the Bitcoin Qt UI.
  */
 namespace GUIUtil {
 
 // Create human-readable string from date
 QString dateTimeStr(const QDateTime &datetime);
 QString dateTimeStr(qint64 nTime);
 
 // Return a monospace font
 QFont fixedPitchFont();
 
 // Generate an invalid, but convincing address.
-std::string DummyAddress(const Config &cfg);
+std::string DummyAddress(const Config &config);
+
+// Convert an address into the user chosen format
+QString convertToConfiguredAddressFormat(const Config &config,
+                                         const QString &addr);
 
 // Set up widgets for address and amounts
 void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent);
 void setupAmountWidget(QLineEdit *widget, QWidget *parent);
 
 QString bitcoinURIScheme(const CChainParams &, bool useCashAddr);
 QString bitcoinURIScheme(const Config &);
 // Parse "bitcoincash:" URI into recipient object, return true on successful
 // parsing
 bool parseBitcoinURI(const QString &scheme, const QUrl &uri,
                      SendCoinsRecipient *out);
 bool parseBitcoinURI(const QString &scheme, QString uri,
                      SendCoinsRecipient *out);
-QString formatBitcoinURI(const Config &cfg, const SendCoinsRecipient &info);
+QString formatBitcoinURI(const Config &config, const SendCoinsRecipient &info);
 
 // Returns true if given address+amount meets "dust" definition
 bool isDust(const QString &address, const Amount amount);
 
 // HTML escaping for rich text controls
 QString HtmlEscape(const QString &str, bool fMultiLine = false);
 QString HtmlEscape(const std::string &str, bool fMultiLine = false);
 
 /** Copy a field of the currently selected entry of a view to the clipboard.
    Does nothing if nothing
     is selected.
    @param[in] column  Data column to extract from the model
    @param[in] role    Data role to extract from the model
    @see  TransactionView::copyLabel, TransactionView::copyAmount,
    TransactionView::copyAddress
  */
 void copyEntryData(QAbstractItemView *view, int column,
                    int role = Qt::EditRole);
 
 /** Return a field of the currently selected entry as a QString. Does nothing if
    nothing
     is selected.
    @param[in] column  Data column to extract from the model
    @see  TransactionView::copyLabel, TransactionView::copyAmount,
    TransactionView::copyAddress
  */
 QList<QModelIndex> getEntryData(QAbstractItemView *view, int column);
 
 void setClipboard(const QString &str);
 
 /** Get save filename, mimics QFileDialog::getSaveFileName, except that it
   appends a default suffix
     when no suffix is provided by the user.
 
   @param[in] parent  Parent window (or 0)
   @param[in] caption Window caption (or empty, for default)
   @param[in] dir     Starting directory (or empty, to default to documents
   directory)
   @param[in] filter  Filter specification such as "Comma Separated Files
   (*.csv)"
   @param[out] selectedSuffixOut  Pointer to return the suffix (file type) that
   was selected (or 0).
               Can be useful when choosing the save file format based on suffix.
  */
 QString getSaveFileName(QWidget *parent, const QString &caption,
                         const QString &dir, const QString &filter,
                         QString *selectedSuffixOut);
 
 /** Get open filename, convenience wrapper for QFileDialog::getOpenFileName.
 
   @param[in] parent  Parent window (or 0)
   @param[in] caption Window caption (or empty, for default)
   @param[in] dir     Starting directory (or empty, to default to documents
   directory)
   @param[in] filter  Filter specification such as "Comma Separated Files
   (*.csv)"
   @param[out] selectedSuffixOut  Pointer to return the suffix (file type) that
   was selected (or 0).
               Can be useful when choosing the save file format based on suffix.
  */
 QString getOpenFileName(QWidget *parent, const QString &caption,
                         const QString &dir, const QString &filter,
                         QString *selectedSuffixOut);
 
 /** Get connection type to call object slot in GUI thread with invokeMethod. The
    call will be blocking.
 
    @returns If called from the GUI thread, return a Qt::DirectConnection.
             If called from another thread, return a
    Qt::BlockingQueuedConnection.
 */
 Qt::ConnectionType blockingGUIThreadConnection();
 
 // Determine whether a widget is hidden behind other windows
 bool isObscured(QWidget *w);
 
 // Open debug.log
 void openDebugLogfile();
 
 // Replace invalid default fonts with known good ones
 void SubstituteFonts(const QString &language);
 
 /** Qt event filter that intercepts ToolTipChange events, and replaces the
  * tooltip with a rich text representation if needed.  This assures that Qt can
  * word-wrap long tooltip messages. Tooltips longer than the provided size
  * threshold (in characters) are wrapped.
  */
 class ToolTipToRichTextFilter : public QObject {
     Q_OBJECT
 
 public:
     explicit ToolTipToRichTextFilter(int size_threshold, QObject *parent = 0);
 
 protected:
     bool eventFilter(QObject *obj, QEvent *evt) override;
 
 private:
     int size_threshold;
 };
 
 /**
  * Makes a QTableView last column feel as if it was being resized from its left
  * border.
  * Also makes sure the column widths are never larger than the table's viewport.
  * In Qt, all columns are resizable from the right, but it's not intuitive
  * resizing the last column from the right.
  * Usually our second to last columns behave as if stretched, and when on strech
  * mode, columns aren't resizable interactively or programmatically.
  *
  * This helper object takes care of this issue.
  *
  */
 class TableViewLastColumnResizingFixer : public QObject {
     Q_OBJECT
 
 public:
     TableViewLastColumnResizingFixer(QTableView *table, int lastColMinimumWidth,
                                      int allColsMinimumWidth, QObject *parent);
     void stretchColumnWidth(int column);
 
 private:
     QTableView *tableView;
     int lastColumnMinimumWidth;
     int allColumnsMinimumWidth;
     int lastColumnIndex;
     int columnCount;
     int secondToLastColumnIndex;
 
     void adjustTableColumnsWidth();
     int getAvailableWidthForColumn(int column);
     int getColumnsWidth();
     void connectViewHeadersSignals();
     void disconnectViewHeadersSignals();
     void setViewHeaderResizeMode(int logicalIndex,
                                  QHeaderView::ResizeMode resizeMode);
     void resizeColumn(int nColumnIndex, int width);
 
 private Q_SLOTS:
     void on_sectionResized(int logicalIndex, int oldSize, int newSize);
     void on_geometriesChanged();
 };
 
 bool GetStartOnSystemStartup();
 bool SetStartOnSystemStartup(bool fAutoStart);
 
 /** Save window size and position */
 void saveWindowGeometry(const QString &strSetting, QWidget *parent);
 /** Restore window size and position */
 void restoreWindowGeometry(const QString &strSetting,
                            const QSize &defaultSizeIn, QWidget *parent);
 
 /* Convert QString to OS specific boost path through UTF-8 */
 fs::path qstringToBoostPath(const QString &path);
 
 /* Convert OS specific boost path to QString through UTF-8 */
 QString boostPathToQString(const fs::path &path);
 
 /* Convert seconds into a QString with days, hours, mins, secs */
 QString formatDurationStr(int secs);
 
 /* Format CNodeStats.nServices bitmask into a user-readable string */
 QString formatServicesStr(quint64 mask);
 
 /* Format a CNodeCombinedStats.dPingTime into a user-readable string or display
  * N/A, if 0*/
 QString formatPingTime(double dPingTime);
 
 /* Format a CNodeCombinedStats.nTimeOffset into a user-readable string. */
 QString formatTimeOffset(int64_t nTimeOffset);
 
 QString formatNiceTimeOffset(qint64 secs);
 
 class ClickableLabel : public QLabel {
     Q_OBJECT
 
 Q_SIGNALS:
     /** Emitted when the label is clicked. The relative mouse coordinates of the
      * click are passed to the signal.
      */
     void clicked(const QPoint &point);
 
 protected:
     void mouseReleaseEvent(QMouseEvent *event) override;
 };
 
 class ClickableProgressBar : public QProgressBar {
     Q_OBJECT
 
 Q_SIGNALS:
     /** Emitted when the progressbar is clicked. The relative mouse coordinates
      * of the click are passed to the signal.
      */
     void clicked(const QPoint &point);
 
 protected:
     void mouseReleaseEvent(QMouseEvent *event) override;
 };
 
 #if defined(Q_OS_MAC) && QT_VERSION >= 0x050000
 // workaround for Qt OSX Bug:
 // https://bugreports.qt-project.org/browse/QTBUG-15631
 // QProgressBar uses around 10% CPU even when app is in background
 class ProgressBar : public ClickableProgressBar {
     bool event(QEvent *e) override {
         return (e->type() != QEvent::StyleAnimationUpdate)
                    ? QProgressBar::event(e)
                    : false;
     }
 };
 #else
 typedef ClickableProgressBar ProgressBar;
 #endif
 
 } // namespace GUIUtil
 
 #endif // BITCOIN_QT_GUIUTIL_H
diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp
index baca00d8d5..741e2ce12b 100644
--- a/src/qt/receiverequestdialog.cpp
+++ b/src/qt/receiverequestdialog.cpp
@@ -1,215 +1,202 @@
 // Copyright (c) 2011-2016 The Bitcoin Core developers
 // Copyright (c) 2017 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "receiverequestdialog.h"
 #include "ui_receiverequestdialog.h"
 
 #include "bitcoinunits.h"
 #include "config.h"
-#include "dstencode.h"
 #include "guiconstants.h"
 #include "guiutil.h"
 #include "optionsmodel.h"
 #include "walletmodel.h"
 
 #include <QClipboard>
 #include <QDrag>
 #include <QMenu>
 #include <QMimeData>
 #include <QMouseEvent>
 #include <QPixmap>
 #if QT_VERSION < 0x050000
 #include <QUrl>
 #endif
 
 #if defined(HAVE_CONFIG_H)
 #include "config/bitcoin-config.h" /* for USE_QRCODE */
 #endif
 
 #ifdef USE_QRCODE
 #include <qrencode.h>
 #endif
 
 QRImageWidget::QRImageWidget(QWidget *parent) : QLabel(parent), contextMenu(0) {
     contextMenu = new QMenu(this);
     QAction *saveImageAction = new QAction(tr("&Save Image..."), this);
     connect(saveImageAction, SIGNAL(triggered()), this, SLOT(saveImage()));
     contextMenu->addAction(saveImageAction);
     QAction *copyImageAction = new QAction(tr("&Copy Image"), this);
     connect(copyImageAction, SIGNAL(triggered()), this, SLOT(copyImage()));
     contextMenu->addAction(copyImageAction);
 }
 
 QImage QRImageWidget::exportImage() {
     if (!pixmap()) return QImage();
     return pixmap()->toImage();
 }
 
 void QRImageWidget::mousePressEvent(QMouseEvent *event) {
     if (event->button() == Qt::LeftButton && pixmap()) {
         event->accept();
         QMimeData *mimeData = new QMimeData;
         mimeData->setImageData(exportImage());
 
         QDrag *drag = new QDrag(this);
         drag->setMimeData(mimeData);
         drag->exec();
     } else {
         QLabel::mousePressEvent(event);
     }
 }
 
 void QRImageWidget::saveImage() {
     if (!pixmap()) return;
     QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(),
                                           tr("PNG Image (*.png)"), nullptr);
     if (!fn.isEmpty()) {
         exportImage().save(fn);
     }
 }
 
 void QRImageWidget::copyImage() {
     if (!pixmap()) return;
     QApplication::clipboard()->setImage(exportImage());
 }
 
 void QRImageWidget::contextMenuEvent(QContextMenuEvent *event) {
     if (!pixmap()) return;
     contextMenu->exec(event->globalPos());
 }
 
-ReceiveRequestDialog::ReceiveRequestDialog(const Config *cfg, QWidget *parent)
-    : QDialog(parent), ui(new Ui::ReceiveRequestDialog), model(0), cfg(cfg) {
+ReceiveRequestDialog::ReceiveRequestDialog(const Config *config,
+                                           QWidget *parent)
+    : QDialog(parent), ui(new Ui::ReceiveRequestDialog), model(0),
+      config(config) {
     ui->setupUi(this);
 
 #ifndef USE_QRCODE
     ui->btnSaveAs->setVisible(false);
     ui->lblQRCode->setVisible(false);
 #endif
 
     connect(ui->btnSaveAs, SIGNAL(clicked()), ui->lblQRCode, SLOT(saveImage()));
 }
 
 ReceiveRequestDialog::~ReceiveRequestDialog() {
     delete ui;
 }
 
 void ReceiveRequestDialog::setModel(OptionsModel *_model) {
     this->model = _model;
 
     if (_model)
         connect(_model, SIGNAL(displayUnitChanged(int)), this, SLOT(update()));
 
     // update the display unit if necessary
     update();
 }
 
-// Addresses are stored in the database with the encoding that the client was
-// configured with at the time of creation.
-//
-// This converts to clients current configuration.
-QString ToCurrentEncoding(const QString &addr, const Config &config) {
-    if (!IsValidDestinationString(addr.toStdString(),
-                                  config.GetChainParams())) {
-        // We have something sketchy as input. Do not try to convert.
-        return addr;
-    }
-    CTxDestination dst =
-        DecodeDestination(addr.toStdString(), config.GetChainParams());
-    return QString::fromStdString(EncodeDestination(dst, config));
-}
-
 void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info) {
     this->info = _info;
     // Display addresses with currently configured encoding.
-    this->info.address = ToCurrentEncoding(this->info.address, *cfg);
+    this->info.address =
+        GUIUtil::convertToConfiguredAddressFormat(*config, this->info.address);
     update();
 }
 
 void ReceiveRequestDialog::update() {
     if (!model) return;
     QString target = info.label;
     if (target.isEmpty()) target = info.address;
     setWindowTitle(tr("Request payment to %1").arg(target));
 
-    QString uri = GUIUtil::formatBitcoinURI(*cfg, info);
+    QString uri = GUIUtil::formatBitcoinURI(*config, info);
     ui->btnSaveAs->setEnabled(false);
     QString html;
     html += "<html><font face='verdana, arial, helvetica, sans-serif'>";
     html += "<b>" + tr("Payment information") + "</b><br>";
     html += "<b>" + tr("URI") + "</b>: ";
     html += "<a href=\"" + uri + "\">" + GUIUtil::HtmlEscape(uri) + "</a><br>";
     html += "<b>" + tr("Address") +
             "</b>: " + GUIUtil::HtmlEscape(info.address) + "<br>";
     if (info.amount != Amount(0))
         html += "<b>" + tr("Amount") +
                 "</b>: " + BitcoinUnits::formatHtmlWithUnit(
                                model->getDisplayUnit(), info.amount) +
                 "<br>";
     if (!info.label.isEmpty())
         html += "<b>" + tr("Label") +
                 "</b>: " + GUIUtil::HtmlEscape(info.label) + "<br>";
     if (!info.message.isEmpty())
         html += "<b>" + tr("Message") +
                 "</b>: " + GUIUtil::HtmlEscape(info.message) + "<br>";
     ui->outUri->setText(html);
 
 #ifdef USE_QRCODE
-    int fontSize = cfg->UseCashAddrEncoding() ? 10 : 12;
+    int fontSize = config->UseCashAddrEncoding() ? 10 : 12;
 
     ui->lblQRCode->setText("");
     if (!uri.isEmpty()) {
         // limit URI length
         if (uri.length() > MAX_URI_LENGTH) {
             ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce "
                                       "the text for label / message."));
         } else {
             QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0,
                                                QR_ECLEVEL_L, QR_MODE_8, 1);
             if (!code) {
                 ui->lblQRCode->setText(tr("Error encoding URI into QR Code."));
                 return;
             }
             QImage qrImage =
                 QImage(code->width + 8, code->width + 8, QImage::Format_RGB32);
             qrImage.fill(0xffffff);
             uint8_t *p = code->data;
             for (int y = 0; y < code->width; y++) {
                 for (int x = 0; x < code->width; x++) {
                     qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff));
                     p++;
                 }
             }
             QRcode_free(code);
 
             QImage qrAddrImage =
                 QImage(QR_IMAGE_SIZE, QR_IMAGE_SIZE + 20, QImage::Format_RGB32);
             qrAddrImage.fill(0xffffff);
             QPainter painter(&qrAddrImage);
             painter.drawImage(0, 0,
                               qrImage.scaled(QR_IMAGE_SIZE, QR_IMAGE_SIZE));
             QFont font = GUIUtil::fixedPitchFont();
             font.setPixelSize(fontSize);
             painter.setFont(font);
             QRect paddedRect = qrAddrImage.rect();
             paddedRect.setHeight(QR_IMAGE_SIZE + 12);
             painter.drawText(paddedRect, Qt::AlignBottom | Qt::AlignCenter,
                              info.address);
             painter.end();
 
             ui->lblQRCode->setPixmap(QPixmap::fromImage(qrAddrImage));
             ui->btnSaveAs->setEnabled(true);
         }
     }
 #endif
 }
 
 void ReceiveRequestDialog::on_btnCopyURI_clicked() {
-    GUIUtil::setClipboard(GUIUtil::formatBitcoinURI(*cfg, info));
+    GUIUtil::setClipboard(GUIUtil::formatBitcoinURI(*config, info));
 }
 
 void ReceiveRequestDialog::on_btnCopyAddress_clicked() {
     GUIUtil::setClipboard(info.address);
 }
diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h
index 788a79a3cf..907129821b 100644
--- a/src/qt/receiverequestdialog.h
+++ b/src/qt/receiverequestdialog.h
@@ -1,76 +1,72 @@
 // Copyright (c) 2011-2016 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #ifndef BITCOIN_QT_RECEIVEREQUESTDIALOG_H
 #define BITCOIN_QT_RECEIVEREQUESTDIALOG_H
 
 #include "walletmodel.h"
 
 #include <QDialog>
 #include <QImage>
 #include <QLabel>
 #include <QPainter>
-#include <QString>
 
 class OptionsModel;
 class Config;
 
 namespace Ui {
 class ReceiveRequestDialog;
 }
 
 QT_BEGIN_NAMESPACE
 class QMenu;
 QT_END_NAMESPACE
 
 /* Label widget for QR code. This image can be dragged, dropped, copied and
  * saved
  * to disk.
  */
 class QRImageWidget : public QLabel {
     Q_OBJECT
 
 public:
     explicit QRImageWidget(QWidget *parent = 0);
     QImage exportImage();
 
 public Q_SLOTS:
     void saveImage();
     void copyImage();
 
 protected:
     virtual void mousePressEvent(QMouseEvent *event) override;
     virtual void contextMenuEvent(QContextMenuEvent *event) override;
 
 private:
     QMenu *contextMenu;
 };
 
 class ReceiveRequestDialog : public QDialog {
     Q_OBJECT
 
 public:
-    explicit ReceiveRequestDialog(const Config *cfg, QWidget *parent = 0);
+    explicit ReceiveRequestDialog(const Config *config, QWidget *parent = 0);
     ~ReceiveRequestDialog();
 
     void setModel(OptionsModel *model);
     void setInfo(const SendCoinsRecipient &info);
 
 private Q_SLOTS:
     void on_btnCopyURI_clicked();
     void on_btnCopyAddress_clicked();
 
     void update();
 
 private:
     Ui::ReceiveRequestDialog *ui;
     OptionsModel *model;
     SendCoinsRecipient info;
-    const Config *cfg;
+    const Config *config;
 };
 
-// exported for unittesting
-QString ToCurrentEncoding(const QString &addr, const Config &);
-
 #endif // BITCOIN_QT_RECEIVEREQUESTDIALOG_H
diff --git a/src/qt/test/guiutiltests.cpp b/src/qt/test/guiutiltests.cpp
index 1a85a9f194..29e8ded2bf 100644
--- a/src/qt/test/guiutiltests.cpp
+++ b/src/qt/test/guiutiltests.cpp
@@ -1,63 +1,67 @@
 // Copyright (c) 2017 The Bitcoin developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include "guiutiltests.h"
 #include "chainparams.h"
 #include "config.h"
 #include "dstencode.h"
 #include "guiutil.h"
-#include "receiverequestdialog.h"
 
 namespace {
 
-class UtilCfgDummy : public DummyConfig {
+class GUIUtilTestConfig : public DummyConfig {
 public:
-    UtilCfgDummy() : useCashAddr(false) {}
+    GUIUtilTestConfig() : useCashAddr(false) {}
     void SetCashAddrEncoding(bool b) override { useCashAddr = b; }
     bool UseCashAddrEncoding() const override { return useCashAddr; }
     const CChainParams &GetChainParams() const override {
         return Params(CBaseChainParams::MAIN);
     }
 
 private:
     bool useCashAddr;
 };
 
 } // namespace
 
 void GUIUtilTests::dummyAddressTest() {
-    UtilCfgDummy config;
+    GUIUtilTestConfig config;
     const CChainParams &params = config.GetChainParams();
 
     std::string dummyaddr;
 
     config.SetCashAddrEncoding(false);
     dummyaddr = GUIUtil::DummyAddress(config);
     QVERIFY(!IsValidDestinationString(dummyaddr, params));
     QVERIFY(!dummyaddr.empty());
 
     config.SetCashAddrEncoding(true);
     dummyaddr = GUIUtil::DummyAddress(config);
     QVERIFY(!IsValidDestinationString(dummyaddr, params));
     QVERIFY(!dummyaddr.empty());
 }
 
 void GUIUtilTests::toCurrentEncodingTest() {
-    UtilCfgDummy config;
+    GUIUtilTestConfig config;
 
     // garbage in, garbage out
-    QVERIFY(ToCurrentEncoding("garbage", config) == "garbage");
+    QVERIFY(GUIUtil::convertToConfiguredAddressFormat(config, "garbage") ==
+            "garbage");
 
     QString cashaddr_pubkey =
         "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a";
     QString base58_pubkey = "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu";
 
     config.SetCashAddrEncoding(true);
-    QVERIFY(ToCurrentEncoding(cashaddr_pubkey, config) == cashaddr_pubkey);
-    QVERIFY(ToCurrentEncoding(base58_pubkey, config) == cashaddr_pubkey);
+    QVERIFY(GUIUtil::convertToConfiguredAddressFormat(
+                config, cashaddr_pubkey) == cashaddr_pubkey);
+    QVERIFY(GUIUtil::convertToConfiguredAddressFormat(config, base58_pubkey) ==
+            cashaddr_pubkey);
 
     config.SetCashAddrEncoding(false);
-    QVERIFY(ToCurrentEncoding(cashaddr_pubkey, config) == base58_pubkey);
-    QVERIFY(ToCurrentEncoding(base58_pubkey, config) == base58_pubkey);
+    QVERIFY(GUIUtil::convertToConfiguredAddressFormat(
+                config, cashaddr_pubkey) == base58_pubkey);
+    QVERIFY(GUIUtil::convertToConfiguredAddressFormat(config, base58_pubkey) ==
+            base58_pubkey);
 }