Line data Source code
1 : // Copyright (c) 2020-2021 The PIVX Core developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or https://www.opensource.org/licenses/mit-license.php. 4 : 5 : #ifndef PIVX_SAPLING_SAPLING_OPERATION_H 6 : #define PIVX_SAPLING_SAPLING_OPERATION_H 7 : 8 : #include "amount.h" 9 : #include "sapling/transaction_builder.h" 10 : #include "operationresult.h" 11 : #include "primitives/transaction.h" 12 : #include "wallet/wallet.h" 13 : 14 : class CCoinControl; 15 : struct TxValues; 16 : 17 1139 : class ShieldedRecipient final : public CRecipientBase 18 : { 19 : public: 20 : const libzcash::SaplingPaymentAddress address; 21 : const std::string memo; 22 1136 : ShieldedRecipient(const libzcash::SaplingPaymentAddress& _address, const CAmount& _amount, const std::string& _memo, bool _fSubtractFeeFromAmount) : 23 1136 : CRecipientBase(_amount, _fSubtractFeeFromAmount), address(_address), memo(_memo) {} 24 8795 : bool isTransparent() const override { return false; } 25 3308 : Optional<libzcash::SaplingPaymentAddress> getSapPaymentAddr() const override { return {address}; }; 26 2178 : std::string getMemo() const override { return memo; } 27 : }; 28 : 29 2497 : struct SendManyRecipient 30 : { 31 : const std::shared_ptr<CRecipientBase> recipient; 32 : 33 5586 : bool IsTransparent() const { return recipient->isTransparent(); } 34 3376 : bool IsSubtractFee() const { return recipient->fSubtractFeeFromAmount; } 35 4434 : CAmount getAmount() const { return recipient->nAmount; }; 36 38 : CScript getScript() const { assert(IsTransparent()); return *recipient->getScript(); } 37 3308 : libzcash::SaplingPaymentAddress getSapPaymentAddr() const { assert(!IsTransparent()); return *recipient->getSapPaymentAddr(); } 38 2178 : std::string getMemo() const { return recipient->getMemo(); } 39 : 40 : // Prevent default empty initialization 41 : SendManyRecipient() = delete; 42 : 43 : // Shielded recipient 44 1136 : SendManyRecipient(const libzcash::SaplingPaymentAddress& address, const CAmount& amount, const std::string& memo, bool fSubtractFeeFromAmount): 45 2272 : recipient(new ShieldedRecipient(address, amount, memo, fSubtractFeeFromAmount)) 46 1136 : {} 47 : 48 : // Transparent recipient: P2PKH 49 25 : SendManyRecipient(const CTxDestination& dest, const CAmount& amount, bool fSubtractFeeFromAmount): 50 50 : recipient(new CRecipient(GetScriptForDestination(dest), amount, fSubtractFeeFromAmount)) 51 25 : {} 52 : 53 : // Transparent recipient: P2CS 54 1 : SendManyRecipient(const CKeyID& ownerKey, const CKeyID& stakerKey, const CAmount& amount, bool fV6Enforced): 55 1 : recipient(new CRecipient(fV6Enforced ? GetScriptForStakeDelegation(stakerKey, ownerKey) 56 3 : : GetScriptForStakeDelegationLOF(stakerKey, ownerKey), amount, false)) 57 1 : {} 58 : 59 : // Transparent recipient: multisig 60 : SendManyRecipient(int nRequired, const std::vector<CPubKey>& keys, const CAmount& amount): 61 : recipient(new CRecipient(GetScriptForMultisig(nRequired, keys), amount, false)) 62 : {} 63 : 64 : // Transparent recipient: OP_RETURN 65 : explicit SendManyRecipient(const uint256& message): 66 : recipient(new CRecipient(GetScriptForOpReturn(message), 0, false)) 67 : {} 68 : }; 69 : 70 1140 : class FromAddress { 71 : public: 72 1097 : explicit FromAddress() {}; 73 16 : explicit FromAddress(const CTxDestination& _fromTaddr) : fromTaddr(_fromTaddr) {}; 74 27 : explicit FromAddress(const libzcash::SaplingPaymentAddress& _fromSapaddr) : fromSapAddr(_fromSapaddr) {}; 75 : 76 3174 : bool isFromTAddress() const { return IsValidDestination(fromTaddr); } 77 1093 : bool isFromSapAddress() const { return fromSapAddr.is_initialized(); } 78 : 79 : CTxDestination fromTaddr{CNoDestination()}; 80 : Optional<libzcash::SaplingPaymentAddress> fromSapAddr{nullopt}; 81 : }; 82 : 83 : class SaplingOperation { 84 : public: 85 : explicit SaplingOperation(const Consensus::Params& consensusParams, CWallet* _wallet); 86 : ~SaplingOperation(); 87 : 88 : OperationResult build(); 89 : OperationResult send(std::string& retTxHash); 90 : OperationResult buildAndSend(std::string& retTxHash); 91 : 92 : void setFromAddress(const CTxDestination&); 93 : void setFromAddress(const libzcash::SaplingPaymentAddress&); 94 1054 : void clearTx() { txBuilder.Clear(); } 95 : // In case of no addressFrom filter selected, it will accept any utxo in the wallet as input. 96 : SaplingOperation* setSelectTransparentCoins(const bool select, const bool _fIncludeDelegated = false); 97 16 : SaplingOperation* setSelectShieldedCoins(const bool select) { selectFromShield = select; return this; }; 98 1093 : SaplingOperation* setRecipients(std::vector<SendManyRecipient>& vec) { recipients = std::move(vec); return this; }; 99 32 : SaplingOperation* setFee(CAmount _fee) { fee = _fee; return this; } 100 1087 : SaplingOperation* setMinDepth(int _mindepth) { assert(_mindepth >= 0); mindepth = _mindepth; return this; } 101 : SaplingOperation* setTransparentKeyChange(CReserveKey* reserveKey) { tkeyChange = reserveKey; return this; } 102 : SaplingOperation* setCoinControl(const CCoinControl* _coinControl) { coinControl = _coinControl; return this; } 103 : 104 : CAmount getFee() { return fee; } 105 22 : CTransaction getFinalTx() { return *finalTx; } 106 : CTransactionRef getFinalTxRef() { return finalTx; } 107 : 108 : private: 109 : /* 110 : * Cannot be nullptr. A pointer to the wallet, used to retrieve the inputs to spend, the keys to create the outputs, 111 : * sapling notes and nullifiers, as well as to commit transactions. 112 : * The same keystore is passed to the transaction builder in order to produce the required signatures. 113 : */ 114 : CWallet* wallet{nullptr}; 115 : 116 : FromAddress fromAddress; 117 : // In case of no addressFrom filter selected, it will accept any utxo in the wallet as input. 118 : bool selectFromtaddrs{false}; 119 : bool selectFromShield{false}; 120 : bool fIncludeDelegated{false}; 121 : const CCoinControl* coinControl{nullptr}; 122 : std::vector<SendManyRecipient> recipients; 123 : std::vector<COutput> transInputs; 124 : std::vector<SaplingNoteEntry> shieldedInputs; 125 : int mindepth{5}; // Min default depth 5. 126 : CAmount fee{0}; // User selected fee. 127 : 128 : // transparent change 129 : CReserveKey* tkeyChange{nullptr}; 130 : 131 : // Builder 132 : TransactionBuilder txBuilder; 133 : CTransactionRef finalTx; 134 : 135 : OperationResult loadUtxos(TxValues& values); 136 : OperationResult loadUtxos(TxValues& txValues, const std::vector<COutput>& selectedUTXO, const CAmount selectedUTXOAmount); 137 : OperationResult loadUnspentNotes(TxValues& txValues, uint256& ovk); 138 : OperationResult checkTxValues(TxValues& txValues, bool isFromtAddress, bool isFromShielded); 139 : }; 140 : 141 : OperationResult GetMemoFromString(const std::string& s, std::array<unsigned char, ZC_MEMO_SIZE>& memoRet); 142 : 143 : OperationResult CheckTransactionSize(std::vector<SendManyRecipient>& recipients, bool fromTaddr); 144 : 145 : #endif // PIVX_SAPLING_SAPLING_OPERATION_H