2018-07-17 09:36:38 -07:00
|
|
|
// Copyright (c) 2018 The Zcash developers
|
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2019-07-18 07:16:09 -07:00
|
|
|
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
2018-07-17 09:36:38 -07:00
|
|
|
|
|
|
|
#ifndef TRANSACTION_BUILDER_H
|
|
|
|
#define TRANSACTION_BUILDER_H
|
|
|
|
|
2018-10-12 17:36:26 -07:00
|
|
|
#include "coins.h"
|
2018-07-17 09:36:38 -07:00
|
|
|
#include "consensus/params.h"
|
2018-07-30 03:03:29 -07:00
|
|
|
#include "keystore.h"
|
2018-07-17 09:36:38 -07:00
|
|
|
#include "primitives/transaction.h"
|
2018-07-30 03:03:29 -07:00
|
|
|
#include "script/script.h"
|
|
|
|
#include "script/standard.h"
|
2018-07-17 09:36:38 -07:00
|
|
|
#include "uint256.h"
|
|
|
|
#include "zcash/Address.hpp"
|
|
|
|
#include "zcash/IncrementalMerkleTree.hpp"
|
2018-10-12 17:36:26 -07:00
|
|
|
#include "zcash/JoinSplit.hpp"
|
2018-07-17 09:36:38 -07:00
|
|
|
#include "zcash/Note.hpp"
|
|
|
|
#include "zcash/NoteEncryption.hpp"
|
|
|
|
|
|
|
|
#include <boost/optional.hpp>
|
|
|
|
|
2018-07-27 00:49:43 -07:00
|
|
|
struct SpendDescriptionInfo {
|
2018-07-30 06:26:29 -07:00
|
|
|
libzcash::SaplingExpandedSpendingKey expsk;
|
2018-07-17 09:36:38 -07:00
|
|
|
libzcash::SaplingNote note;
|
|
|
|
uint256 alpha;
|
|
|
|
uint256 anchor;
|
2018-08-01 09:41:36 -07:00
|
|
|
SaplingWitness witness;
|
2018-07-17 09:36:38 -07:00
|
|
|
|
|
|
|
SpendDescriptionInfo(
|
2018-07-30 06:26:29 -07:00
|
|
|
libzcash::SaplingExpandedSpendingKey expsk,
|
2018-07-17 09:36:38 -07:00
|
|
|
libzcash::SaplingNote note,
|
|
|
|
uint256 anchor,
|
2018-08-01 09:41:36 -07:00
|
|
|
SaplingWitness witness);
|
2018-07-17 09:36:38 -07:00
|
|
|
};
|
|
|
|
|
2018-07-27 00:49:43 -07:00
|
|
|
struct OutputDescriptionInfo {
|
2018-07-17 09:36:38 -07:00
|
|
|
uint256 ovk;
|
|
|
|
libzcash::SaplingNote note;
|
|
|
|
std::array<unsigned char, ZC_MEMO_SIZE> memo;
|
|
|
|
|
|
|
|
OutputDescriptionInfo(
|
|
|
|
uint256 ovk,
|
|
|
|
libzcash::SaplingNote note,
|
|
|
|
std::array<unsigned char, ZC_MEMO_SIZE> memo) : ovk(ovk), note(note), memo(memo) {}
|
2019-05-17 09:39:30 -07:00
|
|
|
|
|
|
|
boost::optional<OutputDescription> Build(void* ctx);
|
2018-07-17 09:36:38 -07:00
|
|
|
};
|
|
|
|
|
2018-07-30 03:03:29 -07:00
|
|
|
struct TransparentInputInfo {
|
|
|
|
CScript scriptPubKey;
|
|
|
|
CAmount value;
|
|
|
|
|
|
|
|
TransparentInputInfo(
|
|
|
|
CScript scriptPubKey,
|
|
|
|
CAmount value) : scriptPubKey(scriptPubKey), value(value) {}
|
|
|
|
};
|
|
|
|
|
2018-10-30 13:12:40 -07:00
|
|
|
class TransactionBuilderResult {
|
|
|
|
private:
|
|
|
|
boost::optional<CTransaction> maybeTx;
|
|
|
|
boost::optional<std::string> maybeError;
|
|
|
|
public:
|
|
|
|
TransactionBuilderResult() = delete;
|
|
|
|
TransactionBuilderResult(const CTransaction& tx);
|
|
|
|
TransactionBuilderResult(const std::string& error);
|
|
|
|
bool IsTx();
|
|
|
|
bool IsError();
|
|
|
|
CTransaction GetTxOrThrow();
|
|
|
|
std::string GetError();
|
|
|
|
};
|
|
|
|
|
2018-07-17 09:36:38 -07:00
|
|
|
class TransactionBuilder
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
Consensus::Params consensusParams;
|
|
|
|
int nHeight;
|
2018-07-30 03:03:29 -07:00
|
|
|
const CKeyStore* keystore;
|
2018-10-12 17:36:26 -07:00
|
|
|
ZCJoinSplit* sproutParams;
|
|
|
|
const CCoinsViewCache* coinsView;
|
|
|
|
CCriticalSection* cs_coinsView;
|
2018-07-17 09:36:38 -07:00
|
|
|
CMutableTransaction mtx;
|
2018-07-30 04:52:48 -07:00
|
|
|
CAmount fee = 10000;
|
2018-07-17 09:36:38 -07:00
|
|
|
|
|
|
|
std::vector<SpendDescriptionInfo> spends;
|
|
|
|
std::vector<OutputDescriptionInfo> outputs;
|
2018-10-12 17:36:26 -07:00
|
|
|
std::vector<libzcash::JSInput> jsInputs;
|
|
|
|
std::vector<libzcash::JSOutput> jsOutputs;
|
2018-07-30 03:03:29 -07:00
|
|
|
std::vector<TransparentInputInfo> tIns;
|
2018-07-17 09:36:38 -07:00
|
|
|
|
2018-10-12 17:36:26 -07:00
|
|
|
boost::optional<std::pair<uint256, libzcash::SaplingPaymentAddress>> saplingChangeAddr;
|
|
|
|
boost::optional<libzcash::SproutPaymentAddress> sproutChangeAddr;
|
2018-07-30 04:36:42 -07:00
|
|
|
boost::optional<CTxDestination> tChangeAddr;
|
|
|
|
|
2018-07-17 09:36:38 -07:00
|
|
|
public:
|
2018-08-04 04:23:13 -07:00
|
|
|
TransactionBuilder() {}
|
2018-10-12 17:36:26 -07:00
|
|
|
TransactionBuilder(
|
|
|
|
const Consensus::Params& consensusParams,
|
|
|
|
int nHeight,
|
|
|
|
CKeyStore* keyStore = nullptr,
|
|
|
|
ZCJoinSplit* sproutParams = nullptr,
|
|
|
|
CCoinsViewCache* coinsView = nullptr,
|
|
|
|
CCriticalSection* cs_coinsView = nullptr);
|
2018-07-17 09:36:38 -07:00
|
|
|
|
2019-07-30 00:16:37 -07:00
|
|
|
void SetExpiryHeight(uint32_t nExpiryHeight);
|
|
|
|
|
2018-07-30 04:52:48 -07:00
|
|
|
void SetFee(CAmount fee);
|
|
|
|
|
2018-10-31 09:15:37 -07:00
|
|
|
// Throws if the anchor does not match the anchor used by
|
2018-07-27 00:46:38 -07:00
|
|
|
// previously-added Sapling spends.
|
2018-10-31 09:15:37 -07:00
|
|
|
void AddSaplingSpend(
|
2018-07-30 06:26:29 -07:00
|
|
|
libzcash::SaplingExpandedSpendingKey expsk,
|
2018-07-17 09:36:38 -07:00
|
|
|
libzcash::SaplingNote note,
|
|
|
|
uint256 anchor,
|
2018-08-01 09:41:36 -07:00
|
|
|
SaplingWitness witness);
|
2018-07-17 09:36:38 -07:00
|
|
|
|
|
|
|
void AddSaplingOutput(
|
2018-09-18 15:22:50 -07:00
|
|
|
uint256 ovk,
|
2018-07-17 09:36:38 -07:00
|
|
|
libzcash::SaplingPaymentAddress to,
|
|
|
|
CAmount value,
|
2018-09-13 14:04:00 -07:00
|
|
|
std::array<unsigned char, ZC_MEMO_SIZE> memo = {{0xF6}});
|
2018-07-17 09:36:38 -07:00
|
|
|
|
2018-10-12 17:36:26 -07:00
|
|
|
// Throws if the anchor does not match the anchor used by
|
|
|
|
// previously-added Sprout inputs.
|
|
|
|
void AddSproutInput(
|
|
|
|
libzcash::SproutSpendingKey sk,
|
|
|
|
libzcash::SproutNote note,
|
|
|
|
SproutWitness witness);
|
|
|
|
|
|
|
|
void AddSproutOutput(
|
|
|
|
libzcash::SproutPaymentAddress to,
|
|
|
|
CAmount value,
|
|
|
|
std::array<unsigned char, ZC_MEMO_SIZE> memo = {{0xF6}});
|
|
|
|
|
2018-07-30 03:03:29 -07:00
|
|
|
// Assumes that the value correctly corresponds to the provided UTXO.
|
|
|
|
void AddTransparentInput(COutPoint utxo, CScript scriptPubKey, CAmount value);
|
|
|
|
|
2018-10-31 09:15:37 -07:00
|
|
|
void AddTransparentOutput(CTxDestination& to, CAmount value);
|
2018-07-30 03:03:29 -07:00
|
|
|
|
2018-09-18 15:22:50 -07:00
|
|
|
void SendChangeTo(libzcash::SaplingPaymentAddress changeAddr, uint256 ovk);
|
2018-07-30 04:36:42 -07:00
|
|
|
|
2018-10-12 17:36:26 -07:00
|
|
|
void SendChangeTo(libzcash::SproutPaymentAddress);
|
|
|
|
|
2018-10-31 09:15:37 -07:00
|
|
|
void SendChangeTo(CTxDestination& changeAddr);
|
2018-07-30 04:36:42 -07:00
|
|
|
|
2018-10-30 13:12:40 -07:00
|
|
|
TransactionBuilderResult Build();
|
2018-10-12 17:36:26 -07:00
|
|
|
|
|
|
|
private:
|
2019-02-28 10:19:36 -08:00
|
|
|
void CreateJSDescriptions();
|
2018-10-12 17:36:26 -07:00
|
|
|
|
|
|
|
void CreateJSDescription(
|
|
|
|
uint64_t vpub_old,
|
|
|
|
uint64_t vpub_new,
|
|
|
|
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS> vjsin,
|
|
|
|
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS> vjsout,
|
|
|
|
std::array<size_t, ZC_NUM_JS_INPUTS>& inputMap,
|
|
|
|
std::array<size_t, ZC_NUM_JS_OUTPUTS>& outputMap);
|
2018-07-17 09:36:38 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* TRANSACTION_BUILDER_H */
|