diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index b54a9b5de..d1573e02f 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -65,8 +65,9 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( std::vector zOutputs, int minDepth, CAmount fee, - UniValue contextInfo) : - tx_(contextualTx), fromaddress_(fromAddress), t_outputs_(tOutputs), z_outputs_(zOutputs), mindepth_(minDepth), fee_(fee), contextinfo_(contextInfo) + UniValue contextInfo, + CScript opret) : + tx_(contextualTx), fromaddress_(fromAddress), t_outputs_(tOutputs), z_outputs_(zOutputs), mindepth_(minDepth), fee_(fee), contextinfo_(contextInfo), opret_(opret) { assert(fee_ >= 0); @@ -469,6 +470,10 @@ bool AsyncRPCOperation_sendmany::main_impl() { } } + // Add optional OP_RETURN if it exists + if ( opret_ != CScript() ) { + builder_.AddOpRet(opret_); + } // Build the transaction auto maybe_tx = builder_.Build(); if (!maybe_tx) { diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 696cf1761..162680e20 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -62,7 +62,9 @@ public: std::vector zOutputs, int minDepth, CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, - UniValue contextInfo = NullUniValue); + UniValue contextInfo = NullUniValue, + CScript opret = CScript() + ); virtual ~AsyncRPCOperation_sendmany(); // We don't want to be copied or moved around @@ -92,6 +94,7 @@ private: CTxDestination fromtaddr_; PaymentAddress frompaymentaddress_; SpendingKey spendingkey_; + CScript opret_ = CScript(); uint256 joinSplitPubKey_; unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES]; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 97c89b97d..87d8ed64f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5001,6 +5001,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) std::vector taddrRecipients; std::vector zaddrRecipients; CAmount nTotalOut = 0; + // Optional OP_RETURN data + CScript opret; bool containsSaplingOutput = false; @@ -5011,8 +5013,9 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) // sanity check, report error if unknown key-value pairs for (const string& name_ : o.getKeys()) { std::string s = name_; - if (s != "address" && s != "amount" && s!="memo") + if (s != "address" && s != "amount" && s!="memo" && s!="opreturn") { throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown key: ")+s); + } } string address = find_value(o, "address").get_str(); @@ -5034,6 +5037,13 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) // throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+address); setAddress.insert(address); + UniValue opretValue = find_value(o, "opreturn"); + + // Create the CScript representation of the OP_RETURN + if (!opretValue.isNull()) { + opret << OP_RETURN << ParseHex(opretValue.get_str().c_str()); + } + UniValue memoValue = find_value(o, "memo"); string memo; if (!memoValue.isNull()) { @@ -5207,7 +5217,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) // Create operation and add to global queue std::shared_ptr q = getAsyncRPCQueue(); - std::shared_ptr operation( new AsyncRPCOperation_sendmany(builder, contextualTx, fromaddress, taddrRecipients, zaddrRecipients, nMinDepth, nFee, contextInfo) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(builder, contextualTx, fromaddress, taddrRecipients, zaddrRecipients, nMinDepth, nFee, contextInfo, opret) ); q->addOperation(operation); if(fZdebug) LogPrintf("%s: Submitted to async queue\n", __FUNCTION__);