]>
Commit | Line | Data |
---|---|---|
4a3587d8 | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
f914f1a7 | 2 | // Copyright (c) 2009-2014 The Bitcoin Core developers |
4a3587d8 | 3 | // Distributed under the MIT software license, see the accompanying |
4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | |
5 | ||
d2270111 LD |
6 | #ifndef BITCOIN_PRIMITIVES_TRANSACTION_H |
7 | #define BITCOIN_PRIMITIVES_TRANSACTION_H | |
4a3587d8 | 8 | |
9 | #include "amount.h" | |
10 | #include "script/script.h" | |
11 | #include "serialize.h" | |
12 | #include "uint256.h" | |
13 | ||
5884044b SB |
14 | #include <boost/array.hpp> |
15 | ||
6c36a9fe | 16 | #include "zcash/NoteEncryption.hpp" |
5961dcb6 | 17 | #include "zcash/Zcash.h" |
2dc35992 | 18 | #include "zcash/JoinSplit.hpp" |
96c31d16 | 19 | |
a8c68ffe | 20 | class JSDescription |
5884044b SB |
21 | { |
22 | public: | |
23 | // These values 'enter from' and 'exit to' the value | |
24 | // pool, respectively. | |
25 | CAmount vpub_old; | |
26 | CAmount vpub_new; | |
27 | ||
4bc00dc1 | 28 | // JoinSplits are always anchored to a root in the note |
5884044b SB |
29 | // commitment tree at some point in the blockchain |
30 | // history or in the history of the current | |
31 | // transaction. | |
32 | uint256 anchor; | |
33 | ||
bfeaf004 | 34 | // Nullifiers are used to prevent double-spends. They |
4bc00dc1 | 35 | // are derived from the secrets placed in the note |
5884044b SB |
36 | // and the secret spend-authority key known by the |
37 | // spender. | |
bfeaf004 | 38 | boost::array<uint256, ZC_NUM_JS_INPUTS> nullifiers; |
5884044b | 39 | |
4bc00dc1 | 40 | // Note commitments are introduced into the commitment |
5884044b | 41 | // tree, blinding the public about the values and |
4bc00dc1 DH |
42 | // destinations involved in the JoinSplit. The presence of |
43 | // a commitment in the note commitment tree is required | |
5884044b | 44 | // to spend it. |
5961dcb6 | 45 | boost::array<uint256, ZC_NUM_JS_OUTPUTS> commitments; |
5884044b | 46 | |
3ebca007 SB |
47 | // Ephemeral key |
48 | uint256 ephemeralKey; | |
49 | ||
5884044b | 50 | // Ciphertexts |
6c36a9fe SB |
51 | // These contain trapdoors, values and other information |
52 | // that the recipient needs, including a memo field. It | |
53 | // is encrypted using the scheme implemented in crypto/NoteEncryption.cpp | |
5961dcb6 | 54 | boost::array<ZCNoteEncryption::Ciphertext, ZC_NUM_JS_OUTPUTS> ciphertexts; |
6c36a9fe | 55 | |
21406393 SB |
56 | // Random seed |
57 | uint256 randomSeed; | |
58 | ||
5884044b | 59 | // MACs |
b7e4abd6 | 60 | // The verification of the JoinSplit requires these MACs |
5884044b | 61 | // to be provided as an input. |
5961dcb6 | 62 | boost::array<uint256, ZC_NUM_JS_INPUTS> macs; |
5884044b | 63 | |
b7e4abd6 SB |
64 | // JoinSplit proof |
65 | // This is a zk-SNARK which ensures that this JoinSplit is valid. | |
9285bba8 | 66 | boost::array<unsigned char, ZKSNARK_PROOF_SIZE> proof; |
5884044b | 67 | |
a8c68ffe | 68 | JSDescription(): vpub_old(0), vpub_new(0) { } |
5884044b | 69 | |
a8c68ffe | 70 | JSDescription(ZCJoinSplit& params, |
21406393 | 71 | const uint256& pubKeyHash, |
96c31d16 | 72 | const uint256& rt, |
2dc35992 SB |
73 | const boost::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs, |
74 | const boost::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs, | |
96c31d16 SB |
75 | CAmount vpub_old, |
76 | CAmount vpub_new | |
77 | ); | |
78 | ||
b7e4abd6 | 79 | // Verifies that the JoinSplit proof is correct. |
2dc35992 SB |
80 | bool Verify(ZCJoinSplit& params, const uint256& pubKeyHash) const; |
81 | ||
82 | // Returns the calculated h_sig | |
83 | uint256 h_sig(ZCJoinSplit& params, const uint256& pubKeyHash) const; | |
96c31d16 | 84 | |
5884044b SB |
85 | ADD_SERIALIZE_METHODS; |
86 | ||
87 | template <typename Stream, typename Operation> | |
88 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
89 | READWRITE(vpub_old); | |
90 | READWRITE(vpub_new); | |
5884044b | 91 | READWRITE(anchor); |
bfeaf004 | 92 | READWRITE(nullifiers); |
5884044b | 93 | READWRITE(commitments); |
6c36a9fe | 94 | READWRITE(ephemeralKey); |
3ebca007 | 95 | READWRITE(ciphertexts); |
21406393 | 96 | READWRITE(randomSeed); |
5884044b SB |
97 | READWRITE(macs); |
98 | READWRITE(proof); | |
99 | } | |
100 | ||
a8c68ffe | 101 | friend bool operator==(const JSDescription& a, const JSDescription& b) |
5884044b SB |
102 | { |
103 | return ( | |
104 | a.vpub_old == b.vpub_old && | |
105 | a.vpub_new == b.vpub_new && | |
5884044b | 106 | a.anchor == b.anchor && |
bfeaf004 | 107 | a.nullifiers == b.nullifiers && |
5884044b | 108 | a.commitments == b.commitments && |
6c36a9fe | 109 | a.ephemeralKey == b.ephemeralKey && |
3ebca007 | 110 | a.ciphertexts == b.ciphertexts && |
21406393 | 111 | a.randomSeed == b.randomSeed && |
5884044b SB |
112 | a.macs == b.macs && |
113 | a.proof == b.proof | |
114 | ); | |
115 | } | |
116 | ||
a8c68ffe | 117 | friend bool operator!=(const JSDescription& a, const JSDescription& b) |
5884044b SB |
118 | { |
119 | return !(a == b); | |
120 | } | |
121 | }; | |
122 | ||
4a3587d8 | 123 | /** An outpoint - a combination of a transaction hash and an index n into its vout */ |
124 | class COutPoint | |
125 | { | |
126 | public: | |
127 | uint256 hash; | |
128 | uint32_t n; | |
129 | ||
130 | COutPoint() { SetNull(); } | |
131 | COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; } | |
132 | ||
133 | ADD_SERIALIZE_METHODS; | |
134 | ||
135 | template <typename Stream, typename Operation> | |
136 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
4f92773f WL |
137 | READWRITE(hash); |
138 | READWRITE(n); | |
4a3587d8 | 139 | } |
140 | ||
4f152496 WL |
141 | void SetNull() { hash.SetNull(); n = (uint32_t) -1; } |
142 | bool IsNull() const { return (hash.IsNull() && n == (uint32_t) -1); } | |
4a3587d8 | 143 | |
144 | friend bool operator<(const COutPoint& a, const COutPoint& b) | |
145 | { | |
146 | return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n)); | |
147 | } | |
148 | ||
149 | friend bool operator==(const COutPoint& a, const COutPoint& b) | |
150 | { | |
151 | return (a.hash == b.hash && a.n == b.n); | |
152 | } | |
153 | ||
154 | friend bool operator!=(const COutPoint& a, const COutPoint& b) | |
155 | { | |
156 | return !(a == b); | |
157 | } | |
158 | ||
159 | std::string ToString() const; | |
160 | }; | |
161 | ||
162 | /** An input of a transaction. It contains the location of the previous | |
163 | * transaction's output that it claims and a signature that matches the | |
164 | * output's public key. | |
165 | */ | |
166 | class CTxIn | |
167 | { | |
168 | public: | |
169 | COutPoint prevout; | |
170 | CScript scriptSig; | |
171 | uint32_t nSequence; | |
172 | ||
173 | CTxIn() | |
174 | { | |
175 | nSequence = std::numeric_limits<unsigned int>::max(); | |
176 | } | |
177 | ||
178 | explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max()); | |
179 | CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<uint32_t>::max()); | |
180 | ||
181 | ADD_SERIALIZE_METHODS; | |
182 | ||
183 | template <typename Stream, typename Operation> | |
184 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
185 | READWRITE(prevout); | |
186 | READWRITE(scriptSig); | |
187 | READWRITE(nSequence); | |
188 | } | |
189 | ||
190 | bool IsFinal() const | |
191 | { | |
192 | return (nSequence == std::numeric_limits<uint32_t>::max()); | |
193 | } | |
194 | ||
195 | friend bool operator==(const CTxIn& a, const CTxIn& b) | |
196 | { | |
197 | return (a.prevout == b.prevout && | |
198 | a.scriptSig == b.scriptSig && | |
199 | a.nSequence == b.nSequence); | |
200 | } | |
201 | ||
202 | friend bool operator!=(const CTxIn& a, const CTxIn& b) | |
203 | { | |
204 | return !(a == b); | |
205 | } | |
206 | ||
207 | std::string ToString() const; | |
208 | }; | |
209 | ||
210 | /** An output of a transaction. It contains the public key that the next input | |
211 | * must be able to sign with to claim it. | |
212 | */ | |
213 | class CTxOut | |
214 | { | |
215 | public: | |
216 | CAmount nValue; | |
217 | CScript scriptPubKey; | |
218 | ||
219 | CTxOut() | |
220 | { | |
221 | SetNull(); | |
222 | } | |
223 | ||
224 | CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn); | |
225 | ||
226 | ADD_SERIALIZE_METHODS; | |
227 | ||
228 | template <typename Stream, typename Operation> | |
229 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
230 | READWRITE(nValue); | |
231 | READWRITE(scriptPubKey); | |
232 | } | |
233 | ||
234 | void SetNull() | |
235 | { | |
236 | nValue = -1; | |
237 | scriptPubKey.clear(); | |
238 | } | |
239 | ||
240 | bool IsNull() const | |
241 | { | |
242 | return (nValue == -1); | |
243 | } | |
244 | ||
245 | uint256 GetHash() const; | |
246 | ||
292623ad | 247 | CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const |
4a3587d8 | 248 | { |
249 | // "Dust" is defined in terms of CTransaction::minRelayTxFee, | |
250 | // which has units satoshis-per-kilobyte. | |
251 | // If you'd pay more than 1/3 in fees | |
252 | // to spend something, then we consider it dust. | |
253 | // A typical txout is 34 bytes big, and will | |
254 | // need a CTxIn of at least 148 bytes to spend: | |
255 | // so dust is a txout less than 546 satoshis | |
256 | // with default minRelayTxFee. | |
257 | size_t nSize = GetSerializeSize(SER_DISK,0)+148u; | |
292623ad CL |
258 | return 3*minRelayTxFee.GetFee(nSize); |
259 | } | |
260 | ||
261 | bool IsDust(const CFeeRate &minRelayTxFee) const | |
262 | { | |
263 | return (nValue < GetDustThreshold(minRelayTxFee)); | |
4a3587d8 | 264 | } |
265 | ||
266 | friend bool operator==(const CTxOut& a, const CTxOut& b) | |
267 | { | |
268 | return (a.nValue == b.nValue && | |
269 | a.scriptPubKey == b.scriptPubKey); | |
270 | } | |
271 | ||
272 | friend bool operator!=(const CTxOut& a, const CTxOut& b) | |
273 | { | |
274 | return !(a == b); | |
275 | } | |
276 | ||
277 | std::string ToString() const; | |
278 | }; | |
279 | ||
280 | struct CMutableTransaction; | |
281 | ||
282 | /** The basic transaction that is broadcasted on the network and contained in | |
283 | * blocks. A transaction can contain multiple inputs and outputs. | |
284 | */ | |
285 | class CTransaction | |
286 | { | |
287 | private: | |
288 | /** Memory only. */ | |
289 | const uint256 hash; | |
290 | void UpdateHash() const; | |
291 | ||
292 | public: | |
320f2cc7 SB |
293 | typedef boost::array<unsigned char, 64> joinsplit_sig_t; |
294 | ||
4a3587d8 | 295 | static const int32_t CURRENT_VERSION=1; |
296 | ||
297 | // The local variables are made const to prevent unintended modification | |
298 | // without updating the cached hash value. However, CTransaction is not | |
299 | // actually immutable; deserialization and assignment are implemented, | |
300 | // and bypass the constness. This is safe, as they update the entire | |
301 | // structure, including the hash. | |
302 | const int32_t nVersion; | |
303 | const std::vector<CTxIn> vin; | |
304 | const std::vector<CTxOut> vout; | |
305 | const uint32_t nLockTime; | |
8675d94b | 306 | const std::vector<JSDescription> vjoinsplit; |
320f2cc7 SB |
307 | const uint256 joinSplitPubKey; |
308 | const joinsplit_sig_t joinSplitSig; | |
4a3587d8 | 309 | |
310 | /** Construct a CTransaction that qualifies as IsNull() */ | |
311 | CTransaction(); | |
312 | ||
313 | /** Convert a CMutableTransaction into a CTransaction. */ | |
314 | CTransaction(const CMutableTransaction &tx); | |
315 | ||
316 | CTransaction& operator=(const CTransaction& tx); | |
317 | ||
318 | ADD_SERIALIZE_METHODS; | |
319 | ||
320 | template <typename Stream, typename Operation> | |
321 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
322 | READWRITE(*const_cast<int32_t*>(&this->nVersion)); | |
323 | nVersion = this->nVersion; | |
324 | READWRITE(*const_cast<std::vector<CTxIn>*>(&vin)); | |
325 | READWRITE(*const_cast<std::vector<CTxOut>*>(&vout)); | |
326 | READWRITE(*const_cast<uint32_t*>(&nLockTime)); | |
5884044b | 327 | if (nVersion >= 2) { |
8675d94b SB |
328 | READWRITE(*const_cast<std::vector<JSDescription>*>(&vjoinsplit)); |
329 | if (vjoinsplit.size() > 0) { | |
320f2cc7 SB |
330 | READWRITE(*const_cast<uint256*>(&joinSplitPubKey)); |
331 | READWRITE(*const_cast<joinsplit_sig_t*>(&joinSplitSig)); | |
6aae9d1a | 332 | } |
5884044b | 333 | } |
4a3587d8 | 334 | if (ser_action.ForRead()) |
335 | UpdateHash(); | |
336 | } | |
337 | ||
338 | bool IsNull() const { | |
339 | return vin.empty() && vout.empty(); | |
340 | } | |
341 | ||
342 | const uint256& GetHash() const { | |
343 | return hash; | |
344 | } | |
345 | ||
346 | // Return sum of txouts. | |
347 | CAmount GetValueOut() const; | |
348 | // GetValueIn() is a method on CCoinsViewCache, because | |
349 | // inputs must be known to compute value in. | |
350 | ||
b7e4abd6 | 351 | // Return sum of JoinSplit vpub_new |
942bc467 | 352 | CAmount GetJoinSplitValueIn() const; |
f512cf7c | 353 | |
4a3587d8 | 354 | // Compute priority, given priority of inputs and (optionally) tx size |
355 | double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const; | |
356 | ||
357 | // Compute modified tx size for priority calculation (optionally given tx size) | |
358 | unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const; | |
359 | ||
360 | bool IsCoinBase() const | |
361 | { | |
362 | return (vin.size() == 1 && vin[0].prevout.IsNull()); | |
363 | } | |
364 | ||
365 | friend bool operator==(const CTransaction& a, const CTransaction& b) | |
366 | { | |
367 | return a.hash == b.hash; | |
368 | } | |
369 | ||
370 | friend bool operator!=(const CTransaction& a, const CTransaction& b) | |
371 | { | |
372 | return a.hash != b.hash; | |
373 | } | |
374 | ||
375 | std::string ToString() const; | |
49689a57 S |
376 | |
377 | // Return the txid which is the double SHA256 hash of the transaction. | |
378 | uint256 GetTxid() const; | |
379 | ||
4a3587d8 | 380 | }; |
381 | ||
382 | /** A mutable version of CTransaction. */ | |
383 | struct CMutableTransaction | |
384 | { | |
385 | int32_t nVersion; | |
386 | std::vector<CTxIn> vin; | |
387 | std::vector<CTxOut> vout; | |
388 | uint32_t nLockTime; | |
8675d94b | 389 | std::vector<JSDescription> vjoinsplit; |
320f2cc7 | 390 | uint256 joinSplitPubKey; |
1e99cbab | 391 | CTransaction::joinsplit_sig_t joinSplitSig; |
4a3587d8 | 392 | |
393 | CMutableTransaction(); | |
394 | CMutableTransaction(const CTransaction& tx); | |
395 | ||
396 | ADD_SERIALIZE_METHODS; | |
397 | ||
398 | template <typename Stream, typename Operation> | |
399 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
400 | READWRITE(this->nVersion); | |
401 | nVersion = this->nVersion; | |
402 | READWRITE(vin); | |
403 | READWRITE(vout); | |
404 | READWRITE(nLockTime); | |
5884044b | 405 | if (nVersion >= 2) { |
8675d94b SB |
406 | READWRITE(vjoinsplit); |
407 | if (vjoinsplit.size() > 0) { | |
6aae9d1a TH |
408 | READWRITE(joinSplitPubKey); |
409 | READWRITE(joinSplitSig); | |
410 | } | |
5884044b | 411 | } |
4a3587d8 | 412 | } |
413 | ||
414 | /** Compute the hash of this CMutableTransaction. This is computed on the | |
415 | * fly, as opposed to GetHash() in CTransaction, which uses a cached result. | |
416 | */ | |
417 | uint256 GetHash() const; | |
49689a57 S |
418 | |
419 | // Compute a non-malleable txid on the fly. | |
420 | uint256 GetTxid() const; | |
4a3587d8 | 421 | }; |
422 | ||
d2270111 | 423 | #endif // BITCOIN_PRIMITIVES_TRANSACTION_H |