aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r--src/wallet/wallet.cpp34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index dd9bc64728..7fb26900e1 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2674,6 +2674,34 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
return true;
}
+OutputType CWallet::TransactionChangeType(const std::vector<CRecipient>& vecSend)
+{
+ // If -changetype is specified, always use that change type.
+ if (g_change_type != OUTPUT_TYPE_NONE) {
+ return g_change_type;
+ }
+
+ // if g_address_type is legacy, use legacy address as change (even
+ // if some of the outputs are P2WPKH or P2WSH).
+ if (g_address_type == OUTPUT_TYPE_LEGACY) {
+ return OUTPUT_TYPE_LEGACY;
+ }
+
+ // if any destination is P2WPKH or P2WSH, use P2WPKH for the change
+ // output.
+ for (const auto& recipient : vecSend) {
+ // Check if any destination contains a witness program:
+ int witnessversion = 0;
+ std::vector<unsigned char> witnessprogram;
+ if (recipient.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
+ return OUTPUT_TYPE_BECH32;
+ }
+ }
+
+ // else use g_address_type for change
+ return g_address_type;
+}
+
bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign)
{
@@ -2769,8 +2797,10 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
return false;
}
- LearnRelatedScripts(vchPubKey, g_change_type);
- scriptChange = GetScriptForDestination(GetDestinationForKey(vchPubKey, g_change_type));
+ const OutputType change_type = TransactionChangeType(vecSend);
+
+ LearnRelatedScripts(vchPubKey, change_type);
+ scriptChange = GetScriptForDestination(GetDestinationForKey(vchPubKey, change_type));
}
CTxOut change_prototype_txout(0, scriptChange);
size_t change_prototype_size = GetSerializeSize(change_prototype_txout, SER_DISK, 0);