Реальная история.
// Copyright (с) 2008 Сатоси Накамото
//
// Разрешение Настоящим предоставляется бесплатно, любому лицу, приобретающему копию
// это программное обеспечение и связанные с ним файлы документации ( "Программного обеспечения"), иметь дело
// Программного обеспечения без ограничений, в том числе, без ограничения прав
// использовать, копировать, изменять, объединять, публиковать, распространять, сублицензировать и / или продавать
// копии программного обеспечения, а также разрешать лицам, которым данное программное обеспечение
// обставленная сделать так, при соблюдении следующих условий:
//
// выше уведомление об авторских правах и данное разрешение должно быть включено в
// все копии или существенные части Программного обеспечения.
//
// ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ "КАК ЕСТЬ", БЕЗ КАКИХ, ЯВНЫХ ИЛИ
// ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИИ КОММЕРЧЕСКОЙ,
// ПРИГОДНОСТИ ДЛЯ КОНКРЕТНЫХ ЦЕЛЕЙ И ОТСУТСТВИЯ НАРУШЕНИЙ. НИ В КОЕМ СЛУЧАЕ
// АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ ОТВЕТСТВЕННОСТИ ЗА Claim, УБЫТКОВ ИЛИ
// ДРУГОЙ ОТВЕТСТВЕННОСТИ, НЕЗАВИСИМО ОТ ДЕЙСТВИЯ ДОГОВОРА, ГРАЖДАНСКОГО ПРАВОНАРУШЕНИЯ ИЛИ ИНАЧЕ, ВОЗНИКАЮЩИЕ
// ИЗ, ИЗ ИЛИ В СВЯЗИ С ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ
// В ПРОГРАММЕ.
класс COutPoint;
класс CInPoint;
класса CDiskTxPos;
класс CCoinBase;
класс CTxIn;
класс CTxOut;
класс CTransaction;
класс CBlock;
класс CBlockIndex;
класс CWalletTx;
класс CKeyItem;
Статическая сопзЬ неподписанных INT MAX_SIZE = 0x02000000;
статический Const int64 МОНЕТКА = 1000000;
статическая Const int64 CENT = 10000;
статический Const int64 TRANSACTIONFEE = 1 * CENT; /// изменить к пользовательской настройке параметров, дополнительный взнос может быть равен нулю
/// статические Const беззнаковое INT MINPROOFOFWORK = 40; /// нужно решить, правильные трудности, чтобы начать с
статические Const беззнаковое INT MINPROOFOFWORK = 20; /// смехотворно легко для тестирования
ехЬегп карта mapBlockIndex;
ехЬегп Const uint256 hashGenesisBlock;
ехЬегп CBlockIndex * pindexGenesisBlock;
ехЬегп INT nBestHeight;
ехЬегп CBlockIndex * pindexBest;
ехЬегп неподписанных INT nTransactionsUpdated;
ехЬегп INT fGenerateBitcoins;
FILE * OpenBlockFile (неподписанных INT nFile неподписанные INT nBlockPos, Const символ * pszMode ="Р.Б.");
FILE * AppendBlockFile (беззнаковое целочисленное значение& nFileRet);
BOOL ADDKEY (Const CKEY& ключ);
вектор<неподписанные символ> GenerateNewKey ();
BOOL AddToWallet (Const CWalletTx& wtxIn);
ReacceptWalletTransactions недействительными ();
RelayWalletTransactions недействительными ();
BOOL LoadBlockIndex (BOOL fAllowNew = истина);
BOOL BitcoinMiner ();
BOOL ProcessMessages (CNode * pfrom);
BOOL ProcessMessage (CNode * pfrom, строка strCommand, CDataStream& vRecv);
BOOL SendMessages (CNode * ВОМ);
Int64 CountMoney ();
BOOL CreateTransaction (CScript scriptPubKey, int64 nValue, CWalletTx& txNew);
BOOL SendMoney (CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew);
класса CDiskTxPos
{
общественности:
неподписанных INT nFile;
неподписанных INT nBlockPos;
неподписанных INT nTxPos;
CDiskTxPos ()
{
SetNull ();
}
CDiskTxPos (неподписанный INT nFileIn, беззнаковое целочисленное значение nBlockPosIn, неподписанные INT nTxPosIn)
{
nFile = nFileIn;
nBlockPos = nBlockPosIn;
nTxPos = nTxPosIn;
}
IMPLEMENT_SERIALIZE (READWRITE (FLATDATA (* это));)
SetNull недействительными () {nFile = -1; nBlockPos = 0; nTxPos = 0; }
BOOL IsNull () Const {возвращение (nFile == -1); }
Друг оператор BOOL == (константные CDiskTxPos& а, константные CDiskTxPos& б)
{
вернуться (a.nFile == b.nFile &&
a.nBlockPos == b.nBlockPos &&
a.nTxPos == b.nTxPos);
}
друг BOOL оператор! = (константные CDiskTxPos& а, константные CDiskTxPos& б)
{
вернуться (а == Ь!);
}
недействительным печати () сопзЬ
{
если (IsNull ())
Е ("ноль");
еще
Е ("(NFile =% d,% nBlockPos = д, nTxPos =% d)", NFile, nBlockPos, nTxPos);
}
};
класс CInPoint
{
общественности:
CTransaction * PTX;
неподписанных Int N;
CInPoint () {SetNull (); }
CInPoint (CTransaction * ptxIn, беззнаковое INT NIN) {PTX = ptxIn; п = NIN; }
SetNull недействительными () {PTX = NULL; п = -1; }
BOOL IsNull () сопзЬ {возвращение (PTX == NULL && п == -1); }
};
класс COutPoint
{
общественности:
uint256 хэш;
неподписанных Int N;
COutPoint () {SetNull (); }
COutPoint (uint256 Хашина, беззнаковое INT NIN) {хэш = Хашина; п = NIN; }
IMPLEMENT_SERIALIZE (READWRITE (FLATDATA (* это));)
SetNull недействительными () {хэш = 0; п = -1; }
BOOL IsNull () сопзЬ {возвращение (хэш == 0 && п == -1); }
Оператор друг BOOL<(Const COutPoint& а, Const COutPoint& б)
Возвращение (a.hash < b.hash
Друг оператор BOOL == (Const COutPoint& а, Const COutPoint& б)
{
вернуться (a.hash == b.hash && a.n == b.n);
}
Оператор друг Его! = (Const COutPoint& а, Const COutPoint& б)
{
вернуться (а == Ь!);
}
недействительным печати () сопзЬ
{
Е ("COutPoint (% s,% d)"., Hash.ToString () зиЬзЬг (0,6) .c_str (), п);
}
};
//
// Входной сделки. Он содержит местоположение предыдущего
// выводит сделки, что он утверждает, что и подпись, которая совпадает с
// открытый ключ Выходов,.
//
класс CTxIn
{
общественности:
COutPoint prevout;
CScript scriptSig;
CTxIn ()
{
}
CTxIn (COutPoint prevoutIn, CScript scriptSigIn)
{
prevout = prevoutIn;
scriptSig = scriptSigIn;
}
CTxIn (uint256 hashPrevTx, неподписанных INT ноут, CScript scriptSigIn)
{
prevout = COutPoint (hashPrevTx, Nout);
scriptSig = scriptSigIn;
}
IMPLEMENT_SERIALIZE
(
READWRITE (prevout);
READWRITE (scriptSig);
)
BOOL IsPrevInMainChain () Const
{
вернуться CTxDB ("р") .ContainsTx (prevout.hash);
}
Друг оператор BOOL == (Const CTxIn& а, Const CTxIn& б)
{
вернуться (a.prevout == b.prevout && a.scriptSig == b.scriptSig);
}
Оператор друг Его! = (Const CTxIn& а, Const CTxIn& б)
{
вернуться (а == Ь!);
}
недействительным печати () сопзЬ
{
Е ("CTxIn (");
prevout.print ();
если (prevout.IsNull ())
{
Е (", Coinbase% s) \ п", HexStr (scriptSig.begin (), scriptSig.end (), ложные) .c_str ());
}
еще
{
если (scriptSig.size () >= 6)
Е (", ScriptSig =% 02x% 02x", ScriptSig [4], scriptSig [5]);
Е (") \ П");
}
}
BOOL IsMine () Const;
Int64 GetDebit () Const;
};
//
// Выход из сделки. Он содержит открытый ключ, что следующий входной
// должен иметь возможность подписать с, чтобы претендовать на него.
//
класс CTxOut
{
общественности:
int64 nValue;
неподписанных INT nSequence;
CScript scriptPubKey;
только // диск
CDiskTxPos posNext; //// до сих пор он используется только как флаг, ничто не использует местоположение
общественности:
CTxOut ()
{
nValue = 0;
nSequence = UINT_MAX;
}
CTxOut (Int64 nValueIn, CSCRIPT scriptPubKeyIn, внутр nSequenceIn = UINT_MAX)
{
nValue = nValueIn;
scriptPubKey = scriptPubKeyIn;
nSequence = nSequenceIn;
}
IMPLEMENT_SERIALIZE
(
READWRITE (nValue);
READWRITE (nSequence);
READWRITE (scriptPubKey);
если (nType & SER_DISK)
READWRITE (posNext);
)
uint256 GetHash () сопзЬ {возвращение SerializeHash (* это); }
BOOL IsFinal () Const
{
возврата (nSequence == UINT_MAX);
}
BOOL IsMine () Const
{
вернуться :: IsMine (scriptPubKey);
}
Int64 GetCredit () Const
{
если (IsMine ())
вернуться nValue;
возвращать 0;
}
Друг оператор BOOL == (Const CTxOut& а, Const CTxOut& б)
{
вернуться (a.nValue == b.nValue &&
a.nSequence == b.nSequence &&
a.scriptPubKey == b.scriptPubKey);
}
Оператор друг Его! = (Const CTxOut& а, Const CTxOut& б)
{
вернуться (а == Ь!);
}
недействительным печати () сопзЬ
{
если (scriptPubKey.size () >= 6)
Е ("CTxOut (nValue =% I64d, nSequence =% и, scriptPubKey =% 02x% 02x, posNext =", NValue, nSequence, scriptPubKey [4], scriptPubKey [5]);
posNext.print ();
Е (") \ П");
}
};
//
// Основная операция, которая транслируется по сети, и содержащаяся в
// блоки. Сделка может содержать несколько входов и выходов.
//
класс CTransaction
{
общественности:
вектор Vin;
вектор Vout;
неподписанных INT nLockTime;
CTransaction ()
{
SetNull ();
}
IMPLEMENT_SERIALIZE
(
если (! (nType & SER_GETHASH))
READWRITE (nVersion);
// Установить версию на поток для записи обратно ту же версию
если (Fread && s.nVersion == -1)
s.nVersion = nVersion;
READWRITE (Vin);
READWRITE (Vout);
READWRITE (nLockTime);
)
SetNull недействительный ()
{
vin.clear ();
vout.clear ();
nLockTime = 0;
}
BOOL IsNull () Const
{
Возвращение (vin.empty () && vout.empty ());
}
uint256 GetHash () Const
{
вернуться SerializeHash (* это);
}
BOOL AllPrevInMainChain () Const
{
Еогеасп (Const CTxIn& txin, Vin)
если (! txin.IsPrevInMainChain ())
вернуться ложным;
возвращает истину;
}
BOOL IsFinal () Const
{
если (nLockTime == 0)
возвращает истину;
если (nLockTime < GetAdjustedTime ())
возвращает истину;
Еогеасп (Const CTxOut& txout, Vout)
если (! txout.IsFinal ())
вернуться ложным;
возвращает истину;
}
BOOL IsUpdate (Const CTransaction& б) Const
{
если (vin.size ()! = b.vin.size () || vout.size ()! = b.vout.size ())
вернуться ложным;
для (INT I = 0; я < vin.size (); я ++)
если (Vin [я] .prevout! = b.vin [я] .prevout)
вернуться ложным;
BOOL fNewer = ложь;
неподписанных INT nLowest = UINT_MAX;
для (INT I = 0; я < vout.size (); я ++)
{
если (Vout [я] .nSequence! = b.vout [я] .nSequence)
{
если (Vout [я] .nSequence <= NLowest)
{
fNewer = ложь;
nLowest = Vout [I] .nSequence;
}
если (b.vout [я] .nSequence < nLowest)
{
fNewer = TRUE;
nLowest = b.vout [I] .nSequence;
}
}
}
вернуться fNewer;
}
BOOL IsCoinBase () Const
{
Возвращение (vin.size () == 1 && Vin [0] .prevout.IsNull ());
}
BOOL CheckTransaction () Const
{
// Основные проверки, которые не зависят от какого-либо контекста
если (vin.empty () || vout.empty ())
вернуться ложным;
// Проверка для отрицательных значений
Int64 nValueOut = 0;
Еогеасп (Const CTxOut& txout, Vout)
{
если (txout.nValue < 0)
вернуться ложным;
nValueOut + = txout.nValue;
}
если (IsCoinBase ())
{
если (Vin [0] .scriptSig.size () > 100)
вернуться ложным;
}
еще
{
Еогеасп (Const CTxIn& txin, Vin)
если (txin.prevout.IsNull ())
вернуться ложным;
}
возвращает истину;
}
BOOL IsMine () Const
{
Еогеасп (Const CTxOut& txout, Vout)
если (txout.IsMine ())
возвращает истину;
вернуться ложным;
}
Int64 GetDebit () Const
{
Int64 nDebit = 0;
Еогеасп (Const CTxIn& txin, Vin)
nDebit + = txin.GetDebit ();
вернуться nDebit;
}
Int64 GetCredit () Const
{
Int64 nCredit = 0;
Еогеасп (Const CTxOut& txout, Vout)
nCredit + = txout.GetCredit ();
вернуться nCredit;
}
Int64 GetValueOut () Const
{
Int64 nValueOut = 0;
Еогеасп (Const CTxOut& txout, Vout)
{
если (txout.nValue < 0)
бросить runtime_error ("CTransaction :: GetValueOut (): отрицательное значение");
nValueOut + = txout.nValue;
}
вернуться nValueOut;
}
BOOL ReadFromDisk (CDiskTxPos поз, FILE ** pfileRet = NULL)
{
CAutoFile filein = OpenBlockFile (pos.nFile, 0, pfileRet? "гь +" : "Р.Б.");
если (! filein)
вернуться ложным;
// транзакция чтения
если (FSEEK (filein, pos.nTxPos, SEEK_SET)! = 0)
вернуться ложным;
filein >> *это;
// указатель возврата файла
если (pfileRet)
{
если (FSEEK (filein, pos.nTxPos, SEEK_SET)! = 0)
вернуться ложным;
* PfileRet = filein.release ();
}
возвращает истину;
}
Друг оператор BOOL == (Const CTransaction& а, Const CTransaction& б)
{
вернуться (a.vin == b.vin &&
a.vout == b.vout &&
a.nLockTime == b.nLockTime);
}
Оператор друг Его! = (Const CTransaction& а, Const CTransaction& б)
{
вернуться (а == Ь!);
}
недействительным печати () сопзЬ
{
Е ("CTransaction (vin.size =% d,% vout.size = д, nLockTime =% d) \ п",
vin.size (),
vout.size (),
nLockTime);
для (INT I = 0; я < vin.size (); я ++)
{
Е (" ");
Vin [я] .print ();
}
для (INT I = 0; я < vout.size (); я ++)
{
Е (" ");
Vout [I] .print ();
}
}
BOOL TestDisconnectInputs (CTxDB& txdb, карта& mapTestPool)
{
возвратные DisconnectInputs (txdb, mapTestPool, правда);
}
BOOL TestConnectInputs (CTxDB& txdb, карта& mapTestPool, BOOL fMemoryTx, BOOL fIgnoreDiskConflicts, int64& nFees)
{
возвращающие ConnectInputs (txdb, mapTestPool, CDiskTxPos (1, 1, 1), 0, правда, fMemoryTx, fIgnoreDiskConflicts, nFees);
}
BOOL DisconnectInputs (CTxDB& txdb)
{
статическая карта mapTestPool;
Обратные DisconnectInputs (txdb, mapTestPool, ложные);
}
BOOL ConnectInputs (CTxDB& txdb, CDiskTxPos posThisTx, внутр nHeight)
{
статическая карта mapTestPool;
Int64 nFees;
вернуть ConnectInputs (txdb, mapTestPool, posThisTx, nHeight, ложный, фальшивый, ложный, nFees);
}
частный:
BOOL DisconnectInputs (CTxDB& txdb, карта& mapTestPool, BOOL FTEST);
BOOL ConnectInputs (CTxDB& txdb, карта& mapTestPool, CDiskTxPos posThisTx, внутр nHeight,
BOOL FTEST, BOOL fMemoryTx, BOOL fIgnoreDiskConflicts, int64& nFees);
общественности:
BOOL AcceptTransaction (CTxDB& txdb, BOOL fCheckInputs = истина);
BOOL AcceptTransaction () {CTxDB txdb ("р"); вернуть AcceptTransaction (txdb); }
BOOL ClientConnectInputs ();
};
//
// Сделка с Merkle филиала связывая его с timechain
//
Класс CMerkleTx: общественный CTransaction
{
общественности:
uint256 hashBlock;
вектор vMerkleBranch;
INT nIndex;
CMerkleTx ()
{
В этом();
}
CMerkleTx (Const CTransaction& txIn): CTransaction (txIn)
{
В этом();
}
недействительные инициализации ()
{
hashBlock = 0;
nIndex = -1;
}
IMPLEMENT_SERIALIZE
(
nSerSize + = SerReadWrite (с, * (CTransaction *) это, nType, nVersion, ser_action);
если (! (nType & SER_GETHASH))
READWRITE (nVersion);
READWRITE (hashBlock);
READWRITE (vMerkleBranch);
READWRITE (nIndex);
)
INT SetMerkleBranch ();
INT IsInMainChain () Const;
BOOL AcceptTransaction (CTxDB& txdb, BOOL fCheckInputs = истина);
BOOL AcceptTransaction () {CTxDB txdb ("р"); вернуть AcceptTransaction (txdb); }
};
//
// Сделка с кучей дополнительной информации, что только владелец ухаживает
// около. Она включает в себя любые незарегистрированные операции, необходимые для связи его обратно
// в timechain.
//
Класс CWalletTx: общественный CMerkleTx
{
общественности:
вектор vtxPrev;
карта<строка, строка> mapValue;
вектор<пара<строка, строка> > vOrderForm;
неподписанных INT NTime;
голец fFromMe;
голец fSpent;
////, вероятно, необходимо подписать данные заказа так знаю, что пришло от плательщика
CWalletTx ()
{
В этом();
}
CWalletTx (Const CMerkleTx& txIn): CMerkleTx (txIn)
{
В этом();
}
CWalletTx (Const CTransaction& txIn): CMerkleTx (txIn)
{
В этом();
}
недействительные инициализации ()
{
Ntime = 0;
fFromMe = ложь;
fSpent = ложь;
}
IMPLEMENT_SERIALIZE
(
/// бы неплохо для того, чтобы вернуть номер версии он читает, может использовать ссылку
nSerSize + = SerReadWrite (с, * (CMerkleTx *) это, nType, nVersion, ser_action);
если (! (nType & SER_GETHASH))
READWRITE (nVersion);
READWRITE (vtxPrev);
READWRITE (mapValue);
READWRITE (vOrderForm);
READWRITE (Ntime);
READWRITE (fFromMe);
READWRITE (fSpent);
)
BOOL WriteToDisk ()
{
вернуться CWalletDB () WriteTx (GetHash (), * это).
}
недействительным AddSupportingTransactions (CTxDB& txdb);
AddSupportingTransactions недействительными () {CTxDB txdb ("р"); AddSupportingTransactions (txdb); }
BOOL AcceptWalletTransaction (CTxDB& txdb, BOOL fCheckInputs = истина);
BOOL AcceptWalletTransaction () {CTxDB txdb ("р"); вернуть AcceptWalletTransaction (txdb); }
недействительным RelayWalletTransaction (CTxDB& txdb);
RelayWalletTransaction недействительными () {CTxDB txdb ("р"); RelayWalletTransaction (txdb); }
};
//
// Узлы собирают новые транзакции в блок, хэш их в хэш-дерево,
// и просканировать Нонс значений, чтобы сделать хэш-блока в удовлетворяют корректуры из-работы
// требования. Когда они решают доказательство правильности работы, они передают блок
// для всех и блока добавляется к timechain. Первая сделка
// в блоке является особенным, который создает новую монету, принадлежащую создателю
// блока.
//
// блоки добавляются к blk0001.dat файлов на диске. Их расположение на диске
// индексируются объекты CBlockIndex в памяти.
//
класс CBlock
{
общественности:
// заголовок
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
неподписанных INT NTime;
неподписанных INT Nbits;
неподписанных INT nNonce;
// сеть и диск
вектор VTX;
только // память
изменяемый вектор vMerkleTree;
CBlock ()
{
SetNull ();
}
IMPLEMENT_SERIALIZE
(
если (! (nType & SER_GETHASH))
READWRITE (nVersion);
READWRITE (hashPrevBlock);
READWRITE (hashMerkleRoot);
READWRITE (Ntime);
READWRITE (Nbits);
READWRITE (nNonce);
// ConnectBlock зависит от фл будучи последним, поэтому он может вычислить смещение
если (! (nType & (SER_GETHASH | SER_BLOCKHEADERONLY)))
READWRITE (VTX);
иначе если (Fread)
const_cast(это)->vtx.clear ();
)
SetNull недействительный ()
{
hashPrevBlock = 0;
hashMerkleRoot = 0;
Ntime = 0;
Nbits = 0;
nNonce = 0;
vtx.clear ();
vMerkleTree.clear ();
}
BOOL IsNull () Const
{
возврата (Nbits == 0);
}
uint256 GetHash () Const
{
вернуть Hash (НАЧАТЬ (hashPrevBlock), КОНЕЦ (nNonce));
}
uint256 BuildMerkleTree () Const
{
vMerkleTree.clear ();
Еогеасп (Const CTransaction& ТХ, VTX)
vMerkleTree.push_back (tx.GetHash ());
Int J = 0;
для (INT = nРазмер: vtx.size (); nРазмер: > 1; nРазмер: = (nРазмер: + 1) / 2)
{
для (INT I = 0; я < nРазмер:; I + = 2)
{
INT i2 = мин (г + 1, nРазмер:-1);
vMerkleTree.push_back (Хэш (НАЧАТЬ (vMerkleTree [J + I]), END (vMerkleTree [J + I]),
НАЧАТЬ (vMerkleTree [J] + i2), END (vMerkleTree [J + i2])));
}
J + = nРазмер:;
}
(? VMerkleTree.empty () 0: vMerkleTree.back ()) возвращение;
}
вектор GetMerkleBranch (интермедиат nIndex) сопзЬ
{
если (vMerkleTree.empty ())
BuildMerkleTree ();
вектор vMerkleBranch;
Int J = 0;
для (INT = nРазмер: vtx.size (); nРазмер: > 1; nРазмер: = (nРазмер: + 1) / 2)
{
INT I = мин (nIndex ^ 1, nРазмер:-1);
vMerkleBranch.push_back (vMerkleTree [J + I]);
nIndex >>= 1;
J + = nРазмер:;
}
вернуться vMerkleBranch;
}
Статическая uint256 CheckMerkleBranch (uint256 хэш, Const вектор& vMerkleBranch, внутр nIndex)
{
Еогеасп (Const uint256& Otherside, vMerkleBranch)
{
если (nIndex & 1)
хэш = Хеш (НАЧАТЬ (Otherside), конец (Otherside), НАЧАТЬ (хэш), КОНЕЦ (хэш));
еще
хэш = Хеш (НАЧАТЬ (хэш), конец (хэш), НАЧАТЬ (Otherside), END (Otherside));
nIndex >>= 1;
}
возвращать хэш;
}
BOOL WriteToDisk (BOOL fWriteTransactions, неподписанных INT& nFileRet, беззнаковое целочисленное значение& nBlockPosRet)
= SER_BLOCKHEADERONLY;
// заголовок записи индекс
неподписанных INT nРазмер: = fileout.GetSerializeSize (* это);
fileout << FLATDATA (pchMessageStart) << nРазмер:;
// Записывает блок
nBlockPosRet = ftell (fileout);
если (nBlockPosRet == -1)
вернуться ложным;
fileout << *это;
возвращает истину;
BOOL ReadFromDisk (неподписанных INT nFile неподписанные INT nBlockPos, BOOL fReadTransactions)
= SER_BLOCKHEADERONLY;
// Читает блок
filein >> *это;
// Проверка заголовка
если (Nbits < MINPROOFOFWORK
недействительным печати () сопзЬ
{
Е ("CBlock (hashPrevBlock =% s, hashMerkleRoot =% s, Ntime =% и, Nbits =% и, nNonce =% и, VTX =% d) \ п",
hashPrevBlock.ToString (). зиЬзЬг (0,6) .c_str (),
hashMerkleRoot.ToString (). зиЬзЬг (0,6) .c_str (),
NTime, Nbits, nNonce,
vtx.size ());
для (INT I = 0; я < vtx.size (); я ++)
{
Е (" ");
VTX [I] .print ();
}
Е (" vMerkleTree: ");
для (INT I = 0; я < vMerkleTree.size (); я ++)
Е ("% s ", VMerkleTree [I] .ToString () SUBSTR (0,6) .c_str ()).
Е ("\ п");
}
BOOL ReadFromDisk (Const CBlockIndex * blockindex, BOOL fReadTransactions);
BOOL TestDisconnectBlock (CTxDB& txdb, карта& mapTestPool);
BOOL TestConnectBlock (CTxDB& txdb, карта& mapTestPool);
BOOL DisconnectBlock ();
BOOL ConnectBlock (беззнаковая INT nFile, без знака INT nBlockPos, Int nHeight);
BOOL AddToBlockIndex (беззнаковая INT nFile, беззнаковый INT nBlockPos, BOOL fWriteDisk);
BOOL CheckBlock () Const;
BOOL AcceptBlock ();
};
//
// timechain представляет собой древовидную структуру формы, начиная с
// Генезис блок в корне, при этом каждый блок потенциально имеющих множественные
// кандидаты быть следующим блоком. pprev и pnext связать путь через
// главная / длинная цепь. Blockindex может иметь несколько pprev указывая назад
// к нему, но pnext только точку вперед на длинной ветви, или будет
// быть нулевым, если блок не является частью самой длинной цепи.
//
класс CBlockIndex
{
общественности:
CBlockIndex * pprev;
CBlockIndex * pnext;
неподписанных INT nFile;
неподписанных INT nBlockPos;
INT nHeight;
CBlockIndex ()
{
pprev = NULL;
pnext = NULL;
nFile = 0;
nBlockPos = 0;
nHeight = 0;
}
CBlockIndex (неподписанный INT nFileIn, неподписанные INT nBlockPosIn)
{
pprev = NULL;
pnext = NULL;
nFile = nFileIn;
nBlockPos = nBlockPosIn;
nHeight = 0;
}
BOOL IsInMainChain () Const
BOOL EraseBlockFromDisk ()
{
// Открыть файл истории
CAutoFile fileout = OpenBlockFile (nFile, nBlockPos, "гь +");
если (! fileout)
вернуться ложным;
// перезапись с пустым блоком нулевой
CBlock блок;
block.SetNull ();
fileout << блок;
возвращает истину;
}
BOOL TestDisconnectBlock (CTxDB& txdb, карта& mapTestPool)
{
CBlock блок;
если (! block.ReadFromDisk (nFile, nBlockPos, правда))
вернуться ложным;
вернуть block.TestDisconnectBlock (txdb, mapTestPool);
}
BOOL TestConnectBlock (CTxDB& txdb, карта& mapTestPool)
{
CBlock блок;
если (! block.ReadFromDisk (nFile, nBlockPos, правда))
вернуться ложным;
вернуть block.TestConnectBlock (txdb, mapTestPool);
}
BOOL DisconnectBlock ()
{
CBlock блок;
если (! block.ReadFromDisk (nFile, nBlockPos, правда))
вернуться ложным;
вернуть block.DisconnectBlock ();
}
BOOL ConnectBlock ()
{
CBlock блок;
если (! block.ReadFromDisk (nFile, nBlockPos, правда))
вернуться ложным;
вернуть block.ConnectBlock (nFile, nBlockPos, nHeight);
}
недействительным печати () сопзЬ
{
Е ("CBlockIndex (nprev =% 08x, pnext =% 08x, nFile =% d,% nBlockPos = д, nHeight =% d) \ п",
pprev, pnext, nFile, nBlockPos, nHeight);
}
};
аннулированию PrintTimechain ();
//
// Описывает место в timechain на другой узел таким образом, что если
// другой узел не имеет ту же ветку, он может найти недавний общий ствол.
// Чем дальше он, тем дальше до точки ветвления может быть.
//
класс CBlockLocator
{
защищенный:
вектор vHave;
общественности:
CBlockLocator ()
{
}
Явный CBlockLocator (Const CBlockIndex * pindex)
{
Набор (pindex);
}
Явный CBlockLocator (uint256 hashBlock)
{
карта:: итератора миль = mapBlockIndex.find (hashBlock);
если (мили! = mapBlockIndex.end ())
Set ((* мили) .second);
}
IMPLEMENT_SERIALIZE
(
если (! (nType & SER_GETHASH))
READWRITE (nVersion);
READWRITE (vHave);
)
аннулированию Set (Уст CBlockIndex * pindex)
{
vHave.clear ();
INT nStep = 1;
в то время как (pindex)
{
CBlock блок;
block.ReadFromDisk (pindex, ложь);
vHave.push_back (block.GetHash ());
// Экспоненциально большие шаги назад
для (INT I = 0; pindex && я < nStep; я ++)
pindex = pindex->pprev;
если (vHave.size () > 10)
nStep * = 2;
}
}
CBlockIndex * GetBlockIndex ()
{
// Найти первый блок звонящий имеет в основной цепи
Еогеасп (Const uint256& хэш, vHave)
{
карта:: итератор мили = mapBlockIndex.find (хэш);
если (мили! = mapBlockIndex.end ())
{
CBlockIndex * pindex = (* мили) .second;
если (pindex->IsInMainChain ())
вернуться pindex;
}
}
вернуться pindexGenesisBlock;
}
uint256 GetBlockHash ()
{
// Найти первый блок звонящий имеет в основной цепи
Еогеасп (Const uint256& хэш, vHave)
{
карта:: итератор мили = mapBlockIndex.find (хэш);
если (мили! = mapBlockIndex.end ())
{
CBlockIndex * pindex = (* мили) .second;
если (pindex->IsInMainChain ())
возвращать хэш;
}
}
вернуться hashGenesisBlock;
}
ИНТ GetHeight ()
{
CBlockIndex * pindex = GetBlockIndex ();
если (! pindex)
возвращать 0;
вернуться pindex->nHeight;
}
};
ехЬегп карта mapTransactions;
ехЬегп карта mapWallet;
ехЬегп вектор<пара > vWalletUpdated;
ехЬегп CCriticalSection cs_mapWallet;
ехЬегп карта<вектор<неподписанные символ>, CPrivKey> mapKeys;
ехЬегп карта > mapPubKeys;
ехЬегп cs_mapKeys CCriticalSection;
ехЬегп CKEY keyUser;
[/ Предварительно]