Skip to content

Commit abba85d

Browse files
committed
Basic Sapling transaction primitive data.
1 parent fc3444c commit abba85d

File tree

4 files changed

+184
-5
lines changed

4 files changed

+184
-5
lines changed

src/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ LIBSAPLING_H = \
135135
sapling/note.hpp \
136136
sapling/zip32.h \
137137
sapling/saplingscriptpubkeyman.h \
138-
sapling/proof.hpp
138+
sapling/proof.hpp \
139+
sapling/sapling_transaction.h
139140

140141
.PHONY: FORCE cargo-build check-symbols check-security
141142
# pivx core #

src/primitives/transaction.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ std::string CTxOut::ToString() const
115115
}
116116

117117
CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
118-
CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {}
118+
CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), sapData(tx.sapData) {}
119119

120120
uint256 CMutableTransaction::GetHash() const
121121
{
@@ -149,7 +149,7 @@ size_t CTransaction::DynamicMemoryUsage() const
149149

150150
CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { }
151151

152-
CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {
152+
CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), sapData(tx.sapData) {
153153
UpdateHash();
154154
}
155155

@@ -159,6 +159,7 @@ CTransaction& CTransaction::operator=(const CTransaction &tx) {
159159
*const_cast<std::vector<CTxOut>*>(&vout) = tx.vout;
160160
*const_cast<unsigned int*>(&nLockTime) = tx.nLockTime;
161161
*const_cast<uint256*>(&hash) = tx.hash;
162+
*const_cast<SaplingTxData*>(&sapData) = tx.sapData;
162163
return *this;
163164
}
164165

src/primitives/transaction.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "serialize.h"
1414
#include "uint256.h"
1515

16+
#include "sapling/sapling_transaction.h"
17+
1618
#include <list>
1719

1820
class CTransaction;
@@ -71,6 +73,16 @@ class COutPoint : public BaseOutPoint
7173
std::string ToString() const;
7274
};
7375

76+
/** An outpoint - a combination of a transaction hash and an index n into its sapling
77+
* output description (vShieldedOutput) */
78+
class SaplingOutPoint : public BaseOutPoint
79+
{
80+
public:
81+
SaplingOutPoint() : BaseOutPoint() {};
82+
SaplingOutPoint(uint256 hashIn, uint32_t nIn) : BaseOutPoint(hashIn, nIn) {};
83+
std::string ToString() const;
84+
};
85+
7486
/** An input of a transaction. It contains the location of the previous
7587
* transaction's output that it claims and a signature that matches the
7688
* output's public key.
@@ -230,7 +242,10 @@ class CTransaction
230242
void UpdateHash() const;
231243

232244
public:
233-
static const int32_t CURRENT_VERSION=1;
245+
static const int32_t STANDARD_VERSION = 1;
246+
static const int32_t SAPLING_VERSION = 2;
247+
248+
static const int32_t CURRENT_VERSION = STANDARD_VERSION;
234249

235250
// The local variables are made const to prevent unintended modification
236251
// without updating the cached hash value. However, CTransaction is not
@@ -241,7 +256,7 @@ class CTransaction
241256
std::vector<CTxIn> vin;
242257
std::vector<CTxOut> vout;
243258
const uint32_t nLockTime;
244-
//const unsigned int nTime;
259+
SaplingTxData sapData;
245260

246261
/** Construct a CTransaction that qualifies as IsNull() */
247262
CTransaction();
@@ -259,6 +274,11 @@ class CTransaction
259274
READWRITE(*const_cast<std::vector<CTxIn>*>(&vin));
260275
READWRITE(*const_cast<std::vector<CTxOut>*>(&vout));
261276
READWRITE(*const_cast<uint32_t*>(&nLockTime));
277+
278+
if (nVersion >= CTransaction::SAPLING_VERSION) {
279+
READWRITE(*const_cast<SaplingTxData*>(&sapData));
280+
}
281+
262282
if (ser_action.ForRead())
263283
UpdateHash();
264284
}
@@ -327,6 +347,7 @@ struct CMutableTransaction
327347
std::vector<CTxIn> vin;
328348
std::vector<CTxOut> vout;
329349
uint32_t nLockTime;
350+
SaplingTxData sapData;
330351

331352
CMutableTransaction();
332353
CMutableTransaction(const CTransaction& tx);
@@ -339,6 +360,10 @@ struct CMutableTransaction
339360
READWRITE(vin);
340361
READWRITE(vout);
341362
READWRITE(nLockTime);
363+
364+
if (nVersion >= CTransaction::SAPLING_VERSION) {
365+
READWRITE(*const_cast<SaplingTxData*>(&sapData));
366+
}
342367
}
343368

