Changeset View
Changeset View
Standalone View
Standalone View
src/primitives/transaction.h
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#ifndef BITCOIN_PRIMITIVES_TRANSACTION_H | #ifndef BITCOIN_PRIMITIVES_TRANSACTION_H | ||||
#define BITCOIN_PRIMITIVES_TRANSACTION_H | #define BITCOIN_PRIMITIVES_TRANSACTION_H | ||||
#include "amount.h" | #include "amount.h" | ||||
#include "script/script.h" | #include "script/script.h" | ||||
#include "serialize.h" | #include "serialize.h" | ||||
#include "uint256.h" | #include "uint256.h" | ||||
static const int SERIALIZE_TRANSACTION = 0x00; | static const int SERIALIZE_TRANSACTION = 0x00; | ||||
/** An outpoint - a combination of a transaction hash and an index n into its | /** | ||||
* vout */ | * An outpoint - a combination of a transaction hash and an index n into its | ||||
* vout. | |||||
*/ | |||||
class COutPoint { | class COutPoint { | ||||
public: | public: | ||||
uint256 hash; | uint256 hash; | ||||
uint32_t n; | uint32_t n; | ||||
COutPoint() { SetNull(); } | COutPoint() { SetNull(); } | ||||
COutPoint(uint256 hashIn, uint32_t nIn) { | COutPoint(uint256 hashIn, uint32_t nIn) { | ||||
hash = hashIn; | hash = hashIn; | ||||
Show All 25 Lines | public: | ||||
friend bool operator!=(const COutPoint &a, const COutPoint &b) { | friend bool operator!=(const COutPoint &a, const COutPoint &b) { | ||||
return !(a == b); | return !(a == b); | ||||
} | } | ||||
std::string ToString() const; | std::string ToString() const; | ||||
}; | }; | ||||
/** An input of a transaction. It contains the location of the previous | /** | ||||
* transaction's output that it claims and a signature that matches the | * An input of a transaction. It contains the location of the previous | ||||
* output's public key. | * transaction's output that it claims and a signature that matches the output's | ||||
* public key. | |||||
*/ | */ | ||||
class CTxIn { | class CTxIn { | ||||
public: | public: | ||||
COutPoint prevout; | COutPoint prevout; | ||||
CScript scriptSig; | CScript scriptSig; | ||||
uint32_t nSequence; | uint32_t nSequence; | ||||
/* Setting nSequence to this value for every input in a transaction | /** | ||||
* disables nLockTime. */ | * Setting nSequence to this value for every input in a transaction disables | ||||
* nLockTime. | |||||
*/ | |||||
static const uint32_t SEQUENCE_FINAL = 0xffffffff; | static const uint32_t SEQUENCE_FINAL = 0xffffffff; | ||||
/* Below flags apply in the context of BIP 68*/ | /* Below flags apply in the context of BIP 68*/ | ||||
/* If this flag set, CTxIn::nSequence is NOT interpreted as a | /** | ||||
* relative lock-time. */ | * If this flag set, CTxIn::nSequence is NOT interpreted as a relative | ||||
* lock-time. | |||||
*/ | |||||
static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31); | static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31); | ||||
/* If CTxIn::nSequence encodes a relative lock-time and this flag | /** | ||||
* is set, the relative lock-time has units of 512 seconds, | * If CTxIn::nSequence encodes a relative lock-time and this flag is set, | ||||
* otherwise it specifies blocks with a granularity of 1. */ | * the relative lock-time has units of 512 seconds, otherwise it specifies | ||||
* blocks with a granularity of 1. | |||||
*/ | |||||
static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22); | static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22); | ||||
/* If CTxIn::nSequence encodes a relative lock-time, this mask is | /** | ||||
* applied to extract that lock-time from the sequence field. */ | * If CTxIn::nSequence encodes a relative lock-time, this mask is applied to | ||||
* extract that lock-time from the sequence field. | |||||
*/ | |||||
static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff; | static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff; | ||||
/* In order to use the same number of bits to encode roughly the | /** | ||||
* same wall-clock duration, and because blocks are naturally | * In order to use the same number of bits to encode roughly the same | ||||
* limited to occur every 600s on average, the minimum granularity | * wall-clock duration, and because blocks are naturally limited to occur | ||||
* for time-based relative lock-time is fixed at 512 seconds. | * every 600s on average, the minimum granularity for time-based relative | ||||
* Converting from CTxIn::nSequence to seconds is performed by | * lock-time is fixed at 512 seconds. Converting from CTxIn::nSequence to | ||||
* multiplying by 512 = 2^9, or equivalently shifting up by | * seconds is performed by multiplying by 512 = 2^9, or equivalently | ||||
* 9 bits. */ | * shifting up by 9 bits. | ||||
*/ | |||||
static const int SEQUENCE_LOCKTIME_GRANULARITY = 9; | static const int SEQUENCE_LOCKTIME_GRANULARITY = 9; | ||||
CTxIn() { nSequence = SEQUENCE_FINAL; } | CTxIn() { nSequence = SEQUENCE_FINAL; } | ||||
explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn = CScript(), | explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn = CScript(), | ||||
uint32_t nSequenceIn = SEQUENCE_FINAL); | uint32_t nSequenceIn = SEQUENCE_FINAL); | ||||
CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn = CScript(), | CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn = CScript(), | ||||
uint32_t nSequenceIn = SEQUENCE_FINAL); | uint32_t nSequenceIn = SEQUENCE_FINAL); | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | public: | ||||
void SetNull() { | void SetNull() { | ||||
nValue = Amount(-1); | nValue = Amount(-1); | ||||
scriptPubKey.clear(); | scriptPubKey.clear(); | ||||
} | } | ||||
bool IsNull() const { return (nValue == Amount(-1)); } | bool IsNull() const { return (nValue == Amount(-1)); } | ||||
Amount GetDustThreshold(const CFeeRate &minRelayTxFee) const { | Amount GetDustThreshold(const 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 | * "Dust" is defined in terms of CTransaction::minRelayTxFee, which has | ||||
// spend something, then we consider it dust. A typical spendable | * units satoshis-per-kilobyte. If you'd pay more than 1/3 in fees to | ||||
// non-segwit txout is 34 bytes big, and will need a CTxIn of at least | * spend something, then we consider it dust. A typical spendable | ||||
// 148 bytes to spend: so dust is a spendable txout less than | * non-segwit txout is 34 bytes big, and will need a CTxIn of at least | ||||
// 546*minRelayTxFee/1000 (in satoshis). A typical spendable segwit | * 148 bytes to spend: so dust is a spendable txout less than | ||||
// txout is 31 bytes big, and will need a CTxIn of at least 67 bytes to | * 546*minRelayTxFee/1000 (in satoshis). A typical spendable segwit | ||||
// spend: so dust is a spendable txout less than 294*minRelayTxFee/1000 | * txout is 31 bytes big, and will need a CTxIn of at least 67 bytes to | ||||
// (in satoshis). | * spend: so dust is a spendable txout less than 294*minRelayTxFee/1000 | ||||
* (in satoshis). | |||||
*/ | |||||
if (scriptPubKey.IsUnspendable()) return Amount(0); | if (scriptPubKey.IsUnspendable()) return Amount(0); | ||||
size_t nSize = GetSerializeSize(*this, SER_DISK, 0); | size_t nSize = GetSerializeSize(*this, SER_DISK, 0); | ||||
// the 148 mentioned above | // the 148 mentioned above | ||||
nSize += (32 + 4 + 1 + 107 + 4); | nSize += (32 + 4 + 1 + 107 + 4); | ||||
return 3 * minRelayTxFee.GetFee(nSize); | return 3 * minRelayTxFee.GetFee(nSize); | ||||
Show All 39 Lines | |||||
template <typename Stream, typename TxType> | template <typename Stream, typename TxType> | ||||
inline void SerializeTransaction(const TxType &tx, Stream &s) { | inline void SerializeTransaction(const TxType &tx, Stream &s) { | ||||
s << tx.nVersion; | s << tx.nVersion; | ||||
s << tx.vin; | s << tx.vin; | ||||
s << tx.vout; | s << tx.vout; | ||||
s << tx.nLockTime; | s << tx.nLockTime; | ||||
} | } | ||||
/** The basic transaction that is broadcasted on the network and contained in | /** | ||||
* The basic transaction that is broadcasted on the network and contained in | |||||
* blocks. A transaction can contain multiple inputs and outputs. | * blocks. A transaction can contain multiple inputs and outputs. | ||||
*/ | */ | ||||
class CTransaction { | class CTransaction { | ||||
public: | public: | ||||
// Default transaction version. | // Default transaction version. | ||||
static const int32_t CURRENT_VERSION = 2; | static const int32_t CURRENT_VERSION = 2; | ||||
// Changing the default transaction version requires a two step process: | // Changing the default transaction version requires a two step process: | ||||
// first adapting relay policy by bumping MAX_STANDARD_VERSION, and then | // first adapting relay policy by bumping MAX_STANDARD_VERSION, and then | ||||
Show All 24 Lines | public: | ||||
/** Convert a CMutableTransaction into a CTransaction. */ | /** Convert a CMutableTransaction into a CTransaction. */ | ||||
CTransaction(const CMutableTransaction &tx); | CTransaction(const CMutableTransaction &tx); | ||||
CTransaction(CMutableTransaction &&tx); | CTransaction(CMutableTransaction &&tx); | ||||
template <typename Stream> inline void Serialize(Stream &s) const { | template <typename Stream> inline void Serialize(Stream &s) const { | ||||
SerializeTransaction(*this, s); | SerializeTransaction(*this, s); | ||||
} | } | ||||
/** This deserializing constructor is provided instead of an Unserialize | /** | ||||
* This deserializing constructor is provided instead of an Unserialize | |||||
* method. Unserialize is not possible, since it would require overwriting | * method. Unserialize is not possible, since it would require overwriting | ||||
* const fields. */ | * const fields. | ||||
*/ | |||||
template <typename Stream> | template <typename Stream> | ||||
CTransaction(deserialize_type, Stream &s) | CTransaction(deserialize_type, Stream &s) | ||||
: CTransaction(CMutableTransaction(deserialize, s)) {} | : CTransaction(CMutableTransaction(deserialize, s)) {} | ||||
bool IsNull() const { return vin.empty() && vout.empty(); } | bool IsNull() const { return vin.empty() && vout.empty(); } | ||||
const uint256 &GetId() const { return hash; } | const uint256 &GetId() const { return hash; } | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | template <typename Stream> inline void Unserialize(Stream &s) { | ||||
UnserializeTransaction(*this, s); | UnserializeTransaction(*this, s); | ||||
} | } | ||||
template <typename Stream> | template <typename Stream> | ||||
CMutableTransaction(deserialize_type, Stream &s) { | CMutableTransaction(deserialize_type, Stream &s) { | ||||
Unserialize(s); | Unserialize(s); | ||||
} | } | ||||
/** Compute the hash of this CMutableTransaction. This is computed on the | /** | ||||
* Compute the hash of this CMutableTransaction. This is computed on the | |||||
* fly, as opposed to GetId() in CTransaction, which uses a cached result. | * fly, as opposed to GetId() in CTransaction, which uses a cached result. | ||||
*/ | */ | ||||
uint256 GetId() const; | uint256 GetId() const; | ||||
friend bool operator==(const CMutableTransaction &a, | friend bool operator==(const CMutableTransaction &a, | ||||
const CMutableTransaction &b) { | const CMutableTransaction &b) { | ||||
return a.GetId() == b.GetId(); | return a.GetId() == b.GetId(); | ||||
} | } | ||||
Show All 29 Lines |