]> Git Repo - VerusCoin.git/blame - src/core.h
main.h->core.h include dependency improvements.
[VerusCoin.git] / src / core.h
CommitLineData
effc2770
EL
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2013 The Bitcoin developers
3// Distributed under the MIT/X11 software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5#ifndef BITCOIN_CORE_H
6#define BITCOIN_CORE_H
7
8#include "uint256.h"
9#include "serialize.h"
10#include "util.h"
05df3fc6 11#include "script.h"
effc2770
EL
12
13#include <stdio.h>
14
788536f1
EL
15class CTransaction;
16
effc2770
EL
17/** An outpoint - a combination of a transaction hash and an index n into its vout */
18class COutPoint
19{
20public:
21 uint256 hash;
22 unsigned int n;
23
24 COutPoint() { SetNull(); }
25 COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
26 IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
27 void SetNull() { hash = 0; n = (unsigned int) -1; }
28 bool IsNull() const { return (hash == 0 && n == (unsigned int) -1); }
29
30 friend bool operator<(const COutPoint& a, const COutPoint& b)
31 {
32 return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
33 }
34
35 friend bool operator==(const COutPoint& a, const COutPoint& b)
36 {
37 return (a.hash == b.hash && a.n == b.n);
38 }
39
40 friend bool operator!=(const COutPoint& a, const COutPoint& b)
41 {
42 return !(a == b);
43 }
44
45 std::string ToString() const
46 {
47 return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10).c_str(), n);
48 }
49
50 void print() const
51 {
52 printf("%s\n", ToString().c_str());
53 }
54};
55
788536f1
EL
56/** An inpoint - a combination of a transaction and an index n into its vin */
57class CInPoint
58{
59public:
60 CTransaction* ptx;
61 unsigned int n;
62
63 CInPoint() { SetNull(); }
64 CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
65 void SetNull() { ptx = NULL; n = (unsigned int) -1; }
66 bool IsNull() const { return (ptx == NULL && n == (unsigned int) -1); }
67};
68
05df3fc6
EL
69/** An input of a transaction. It contains the location of the previous
70 * transaction's output that it claims and a signature that matches the
71 * output's public key.
72 */
73class CTxIn
74{
75public:
76 COutPoint prevout;
77 CScript scriptSig;
78 unsigned int nSequence;
79
80 CTxIn()
81 {
82 nSequence = std::numeric_limits<unsigned int>::max();
83 }
84
85 explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
86 {
87 prevout = prevoutIn;
88 scriptSig = scriptSigIn;
89 nSequence = nSequenceIn;
90 }
91
92 CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
93 {
94 prevout = COutPoint(hashPrevTx, nOut);
95 scriptSig = scriptSigIn;
96 nSequence = nSequenceIn;
97 }
98
99 IMPLEMENT_SERIALIZE
100 (
101 READWRITE(prevout);
102 READWRITE(scriptSig);
103 READWRITE(nSequence);
104 )
105
106 bool IsFinal() const
107 {
108 return (nSequence == std::numeric_limits<unsigned int>::max());
109 }
110
111 friend bool operator==(const CTxIn& a, const CTxIn& b)
112 {
113 return (a.prevout == b.prevout &&
114 a.scriptSig == b.scriptSig &&
115 a.nSequence == b.nSequence);
116 }
117
118 friend bool operator!=(const CTxIn& a, const CTxIn& b)
119 {
120 return !(a == b);
121 }
122
123 std::string ToString() const
124 {
125 std::string str;
126 str += "CTxIn(";
127 str += prevout.ToString();
128 if (prevout.IsNull())
129 str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
130 else
131 str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
132 if (nSequence != std::numeric_limits<unsigned int>::max())
133 str += strprintf(", nSequence=%u", nSequence);
134 str += ")";
135 return str;
136 }
137
138 void print() const
139 {
140 printf("%s\n", ToString().c_str());
141 }
142};
143
144
145
146
147/** An output of a transaction. It contains the public key that the next input
148 * must be able to sign with to claim it.
149 */
150class CTxOut
151{
152public:
153 int64 nValue;
154 CScript scriptPubKey;
155
156 CTxOut()
157 {
158 SetNull();
159 }
160
161 CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
162 {
163 nValue = nValueIn;
164 scriptPubKey = scriptPubKeyIn;
165 }
166
167 IMPLEMENT_SERIALIZE
168 (
169 READWRITE(nValue);
170 READWRITE(scriptPubKey);
171 )
172
173 void SetNull()
174 {
175 nValue = -1;
176 scriptPubKey.clear();
177 }
178
179 bool IsNull() const
180 {
181 return (nValue == -1);
182 }
183
184 uint256 GetHash() const
185 {
186 return SerializeHash(*this);
187 }
188
189 bool IsDust(int64 nMinRelayTxFee) const
190 {
191 // "Dust" is defined in terms of CTransaction::nMinRelayTxFee,
192 // which has units satoshis-per-kilobyte.
193 // If you'd pay more than 1/3 in fees
194 // to spend something, then we consider it dust.
346427f0 195 // A typical txout is 34 bytes big, and will
05df3fc6
EL
196 // need a CTxIn of at least 148 bytes to spend,
197 // so dust is a txout less than 54 uBTC
346427f0 198 // (5460 satoshis) with default nMinRelayTxFee
05df3fc6
EL
199 return ((nValue*1000)/(3*((int)GetSerializeSize(SER_DISK,0)+148)) < nMinRelayTxFee);
200 }
201
202 friend bool operator==(const CTxOut& a, const CTxOut& b)
203 {
204 return (a.nValue == b.nValue &&
205 a.scriptPubKey == b.scriptPubKey);
206 }
207
208 friend bool operator!=(const CTxOut& a, const CTxOut& b)
209 {
210 return !(a == b);
211 }
212
213 std::string ToString() const
214 {
215 if (scriptPubKey.size() < 6)
216 return "CTxOut(error)";
217 return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
218 }
219
220 void print() const
221 {
222 printf("%s\n", ToString().c_str());
223 }
224};
225
226
227/** The basic transaction that is broadcasted on the network and contained in
228 * blocks. A transaction can contain multiple inputs and outputs.
229 */
230class CTransaction
231{
232public:
233 static int64 nMinTxFee;
234 static int64 nMinRelayTxFee;
235 static const int CURRENT_VERSION=1;
236 int nVersion;
237 std::vector<CTxIn> vin;
238 std::vector<CTxOut> vout;
239 unsigned int nLockTime;
240
241 CTransaction()
242 {
243 SetNull();
244 }
245
246 IMPLEMENT_SERIALIZE
247 (
248 READWRITE(this->nVersion);
249 nVersion = this->nVersion;
250 READWRITE(vin);
251 READWRITE(vout);
252 READWRITE(nLockTime);
253 )
254
255 void SetNull()
256 {
257 nVersion = CTransaction::CURRENT_VERSION;
258 vin.clear();
259 vout.clear();
260 nLockTime = 0;
261 }
262
263 bool IsNull() const
264 {
265 return (vin.empty() && vout.empty());
266 }
267
268 uint256 GetHash() const
269 {
270 return SerializeHash(*this);
271 }
272
273 bool IsNewerThan(const CTransaction& old) const
274 {
275 if (vin.size() != old.vin.size())
276 return false;
277 for (unsigned int i = 0; i < vin.size(); i++)
278 if (vin[i].prevout != old.vin[i].prevout)
279 return false;
280
281 bool fNewer = false;
282 unsigned int nLowest = std::numeric_limits<unsigned int>::max();
283 for (unsigned int i = 0; i < vin.size(); i++)
284 {
285 if (vin[i].nSequence != old.vin[i].nSequence)
286 {
287 if (vin[i].nSequence <= nLowest)
288 {
289 fNewer = false;
290 nLowest = vin[i].nSequence;
291 }
292 if (old.vin[i].nSequence < nLowest)
293 {
294 fNewer = true;
295 nLowest = old.vin[i].nSequence;
296 }
297 }
298 }
299 return fNewer;
300 }
301
302 bool IsCoinBase() const
303 {
304 return (vin.size() == 1 && vin[0].prevout.IsNull());
305 }
306
307 friend bool operator==(const CTransaction& a, const CTransaction& b)
308 {
309 return (a.nVersion == b.nVersion &&
310 a.vin == b.vin &&
311 a.vout == b.vout &&
312 a.nLockTime == b.nLockTime);
313 }
314
315 friend bool operator!=(const CTransaction& a, const CTransaction& b)
316 {
317 return !(a == b);
318 }
319
320
321 std::string ToString() const
322 {
323 std::string str;
324 str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%"PRIszu", vout.size=%"PRIszu", nLockTime=%u)\n",
325 GetHash().ToString().substr(0,10).c_str(),
326 nVersion,
327 vin.size(),
328 vout.size(),
329 nLockTime);
330 for (unsigned int i = 0; i < vin.size(); i++)
331 str += " " + vin[i].ToString() + "\n";
332 for (unsigned int i = 0; i < vout.size(); i++)
333 str += " " + vout[i].ToString() + "\n";
334 return str;
335 }
336
337 void print() const
338 {
339 printf("%s", ToString().c_str());
340 }
341};
342
65e7bbef
EL
343/** wrapper for CTxOut that provides a more compact serialization */
344class CTxOutCompressor
345{
346private:
347 CTxOut &txout;
348
349public:
350 static uint64 CompressAmount(uint64 nAmount);
351 static uint64 DecompressAmount(uint64 nAmount);
352
353 CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { }
354
355 IMPLEMENT_SERIALIZE(({
356 if (!fRead) {
357 uint64 nVal = CompressAmount(txout.nValue);
358 READWRITE(VARINT(nVal));
359 } else {
360 uint64 nVal = 0;
361 READWRITE(VARINT(nVal));
362 txout.nValue = DecompressAmount(nVal);
363 }
364 CScriptCompressor cscript(REF(txout.scriptPubKey));
365 READWRITE(cscript);
366 });)
367};
368
369/** Undo information for a CTxIn
370 *
371 * Contains the prevout's CTxOut being spent, and if this was the
372 * last output of the affected transaction, its metadata as well
373 * (coinbase or not, height, transaction version)
374 */
375class CTxInUndo
376{
377public:
378 CTxOut txout; // the txout data before being spent
379 bool fCoinBase; // if the outpoint was the last unspent: whether it belonged to a coinbase
380 unsigned int nHeight; // if the outpoint was the last unspent: its height
381 int nVersion; // if the outpoint was the last unspent: its version
382
383 CTxInUndo() : txout(), fCoinBase(false), nHeight(0), nVersion(0) {}
384 CTxInUndo(const CTxOut &txoutIn, bool fCoinBaseIn = false, unsigned int nHeightIn = 0, int nVersionIn = 0) : txout(txoutIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nVersion(nVersionIn) { }
385
386 unsigned int GetSerializeSize(int nType, int nVersion) const {
387 return ::GetSerializeSize(VARINT(nHeight*2+(fCoinBase ? 1 : 0)), nType, nVersion) +
388 (nHeight > 0 ? ::GetSerializeSize(VARINT(this->nVersion), nType, nVersion) : 0) +
389 ::GetSerializeSize(CTxOutCompressor(REF(txout)), nType, nVersion);
390 }
391
392 template<typename Stream>
393 void Serialize(Stream &s, int nType, int nVersion) const {
394 ::Serialize(s, VARINT(nHeight*2+(fCoinBase ? 1 : 0)), nType, nVersion);
395 if (nHeight > 0)
396 ::Serialize(s, VARINT(this->nVersion), nType, nVersion);
397 ::Serialize(s, CTxOutCompressor(REF(txout)), nType, nVersion);
398 }
399
400 template<typename Stream>
401 void Unserialize(Stream &s, int nType, int nVersion) {
402 unsigned int nCode = 0;
403 ::Unserialize(s, VARINT(nCode), nType, nVersion);
404 nHeight = nCode / 2;
405 fCoinBase = nCode & 1;
406 if (nHeight > 0)
407 ::Unserialize(s, VARINT(this->nVersion), nType, nVersion);
408 ::Unserialize(s, REF(CTxOutCompressor(REF(txout))), nType, nVersion);
409 }
410};
411
412/** Undo information for a CTransaction */
413class CTxUndo
414{
415public:
416 // undo information for all txins
417 std::vector<CTxInUndo> vprevout;
418
419 IMPLEMENT_SERIALIZE(
420 READWRITE(vprevout);
421 )
422};
423
424
425/** pruned version of CTransaction: only retains metadata and unspent transaction outputs
426 *
427 * Serialized format:
428 * - VARINT(nVersion)
429 * - VARINT(nCode)
430 * - unspentness bitvector, for vout[2] and further; least significant byte first
431 * - the non-spent CTxOuts (via CTxOutCompressor)
432 * - VARINT(nHeight)
433 *
434 * The nCode value consists of:
435 * - bit 1: IsCoinBase()
436 * - bit 2: vout[0] is not spent
437 * - bit 4: vout[1] is not spent
438 * - The higher bits encode N, the number of non-zero bytes in the following bitvector.
439 * - In case both bit 2 and bit 4 are unset, they encode N-1, as there must be at
440 * least one non-spent output).
441 *
442 * Example: 0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e
443 * <><><--------------------------------------------><---->
444 * | \ | /
445 * version code vout[1] height
446 *
447 * - version = 1
448 * - code = 4 (vout[1] is not spent, and 0 non-zero bytes of bitvector follow)
449 * - unspentness bitvector: as 0 non-zero bytes follow, it has length 0
450 * - vout[1]: 835800816115944e077fe7c803cfa57f29b36bf87c1d35
451 * * 8358: compact amount representation for 60000000000 (600 BTC)
452 * * 00: special txout type pay-to-pubkey-hash
453 * * 816115944e077fe7c803cfa57f29b36bf87c1d35: address uint160
454 * - height = 203998
455 *
456 *
457 * Example: 0109044086ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4eebbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa486af3b
458 * <><><--><--------------------------------------------------><----------------------------------------------><---->
459 * / \ \ | | /
460 * version code unspentness vout[4] vout[16] height
461 *
462 * - version = 1
463 * - code = 9 (coinbase, neither vout[0] or vout[1] are unspent,
464 * 2 (1, +1 because both bit 2 and bit 4 are unset) non-zero bitvector bytes follow)
465 * - unspentness bitvector: bits 2 (0x04) and 14 (0x4000) are set, so vout[2+2] and vout[14+2] are unspent
466 * - vout[4]: 86ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4ee
467 * * 86ef97d579: compact amount representation for 234925952 (2.35 BTC)
468 * * 00: special txout type pay-to-pubkey-hash
469 * * 61b01caab50f1b8e9c50a5057eb43c2d9563a4ee: address uint160
470 * - vout[16]: bbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa4
471 * * bbd123: compact amount representation for 110397 (0.001 BTC)
472 * * 00: special txout type pay-to-pubkey-hash
473 * * 8c988f1a4a4de2161e0f50aac7f17e7f9555caa4: address uint160
474 * - height = 120891
475 */
476class CCoins
477{
478public:
479 // whether transaction is a coinbase
480 bool fCoinBase;
481
482 // unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are dropped
483 std::vector<CTxOut> vout;
484
485 // at which height this transaction was included in the active block chain
486 int nHeight;
487
488 // version of the CTransaction; accesses to this value should probably check for nHeight as well,
489 // as new tx version will probably only be introduced at certain heights
490 int nVersion;
491
492 // construct a CCoins from a CTransaction, at a given height
493 CCoins(const CTransaction &tx, int nHeightIn) : fCoinBase(tx.IsCoinBase()), vout(tx.vout), nHeight(nHeightIn), nVersion(tx.nVersion) { }
494
495 // empty constructor
496 CCoins() : fCoinBase(false), vout(0), nHeight(0), nVersion(0) { }
497
498 // remove spent outputs at the end of vout
499 void Cleanup() {
500 while (vout.size() > 0 && vout.back().IsNull())
501 vout.pop_back();
502 if (vout.empty())
503 std::vector<CTxOut>().swap(vout);
504 }
505
506 void swap(CCoins &to) {
507 std::swap(to.fCoinBase, fCoinBase);
508 to.vout.swap(vout);
509 std::swap(to.nHeight, nHeight);
510 std::swap(to.nVersion, nVersion);
511 }
512
513 // equality test
514 friend bool operator==(const CCoins &a, const CCoins &b) {
515 return a.fCoinBase == b.fCoinBase &&
516 a.nHeight == b.nHeight &&
517 a.nVersion == b.nVersion &&
518 a.vout == b.vout;
519 }
520 friend bool operator!=(const CCoins &a, const CCoins &b) {
521 return !(a == b);
522 }
523
524 // calculate number of bytes for the bitmask, and its number of non-zero bytes
525 // each bit in the bitmask represents the availability of one output, but the
526 // availabilities of the first two outputs are encoded separately
527 void CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) const {
528 unsigned int nLastUsedByte = 0;
529 for (unsigned int b = 0; 2+b*8 < vout.size(); b++) {
530 bool fZero = true;
531 for (unsigned int i = 0; i < 8 && 2+b*8+i < vout.size(); i++) {
532 if (!vout[2+b*8+i].IsNull()) {
533 fZero = false;
534 continue;
535 }
536 }
537 if (!fZero) {
538 nLastUsedByte = b + 1;
539 nNonzeroBytes++;
540 }
541 }
542 nBytes += nLastUsedByte;
543 }
544
545 bool IsCoinBase() const {
546 return fCoinBase;
547 }
548
549 unsigned int GetSerializeSize(int nType, int nVersion) const {
550 unsigned int nSize = 0;
551 unsigned int nMaskSize = 0, nMaskCode = 0;
552 CalcMaskSize(nMaskSize, nMaskCode);
553 bool fFirst = vout.size() > 0 && !vout[0].IsNull();
554 bool fSecond = vout.size() > 1 && !vout[1].IsNull();
555 assert(fFirst || fSecond || nMaskCode);
556 unsigned int nCode = 8*(nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0);
557 // version
558 nSize += ::GetSerializeSize(VARINT(this->nVersion), nType, nVersion);
559 // size of header code
560 nSize += ::GetSerializeSize(VARINT(nCode), nType, nVersion);
561 // spentness bitmask
562 nSize += nMaskSize;
563 // txouts themself
564 for (unsigned int i = 0; i < vout.size(); i++)
565 if (!vout[i].IsNull())
566 nSize += ::GetSerializeSize(CTxOutCompressor(REF(vout[i])), nType, nVersion);
567 // height
568 nSize += ::GetSerializeSize(VARINT(nHeight), nType, nVersion);
569 return nSize;
570 }
571
572 template<typename Stream>
573 void Serialize(Stream &s, int nType, int nVersion) const {
574 unsigned int nMaskSize = 0, nMaskCode = 0;
575 CalcMaskSize(nMaskSize, nMaskCode);
576 bool fFirst = vout.size() > 0 && !vout[0].IsNull();
577 bool fSecond = vout.size() > 1 && !vout[1].IsNull();
578 assert(fFirst || fSecond || nMaskCode);
579 unsigned int nCode = 8*(nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0);
580 // version
581 ::Serialize(s, VARINT(this->nVersion), nType, nVersion);
582 // header code
583 ::Serialize(s, VARINT(nCode), nType, nVersion);
584 // spentness bitmask
585 for (unsigned int b = 0; b<nMaskSize; b++) {
586 unsigned char chAvail = 0;
587 for (unsigned int i = 0; i < 8 && 2+b*8+i < vout.size(); i++)
588 if (!vout[2+b*8+i].IsNull())
589 chAvail |= (1 << i);
590 ::Serialize(s, chAvail, nType, nVersion);
591 }
592 // txouts themself
593 for (unsigned int i = 0; i < vout.size(); i++) {
594 if (!vout[i].IsNull())
595 ::Serialize(s, CTxOutCompressor(REF(vout[i])), nType, nVersion);
596 }
597 // coinbase height
598 ::Serialize(s, VARINT(nHeight), nType, nVersion);
599 }
600
601 template<typename Stream>
602 void Unserialize(Stream &s, int nType, int nVersion) {
603 unsigned int nCode = 0;
604 // version
605 ::Unserialize(s, VARINT(this->nVersion), nType, nVersion);
606 // header code
607 ::Unserialize(s, VARINT(nCode), nType, nVersion);
608 fCoinBase = nCode & 1;
609 std::vector<bool> vAvail(2, false);
610 vAvail[0] = nCode & 2;
611 vAvail[1] = nCode & 4;
612 unsigned int nMaskCode = (nCode / 8) + ((nCode & 6) != 0 ? 0 : 1);
613 // spentness bitmask
614 while (nMaskCode > 0) {
615 unsigned char chAvail = 0;
616 ::Unserialize(s, chAvail, nType, nVersion);
617 for (unsigned int p = 0; p < 8; p++) {
618 bool f = (chAvail & (1 << p)) != 0;
619 vAvail.push_back(f);
620 }
621 if (chAvail != 0)
622 nMaskCode--;
623 }
624 // txouts themself
625 vout.assign(vAvail.size(), CTxOut());
626 for (unsigned int i = 0; i < vAvail.size(); i++) {
627 if (vAvail[i])
628 ::Unserialize(s, REF(CTxOutCompressor(vout[i])), nType, nVersion);
629 }
630 // coinbase height
631 ::Unserialize(s, VARINT(nHeight), nType, nVersion);
632 Cleanup();
633 }
634
635 // mark an outpoint spent, and construct undo information
636 bool Spend(const COutPoint &out, CTxInUndo &undo) {
637 if (out.n >= vout.size())
638 return false;
639 if (vout[out.n].IsNull())
640 return false;
641 undo = CTxInUndo(vout[out.n]);
642 vout[out.n].SetNull();
643 Cleanup();
644 if (vout.size() == 0) {
645 undo.nHeight = nHeight;
646 undo.fCoinBase = fCoinBase;
647 undo.nVersion = this->nVersion;
648 }
649 return true;
650 }
651
652 // mark a vout spent
653 bool Spend(int nPos) {
654 CTxInUndo undo;
655 COutPoint out(0, nPos);
656 return Spend(out, undo);
657 }
658
659 // check whether a particular output is still available
660 bool IsAvailable(unsigned int nPos) const {
661 return (nPos < vout.size() && !vout[nPos].IsNull());
662 }
663
664 // check whether the entire CCoins is spent
665 // note that only !IsPruned() CCoins can be serialized
666 bool IsPruned() const {
667 BOOST_FOREACH(const CTxOut &out, vout)
668 if (!out.IsNull())
669 return false;
670 return true;
671 }
672};
673
674
aabdf9e8
EL
675/** Nodes collect new transactions into a block, hash them into a hash tree,
676 * and scan through nonce values to make the block's hash satisfy proof-of-work
677 * requirements. When they solve the proof-of-work, they broadcast the block
678 * to everyone and the block is added to the block chain. The first transaction
679 * in the block is a special one that creates a new coin owned by the creator
680 * of the block.
681 */
682class CBlockHeader
683{
684public:
685 // header
686 static const int CURRENT_VERSION=2;
687 int nVersion;
688 uint256 hashPrevBlock;
689 uint256 hashMerkleRoot;
690 unsigned int nTime;
691 unsigned int nBits;
692 unsigned int nNonce;
693
694 CBlockHeader()
695 {
696 SetNull();
697 }
698
699 IMPLEMENT_SERIALIZE
700 (
701 READWRITE(this->nVersion);
702 nVersion = this->nVersion;
703 READWRITE(hashPrevBlock);
704 READWRITE(hashMerkleRoot);
705 READWRITE(nTime);
706 READWRITE(nBits);
707 READWRITE(nNonce);
708 )
709
710 void SetNull()
711 {
712 nVersion = CBlockHeader::CURRENT_VERSION;
713 hashPrevBlock = 0;
714 hashMerkleRoot = 0;
715 nTime = 0;
716 nBits = 0;
717 nNonce = 0;
718 }
719
720 bool IsNull() const
721 {
722 return (nBits == 0);
723 }
724
725 uint256 GetHash() const
726 {
727 return Hash(BEGIN(nVersion), END(nNonce));
728 }
729
730 int64 GetBlockTime() const
731 {
732 return (int64)nTime;
733 }
734};
735
33944573
EL
736
737class CBlock : public CBlockHeader
738{
739public:
740 // network and disk
741 std::vector<CTransaction> vtx;
742
743 // memory only
744 mutable std::vector<uint256> vMerkleTree;
745
746 CBlock()
747 {
748 SetNull();
749 }
750
751 CBlock(const CBlockHeader &header)
752 {
753 SetNull();
754 *((CBlockHeader*)this) = header;
755 }
756
757 IMPLEMENT_SERIALIZE
758 (
759 READWRITE(*(CBlockHeader*)this);
760 READWRITE(vtx);
761 )
762
763 void SetNull()
764 {
765 CBlockHeader::SetNull();
766 vtx.clear();
767 vMerkleTree.clear();
768 }
769
770 CBlockHeader GetBlockHeader() const
771 {
772 CBlockHeader block;
773 block.nVersion = nVersion;
774 block.hashPrevBlock = hashPrevBlock;
775 block.hashMerkleRoot = hashMerkleRoot;
776 block.nTime = nTime;
777 block.nBits = nBits;
778 block.nNonce = nNonce;
779 return block;
780 }
781
782 uint256 BuildMerkleTree() const
783 {
784 vMerkleTree.clear();
785 BOOST_FOREACH(const CTransaction& tx, vtx)
786 vMerkleTree.push_back(tx.GetHash());
787 int j = 0;
788 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
789 {
790 for (int i = 0; i < nSize; i += 2)
791 {
792 int i2 = std::min(i+1, nSize-1);
793 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
794 BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
795 }
796 j += nSize;
797 }
798 return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
799 }
800
801 const uint256 &GetTxHash(unsigned int nIndex) const {
802 assert(vMerkleTree.size() > 0); // BuildMerkleTree must have been called first
803 assert(nIndex < vtx.size());
804 return vMerkleTree[nIndex];
805 }
806
807 std::vector<uint256> GetMerkleBranch(int nIndex) const
808 {
809 if (vMerkleTree.empty())
810 BuildMerkleTree();
811 std::vector<uint256> vMerkleBranch;
812 int j = 0;
813 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
814 {
815 int i = std::min(nIndex^1, nSize-1);
816 vMerkleBranch.push_back(vMerkleTree[j+i]);
817 nIndex >>= 1;
818 j += nSize;
819 }
820 return vMerkleBranch;
821 }
822
823 static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
824 {
825 if (nIndex == -1)
826 return 0;
827 BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
828 {
829 if (nIndex & 1)
830 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
831 else
832 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
833 nIndex >>= 1;
834 }
835 return hash;
836 }
837
838 void print() const
839 {
840 printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%"PRIszu")\n",
841 GetHash().ToString().c_str(),
842 nVersion,
843 hashPrevBlock.ToString().c_str(),
844 hashMerkleRoot.ToString().c_str(),
845 nTime, nBits, nNonce,
846 vtx.size());
847 for (unsigned int i = 0; i < vtx.size(); i++)
848 {
849 printf(" ");
850 vtx[i].print();
851 }
852 printf(" vMerkleTree: ");
853 for (unsigned int i = 0; i < vMerkleTree.size(); i++)
854 printf("%s ", vMerkleTree[i].ToString().c_str());
855 printf("\n");
856 }
857};
858
05df3fc6 859#endif
This page took 0.108876 seconds and 4 git commands to generate.