Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F10615120
core.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Subscribers
None
core.h
View Options
// 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
;
/** 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
;
unsigned
int
n
;
COutPoint
()
{
SetNull
();
}
COutPoint
(
uint256
hashIn
,
unsigned
int
nIn
)
{
hash
=
hashIn
;
n
=
nIn
;
}
IMPLEMENT_SERIALIZE
(
READWRITE
(
FLATDATA
(
*
this
));
)
void
SetNull
()
{
hash
=
0
;
n
=
(
unsigned
int
)
-1
;
}
bool
IsNull
()
const
{
return
(
hash
==
0
&&
n
==
(
unsigned
int
)
-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
;
void
print
()
const
;
};
/** An inpoint - a combination of a transaction and an index n into its vin */
class
CInPoint
{
public
:
const
CTransaction
*
ptx
;
unsigned
int
n
;
CInPoint
()
{
SetNull
();
}
CInPoint
(
const
CTransaction
*
ptxIn
,
unsigned
int
nIn
)
{
ptx
=
ptxIn
;
n
=
nIn
;
}
void
SetNull
()
{
ptx
=
NULL
;
n
=
(
unsigned
int
)
-1
;
}
bool
IsNull
()
const
{
return
(
ptx
==
NULL
&&
n
==
(
unsigned
int
)
-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
;
unsigned
int
nSequence
;
CTxIn
()
{
nSequence
=
std
::
numeric_limits
<
unsigned
int
>::
max
();
}
explicit
CTxIn
(
COutPoint
prevoutIn
,
CScript
scriptSigIn
=
CScript
(),
unsigned
int
nSequenceIn
=
std
::
numeric_limits
<
unsigned
int
>::
max
());
CTxIn
(
uint256
hashPrevTx
,
unsigned
int
nOut
,
CScript
scriptSigIn
=
CScript
(),
unsigned
int
nSequenceIn
=
std
::
numeric_limits
<
unsigned
int
>::
max
());
IMPLEMENT_SERIALIZE
(
READWRITE
(
prevout
);
READWRITE
(
scriptSig
);
READWRITE
(
nSequence
);
)
bool
IsFinal
()
const
{
return
(
nSequence
==
std
::
numeric_limits
<
unsigned
int
>::
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
;
void
print
()
const
;
};
/** 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
);
IMPLEMENT_SERIALIZE
(
READWRITE
(
nValue
);
READWRITE
(
scriptPubKey
);
)
void
SetNull
()
{
nValue
=
-1
;
scriptPubKey
.
clear
();
}
bool
IsNull
()
const
{
return
(
nValue
==
-1
);
}
uint256
GetHash
()
const
;
bool
IsDust
(
int64_t
nMinRelayTxFee
)
const
{
// "Dust" is defined in terms of CTransaction::nMinRelayTxFee,
// 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 nMinRelayTxFee.
return
((
nValue
*
1000
)
/
(
3
*
((
int
)
GetSerializeSize
(
SER_DISK
,
0
)
+
148
))
<
nMinRelayTxFee
);
}
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
;
void
print
()
const
;
};
/** The basic transaction that is broadcasted on the network and contained in
* blocks. A transaction can contain multiple inputs and outputs.
*/
class
CTransaction
{
public
:
static
int64_t
nMinTxFee
;
static
int64_t
nMinRelayTxFee
;
static
const
int
CURRENT_VERSION
=
1
;
int
nVersion
;
std
::
vector
<
CTxIn
>
vin
;
std
::
vector
<
CTxOut
>
vout
;
unsigned
int
nLockTime
;
CTransaction
()
{
SetNull
();
}
IMPLEMENT_SERIALIZE
(
READWRITE
(
this
->
nVersion
);
nVersion
=
this
->
nVersion
;
READWRITE
(
vin
);
READWRITE
(
vout
);
READWRITE
(
nLockTime
);
)
void
SetNull
()
{
nVersion
=
CTransaction
::
CURRENT_VERSION
;
vin
.
clear
();
vout
.
clear
();
nLockTime
=
0
;
}
bool
IsNull
()
const
{
return
(
vin
.
empty
()
&&
vout
.
empty
());
}
uint256
GetHash
()
const
;
bool
IsNewerThan
(
const
CTransaction
&
old
)
const
;
// 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
.
nVersion
==
b
.
nVersion
&&
a
.
vin
==
b
.
vin
&&
a
.
vout
==
b
.
vout
&&
a
.
nLockTime
==
b
.
nLockTime
);
}
friend
bool
operator
!=
(
const
CTransaction
&
a
,
const
CTransaction
&
b
)
{
return
!
(
a
==
b
);
}
std
::
string
ToString
()
const
;
void
print
()
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
)
{
}
IMPLEMENT_SERIALIZE
(({
if
(
!
fRead
)
{
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
;
IMPLEMENT_SERIALIZE
(
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
int
CURRENT_VERSION
=
2
;
int
nVersion
;
uint256
hashPrevBlock
;
uint256
hashMerkleRoot
;
unsigned
int
nTime
;
unsigned
int
nBits
;
unsigned
int
nNonce
;
CBlockHeader
()
{
SetNull
();
}
IMPLEMENT_SERIALIZE
(
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
;
}
IMPLEMENT_SERIALIZE
(
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
;
const
uint256
&
GetTxHash
(
unsigned
int
nIndex
)
const
{
assert
(
vMerkleTree
.
size
()
>
0
);
// BuildMerkleTree must have been called first
assert
(
nIndex
<
vtx
.
size
());
return
vMerkleTree
[
nIndex
];
}
std
::
vector
<
uint256
>
GetMerkleBranch
(
int
nIndex
)
const
;
static
uint256
CheckMerkleBranch
(
uint256
hash
,
const
std
::
vector
<
uint256
>&
vMerkleBranch
,
int
nIndex
);
void
print
()
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
;
}
IMPLEMENT_SERIALIZE
(
if
(
!
(
nType
&
SER_GETHASH
))
READWRITE
(
nVersion
);
READWRITE
(
vHave
);
)
void
SetNull
()
{
vHave
.
clear
();
}
bool
IsNull
()
{
return
vHave
.
empty
();
}
};
#endif
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sat, Nov 23, 09:57 (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4537722
Default Alt Text
core.h (12 KB)
Attached To
rSTAGING Bitcoin ABC staging
Event Timeline
Log In to Comment