344369
/** Compute the hash of this CMutableTransaction. This is computed on the

src/sapling/sapling_transaction.h

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// Copyright (c) 2016-2020 The ZCash developers
2+
// Copyright (c) 2020 The PIVX developers
3+
// Distributed under the MIT software license, see the accompanying
4+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
#ifndef PIVX_SAPLING_TRANSACTION_H
7+
#define PIVX_SAPLING_TRANSACTION_H
8+
9+
#include "serialize.h"
10+
#include "streams.h"
11+
#include "uint256.h"
12+
#include "consensus/consensus.h"
13+
14+
#include "sapling/noteencryption.hpp"
15+
#include "sapling/sapling.h"
16+
#include "sapling/proof.hpp"
17+
18+
#include <boost/variant.hpp>
19+
20+
// These constants are defined in the protocol § 7.1:
21+
// https://zips.z.cash/protocol/protocol.pdf#txnencoding
22+
#define OUTPUTDESCRIPTION_SIZE 948
23+
#define SPENDDESCRIPTION_SIZE 384
24+
25+
namespace libzcash {
26+
static constexpr size_t GROTH_PROOF_SIZE = (
27+
48 + // π_A
28+
96 + // π_B
29+
48); // π_C
30+
31+
typedef std::array<unsigned char, GROTH_PROOF_SIZE> GrothProof;
32+
}
33+
34+
/**
35+
* A shielded input to a transaction. It contains data that describes a Spend transfer.
36+
*/
37+
class SpendDescription
38+
{
39+
public:
40+
typedef std::array<unsigned char, 64> spend_auth_sig_t;
41+
42+
uint256 cv; //!< A value commitment to the value of the input note.
43+
uint256 anchor; //!< A Merkle root of the Sapling note commitment tree at some block height in the past.
44+
uint256 nullifier; //!< The nullifier of the input note.
45+
uint256 rk; //!< The randomized public key for spendAuthSig.
46+
libzcash::GrothProof zkproof; //!< A zero-knowledge proof using the spend circuit.
47+
spend_auth_sig_t spendAuthSig; //!< A signature authorizing this spend.
48+
49+
SpendDescription() { }
50+
51+
ADD_SERIALIZE_METHODS;
52+
53+
template <typename Stream, typename Operation>
54+
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
55+
READWRITE(cv);
56+
READWRITE(anchor);
57+
READWRITE(nullifier);
58+
READWRITE(rk);
59+
READWRITE(zkproof);
60+
READWRITE(spendAuthSig);
61+
}
62+
63+
friend bool operator==(const SpendDescription& a, const SpendDescription& b)
64+
{
65+
return (
66+
a.cv == b.cv &&
67+
a.anchor == b.anchor &&
68+
a.nullifier == b.nullifier &&
69+
a.rk == b.rk &&
70+
a.zkproof == b.zkproof &&
71+
a.spendAuthSig == b.spendAuthSig
72+
);
73+
}
74+
75+
friend bool operator!=(const SpendDescription& a, const SpendDescription& b)
76+
{
77+
return !(a == b);
78+
}
79+
};
80+
81+
/**
82+
* A shielded output to a transaction. It contains data that describes an Output transfer.
83+
*/
84+
class OutputDescription
85+
{
86+
public:
87+
uint256 cv; //!< A value commitment to the value of the output note.
88+
uint256 cmu; //!< The u-coordinate of the note commitment for the output note.
89+
uint256 ephemeralKey; //!< A Jubjub public key.
90+
libzcash::SaplingEncCiphertext encCiphertext; //!< A ciphertext component for the encrypted output note.
91+
libzcash::SaplingOutCiphertext outCiphertext; //!< A ciphertext component for the encrypted output note.
92+
libzcash::GrothProof zkproof; //!< A zero-knowledge proof using the output circuit.
93+
94+
OutputDescription() { }
95+
96+
ADD_SERIALIZE_METHODS;
97+
98+
template <typename Stream, typename Operation>
99+
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
100+
READWRITE(cv);
101+
READWRITE(cmu);
102+
READWRITE(ephemeralKey);
103+
READWRITE(encCiphertext);
104+
READWRITE(outCiphertext);
105+
READWRITE(zkproof);
106+
}
107+
108+
friend bool operator==(const OutputDescription& a, const OutputDescription& b)
109+
{
110+
return (
111+
a.cv == b.cv &&
112+
a.cmu == b.cmu &&
113+
a.ephemeralKey == b.ephemeralKey &&
114+
a.encCiphertext == b.encCiphertext &&
115+
a.outCiphertext == b.outCiphertext &&
116+
a.zkproof == b.zkproof
117+
);
118+
}
119+
120+
friend bool operator!=(const OutputDescription& a, const OutputDescription& b)
121+
{
122+
return !(a == b);
123+
}
124+
};
125+
126+
class SaplingTxData
127+
{
128+
public:
129+
typedef std::array<unsigned char, 64> binding_sig_t;
130+
131+
CAmount valueBalance{0};
132+
std::vector<SpendDescription> vShieldedSpend;
133+
std::vector<OutputDescription> vShieldedOutput;
134+
binding_sig_t bindingSig = {{0}};
135+
136+
ADD_SERIALIZE_METHODS;
137+
138+
template <typename Stream, typename Operation>
139+
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
140+
{
141+
READWRITE(*const_cast<CAmount*>(&valueBalance));
142+
READWRITE(*const_cast<std::vector<SpendDescription>*>(&vShieldedSpend));
143+
READWRITE(*const_cast<std::vector<OutputDescription>*>(&vShieldedOutput));
144+
READWRITE(*const_cast<binding_sig_t*>(&bindingSig));
145+
}
146+
147+
explicit SaplingTxData() : valueBalance(0), vShieldedSpend(), vShieldedOutput() { }
148+
explicit SaplingTxData(const SaplingTxData& from) : valueBalance(from.valueBalance), vShieldedSpend(from.vShieldedSpend), vShieldedOutput(from.vShieldedOutput), bindingSig(from.bindingSig) {}
149+
};
150+
151+
152+
#endif //PIVX_SAPLING_TRANSACTION_H

0 commit comments

Comments
 (0)