123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570 |
- // Copyright (c) 2009-2010 Satoshi Nakamoto
- // Copyright (c) 2009-2013 The Bitcoin developers
- // Distributed under the MIT/X11 software license, see the accompanying
- // file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
- #ifndef BITCOIN_CORE_H
- #define BITCOIN_CORE_H
-
- #include "script.h"
- #include "serialize.h"
- #include "uint256.h"
-
- #include <stdint.h>
-
- class CTransaction;
-
- static const int64_t COIN = 100000000;
- static const int64_t CENT = 1000000;
-
- /** No amount larger than this (in satoshi) is valid */
- static const int64_t MAX_MONEY = 21000000 * COIN;
- inline bool MoneyRange(int64_t nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
-
- /** An outpoint - a combination of a transaction hash and an index n into its vout */
- class COutPoint
- {
- public:
- uint256 hash;
- uint32_t n;
-
- COutPoint() { SetNull(); }
- COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(FLATDATA(*this));
- }
-
- void SetNull() { hash = 0; n = (uint32_t) -1; }
- bool IsNull() const { return (hash == 0 && n == (uint32_t) -1); }
-
- friend bool operator<(const COutPoint& a, const COutPoint& b)
- {
- return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
- }
-
- friend bool operator==(const COutPoint& a, const COutPoint& b)
- {
- return (a.hash == b.hash && a.n == b.n);
- }
-
- friend bool operator!=(const COutPoint& a, const COutPoint& b)
- {
- return !(a == b);
- }
-
- std::string ToString() const;
- };
-
- /** An inpoint - a combination of a transaction and an index n into its vin */
- class CInPoint
- {
- public:
- const CTransaction* ptx;
- uint32_t n;
-
- CInPoint() { SetNull(); }
- CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; }
- void SetNull() { ptx = NULL; n = (uint32_t) -1; }
- bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); }
- };
-
- /** An input of a transaction. It contains the location of the previous
- * transaction's output that it claims and a signature that matches the
- * output's public key.
- */
- class CTxIn
- {
- public:
- COutPoint prevout;
- CScript scriptSig;
- uint32_t nSequence;
-
- CTxIn()
- {
- nSequence = std::numeric_limits<unsigned int>::max();
- }
-
- explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max());
- CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<uint32_t>::max());
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(prevout);
- READWRITE(scriptSig);
- READWRITE(nSequence);
- }
-
- bool IsFinal() const
- {
- return (nSequence == std::numeric_limits<uint32_t>::max());
- }
-
- friend bool operator==(const CTxIn& a, const CTxIn& b)
- {
- return (a.prevout == b.prevout &&
- a.scriptSig == b.scriptSig &&
- a.nSequence == b.nSequence);
- }
-
- friend bool operator!=(const CTxIn& a, const CTxIn& b)
- {
- return !(a == b);
- }
-
- std::string ToString() const;
- };
-
-
-
- /** Type-safe wrapper class to for fee rates
- * (how much to pay based on transaction size)
- */
- class CFeeRate
- {
- private:
- int64_t nSatoshisPerK; // unit is satoshis-per-1,000-bytes
- public:
- CFeeRate() : nSatoshisPerK(0) { }
- explicit CFeeRate(int64_t _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { }
- CFeeRate(int64_t nFeePaid, size_t nSize);
- CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; }
-
- int64_t GetFee(size_t size) const; // unit returned is satoshis
- int64_t GetFeePerK() const { return GetFee(1000); } // satoshis-per-1000-bytes
-
- friend bool operator<(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK < b.nSatoshisPerK; }
- friend bool operator>(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK > b.nSatoshisPerK; }
- friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; }
- friend bool operator<=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK <= b.nSatoshisPerK; }
- friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; }
- std::string ToString() const;
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(nSatoshisPerK);
- }
- };
-
-
- /** An output of a transaction. It contains the public key that the next input
- * must be able to sign with to claim it.
- */
- class CTxOut
- {
- public:
- int64_t nValue;
- CScript scriptPubKey;
-
- CTxOut()
- {
- SetNull();
- }
-
- CTxOut(int64_t nValueIn, CScript scriptPubKeyIn);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(nValue);
- READWRITE(scriptPubKey);
- }
-
- void SetNull()
- {
- nValue = -1;
- scriptPubKey.clear();
- }
-
- bool IsNull() const
- {
- return (nValue == -1);
- }
-
- uint256 GetHash() const;
-
- bool IsDust(CFeeRate minRelayTxFee) const
- {
- // "Dust" is defined in terms of CTransaction::minRelayTxFee,
- // which has units satoshis-per-kilobyte.
- // If you'd pay more than 1/3 in fees
- // to spend something, then we consider it dust.
- // A typical txout is 34 bytes big, and will
- // need a CTxIn of at least 148 bytes to spend:
- // so dust is a txout less than 546 satoshis
- // with default minRelayTxFee.
- size_t nSize = GetSerializeSize(SER_DISK,0)+148u;
- return (nValue < 3*minRelayTxFee.GetFee(nSize));
- }
-
- friend bool operator==(const CTxOut& a, const CTxOut& b)
- {
- return (a.nValue == b.nValue &&
- a.scriptPubKey == b.scriptPubKey);
- }
-
- friend bool operator!=(const CTxOut& a, const CTxOut& b)
- {
- return !(a == b);
- }
-
- std::string ToString() const;
- };
-
-
- struct CMutableTransaction;
-
- /** The basic transaction that is broadcasted on the network and contained in
- * blocks. A transaction can contain multiple inputs and outputs.
- */
- class CTransaction
- {
- private:
- /** Memory only. */
- const uint256 hash;
- void UpdateHash() const;
-
- public:
- static const int32_t CURRENT_VERSION=1;
-
- // The local variables are made const to prevent unintended modification
- // without updating the cached hash value. However, CTransaction is not
- // actually immutable; deserialization and assignment are implemented,
- // and bypass the constness. This is safe, as they update the entire
- // structure, including the hash.
- const int32_t nVersion;
- const std::vector<CTxIn> vin;
- const std::vector<CTxOut> vout;
- const uint32_t nLockTime;
-
- /** Construct a CTransaction that qualifies as IsNull() */
- CTransaction();
-
- /** Convert a CMutableTransaction into a CTransaction. */
- CTransaction(const CMutableTransaction &tx);
-
- CTransaction& operator=(const CTransaction& tx);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(*const_cast<int32_t*>(&this->nVersion));
- nVersion = this->nVersion;
- READWRITE(*const_cast<std::vector<CTxIn>*>(&vin));
- READWRITE(*const_cast<std::vector<CTxOut>*>(&vout));
- READWRITE(*const_cast<uint32_t*>(&nLockTime));
- if (ser_action.ForRead())
- UpdateHash();
- }
-
- bool IsNull() const {
- return vin.empty() && vout.empty();
- }
-
- const uint256& GetHash() const {
- return hash;
- }
-
- // Return sum of txouts.
- int64_t GetValueOut() const;
- // GetValueIn() is a method on CCoinsViewCache, because
- // inputs must be known to compute value in.
-
- // Compute priority, given priority of inputs and (optionally) tx size
- double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const;
-
- bool IsCoinBase() const
- {
- return (vin.size() == 1 && vin[0].prevout.IsNull());
- }
-
- friend bool operator==(const CTransaction& a, const CTransaction& b)
- {
- return a.hash == b.hash;
- }
-
- friend bool operator!=(const CTransaction& a, const CTransaction& b)
- {
- return a.hash != b.hash;
- }
-
- std::string ToString() const;
- };
-
- /** A mutable version of CTransaction. */
- struct CMutableTransaction
- {
- int32_t nVersion;
- std::vector<CTxIn> vin;
- std::vector<CTxOut> vout;
- uint32_t nLockTime;
-
- CMutableTransaction();
- CMutableTransaction(const CTransaction& tx);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(this->nVersion);
- nVersion = this->nVersion;
- READWRITE(vin);
- READWRITE(vout);
- READWRITE(nLockTime);
- }
-
- /** Compute the hash of this CMutableTransaction. This is computed on the
- * fly, as opposed to GetHash() in CTransaction, which uses a cached result.
- */
- uint256 GetHash() const;
- };
-
- /** wrapper for CTxOut that provides a more compact serialization */
- class CTxOutCompressor
- {
- private:
- CTxOut &txout;
-
- public:
- static uint64_t CompressAmount(uint64_t nAmount);
- static uint64_t DecompressAmount(uint64_t nAmount);
-
- CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- if (!ser_action.ForRead()) {
- uint64_t nVal = CompressAmount(txout.nValue);
- READWRITE(VARINT(nVal));
- } else {
- uint64_t nVal = 0;
- READWRITE(VARINT(nVal));
- txout.nValue = DecompressAmount(nVal);
- }
- CScriptCompressor cscript(REF(txout.scriptPubKey));
- READWRITE(cscript);
- }
- };
-
- /** Undo information for a CTxIn
- *
- * Contains the prevout's CTxOut being spent, and if this was the
- * last output of the affected transaction, its metadata as well
- * (coinbase or not, height, transaction version)
- */
- class CTxInUndo
- {
- public:
- CTxOut txout; // the txout data before being spent
- bool fCoinBase; // if the outpoint was the last unspent: whether it belonged to a coinbase
- unsigned int nHeight; // if the outpoint was the last unspent: its height
- int nVersion; // if the outpoint was the last unspent: its version
-
- CTxInUndo() : txout(), fCoinBase(false), nHeight(0), nVersion(0) {}
- CTxInUndo(const CTxOut &txoutIn, bool fCoinBaseIn = false, unsigned int nHeightIn = 0, int nVersionIn = 0) : txout(txoutIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nVersion(nVersionIn) { }
-
- unsigned int GetSerializeSize(int nType, int nVersion) const {
- return ::GetSerializeSize(VARINT(nHeight*2+(fCoinBase ? 1 : 0)), nType, nVersion) +
- (nHeight > 0 ? ::GetSerializeSize(VARINT(this->nVersion), nType, nVersion) : 0) +
- ::GetSerializeSize(CTxOutCompressor(REF(txout)), nType, nVersion);
- }
-
- template<typename Stream>
- void Serialize(Stream &s, int nType, int nVersion) const {
- ::Serialize(s, VARINT(nHeight*2+(fCoinBase ? 1 : 0)), nType, nVersion);
- if (nHeight > 0)
- ::Serialize(s, VARINT(this->nVersion), nType, nVersion);
- ::Serialize(s, CTxOutCompressor(REF(txout)), nType, nVersion);
- }
-
- template<typename Stream>
- void Unserialize(Stream &s, int nType, int nVersion) {
- unsigned int nCode = 0;
- ::Unserialize(s, VARINT(nCode), nType, nVersion);
- nHeight = nCode / 2;
- fCoinBase = nCode & 1;
- if (nHeight > 0)
- ::Unserialize(s, VARINT(this->nVersion), nType, nVersion);
- ::Unserialize(s, REF(CTxOutCompressor(REF(txout))), nType, nVersion);
- }
- };
-
- /** Undo information for a CTransaction */
- class CTxUndo
- {
- public:
- // undo information for all txins
- std::vector<CTxInUndo> vprevout;
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(vprevout);
- }
- };
-
-
- /** Nodes collect new transactions into a block, hash them into a hash tree,
- * and scan through nonce values to make the block's hash satisfy proof-of-work
- * requirements. When they solve the proof-of-work, they broadcast the block
- * to everyone and the block is added to the block chain. The first transaction
- * in the block is a special one that creates a new coin owned by the creator
- * of the block.
- */
- class CBlockHeader
- {
- public:
- // header
- static const int32_t CURRENT_VERSION=2;
- int32_t nVersion;
- uint256 hashPrevBlock;
- uint256 hashMerkleRoot;
- uint32_t nTime;
- uint32_t nBits;
- uint32_t nNonce;
-
- CBlockHeader()
- {
- SetNull();
- }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(this->nVersion);
- nVersion = this->nVersion;
- READWRITE(hashPrevBlock);
- READWRITE(hashMerkleRoot);
- READWRITE(nTime);
- READWRITE(nBits);
- READWRITE(nNonce);
- }
-
- void SetNull()
- {
- nVersion = CBlockHeader::CURRENT_VERSION;
- hashPrevBlock = 0;
- hashMerkleRoot = 0;
- nTime = 0;
- nBits = 0;
- nNonce = 0;
- }
-
- bool IsNull() const
- {
- return (nBits == 0);
- }
-
- uint256 GetHash() const;
-
- int64_t GetBlockTime() const
- {
- return (int64_t)nTime;
- }
- };
-
-
- class CBlock : public CBlockHeader
- {
- public:
- // network and disk
- std::vector<CTransaction> vtx;
-
- // memory only
- mutable std::vector<uint256> vMerkleTree;
-
- CBlock()
- {
- SetNull();
- }
-
- CBlock(const CBlockHeader &header)
- {
- SetNull();
- *((CBlockHeader*)this) = header;
- }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(*(CBlockHeader*)this);
- READWRITE(vtx);
- }
-
- void SetNull()
- {
- CBlockHeader::SetNull();
- vtx.clear();
- vMerkleTree.clear();
- }
-
- CBlockHeader GetBlockHeader() const
- {
- CBlockHeader block;
- block.nVersion = nVersion;
- block.hashPrevBlock = hashPrevBlock;
- block.hashMerkleRoot = hashMerkleRoot;
- block.nTime = nTime;
- block.nBits = nBits;
- block.nNonce = nNonce;
- return block;
- }
-
- uint256 BuildMerkleTree() const;
-
- std::vector<uint256> GetMerkleBranch(int nIndex) const;
- static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
- std::string ToString() const;
- };
-
-
- /** Describes a place in the block chain to another node such that if the
- * other node doesn't have the same branch, it can find a recent common trunk.
- * The further back it is, the further before the fork it may be.
- */
- struct CBlockLocator
- {
- std::vector<uint256> vHave;
-
- CBlockLocator() {}
-
- CBlockLocator(const std::vector<uint256>& vHaveIn)
- {
- vHave = vHaveIn;
- }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- if (!(nType & SER_GETHASH))
- READWRITE(nVersion);
- READWRITE(vHave);
- }
-
- void SetNull()
- {
- vHave.clear();
- }
-
- bool IsNull()
- {
- return vHave.empty();
- }
- };
-
- #endif // BITCOIN_CORE_H
|