Вернуться   Биткоин Форум > Разработка и Техническое Обсуждение
23 декабря 2013, 7:27:01 PM   # 1
 
 
Сообщения: 840
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Взлом Биткоин адресов.
500 Биткоинов взломаны в "мозговом кошельке" с паролем "bitcoin is awesome"
Адрес кошелька: 14NWDXkQwcGN1Pd9fboL8npVynD5SfyJAE
Приватный ключ: 5J64pq77XjeacCezwmAr2V1s7snvvJkuAz8sENxw7xCkikceV6e
подробнее...


Всем кто хочет заработать Биткоины без вложений - рекомендую сайт http://bitcoin-zarabotat.ru
У меня есть этот архив в моей электронной почте.  

Это источники Bitcoin от 16 ноября 2008 года - за несколько месяцев до начала текущего blockchain.

Это четыре файлы исходного кода, и я собираюсь вставить их в 4 пять сообщений здесь. Я надеюсь, что программное обеспечение форума позволяет длинные сообщения; один из них 66K.  

Изменить: Программное обеспечение Форум позволяет только 64K в одном посте, поэтому я разделил main.cpp на две должности. 

Пост ниже этого является то, что содержимое файла, main.h
Cryddit сейчас офлайн Пожаловаться на Cryddit   Ответить с цитированием Мультицитирование сообщения от Cryddit Быстрый ответ на сообщение Cryddit


Как заработать Биткоины?
Без вложений. Не майнинг.


23 декабря 2013, 7:30:00 PM   # 2
 
 
Сообщения: 840
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Получил 1806 Биткоинов
Реальная история.






Код:
// 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;
[/ Предварительно]
Cryddit сейчас офлайн Пожаловаться на Cryddit   Ответить с цитированием Мультицитирование сообщения от Cryddit Быстрый ответ на сообщение Cryddit

23 декабря 2013, 7:32:23 PM   # 3
 
 
Сообщения: 840
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Это первая половина main.cpp. Я собираюсь отправить его на две половинки, потому что программное обеспечение форума позволяет немного меньше, чем 66K в одном посте. 

Код:
// Copyright (с) 2008 Сатоси Накамото
//
// Разрешение Настоящим предоставляется бесплатно, любому лицу, приобретающему копию
// это программное обеспечение и связанные с ним файлы документации ( "Программного обеспечения"), иметь дело
// Программного обеспечения без ограничений, в том числе, без ограничения прав
// использовать, копировать, изменять, объединять, публиковать, распространять, сублицензировать и / или продавать
// копии программного обеспечения, а также разрешать лицам, которым данное программное обеспечение
// обставленная сделать так, при соблюдении следующих условий:
//
// выше уведомление об авторских правах и данное разрешение должно быть включено в
// все копии или существенные части Программного обеспечения.
//
// ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ "КАК ЕСТЬ", БЕЗ КАКИХ, ЯВНЫХ ИЛИ
// ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИИ КОММЕРЧЕСКОЙ,
// ПРИГОДНОСТИ ДЛЯ КОНКРЕТНЫХ ЦЕЛЕЙ И ОТСУТСТВИЯ НАРУШЕНИЙ. НИ В КОЕМ СЛУЧАЕ
// АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ ОТВЕТСТВЕННОСТИ ЗА Claim, УБЫТКОВ ИЛИ
// ДРУГОЙ ОТВЕТСТВЕННОСТИ, НЕЗАВИСИМО ОТ ДЕЙСТВИЯ ДОГОВОРА, ГРАЖДАНСКОГО ПРАВОНАРУШЕНИЯ ИЛИ ИНАЧЕ, ВОЗНИКАЮЩИЕ
// ИЗ, ИЗ ИЛИ В СВЯЗИ С ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ
// В ПРОГРАММЕ.

#включают "headers.h"
#включают "sha.h"





//
// Глобальное состояние
//

карта mapTransactions;
CCriticalSection cs_mapTransactions;
беззнаковое INT nTransactionsUpdated = 0;
/// mapNextTx только используется больше для отслеживания диска ОГО Outpoints используемого txes памяти
карта mapNextTx;

карта mapBlockIndex;
Const uint256 hashGenesisBlock ("0x000006b15d1327d67e971d1de9116bd60a3a01556c91b6ebaa416ebc0cfaa646");
CBlockIndex * pindexGenesisBlock = NULL;
INT nBestHeight = -1;
uint256 hashTimeChainBest = 0;
CBlockIndex * pindexBest = NULL;

карта mapOrphanBlocks;
MultiMap mapOrphanBlocksByPrev;

карта mapWallet;
вектор<пара > vWalletUpdated;
CCriticalSection cs_mapWallet;

карта<вектор<неподписанные символ>, CPrivKey> mapKeys;
карта > mapPubKeys;
CCriticalSection cs_mapKeys;
CKEY keyUser;

ИНТ fGenerateBitcoins;












////////////////////////////////////////////////// ////////////////////////////
//
// mapKeys
//

BOOL ADDKEY (Const CKEY& ключ)
{
    CRITICAL_BLOCK (cs_mapKeys)
    {
        mapKeys [key.GetPubKey ()] = key.GetPrivKey ();
        mapPubKeys [Hash160 (key.GetPubKey ())] = key.GetPubKey ();
    }
    вернуть CWalletDB () WriteKey (key.GetPubKey (), key.GetPrivKey ()).
}

вектор<неподписанные символ> GenerateNewKey ()
{
    ключ CKEY;
    key.MakeNewKey ();
    если (! ADDKEY (ключ))
        бросить runtime_error ("GenerateNewKey (): ADDKEY не удалось \ п");
    вернуть key.GetPubKey ();
}




////////////////////////////////////////////////// ////////////////////////////
//
// mapWallet
//

BOOL AddToWallet (Const CWalletTx& wtxIn)
{
    uint256 хэш = wtxIn.GetHash ();
    CRITICAL_BLOCK (cs_mapWallet)
    {
        // Вставка только если уже не там, возвращается ТМ вставленными или ТМИ найдено
        пара<карта:: итератор, BOOL> RET = mapWallet.insert (make_pair (хэш, wtxIn));
        CWalletTx& WTX = (* ret.first) .second;
        BOOL fInsertedNew = ret.second;

        //// отладки печати
        Е ("AddToWallet% s% d \ п", WtxIn.GetHash () ToString () c_str (), fInsertedNew)..;

        если (! fInsertedNew)
        {
            // Объединить
            BOOL fUpdated = ложь;
            если (wtxIn.hashBlock! = 0 && wtxIn.hashBlock! = wtx.hashBlock)
            {
                wtx.hashBlock = wtxIn.hashBlock;
                fUpdated = TRUE;
            }
            если (wtxIn.fFromMe && wtxIn.fFromMe! = wtx.fFromMe)
            {
                wtx.fFromMe = wtxIn.fFromMe;
                fUpdated = TRUE;
            }
            если (wtxIn.fSpent && wtxIn.fSpent! = wtx.fSpent)
            {
                wtx.fSpent = wtxIn.fSpent;
                fUpdated = TRUE;
            }
            если (! fUpdated)
                возвращает истину;
        }

        // Записать на диск
        если (! wtx.WriteToDisk ())
            вернуться ложным;

        // Notify UI
        vWalletUpdated.push_back (make_pair (хэш, fInsertedNew));
    }

    // Обновить UI
    MainFrameRepaint ();
    возвращает истину;
}

BOOL AddToWalletIfMine (Const CTransaction& ТХ, Const CBlock * pblock)
{
    если (tx.IsMine ())
    {
        CWalletTx WTX (ТХ);
        если (pblock)
        {
            wtx.hashBlock = pblock->GetHash ();
            wtx.nTime = pblock->NTime;
        }
        еще
        {
            wtx.nTime = GetAdjustedTime ();
        }
        вернуть AddToWallet (WTX);
    }
    возвращает истину;
}

ReacceptWalletTransactions недействительными ()
{
    // любая txes приняла назад из наших, которые уже не в блоке
    CRITICAL_BLOCK (cs_mapWallet)
    {
        CTxDB txdb ("р");
        Еогеасп (PAIRTYPE (Const uint256, CWalletTx)& пункт, mapWallet)
        {
            CWalletTx& WTX = item.second;
            если (! txdb.ContainsTx (wtx.GetHash ()))
                wtx.AcceptWalletTransaction (txdb, ложь);
        }
    }
}

RelayWalletTransactions недействительными ()
{
    Статическая int64 nLastTime;
    если (GetTime () - nLastTime < 15 * 60)
        вернуть;
    nLastTime = GetTime ();

    // ретрансляция любого из нашего txes, которые не в блоке еще
    CRITICAL_BLOCK (cs_mapWallet)
    {
        CTxDB txdb ("р");
        Еогеасп (PAIRTYPE (Const uint256, CWalletTx)& пункт, mapWallet)
            item.second.RelayWalletTransaction (txdb);
    }
}











////////////////////////////////////////////////// ////////////////////////////
//
// CTransaction
//

BOOL CTxIn :: IsMine () Const
{
    карта:: итератор мили = mapWallet.find (prevout.hash);
    если (мили! = mapWallet.end ())
    {
        Const CWalletTx& пред = (* мили) .second;
        если (prevout.n < prev.vout.size ())
            если (prev.vout [prevout.n] .IsMine ())
                возвращает истину;
    }
    вернуться ложным;
}

int64 CTxIn :: GetDebit () Const
{
    карта:: итератор мили = mapWallet.find (prevout.hash);
    если (мили! = mapWallet.end ())
    {
        Const CWalletTx& пред = (* мили) .second;
        если (prevout.n < prev.vout.size ())
            если (prev.vout [prevout.n] .IsMine ())
                вернуть prev.vout [prevout.n] .nValue;
    }
    возвращать 0;
}




INT CMerkleTx :: SetMerkleBranch ()
{
    если (fClient)
    {
        если (hashBlock == 0)
            возвращать 0;
    }
    еще
    {
        // загружает блок этого ТХ в
        CDiskTxPos позы;
        если (! CTxDB ("р") .ReadTxPos (GetHash (), позы))
            возвращать 0;
        CBlock блок;
        если (! block.ReadFromDisk (pos.nFile, pos.nBlockPos, правда))
            возвращать 0;

        // Обновление hashBlock ОГО в
        hashBlock = block.GetHash ();

        // Расположить сделки
        для (nIndex = 0; nIndex < block.vtx.size (); nIndex ++)
            если (block.vtx [nIndex] == * (CTransaction *) это)
                ломать;
        если (nIndex == block.vtx.size ())
        {
            vMerkleBranch.clear ();
            nIndex = -1;
            Е ("ОШИБКА: SetMerkleBranch (): не удалось найти ТХ в блоке \ п");
            возвращать 0;
        }

        // Заполнить Merkle отрасли
        vMerkleBranch = block.GetMerkleBranch (nIndex);
    }

    // Является ли АЯ в блоке, которая находится в основной цепи
    карта:: итератора миль = mapBlockIndex.find (hashBlock);
    если (мили == mapBlockIndex.end ())
        возвращать 0;
    CBlockIndex * pindex = (* мили) .second;
    если (! pindex ||! pindex->IsInMainChain ())
        возвращать 0;

    вернуться pindexBest->nHeight - pindex->nHeight + 1;
}

аннулированию CWalletTx :: AddSupportingTransactions (CTxDB& txdb)
{
    vtxPrev.clear ();

    Const INT COPY_DEPTH = 3;
    если (SetMerkleBranch () < COPY_DEPTH)
    {
        вектор vWorkQueue;
        Еогеасп (Const CTxIn& txin, Vin)
            vWorkQueue.push_back (txin.prevout.hash);

        карта mapWalletPrev;
        задавать setAlreadyDone;
        для (INT I = 0; я < vWorkQueue.size (); я ++)
        {
            uint256 хэш = vWorkQueue [I];
            если (setAlreadyDone.count (хэш))
                Продолжать;
            setAlreadyDone.insert (хэш);

            CMerkleTx ТХ;
            если (mapWallet.count (хэш))
            {
                Тх = mapWallet [хэш];
                Еогеасп (Const CMerkleTx& txWalletPrev, mapWallet [хэш] .vtxPrev)
                    mapWalletPrev [txWalletPrev.GetHash ()] = &txWalletPrev;
            }
            иначе если (mapWalletPrev.count (хэш))
            {
                Тх = * mapWalletPrev [хэш];
            }
            иначе если (! fClient && txdb.ReadDiskTx (хэш, TX))
            {
                ;
            }
            еще
            {
                Е ("ОШИБКА: AddSupportingTransactions (): неподдерживаемый сделка \ п");
                Продолжать;
            }

            INT nDepth = tx.SetMerkleBranch ();
            vtxPrev.push_back (ТХ);

            если (nDepth < COPY_DEPTH)
                Еогеасп (Const CTxIn& txin, tx.vin)
                    vWorkQueue.push_back (txin.prevout.hash);
        }
    }

    задний ход (vtxPrev.begin (), vtxPrev.end ());
}










BOOL CTransaction :: DisconnectInputs (CTxDB& txdb, карта& mapTestPool, BOOL FTEST)
{
    // Откажитесь posNext указатели предыдущих сделок
    если (! IsCoinBase ())
    {
        Еогеасп (Const CTxIn& txin, Vin)
        {
            COutPoint prevout = txin.prevout;

            CAutoFile fileout = NULL;
            CTransaction txPrevBuf;
            CTransaction& txPrev = (FTEST mapTestPool [prevout.hash]: txPrevBuf);
            если (txPrev.IsNull ())
            {
                // Получаем пред ТХ с диска
                // Версия -1 говорит десериализации установить версию, так мы пишем обратно ту же версию
                fileout.SetVersion (-1);
                если (! txdb.ReadDiskTx (prevout.hash, txPrev, &fileout))
                    вернуться ложным;
            }

            если (prevout.n >= TxPrev.vout.size ())
                вернуться ложным;

            // указатель уступит posNext
            txPrev.vout [prevout.n] .posNext.SetNull ();

            // Записываем обратно
            если (! FTEST)
                fileout << txPrev;
        }
    }

    если (FTEST)
    {
        // Поместите блок- копию этой сделки в тестовом бассейне
        CTransaction& txPool = mapTestPool [GetHash ()];
        txPool = * это;
        Еогеасп (CTxOut& txout, txPool.vout)
            txout.posNext = CDiskTxPos (1, 1, 1);
    }
    еще
    {
        // Удалить транзакцию из индекса
        если (! txdb.EraseTxPos (* это))
            вернуться ложным;

        // воскрешать объекты одной транзакции
        если (! IsCoinBase ())
            AcceptTransaction (txdb, ложь);
    }

    возвращает истину;
}


BOOL CTransaction :: ConnectInputs (CTxDB& txdb, карта& mapTestPool, CDiskTxPos posThisTx, внутр nHeight,
                                 BOOL FTEST, BOOL fMemoryTx, BOOL fIgnoreDiskConflicts, int64& nFees)
{
    // Захватить posNext указатели предыдущих сделок
    если (! IsCoinBase ())
    {
        Int64 nValueIn = 0;
        для (INT I = 0; я < vin.size (); я ++)
        {
            COutPoint prevout = Vin [I] .prevout;

            CAutoFile fileout = NULL;
            CTransaction txPrevBuf;
            CTransaction& txPrev = (FTEST mapTestPool [prevout.hash]: txPrevBuf);
            если (txPrev.IsNull () && FTEST && fMemoryTx && mapTransactions.count (prevout.hash))
            {
                // Получает пред ТХ от разовых сделок в памяти
                txPrev = mapTransactions [prevout.hash];
            }
            иначе если (txPrev.IsNull ())
            {
                // Получаем пред ТХ с диска
                // Версия -1 говорит десериализации установить версию, так мы пишем обратно ту же версию
                fileout.SetVersion (-1);
                если (! txdb.ReadDiskTx (prevout.hash, txPrev, &fileout))
                    возвращать ошибку ("ConnectInputs (): предыдущая не найдено ТХ");

                // Если ТЙ будут подключены только в REORG,
                // то эти минусы будут проверены в то время
                если (fIgnoreDiskConflicts)
                    Еогеасп (CTxOut& txout, txPrev.vout)
                        txout.posNext.SetNull ();
            }

            если (prevout.n >= TxPrev.vout.size ())
                вернуться ложным;

            // Проверка подписи
            если (! VerifySignature (txPrev, * это, я))
                возвращать ошибку ("ConnectInputs (): VerifySignature не удалось");

            // Проверка на наличие конфликтов
            если (! txPrev.vout [prevout.n] .posNext.IsNull ())
                возвращать ошибку ("ConnectInputs (): предыдущая ТХ уже используется");

            // Флаг перебоксировал, используемый
            txPrev.vout [prevout.n] .posNext = posThisTx;

            // Записываем обратно
            если (! FTEST)
                fileout << txPrev;

            nValueIn + = txPrev.vout [prevout.n] .nValue;
        }

        // сборы Tally сделки
        Int64 nTransactionFee = nValueIn - GetValueOut ();
        если (nTransactionFee < 0)
            вернуться ложным;
        nFees + = nTransactionFee;
    }

    если (FTEST)
    {
        // Добавить транзакцию, чтобы проверить бассейн
        mapTestPool [GetHash ()] = * это;
    }
    еще
    {
        // Добавить транзакцию индекс диска
        если (! txdb.WriteTxPos (* это, posThisTx, nHeight))
            вернуться ложным;

        // Удалить лишние отдельные объекты транзакций
        CRITICAL_BLOCK (cs_mapTransactions)
        {
            Еогеасп (Const CTxIn& txin, Vin)
                mapNextTx.erase (txin.prevout);
            mapTransactions.erase (GetHash ());
        }
    }

    возвращает истину;
}




BOOL CTransaction :: AcceptTransaction (CTxDB& txdb, BOOL fCheckInputs)
{
    // Coinbase действует только в блоке, а не рыхлая сделки
    если (IsCoinBase ())
        возвращать ошибку ("AcceptTransaction (): coinbase в виде индивидуальных ТХ");

    если (! CheckTransaction ())
        возвращать ошибку ("AcceptTransaction (): CheckTransaction не удалось");

    uint256 хэш = GetHash ();
    если (mapTransactions.count (хэш))
        вернуться ложным;

    // Проверка на наличие конфликтов с операциями в оперативной памяти
    // и позволяет заменить более новой версией той же самой транзакции
    CTransaction * ptxOld = NULL;
    для (INT I = 0; я < vin.size (); я ++)
    {
        COutPoint = VIN очкам [I] .prevout;
        если (mapNextTx.count (минус))
        {
            если (ptxOld == NULL)
            {
                ptxOld = mapNextTx [] .ptx очкам;
                если (! IsUpdate (* ptxOld))
                    вернуться ложным;
            }
            иначе если (ptxOld! = mapNextTx [очкам] .ptx)
                вернуться ложным;
        }
    }

    // Проверка против предыдущих сделок
    карта mapTestPool;
    Int64 nFees = 0;
    если (fCheckInputs)
        если (! TestConnectInputs (txdb, mapTestPool, истинный, ложный, nFees))
            возвращать ошибку ("AcceptTransaction (): TestConnectInputs не удалось");

    // транзакции Хранить в памяти
    CRITICAL_BLOCK (cs_mapTransactions)
    {
        если (ptxOld)
        {
            Е ("mapTransaction.erase (% s) замена новой версии \ п", ptxOld->.. GetHash () ToString () c_str ());
            mapTransactions.erase (ptxOld->GetHash ());
        }
        // Е ("mapTransaction.insert (% s) \ п  ", Hash.ToString () c_str ()).
        //Распечатать();
        mapTransactions [хэш] = * это;
        для (INT I = 0; я < vin.size (); я ++)
            mapNextTx [Vin [я] .prevout] = CInPoint (&mapTransactions [хэш], я);
    }

    // Если обновляется, стереть старую Тх из бумажника
    если (ptxOld)
        CRITICAL_BLOCK (cs_mapWallet)
            mapWallet.erase (ptxOld->GetHash ());

    nTransactionsUpdated ++;
    возвращает истину;
}





INT CMerkleTx :: IsInMainChain () Const
!pindex->IsInMainChain ())
        возвращать 0;

    // Получить корень Merkle
    CBlock блок;
    если (! block.ReadFromDisk (pindex, ложь))
        возвращать 0;

    // Убедитесь, что Merkle филиал подключается к этому блоку
    если (CBlock :: CheckMerkleBranch (GetHash (), vMerkleBranch, nIndex)! = block.hashMerkleRoot)
        возвращать 0;

    вернуться pindexBest->nHeight - pindex->nHeight + 1;




BOOL CMerkleTx :: AcceptTransaction (CTxDB& txdb, BOOL fCheckInputs)
{
    если (fClient)
    {
        если (! IsInMainChain () && ! ClientConnectInputs ())
            вернуться ложным;
        вернуться CTransaction :: AcceptTransaction (txdb, ложь);
    }
    еще
    {
        вернуться CTransaction :: AcceptTransaction (txdb, fCheckInputs);
    }
}



BOOL CWalletTx :: AcceptWalletTransaction (CTxDB& txdb, BOOL fCheckInputs)
{
    Еогеасп (CMerkleTx& ТХ, vtxPrev)
    {
        uint256 хэш = tx.GetHash ();
        если (! mapTransactions.count (хэш) && ! Txdb.ContainsTx (хэш))
            tx.AcceptTransaction (txdb, fCheckInputs);
    }
    вернуть AcceptTransaction (txdb, fCheckInputs);
}


аннулируются CWalletTx :: RelayWalletTransaction (CTxDB& txdb)
{
    Еогеасп (CMerkleTx& ТХ, vtxPrev)
    {
        uint256 хэш = tx.GetHash ();
        если (! txdb.ContainsTx (хэш))
            RelayMessage (CINV (MSG_TX, хэш), (CTransaction) ТХ);
    }
    uint256 хэш = GetHash ();
    если (! txdb.ContainsTx (хэш))
        RelayMessage (CINV (MSG_TX, хэш), (CTransaction) * это);
}










////////////////////////////////////////////////// ////////////////////////////
//
// CBlock и CBlockIndex
//

BOOL CBlock :: ReadFromDisk (Const CBlockIndex * pblockindex, BOOL fReadTransactions)
{
    вернуться ReadFromDisk (pblockindex->nFile, pblockindex->nBlockPos, fReadTransactions);
}

Int64 GetBlockValue (Int64 nFees)
{
    Int64 nSubsidy = 10000 * CENT;
    для (INT I = 100000; я <= NBestHeight; I + = 100000)
        nSubsidy / = 2;
    вернуться nSubsidy + nFees;
}

неподписанных INT GetNextWorkRequired (Const CBlockIndex * pindexLast)
{
    Const беззнаковое INT nTargetTimespan = 30 * 24 * 60 * 60;
    сопзИте неподписанный INT nTargetSpacing = 15 * 60;
    Const беззнаковое INT nIntervals = nTargetTimespan / nTargetSpacing;

    // кэш
    Статическая Const CBlockIndex * pindexLastCache;
    Статический неподписанный INT nBitsCache;
    Статическая CCriticalSection cs_cache;
    CRITICAL_BLOCK (cs_cache)
        если (pindexLast && pindexLast == pindexLastCache)
            вернуться nBitsCache;

    // Возвращается 30 дней
    Const CBlockIndex * pindexFirst = pindexLast;
    для (INT I = 0; pindexFirst && я < nIntervals; я ++)
        pindexFirst = pindexFirst->pprev;
    если (pindexFirst == NULL)
        вернуться MINPROOFOFWORK;

    // Загрузка первого и последнего блока
    CBlock blockFirst;
    если (! blockFirst.ReadFromDisk (pindexFirst, ложь))
        бросить runtime_error ("GetNextWorkRequired (): blockFirst.ReadFromDisk не удалось \ п");
    CBlock blockLast;
    если (! blockLast.ReadFromDisk (pindexLast, ложь))
        бросить runtime_error ("GetNextWorkRequired (): blockLast.ReadFromDisk не удалось \ п");

    // Ограничить одно изменение за отрезок времени
    неподписанный INT Nbits = blockLast.nBits;
    если (blockFirst.nBits == blockLast.nBits)
    {
        неподписанный INT nTimespan = blockLast.nTime - blockFirst.nTime;
        если (nTimespan > nTargetTimespan * 2 && Nbits >= MINPROOFOFWORK)
            nBits--;
        иначе если (nTimespan < nTargetTimespan / 2)
            Nbits ++;
    }

    CRITICAL_BLOCK (cs_cache)
    {
        pindexLastCache = pindexLast;
        nBitsCache = Nbits;
    }
    вернуться Nbits;
}

uint256 GetOrphanRoot (Const CBlock * pblock)
{
    // Работа обратно к первому блоку в сиротской цепи
    в то время как (mapOrphanBlocks.count (pblock->hashPrevBlock))
        pblock = mapOrphanBlocks [pblock->hashPrevBlock];
    вернуться pblock->hashPrevBlock;
}









BOOL CBlock :: TestDisconnectBlock (CTxDB& txdb, карта& mapTestPool)
{
    Еогеасп (CTransaction& ТХ, VTX)
        если (! tx.TestDisconnectInputs (txdb, mapTestPool))
            вернуться ложным;
    возвращает истину;
}

BOOL CBlock :: TestConnectBlock (CTxDB& txdb, карта& mapTestPool)
{
    Int64 nFees = 0;
    Еогеасп (CTransaction& ТХ, VTX)
        если (! tx.TestConnectInputs (txdb, mapTestPool, ложный, фальшивый, nFees))
            вернуться ложным;

    если (VTX [0] .GetValueOut ()! = GetBlockValue (nFees))
        вернуться ложным;
    возвращает истину;
}

BOOL CBlock :: DisconnectBlock ()
{
    CTxDB txdb;
    Еогеасп (CTransaction& ТХ, VTX)
        если (! tx.DisconnectInputs (txdb))
            вернуться ложным;
    возвращает истину;
}

BOOL CBlock :: ConnectBlock (неподписанных INT nFile неподписанные INT nBlockPos, Int nHeight)
{
    //// вопрос здесь: он не знает версию
    беззнаковое INT nTxPos = nBlockPos + :: GetSerializeSize (CBlock (), SER_DISK) - 1 + GetSizeOfCompactSize (vtx.size ());

    CTxDB txdb;
    Еогеасп (CTransaction& ТХ, VTX)
    {
        CDiskTxPos posThisTx (nFile, nBlockPos, nTxPos);
        nTxPos + = :: GetSerializeSize (ТХ, SER_DISK);

        если (! tx.ConnectInputs (txdb, posThisTx, nHeight))
            вернуться ложным;
    }
    txdb.Close ();

    // Следите за сделки платить мне
    Еогеасп (CTransaction& ТХ, VTX)
        AddToWalletIfMine (ТХ, это);

    возвращает истину;
}



BOOL Реорганизовать (CBlockIndex * pindexNew, BOOL fWriteDisk)
{
    // Найти вилы
    CBlockIndex * pfork = pindexBest;
    CBlockIndex * plonger = pindexNew;
    в то время как (pfork! = plonger)
    {
        если (! (pfork = pfork->pprev))
            вернуться ложным;
        в то время как (plonger->nHeight > pfork->nHeight)
            если (! (plonger = plonger->pprev))
                вернуться ложным;
    }

    // Список чем отсоединять
    вектор vDisconnect;
    для (CBlockIndex * pindex = pindexBest; pindex = pfork;! pindex = pindex->pprev)
        vDisconnect.push_back (pindex);

    // Список того, что для подключения
    вектор vConnect;
    для (CBlockIndex * pindex = pindexNew; pindex = pfork;! pindex = pindex->pprev)
        vConnect.push_back (pindex);
    задний ход (vConnect.begin (), vConnect.end ());

    // Претест REORG
    если (fWriteDisk)
    {
        CTxDB txdb ("р");
        карта mapTestPool;

        Еогеасп (CBlockIndex * pindex, vDisconnect)
            если (! pindex->TestDisconnectBlock (txdb, mapTestPool))
                вернуться ложным;

        BOOL fValid = TRUE;
        Еогеасп (CBlockIndex * pindex, vConnect)
        {
            fValid = fValid && pindex->TestConnectBlock (txdb, mapTestPool);
            если (! fValid)
            {
                // Invalid блок, удалить остальную часть этой отрасли
                CBlock блок;
                block.ReadFromDisk (pindex, ложь);
                pindex->EraseBlockFromDisk ();
                mapBlockIndex.erase (block.GetHash ());
                удалить pindex;
            }
        }
        если (! fValid)
            вернуться ложным;
    }

    // Отключить короткую ветвь
    Еогеасп (CBlockIndex * pindex, vDisconnect)
    {
        если (fWriteDisk && ! pindex->DisconnectBlock ())
            вернуться ложным;
        если (pindex->pprev)
            pindex->pprev->pnext = NULL;
    }

    // Подключаем длинную ветку
    Еогеасп (CBlockIndex * pindex, vConnect)
    {
        если (fWriteDisk && ! pindex->ConnectBlock ())
            вернуться ложным;
        если (pindex->pprev)
            pindex->pprev->pnext = pindex;
    }

    возвращает истину;
}


BOOL CBlock :: AddToBlockIndex (неподписанных INT nFile неподписанные INT nBlockPos, BOOL fWriteDisk)
{
    uint256 хэш = GetHash ();

    // Добавить блокировать индекс
    CBlockIndex * pindexNew = новый CBlockIndex (nFile, nBlockPos);
    если (! pindexNew)
        вернуться ложным;
    mapBlockIndex [хэш] = pindexNew;
    карта:: итератора миль = mapBlockIndex.find (hashPrevBlock);
    если (мили! = mapBlockIndex.end ())
    {
        pindexNew->pprev = (* миля) .second;
        pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
    }

    // Новый лучший
    если (pindexNew->nHeight > nBestHeight)
    {
        если (pindexGenesisBlock == NULL && Хэш == hashGenesisBlock)
        {
            pindexGenesisBlock = pindexNew;
        }
        иначе если (hashPrevBlock == hashTimeChainBest)
        {
            // Добавление к текущей лучшей отрасли
            если (fWriteDisk)
                если (! pindexNew->ConnectBlock ())
                    вернуться ложным;
            pindexNew->pprev->pnext = pindexNew;
        }
        еще
        {
            // Новый лучший филиал
            если (! Реорганизовать (pindexNew, fWriteDisk))
                вернуться ложным;
        }

        // Новая лучшая ссылка
        nBestHeight = pindexNew->nHeight;
        hashTimeChainBest = хэш;
        pindexBest = pindexNew;
        nTransactionsUpdated ++;

        // Релейный бумажник операция, которые не получили в еще
        если (fWriteDisk && NTime > GetAdjustedTime () - 30 * 60)
            RelayWalletTransactions ();
    }

    MainFrameRepaint ();
    возвращает истину;
}





шаблон<имяТипа поток>
BOOL ScanMessageStart (Stream& s)
{
    // Сканирование вперед к следующему pchMessageStart, которые обычно должны быть немедленно
    // в указатель файла. Листья указатель файла на конец pchMessageStart.
    s.clear (0);
    Короче говоря prevmask = s.exceptions (0);
    Const символ * р = НАЧАТЬ (pchMessageStart);
    пытаться
    {
        петля
        {
            символ с;
            s.read (&с, 1);
            если (s.fail ())
            {
                s.clear (0);
                s.exceptions (prevmask);
                вернуться ложным;
            }
            если (* р! = с)
                р = НАЧАТЬ (pchMessageStart);
            если (* р == с)
            {
                если (++ р == END (pchMessageStart))
                {
                    s.clear (0);
                    s.exceptions (prevmask);
                    возвращает истину;
                }
            }
        }
    }
    поймать (...)
    {
        s.clear (0);
        s.exceptions (prevmask);
        вернуться ложным;
    }
}

FILE * OpenBlockFile (неподписанных INT nFile неподписанные INT nBlockPos, Const символ * pszMode)
{
    если (nFile == -1)
        возвращать NULL;
    FILE * файл = Еореп (strprintf ("BLK% 04d.dat", NFile) .c_str (), pszMode);
    если (! файл)
        возвращать NULL;
    если (nBlockPos! = 0 && ! Strchr (pszMode, 'а') && ! Strchr (pszMode, 'ж'))
    {
        если (FSEEK (файл, nBlockPos, SEEK_SET)! = 0)
        {
            fclose (файл);
            возвращать NULL;
        }
    }
    вернуть файл;
}

статический беззнаковый INT nCurrentBlockFile = 1;

FILE * AppendBlockFile (беззнаковое целочисленное значение& nFileRet)
{
    nFileRet = 0;
    петля
    {
        FILE * файл = OpenBlockFile (nCurrentBlockFile, 0, "аб");
        если (! файл)
            возвращать NULL;
        если (FSEEK (файл, 0, SEEK_END)! = 0)
            возвращать NULL;
        // FAT32 размер файла не более 4 Гб, FSEEK и ftell макс 2 Гб, так что мы должны оставаться под 2 Гб
        если (ftell (файл) < 0x7F000000 - MAX_SIZE)
        {
            nFileRet = nCurrentBlockFile;
            вернуть файл;
        }
        fclose (файл);
        nCurrentBlockFile ++;
    }
}

BOOL LoadBlockIndex (BOOL fAllowNew)
{
    //
    // Загрузка с диска
    //
    для (nCurrentBlockFile = 1 ;; nCurrentBlockFile ++)
    {
        CAutoFile filein = OpenBlockFile (nCurrentBlockFile, 0, "Р.Б.");
        если (filein == NULL)
        {
            если (nCurrentBlockFile > 1)
            {
                nCurrentBlockFile--;
                ломать;
            }
            если (! fAllowNew)
                вернуться ложным;

            //// отладки
            // Генезис Блок:
            // GetHash () = 0x000006b15d1327d67e971d1de9116bd60a3a01556c91b6ebaa416ebc0cfaa646
            // hashPrevBlock = 0x0000000000000000000000000000000000000000000000000000000000000000
            // hashMerkleRoot = 0x769a5e93fac273fd825da42d39ead975b5d712b2d50953f35a4fdebdec8083e3
            // txNew.vin [0] .scriptSig = 247422313
            // txNew.vout [0] = 10000 .nValue
            // txNew.vout [0] = .scriptPubKey OP_CODESEPARATOR 0x31D18A083F381B4BDE37B649AACF8CD0AFD88C53A3587ECDB7FAF23D449C800AF1CE516199390BFE42991F10E7F5340F2A63449F0B639A7115C667E5D7B051D404 OP_CHECKSIG
            // NTime = 1221069728
            // Nbits = 20
            // nNonce = 141755
            // CBlock (hashPrevBlock = 000000, hashMerkleRoot = 769a5e, Ntime = 1221069728, Nbits = 20, nNonce = 141 755, VTX = 1)
            // CTransaction (vin.size = 1, vout.size = 1, nLockTime = 0)
            // CTxIn (COutPoint (000000, -1), coinbase 04695dbf0e)
            // CTxOut (nValue = 10000, nSequence = 4294967295, scriptPubKey = 51b0, posNext = нуль)
            // vMerkleTree: 769a5e

            // Генезис блок
            CTransaction txNew;
            txNew.vin.resize (1);
            txNew.vout.resize (1);
            txNew.vin [0] = .scriptSig CScript () << 247422313;
            txNew.vout [0] .nValue = 10000;
            txNew.vout [0] = .scriptPubKey CScript () << OP_CODESEPARATOR << CBigNum ("0x31D18A083F381B4BDE37B649AACF8CD0AFD88C53A3587ECDB7FAF23D449C800AF1CE516199390BFE42991F10E7F5340F2A63449F0B639A7115C667E5D7B051D404") << OP_CHECKSIG;
            CBlock блок;
            block.vtx.push_back (txNew);
            block.hashPrevBlock = 0;
            block.hashMerkleRoot = block.BuildMerkleTree ();
            block.nTime = 1221069728;
            block.nBits = 20;
            block.nNonce = 141755;

                //// отладки печати
                Е ("% S \ п", Block.GetHash () ToString () c_str ())..;
                Е ("% S \ п", Block.hashMerkleRoot.ToString () c_str ()).
                Е ("% S \ п", HashGenesisBlock.ToString () c_str ()).
                txNew.vout [0] .scriptPubKey.print ();
                block.print ();
                утверждать (block.hashMerkleRoot == uint256 ("0x769a5e93fac273fd825da42d39ead975b5d712b2d50953f35a4fdebdec8083e3"));

            утверждают (block.GetHash () == hashGenesisBlock);

            // Начинаем новый блок файла
            неподписанных INT nFile;
            неподписанных INT nBlockPos;
            если (! block.WriteToDisk (правда, nFile, nBlockPos))
                вернуться ложным;
            если (! block.AddToBlockIndex (nFile, nBlockPos, правда))
                вернуться ложным;
            ломать;
        }

        INT nFilesize = GetFileSize (filein);
        если (nFilesize == -1)
            вернуться ложным;
        filein.nType | = SER_BLOCKHEADERONLY;

        в то время как (ScanMessageStart (filein))
       
            // заголовок индекса Read
            неподписанных INT nРазмер:;
            filein >> nРазмер:;
            если (nРазмер: > MAX_SIZE
    }
    возвращает истину;
}



аннулированию PrintTimechain ()
{
    // структура дерева предвычисления
    карта > mapNext;
    для (показать на карте:: итератор мили = mapBlockIndex.begin (); миль = mapBlockIndex.end (!); ++ мили)
    {
        CBlockIndex * pindex = (* мили) .second;
        mapNext [pindex->pprev] .push_back (pindex);
        // контрольная работа
        // в то время как (RAND ()% 3 == 0)
        // mapNext [pindex->pprev] .push_back (pindex);
    }

    вектор<пара<ИНТ, CBlockIndex *> > vStack;
    vStack.push_back (make_pair (0, pindexGenesisBlock));

    INT nPrevCol = 0;
    в то время как (! vStack.empty ())
    {
        INT Ncol = vStack.back () сначала.
        CBlockIndex * pindex = vStack.back () второй.
        vStack.pop_back ();

        // раскол печати или разрыв
        если (Ncol > nPrevCol)
        \\\ п");
       
        иначе если (Ncol < nPrevCol)
        ");
            Е ("
        nPrevCol = Ncol;

        // столбцы печати
        для (INT I = 0; я < Ncol; я ++)
            Е ("| ");

        // элемент печати
        Е ("% D (% и,% и) \ п", pindex->nHeight, pindex->nFile, pindex->nBlockPos);

        // помещаем главный timechain первый
        вектор& vNext = mapNext [pindex];
        для (INT I = 0; я < vNext.size (); я ++)
        {
            если (vNext [I] ->pnext)
            {
                подкачки (vNext [0], vNext [I]);
                ломать;
            }
        }

        // Итерация детей
        для (INT I = 0; я < vNext.size (); я ++)
            vStack.push_back (make_pair (Ncol + I, vNext [I]));
    }
}






BOOL CBlock :: CheckBlock () Const


BOOL CBlock :: AcceptBlock ()
{
    // Проверка дубликатов
    uint256 хэш = GetHash ();
    если (mapBlockIndex.count (хэш))
        вернуться ложным;

    // Получает указатель предыдущей блок
    карта:: итератора миль = mapBlockIndex.find (hashPrevBlock);
    если (мили == mapBlockIndex.end ())
        вернуться ложным;
    CBlockIndex * pindexPrev = (* мили) .second;

    // Проверяем метки против пред
    CBlock blockPrev;
    если (! blockPrev.ReadFromDisk (pindexPrev, ложь))
        вернуться ложным;
    если (NTime <= BlockPrev.nTime)
        вернуться ложным;

    // Проверяем доказательство работы
    если (Nbits! = GetNextWorkRequired (pindexPrev))
        вернуться ложным;

    // Проверка входов транзакций и проверки подписей
    {
        CTxDB txdb ("р");
        карта mapTestPool;
        BOOL fIgnoreDiskConflicts = (! hashPrevBlock = hashTimeChainBest);
        Int64 nFees = 0;
        Еогеасп (CTransaction& ТХ, VTX)
            если (! tx.TestConnectInputs (txdb, mapTestPool, ложные, fIgnoreDiskConflicts, nFees))
                возвращать ошибку ("AcceptBlock (): TestConnectInputs не удалось");
        если (VTX [0] .GetValueOut ()! = GetBlockValue (nFees))
            вернуться ложным;
    }

    // Записывает блок в файл история
    неподписанных INT nFile;
    неподписанных INT nBlockPos;
    если (! WriteToDisk (! fClient, nFile, nBlockPos))
        вернуться ложным;
    если (! AddToBlockIndex (nFile, nBlockPos, правда))
        вернуться ложным;

    если (hashTimeChainBest == хэш)
        RelayInventory (CINV (MSG_BLOCK, хэш));

    // Добавить атомы отзывов пользователей для монет, созданных
    вектор<неподписанные символ> vchPubKey;
    если (ExtractPubKey (VTX [0] .vout [0] .scriptPubKey, ложь, vchPubKey))
    {
        UInt64 nRand = 0;
        RAND_bytes ((неподписанные символ *)&nRand, SizeOf (nRand));
        без знака короткого nAtom = nRand% (USHRT_MAX - 100) + 100;
        вектор<беззнаковое короткое> vAtoms (1, nAtom);
        AddAtomsAndPropagate (Хэш (vchPubKey.begin (), vchPubKey.end ()), vAtoms, правда);
    }

    возвращает истину;
}

BOOL ProcessBlock (CNode * pfrom, CBlock * pblock)
{
    // Проверка дубликатов
    uint256 хэш = pblock->GetHash ();
    если (mapBlockIndex.count (хэш) || mapOrphanBlocks.count (хэш))
        вернуться ложным;

    // Предварительные проверки
    если (! pblock->CheckBlock ())
    {
        Е ("CheckBlock FAILED \ п");
        удалить pblock;
        вернуться ложным;
    }

    // Если еще не имеет свой предыдущий блока, шунтирующий его холдинг области, пока мы не получим его
    если (! mapBlockIndex.count (pblock->hashPrevBlock))
    {
        mapOrphanBlocks.insert (make_pair (хэш, pblock));
        mapOrphanBlocksByPrev.insert (make_pair (pblock->hashPrevBlock, pblock));

        // Спросите этого парня, чтобы заполнить то, что нам не хватает
        если (pfrom)
            pfrom->PushMessage ("getblocks", CBlockLocator (pindexBest), GetOrphanRoot (pblock));
        возвращает истину;
    }

    // Сохранить на диск
    если (! pblock->AcceptBlock ())
    {
        Е ("AcceptBlock FAILED \ п");
        удалить pblock;
        вернуться ложным;
    }
    удалить pblock;

    // Теперь обработаем все бесхозные блоки, которые зависели на этом
    для (Multimap:: итератор мили = mapOrphanBlocksByPrev.lower_bound (хэш);
         ми = mapOrphanBlocksByPrev.upper_bound (хэш!);
         ++мили)
    {
        CBlock * pblockOrphan = (* мили) .second;
        pblockOrphan->AcceptBlock ();
        mapOrphanBlocks.erase (pblockOrphan->GetHash ());
        удалить pblockOrphan;
    }
    mapOrphanBlocksByPrev.erase (хэш);

    возвращает истину;
}

[/ Предварительно]
Cryddit сейчас офлайн Пожаловаться на Cryddit   Ответить с цитированием Мультицитирование сообщения от Cryddit Быстрый ответ на сообщение Cryddit

23 декабря 2013, 7:33:53 PM   # 4
 
 
Сообщения: 840
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Это вторая половина main.cpp. 

Код:





////////////////////////////////////////////////// ////////////////////////////
//
// Сообщения
//


BOOL AlreadyHave (Const CINV& и)
{
    Переключатель (inv.type)
   
    // Не знаю, что это такое, просто сказать, что мы уже получили один
    возвращает истину;
}







BOOL ProcessMessages (CNode * pfrom)
{
    CDataStream& vRecv = pfrom->vRecv;
    если (vRecv.empty ())
        возвращает истину;
    Е ("ProcessMessages (% d байт) \ П", VRecv.size ());

    //
    // Формат сообщения
    // (4) сообщение о начале
    Команда // (12)
    // (4) размер
    // данные (х)
    //

    петля
    {
        // Проверка на начало сообщения
        CDataStream :: итератор PSTART = поиск (vRecv.begin (), vRecv.end (), НАЧАТЬ (pchMessageStart), END (pchMessageStart));
        если (vRecv.end () - PSTART < SizeOf (CMessageHeader))
        {
            если (vRecv.size () > SizeOf (CMessageHeader))
            {
                Е ("\ П \ nPROCESSMESSAGE MESSAGESTART НЕ НАЙДЕНО \ п \ п");
                vRecv.erase (vRecv.begin (), vRecv.end () - SizeOf (CMessageHeader));
            }
            ломать;
        }
        если (PSTART - vRecv.begin () > 0)
            Е ("\ N \ nPROCESSMESSAGE SKIPPED% D БАЙТОВ \ N \ N", PSTART - vRecv.begin ());
        vRecv.erase (vRecv.begin (), PSTART);

        // Читаем заголовок
        CMessageHeader HDR;
        vRecv >> HDR;
        если (! hdr.IsValid ())
        {
            Е ("\ п \ nPROCESSMESSAGE: ОШИБКИ В ЗАГОЛОВОК% s \ п \ п \ п", Hdr.GetCommand () c_str ()).
            Продолжать;
        }
        Строка strCommand = hdr.GetCommand ();

        // Размер сообщения
        неподписанных INT nMessageSize = hdr.nMessageSize;
        если (nMessageSize > vRecv.size ())
        {
            // Перемотка и ждать остальных сообщений
            ///// нужен механизм, чтобы отказаться от ожидая ошибки размера сверхдолгого сообщения
            Е ("ПОСЛАНИЕ-BREAK 2 \ п");
            vRecv.insert (vRecv.begin (), НАЧАТЬ (ДРЧ), КОНЕЦ (ДРЧ));
            ломать;
        }

        // Копировать сообщение в свой собственный буфер
        CDataStream vMsg (vRecv.begin (), vRecv.begin () + nMessageSize, vRecv.nType, vRecv.nVersion);
        vRecv.ignore (nMessageSize);

        // сообщение процесса
        BOOL ладу = ложь;
        пытаться
        {
            ладу = ProcessMessage (pfrom, strCommand, vMsg);
        }
        CATCH_PRINT_EXCEPTION ("ProcessMessage ()")
        если (! ладу)
            Е ("ProcessMessage (% s,% d байт) от% S в% S \ N FAILED", StrCommand.c_str (), nMessageSize, pfrom->.. Addr.ToString () c_str (), addrLocalHost.ToString () c_str ());
    }

    vRecv.Compact ();
    возвращает истину;
}




BOOL ProcessMessage (CNode * pfrom, строка strCommand, CDataStream& vRecv)
{
    статическая карта<неподписанных INT, вектор<неподписанные символ> > mapReuseKey;
    CheckForShutdown (2);
    Е ("получен:% -12s (% d байт)  ", StrCommand.c_str (), vRecv.size ());
    для (INT I = 0; я < мин (vRecv.size (), (без знака целое) 25); я ++)
        Е ("% 02x ", VRecv [я] & 0xff);
    Е ("\ п");


    если (strCommand == "версия")
    {
        // Можно сделать только один раз
        если (pfrom->nVersion! = 0)
            вернуться ложным;

        неподписанных INT NTime;
        vRecv >> pfrom->nVersion >> pfrom->nServices >> NTime;
        если (pfrom->nVersion == 0)
            вернуться ложным;

        pfrom->vSend.SetVersion (мин (pfrom->nVersion, версия));
        pfrom->vRecv.SetVersion (мин (pfrom->nVersion, версия));

        pfrom->fClient =! (pfrom->nServices & NODE_NETWORK);
        если (pfrom->fClient)
        = SER_BLOCKHEADERONLY;
       

        AddTimeData (pfrom->addr.ip, Ntime);

        // Задать первый подключенный узел для обновления блока
        статический BOOL fAskedForBlocks;
        если (! fAskedForBlocks && ! pfrom->fClient)
        {
            fAskedForBlocks = TRUE;
            pfrom->PushMessage ("getblocks", CBlockLocator (pindexBest), uint256 (0));
        }
    }


    иначе если (pfrom->nVersion == 0)
    {
        // Должно быть сообщение о версии, прежде чем что-либо еще
        вернуться ложным;
    }


    иначе если (strCommand == "адр")
    {
        вектор vAddr;
        vRecv >> vAddr;

        // Сохраняем новые адреса
        CAddrDB addrdb;
        Еогеасп (Const CAddress& адр, vAddr)
        {
            если (AddAddress (addrdb, адр))
            {
                // Помещаем в списки для отправки на другие узлы
                pfrom->setAddrKnown.insert (адрес);
                CRITICAL_BLOCK (cs_vNodes)
                    Еогеасп (CNode * pnode, vNodes)
                        если (! pnode->setAddrKnown.count (адрес))
                            pnode->vAddrToSend.push_back (адрес);
            }
        }
    }


    иначе если (strCommand == "фактура")
    {
        вектор VINV;
        vRecv >> VINV;

        Еогеасп (Const CINV& и, VINV)
        {
            Е ("  получил инвентарный:% s% s \ п", Inv.ToString (). C_str (), AlreadyHave (и)? "иметь" : "новый");

            CRITICAL_BLOCK (pfrom->cs_inventory)
                pfrom->setInventoryKnown.insert (INV);

            если (! AlreadyHave (и))
                pfrom->AskFor (INV);
            иначе если (inv.type == MSG_BLOCK && mapOrphanBlocks.count (inv.hash))
                pfrom->PushMessage ("getblocks", CBlockLocator (pindexBest), GetOrphanRoot (mapOrphanBlocks [inv.hash]));
        }
    }


    иначе если (strCommand == "получить данные")
    {
        вектор VINV;
        vRecv >> VINV;

        Еогеасп (Const CINV& и, VINV)
        {
            Е ("получил GetData для:% s \ п", Inv.ToString () c_str ()).

            если (inv.type == MSG_BLOCK)
            {
                // Отправить блок с диска
                карта:: итератор мили = mapBlockIndex.find (inv.hash);
                если (мили! = mapBlockIndex.end ())
                {
                    CBlock блок;
                    block.ReadFromDisk ((* мили) .second,! pfrom->fClient);
                    pfrom->PushMessage ("блок", Блок);
                }
            }
            иначе если (inv.IsKnownType ())
            {
                // Отправить поток из памяти реле
                CRITICAL_BLOCK (cs_mapRelay)
                {
                    карта:: итератор мили = mapRelay.find (INV);
                    если (миль! = mapRelay.end ())
                        pfrom->PushMessage (inv.GetCommand (), (* мили) .second);
                }
            }
        }
    }


    иначе если (strCommand == "getblocks")
    {
        CBlockLocator локатор;
        uint256 hashStop;
        vRecv >> локатор >> hashStop;

        // Найти первый блок звонящий имеет в основной цепи
        CBlockIndex * pindex = locator.GetBlockIndex ();

        // Отправляем остальную часть цепи
        если (pindex)
            pindex = pindex->pnext;
        (для; pindex; pindex = pindex->pnext)
        {
            CBlock блок;
            block.ReadFromDisk (pindex,! pfrom->fClient);
            если (block.GetHash () == hashStop)
                ломать;
            pfrom->PushMessage ("блок", Блок);
        }
    }


    иначе если (strCommand == "getmywtxes")
    {
        CBlockLocator локатор;
        вектор vPubKeyHashes;
        vRecv >> локатор >> vPubKeyHashes;

        // Поиск новых сделок владельца
        INT nHeight = locator.GetHeight ();
        CTxDB txdb ("р");
        Еогеасп (uint160 hash160, vPubKeyHashes)
        {
            вектор VTX;
            если (txdb.ReadOwnerTxes (hash160, nHeight, VTX))
            {
                Еогеасп (Const CTransaction& ТХ, VTX)
                {
                    // Обновление сделки с полной поддержкой CWalletTx
                    CWalletTx WTX (ТХ);
                    wtx.AddSupportingTransactions (txdb);

                    pfrom->PushMessage ("WTX", WTX);
                }
            }
        }
    }


    иначе если (strCommand == "WTX")
    {
        CWalletTx WTX;
        vRecv >> WTX;

        если (! wtx.AcceptWalletTransaction ())
            возвращать ошибку ("Сообщение WTX: AcceptWalletTransaction не удалось!");
        AddToWallet (WTX);
    }


    иначе если (strCommand == "Техас")
    {
        CDataStream vMsg (vRecv);
        CTransaction ТХ;
        vRecv >> ТХ;

        CINV INV (MSG_TX, tx.GetHash ());
        pfrom->AddInventoryKnown (INV);

        если (tx.AcceptTransaction ())
        {
            AddToWalletIfMine (ТХ, NULL);
            RelayMessage (INV, vMsg);
            mapAlreadyAskedFor.erase (INV);
        }
    }


    иначе если (strCommand == "блок")
    {
        auto_ptr pblock (новый CBlock);
        vRecv >> * Pblock;

        //// отладки печати
        Е ("принятый блок: \ п"); pblock->Распечатать();

        CINV и (MSG_BLOCK, pblock->GetHash ());
        pfrom->AddInventoryKnown (INV);

        если (ProcessBlock (pfrom, pblock.release ()))
            mapAlreadyAskedFor.erase (INV);
    }


    иначе если (strCommand == "getaddr")
    {
        pfrom->vAddrToSend.clear ();
        //// необходимо расширить диапазон времени, если не достаточно найдены
        Int64 nТак как = GetAdjustedTime () - 60 * 60; // в последний час
        CRITICAL_BLOCK (cs_mapAddresses)
        {
            Еогеасп (Const PAIRTYPE (вектор<неподписанные символ>, CAddress)& пункт, mapAddresses)
            {
                Const CAddress& адр = item.second;
                если (addr.nTime > nТак как)
                    pfrom->vAddrToSend.push_back (адрес);
            }
        }
    }


    иначе если (strCommand == "checkorder")
    {
        uint256 hashReply;
        CWalletTx заказ;
        vRecv >> hashReply >> заказ;

        /// у нас есть возможность проверить заказ здесь

        // Продолжайте давать один и тот же ключ к тому же IP, пока они не используют его
        если (! mapReuseKey.count (pfrom->addr.ip))
            mapReuseKey [pfrom->addr.ip] = GenerateNewKey ();

        // Отправляет обратно утверждение порядка и Публичный использовать
        CScript scriptPubKey;
        scriptPubKey << OP_CODESEPARATOR << mapReuseKey [pfrom->addr.ip] << OP_CHECKSIG;
        pfrom->PushMessage ("Ответить", HashReply, (INT) 0, scriptPubKey);
    }


    иначе если (strCommand == "подтвердить заказ")
    {
        uint256 hashReply;
        CWalletTx wtxNew;
        vRecv >> hashReply >> wtxNew;

        // Broadcast
        если (! wtxNew.AcceptWalletTransaction ())
        {
            pfrom->PushMessage ("Ответить", HashReply, (INT) 1);
            возвращать ошибку ("submitorder AcceptWalletTransaction () не удалось, возвращая ошибку 1");
        }
        AddToWallet (wtxNew);
        wtxNew.RelayWalletTransaction ();
        mapReuseKey.erase (pfrom->addr.ip);

        // Отправить обратно подтверждение
        pfrom->PushMessage ("Ответить", HashReply, (INT) 0);
    }


    иначе если (strCommand == "Ответить")
    {
        uint256 hashReply;
        vRecv >> hashReply;

        CRequestTracker трекер;
        CRITICAL_BLOCK (pfrom->cs_mapRequests)
        {
            карта:: итератор миль = pfrom->mapRequests.find (hashReply);
            если (ми! = pfrom->mapRequests.end ())
            {
                трекер = (* мили) .second;
                pfrom->mapRequests.erase (ми);
            }
        }
        если (! tracker.IsNull ())
            tracker.fn (tracker.param1, vRecv);
    }


    еще
    {
        // Игнорировать неизвестные команды для расширяемости
        Е ("ProcessMessage (% s): Игнорируется неизвестное сообщение \ п", StrCommand.c_str ());
    }


    если (! vRecv.empty ())
        Е ("ProcessMessage (% s):% d дополнительные байты \ п", StrCommand.c_str (), vRecv.size ());

    возвращает истину;
}









BOOL SendMessages (CNode * ВОМ)
{
    CheckForShutdown (2);

    // Не посылать ничего, пока мы не получим их версию сообщений
    если (pto->nVersion == 0)
        возвращает истину;


    //
    // Сообщение: адр
    //
    вектор vAddrToSend;
    vAddrToSend.reserve (pto->vAddrToSend.size ());
    Еогеасп (Const CAddress& адр, pto->vAddrToSend)
        если (! pto->setAddrKnown.count (адрес))
            vAddrToSend.push_back (адрес);
    pto->vAddrToSend.clear ();
    если (! vAddrToSend.empty ())
        pto->PushMessage ("адр", VAddrToSend);


    //
    // Сообщение: инвентарь
    //
    вектор vInventoryToSend;
    CRITICAL_BLOCK (pto->cs_inventory)
    {
        vInventoryToSend.reserve (pto->vInventoryToSend.size ());
        Еогеасп (Const CINV& и, pto->vInventoryToSend)
            если (! pto->setInventoryKnown.count (INV))
                vInventoryToSend.push_back (INV);
        pto->vInventoryToSend.clear ();
    }
    если (! vInventoryToSend.empty ())
        pto->PushMessage ("фактура", VInventoryToSend);


    //
    // Сообщение: GetData
    //
    вектор vAskFor;
    Int64 NNow = GetTime ();
    в то время как (! pto->mapAskFor.empty () && (* Pto->mapAskFor.begin ()). первый <= NNow)
    {
        Const CINV& и = (* pto->mapAskFor.begin ()) второй.
        Е ("GetData% s \ п", Inv.ToString () c_str ()).
        если (! AlreadyHave (и))
            vAskFor.push_back (INV);
        pto->mapAskFor.erase (pto->mapAskFor.begin ());
    }
    если (! vAskFor.empty ())
        pto->PushMessage ("получить данные", VAskFor);



    возвращает истину;
}














////////////////////////////////////////////////// ////////////////////////////
//
// BitcoinMiner
//

Int FormatHashBlocks (пустое * пиксельный буфер, беззнаковое целочисленное значение LEN)
{
    неподписанный символ * PDATA = (неподписанный символ *) пиксельный буфер;
    без знака INT блоков = 1 + ((Len + 8) / 64);
    неподписанные символ * PEND = PDATA + 64 * блоки;
    MemSet (PDATA + LEN, 0, 64 * блоки - LEN);
    PDATA [Len] = 0x80;
    беззнаковое целочисленное значение бит = Len * 8;
    PEND [-1] = (биты >> 0) & 0xff;
    PEND [-2] = (биты >> 8) & 0xff;
    PEND [-3] = (биты >> 16) & 0xff;
    PEND [-4] = (биты >> 24) & 0xff;
    возвращать блоки;
}

используя CryptoPP :: ByteReverse;
статические INT detectlittleendian = 1;

аннулированию BlockSHA256 (сопзЬ пустота * контактный, неподписанные INT nBlocks, недействительным * выпячивание)
{
    беззнаковое INT * Pinput = (беззнаковое INT *) контактный;
    неподписанных INT * pstate = (беззнаковое INT *) выпячивание;

    CryptoPP :: SHA256 :: InitState (pstate);

    если (* (символ *)&detectlittleendian! = 0)
    {
        для (Int N = 0; п < nBlocks; п ++)
        {
            беззнаковое INT pbuf [16];
            для (INT I = 0; я < 16; я ++)
                pbuf [I] = ByteReverse (Pinput [п * 16 + I]);
            CryptoPP :: SHA256 :: Transform (pstate, pbuf);
        }
        для (INT I = 0; я < 8; я ++)
            pstate [I] = ByteReverse (pstate [I]);
    }
    еще
    {
        для (Int N = 0; п < nBlocks; п ++)
            CryptoPP :: SHA256 :: Transform (pstate, Pinput + п * 16);
    }
}


BOOL BitcoinMiner ()
{
    Е ("BitcoinMiner начал \ п");

    SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_LOWEST);



    CBlock blockPrev;
    в то время как (fGenerateBitcoins)
    {
        CheckForShutdown (3);

        //
        // Создать coinbase ТХ
        //
        CTransaction txNew;
        txNew.vin.resize (1);
        txNew.vin [0] .prevout.SetNull ();
        CBigNum bnNonce; // это одноразовое значение так несколько процессов, работающих на одной и той же keyUser
        BN_rand_range (&bnNonce, &CBigNum (INT_MAX)); // не покрывают ту же землю
        txNew.vin [0] .scriptSig << bnNonce;
        txNew.vout.resize (1);
        txNew.vout [0] .scriptPubKey << OP_CODESEPARATOR << keyUser.GetPubKey () << OP_CHECKSIG;
        txNew.vout [0] .posNext.SetNull ();


        //
        // Создать новый блок
        //
        auto_ptr pblock (новый CBlock ());
        если (! pblock.get ())
            вернуться ложным;

        // Добавляем наш coinbase ТХ в качестве первой сделки
        pblock->vtx.push_back (txNew);

        // Собрать последние транзакции в блок
        неподписанных INT nTransactionsUpdatedLast = nTransactionsUpdated;
        Int64 nFees = 0;
        CRITICAL_BLOCK (cs_mapTransactions)
        {
            CTxDB txdb ("р");
            задавать setInThisBlock;
            вектор<голец> vfAlreadyAdded (mapTransactions.size ());
            BOOL fFoundSomething = TRUE;
            беззнаковое INT nРазмер: = 0;
            в то время как (fFoundSomething && nРазмер: < MAX_SIZE / 2)
            {
                fFoundSomething = ложь;
                без знака Int N = 0;
                для (показать на карте:: итератор мили = mapTransactions.begin (); миль = mapTransactions.end (!); ++ ми, ++, п)
                {
                    если (vfAlreadyAdded [п])
                        Продолжать;
                    CTransaction& Тх = (* мили) .second;
                    если (! tx.IsFinal () || tx.IsCoinBase ())
                        Продолжать;

                    // Найти, если все зависимости в той или предыдущих блоков
                    BOOL fHaveAllPrev = TRUE;
                    Int64 nValueIn = 0;
                    Еогеасп (Const CTxIn& txin, tx.vin)
                    {
                        COutPoint prevout = txin.prevout;
                        CTransaction txPrev;
                        если (setInThisBlock.count (prevout.hash))
                        {
                            txPrev = mapTransactions [prevout.hash];
                        }
                        иначе если (! txdb.ReadDiskTx (prevout.hash, txPrev))
                        {
                            fHaveAllPrev = ложь;
                            ломать;
                        }
                        если (prevout.n >= TxPrev.vout.size ())
                        {
                            fHaveAllPrev = ложь;
                            ломать;
                        }
                        nValueIn + = txPrev.vout [prevout.n] .nValue;
                    }
                    Int64 nTransactionFee = nValueIn - tx.GetValueOut ();
                    если (nTransactionFee < 0) // может потребовать плату TX здесь
                        Продолжать;

                    // Добавить ТХ блокировать
                    если (fHaveAllPrev)
                    {
                        fFoundSomething = TRUE;
                        pblock->vtx.push_back (ТХ);
                        nРазмер: + = :: GetSerializeSize (ТХ, SER_NETWORK);
                        nFees + = nTransactionFee;
                        vfAlreadyAdded [п] = TRUE;
                        setInThisBlock.insert (tx.GetHash ());
                    }
                }
            }
        }

        // Обновление последние несколько вещей
        pblock->VTX [0] .vout [0] = .nValue GetBlockValue (nFees);
        pblock->hashMerkleRoot = pblock->BuildMerkleTree ();


        Е ("\ N \ nRunning BitcoinMiner с% D операций в блоке \ п", pblock->vtx.size ());


        //
        // Prebuild хэш-буфер
        //
        структура unnamed1
        {
            структура unnamed2
            {
                uint256 hashPrevBlock;
                uint256 hashMerkleRoot;
                неподписанных INT NTime;
                неподписанных INT Nbits;
                неподписанных INT nNonce;
            }
            блок;
            символ без знака pchPadding0 [64];
            uint256 hash1;
            символ без знака pchPadding1 [64];
        }
        TMP;

        Const CBlockIndex * pindexPrev = pindexBest;
        tmp.block.hashPrevBlock = pblock->hashPrevBlock = hashTimeChainBest;
        tmp.block.hashMerkleRoot = pblock->hashMerkleRoot;

        // Получает время предыдущего блока
        если (pindexPrev)
        {
            если (blockPrev.GetHash ()! = pblock->hashPrevBlock)
                blockPrev.ReadFromDisk (pindexPrev, ложь);
            если (blockPrev.GetHash ()! = pblock->hashPrevBlock)
            {
                Е ("pindexBest и hashTimeChainBest из синхронизации \ п");
                Продолжать;
            }
        }
        tmp.block.nTime = pblock->Ntime = макс (blockPrev.nTime + 1, (беззнаковое целое) GetAdjustedTime ());
        tmp.block.nBits = pblock->Nbits = GetNextWorkRequired (pindexPrev);
        tmp.block.nNonce = 1;

        неподписанных INT nBlocks0 = FormatHashBlocks (&tmp.block, SizeOf (tmp.block));
        неподписанных INT nBlocks1 = FormatHashBlocks (&tmp.hash1, SizeOf (tmp.hash1));


        //
        // Поиск
        //
        uint256 hashTarget = (~ uint256 (0) >> pblock->Nbits);
        uint256 хэш;
        в то время как (nTransactionsUpdated == nTransactionsUpdatedLast)
        {
            BlockSHA256 (&tmp.block, nBlocks0, &tmp.hash1);
            BlockSHA256 (&tmp.hash1, nBlocks1, &хэш);

            если (хэш <= HashTarget)
            {
                pblock->nNonce = tmp.block.nNonce;
                утверждать (хэш == pblock->GetHash ());

                    //// отладки печати
                    Е ("BitcoinMiner: \ п");
                    Е ("supercoin найдено \ п хэша:% s \ ntarget:% s \ п", Hash.GetHex () c_str (), hashTarget.GetHex () c_str ())..;
                    pblock->Распечатать();

                // Процесс этот блок так же, как если бы мы получили от другого узла
                если (! ProcessBlock (NULL, pblock.release ()))
                    Е ("ОШИБКА в BitcoinMiner, ProcessBlock, блок не принял \ п");
                ломать;
            }

            // Обновление NTime каждые несколько секунд
            если ((++ tmp.block.nNonce & 0xFFFFF) == 0)
            {
                если (tmp.block.nNonce == 0)
                    ломать;
                tmp.block.nTime = pblock->Ntime = макс (blockPrev.nTime + 1, (беззнаковое целое) GetAdjustedTime ());
            }
        }
    }

    возвращает истину;
}


















////////////////////////////////////////////////// ////////////////////////////
//
// Действия
//


Int64 CountMoney ()
{
    Int64 Ntotal = 0;
    CRITICAL_BLOCK (cs_mapWallet)
    {
        для (показать на карте:: итератора он = mapWallet.begin (); это = mapWallet.end (!); ++ это)
       
    }
    вернуться Ntotal;
}



BOOL SelectCoins (Int64 nTargetValue, установите& setCoinsRet)
{
    setCoinsRet.clear ();

    // Список значений меньше, чем цели
    Int64 nLowestLarger = _I64_MAX;
    CWalletTx * pcoinLowestLarger = NULL;
    вектор<пара > VVALUE;
    Int64 nTotalLower = 0;

    CRITICAL_BLOCK (cs_mapWallet)
    {
        для (показать на карте:: итератора он = mapWallet.begin (); это = mapWallet.end (!); ++ это)
        {
            CWalletTx * pcoin = &(* Это) .second;
            если (! pcoin->IsFinal () || pcoin->fSpent)
                Продолжать;
            Int64 п = pcoin->GetCredit ();
            если (п < nTargetValue)
            {
                vValue.push_back (make_pair (п, pcoin));
                nTotalLower + = п;
            }
            иначе если (п == nTargetValue)
            {
                setCoinsRet.insert (pcoin);
                возвращает истину;
            }
            иначе если (п < nLowestLarger)
            {
                nLowestLarger = п;
                pcoinLowestLarger = pcoin;
            }
        }
    }

    если (nTotalLower < nTargetValue)
    {
        если (pcoinLowestLarger == NULL)
            вернуться ложным;
        setCoinsRet.insert (pcoinLowestLarger);
        возвращает истину;
    }

    // Решите сумму подмножества по стохастической аппроксимации
    сортировать (vValue.rbegin (), vValue.rend ());
    вектор<голец> vfIncluded;
    вектор<голец> vfBest (vValue.size (), правда);
    Int64 nBest = nTotalLower;

    для (Int НПДРад = 0; НПДРад < 1000 && nBest = nTargetValue!; СМЭТ ++)
    {
        vfIncluded.assign (vValue.size (), ложные);
        Int64 Ntotal = 0;
        для (INT I = 0; я < vValue.size (); я ++)
        {
            если (RAND ()% 2)
            {
                Ntotal + = VVALUE [I] .first;
                vfIncluded [I] = TRUE;
                если (Ntotal >= NTargetValue)
                {
                    если (Ntotal < nBest)
                    {
                        nBest = Ntotal;
                        vfBest = vfIncluded;
                    }
                    Ntotal - = VVALUE [I] .first;
                    vfIncluded [I] = FALSE;
                }
            }
        }
    }

    // Если следующая больше еще ближе, вернуть его
    если (pcoinLowestLarger && nLowestLarger - nTargetValue <= NBest - nTargetValue)
        setCoinsRet.insert (pcoinLowestLarger);
    еще
        для (INT I = 0; я < vValue.size (); я ++)
            если (vfBest [I])
                setCoinsRet.insert (VVALUE [я] .second);
    возвращает истину;
}



BOOL CreateTransaction (CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew)
{
    wtxNew.vin.clear ();
    wtxNew.vout.clear ();
    если (nValue < КОМИССИЯ НА ПЕРЕВОД)
        вернуться ложным;

    // Выбираем монеты для использования
    задавать setCoins;
    если (! SelectCoins (nValue, setCoins))
        вернуться ложным;
    Int64 nValueIn = 0;
    Еогеасп (CWalletTx * pcoin, setCoins)
        nValueIn + = pcoin->GetCredit ();

    // Заполнить Vout [0] получателю
    Int64 nValueOut = nValue - TRANSACTIONFEE;
    wtxNew.vout.push_back (CTxOut (nValueOut, scriptPubKey));

    // Заполнить Vout [1] обратно к себе с какими-либо изменениями
    если (nValueIn - TRANSACTIONFEE > nValueOut)
    {
        // Используйте один и тот же ключ, как один из монет
        вектор<неподписанные символ> vchPubKey;
        CTransaction& txFirst = * (* setCoins.begin ());
        Еогеасп (Const CTxOut& txout, txFirst.vout)
            если (txout.IsMine ())
                если (ExtractPubKey (txout.scriptPubKey, правда, vchPubKey))
                    ломать;
        если (vchPubKey.empty ())
            вернуться ложным;

        // Заполнить Vout [1] самим себе
        CScript scriptPubKey;
        scriptPubKey << OP_CODESEPARATOR << vchPubKey << OP_CHECKSIG;
        wtxNew.vout.push_back (CTxOut (nValueIn - TRANSACTIONFEE - nValueOut, scriptPubKey));
    }

    // Заполнить ВИНА
    Еогеасп (CWalletTx * pcoin, setCoins)
        для (Int Nout = 0; NOUT < pcoin->vout.size (); Нут ++)
            если (pcoin->Vout [NOUT] .IsMine ())
                SignSignature (* pcoin, Nout, wtxNew, -1, "все");

    // Заполнит vtxPrev путем копирования из предыдущих сделок vtxPrev
    wtxNew.AddSupportingTransactions ();

    // Добавить ПРД бумажник, потому что если он изменит это тоже наше,
    // иначе просто для истории транзакций.
    wtxNew.nTime = GetAdjustedTime ();
    AddToWallet (wtxNew);

    // Все старые монеты, как провел
    Еогеасп (CWalletTx * pcoin, setCoins)
    {
        pcoin->fSpent = TRUE;
        pcoin->Записать на диск();
        vWalletUpdated.push_back (make_pair (pcoin->GetHash (), ложные));
    }

    возвращает истину;
}



BOOL SendMoney (CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew)
{
    если (! CreateTransaction (scriptPubKey, nValue, wtxNew))
        вернуться ложным;

    // Broadcast
    если (! wtxNew.AcceptTransaction ())
    {
        // Это не должно потерпеть неудачу. Сделка уже подписана и зарегистрирована.
        бросить runtime_error ("SendMoney (): wtxNew.AcceptTransaction () не удалось \ п");
        вернуться ложным;
    }
    wtxNew.RelayWalletTransaction ();

    возвращает истину;
}
[/ Предварительно]
Cryddit сейчас офлайн Пожаловаться на Cryddit   Ответить с цитированием Мультицитирование сообщения от Cryddit Быстрый ответ на сообщение Cryddit

23 декабря 2013, 7:35:15 PM   # 5
 
 
Сообщения: 840
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Это содержимое файла node.h.

Код:
// Copyright (с) 2008 Сатоси Накамото
//
// Разрешение Настоящим предоставляется бесплатно, любому лицу, приобретающему копию
// это программное обеспечение и связанные с ним файлы документации ( "Программного обеспечения"), иметь дело
// Программного обеспечения без ограничений, в том числе, без ограничения прав
// использовать, копировать, изменять, объединять, публиковать, распространять, сублицензировать и / или продавать
// копии программного обеспечения, а также разрешать лицам, которым данное программное обеспечение
// обставленная сделать так, при соблюдении следующих условий:
//
// выше уведомление об авторских правах и данное разрешение должно быть включено в
// все копии или существенные части Программного обеспечения.
//
// ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ "КАК ЕСТЬ", БЕЗ КАКИХ, ЯВНЫХ ИЛИ
// ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИИ КОММЕРЧЕСКОЙ,
// ПРИГОДНОСТИ ДЛЯ КОНКРЕТНЫХ ЦЕЛЕЙ И ОТСУТСТВИЯ НАРУШЕНИЙ. НИ В КОЕМ СЛУЧАЕ
// АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ ОТВЕТСТВЕННОСТИ ЗА Claim, УБЫТКОВ ИЛИ
// ДРУГОЙ ОТВЕТСТВЕННОСТИ, НЕЗАВИСИМО ОТ ДЕЙСТВИЯ ДОГОВОРА, ГРАЖДАНСКОГО ПРАВОНАРУШЕНИЯ ИЛИ ИНАЧЕ, ВОЗНИКАЮЩИЕ
// ИЗ, ИЗ ИЛИ В СВЯЗИ С ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ
// В ПРОГРАММЕ.

класс CMessageHeader;
класс CAddress;
класс CINV;
класс CRequestTracker;
класс CNode;



статического сопзЬ без знака короткого DEFAULT_PORT = htons (2222);
статический Const беззнаковый INT BROADCAST_HOPS = 5;
перечисление
{
    NODE_NETWORK = (1 << 0),
};







BOOL AddAddress (CAddrDB& addrdb, Const CAddress& адр);
CNode * FindNode (беззнаковое целочисленное значение ф);
CNode * ConnectNode (CAddress addrConnect, Int64 nTimeout = 0);
недействительный AbandonRequests (недействительный (* п) (пустота *, CDataStream&), Аннулирует * param1);
BOOL AnySubscribed (беззнаковое INT nChannel);
аннулированию ThreadBitcoinMiner (недействительный * PARG);
BOOL StartNode (строка& strError = REF (строка ()));
BOOL StopNode ();
аннулированию CheckForShutdown (Int N);









//
// Заголовок сообщения
// (4) сообщение о начале
Команда // (12)
// (4) размер

// Начало строки сообщения предназначена для маловероятен в нормальных данных.
// Символы редко используются верхний ASCII, не действительный, как UTF-8, и производят
// большой 4-байтовый INT в любом выравнивании.
статический Const символ pchMessageStart [4] = {0xf9, 0xbe, 0xb4, 0xd9};

класс CMessageHeader
{
общественности:
    перечисление {COMMAND_SIZE = 12};
    символ pchMessageStart [SizeOf (:: pchMessageStart)];
    символ pchCommand [COMMAND_SIZE];
    неподписанных INT nMessageSize;

    CMessageHeader ()
    {
        тетср (pchMessageStart, :: pchMessageStart, SizeOf (pchMessageStart));
        MemSet (pchCommand, 0, SizeOf (pchCommand));
        pchCommand [1] = 1;
        nMessageSize = -1;
    }

    CMessageHeader (Const символ * pszCommand, неподписанный INT nMessageSizeIn)
    {
        тетср (pchMessageStart, :: pchMessageStart, SizeOf (pchMessageStart));
        strncpy (pchCommand, pszCommand, COMMAND_SIZE);
        nMessageSize = nMessageSizeIn;
    }

    IMPLEMENT_SERIALIZE
    (
        READWRITE (FLATDATA (pchMessageStart));
        READWRITE (FLATDATA (pchCommand));
        READWRITE (nMessageSize);
    )

    Строка GetCommand ()
    {
        если (pchCommand [COMMAND_SIZE-1] == 0)
            возвращенная строка (pchCommand, pchCommand + StrLen (pchCommand));
        еще
            возвращенная строка (pchCommand, pchCommand + COMMAND_SIZE);
    }

    BOOL IsValid ()
    {
        // Проверка начала строки
        если (memcmp (pchMessageStart, :: pchMessageStart, SizeOf (pchMessageStart))! = 0)
            вернуться ложным;

        // Проверяем командную строку на наличие ошибок
        для (полукокса * р1 = pchCommand; р1 < pchCommand + COMMAND_SIZE; p1 ++)
        {
            если (* p1 == 0)
            {
                // Должно быть все нули после первого нуля
                для (p1; < pchCommand + COMMAND_SIZE; p1 ++)
                    если (* p1! = 0)
                        вернуться ложным;
            }
            иначе если (* p1 < '' || * p1 > 0x7E)
                вернуться ложным;
        }

        // Размер сообщения
        если (nMessageSize > 0x10000000)
        {
            Е ("CMessageHeader :: IsValid (): nMessageSize слишком большой% и \ ​​п", NMessageSize);
            вернуться ложным;
        }

        возвращает истину;
    }
};







статический Const символ без знака pchIPv4 [12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};

класс CAddress
{
общественности:
    UInt64 nServices;
    символ без знака pchReserved [12];
    беззнаковое целочисленное значение ф;
    неподписанный короткий порт;

    только // диск
    неподписанных INT NTime;

    CAddress ()
    {
        nServices = 0;
        тетср (pchReserved, pchIPv4, SizeOf (pchReserved));
        ф = 0;
        Порт = DEFAULT_PORT;
        Ntime = GetAdjustedTime ();
    }

    CAddress (беззнаковое INT IPIN, неподписанные короткий Portin, uint64 nServicesIn = 0)
    {
        nServices = nServicesIn;
        тетср (pchReserved, pchIPv4, SizeOf (pchReserved));
        ф = IPIN;
        Порт = Portin;
        Ntime = GetAdjustedTime ();
    }

    Явный CAddress (Const символ * pszIn, uint64 nServicesIn = 0)
    {
        nServices = nServicesIn;
        тетср (pchReserved, pchIPv4, SizeOf (pchReserved));
        ф = 0;
        Порт = DEFAULT_PORT;
        Ntime = GetAdjustedTime ();

        символьный ПСЗ [100];
        если (STRLEN (pszIn) > ARRAYLEN (ПСЗ) -1)
            вернуть;
        зЬгср (ПСЗ, pszIn);
        беззнаковое целочисленное значение а, б, в, г, д;
        если (sscanf (ПСЗ, "% U% U% U% и:...% U", &а, &б, &с, &д, &е) < 4)
            вернуть;
        символ * pszPort = strchr (ПСЗ, ':');
        если (pszPort)
        {
            * PszPort ++ = '\ 0';
            Порт = htons (atoi (pszPort));
        }
        ф = inet_addr (ПСЗ);
    }

    IMPLEMENT_SERIALIZE
    (
        если (nType & SER_DISK)
        {
            READWRITE (nVersion);
            READWRITE (Ntime);
        }
        READWRITE (nServices);
        READWRITE (FLATDATA (pchReserved));
        READWRITE (ф);
        READWRITE (порт);
    )

    друг оператор рядный BOOL == (Const CAddress& а, Const CAddress& б)
    {
        Возвращение (memcmp (a.pchReserved, b.pchReserved, SizeOf (a.pchReserved)) == 0 &&
                a.ip == b.ip &&
                a.port == b.port);
    }

    друг оператор рядный BOOL<(Const CAddress& а, Const CAddress& б)
    {
        INT RET = memcmp (a.pchReserved, b.pchReserved, SizeOf (a.pchReserved));
        если (RET < 0)
            возвращает истину;
        иначе если (в отставке == 0)
        {
            если (ntohl (a.ip) < ntohl (b.ip))
                возвращает истину;
            иначе если (a.ip == b.ip)
                возвратные ntohs (a.port) < ntohs (b.port);
        }
        вернуться ложным;
    }

    вектор<неподписанные символ> GetKey () Const
    {
        CDataStream сс;
        сс << FLATDATA (pchReserved) << IP << порт;
        обратный вектор<неподписанные символ>((Неподписанные символ *)&ss.begin () [0], (неподписанные символ *)&ss.end () [0]);
    }

    BOOL IsIPv4 () Const
    {
        Возвращение (memcmp (pchReserved, pchIPv4, SizeOf (pchIPv4)) == 0);
    }

    символ без знака GetByte (Int N) Const
    {
        Возвращение ((неподписанные символ *)&ф) [3-п];
    }

    Строка ToString () Const
    {
        вернуться strprintf ("% U% U% U% и:...% U", GetByte (3), GetByte (2), GetByte (1), GetByte (0), ntohs (порт));
    }

    недействительным печати () сопзЬ
    {
        Е ("CAddress (% s) \ п", ToString () c_str ()).
    }
};







перечисление
{
    MSG_TX = 1,
    MSG_BLOCK,
    MSG_REVIEW,
    MSG_PRODUCT,
    MSG_TABLE,
};

статический Const символ * ppszTypeName [] =
{
    "ОШИБКА",
    "Техас",
    "блок",
    "обзор",
    "продукт",
    "Таблица",
};

класс CINV
{
общественности:
    тип INT;
    uint256 хэш;

    CINV ()
    {
        тип = 0;
        хэш = 0;
    }

    CINV (интермедиат typeIn, Const uint256& Хашина)
    {
        тип = typeIn;
        хэш = Хашина;
    }

    CINV (Const строка& strType, Const uint256& Хашина)
    {
        Int я;
        для (я = 1; я < ARRAYLEN (ppszTypeName); я ++)
        {
            если (strType == ppszTypeName [I])
            {
                тип = я;
                ломать;
            }
        }
        если (я == ARRAYLEN (ppszTypeName))
            бросить STD :: out_of_range (strprintf ("CI :: CI (строка, uint256): неизвестный типа '% s'", StrType.c_str ()));
        хэш = Хашина;
    }

    IMPLEMENT_SERIALIZE
    (
        READWRITE (тип);
        READWRITE (хэш);
    )

    друг оператор рядный BOOL<(Const CINV& а, Const CINV& б)
   

    BOOL IsKnownType () Const
    {
        Возвращение (тип >= 1 && тип < ARRAYLEN (ppszTypeName));
    }

    Const символ * GetCommand () Const
    {
        если (! IsKnownType ())
            бросить STD :: out_of_range (strprintf ("CINV :: GetCommand (): тип =% неизвестный тип", тип));
        вернуть ppszTypeName [тип];
    }

    Строка ToString () Const
    {
        вернуться strprintf ("% S% s"., GetCommand (), hash.ToString () зиЬзЬг (0,6) .c_str ());
    }

    недействительным печати () сопзЬ
    {
        Е ("CINV (% s) \ п", ToString () c_str ()).
    }
};





класс CRequestTracker
{
общественности:
    недействительный (* п) (пустота *, CDataStream&);
    недействительные * param1;

    Явный CRequestTracker (аннулируются (* fnIn) (пустота *, CDataStream&) = NULL, аннулируются * param1In = NULL)
    {
        п = fnIn;
        param1 = param1In;
    }

    BOOL IsNull ()
    {
        вернуться Fn == NULL;
    }
};





ехЬегп BOOL fClient;
ехЬегп nLocalServices uint64;
ехЬегп CAddress addrLocalHost;
ехЬегп CNode * pnodeLocalHost;
ехЬегп BOOL fShutdown;
ехЬегп массив vfThreadRunning;
ехЬегп вектор vNodes;
ехЬегп cs_vNodes CCriticalSection;
ехЬегп карта<вектор<неподписанные символ>, CAddress> mapAddresses;
ехЬегп cs_mapAddresses CCriticalSection;
ехЬегп карта mapRelay;
ехЬегп Deque<пара > vRelayExpiration;
ехЬегп CCriticalSection cs_mapRelay;
ехЬегп карта mapAlreadyAskedFor;





класс CNode
{
общественности:
    // разъем
    UInt64 nServices;
    SOCKET hSocket;
    CDataStream vSend;
    CDataStream vRecv;
    CCriticalSection cs_vSend;
    CCriticalSection cs_vRecv;
    неподписанных INT nPushPos;
    CAddress адр;
    INT nVersion;
    BOOL fClient;
    BOOL fInbound;
    BOOL fNetworkNode;
    BOOL fDisconnect;
защищенный:
    INT nRefCount;
общественности:
    int64 nReleaseTime;
    карта mapRequests;
    CCriticalSection cs_mapRequests;

    // потоп
    вектор vAddrToSend;
    задавать setAddrKnown;

    // реле инвентаризации на основе
    вектор vInventoryToSend;
    задавать setInventoryKnown;
    CCriticalSection cs_inventory;
    MultiMap mapAskFor;

    // трансляция и подписка
    вектор<голец> vfSubscribe;


    CNode (РАЗЪЕМ hSocketIn, CAddress addrIn)
    {
        nServices = 0;
        hSocket = hSocketIn;
        vSend.SetType (SER_NETWORK);
        vRecv.SetType (SER_NETWORK);
        nPushPos = -1;
        адр = addrIn;
        nVersion = 0;
        fClient = ложь; // устанавливается версия сообщения
        fInbound = ложь;
        fNetworkNode = ложь;
        fDisconnect = FALSE;
        nRefCount = 0;
        nReleaseTime = 0;
        vfSubscribe.assign (256, ложь);

        // Поместить сообщение версии
        беззнаковая INT Ntime = GetAdjustedTime ();
        PushMessage ("версия", версия, nLocalServices, Ntime);
    }

    ~ CNode ()
    {
        если (hSocket! = INVALID_SOCKET)
            closesocket (hSocket);
    }

частный:
    CNode (Const CNode&);
    недействительный оператор = (Const CNode&);
общественности:


    BOOL ReadyToDisconnect ()
    GetRefCount () <= 0;
   

    ИНТ GetRefCount ()
    {
        вернуться макс (nRefCount, 0) + (GetTime () < nReleaseTime? 1: 0);
    }

    аннулированию AddRef (Int64 nTimeout = 0)
    {
        если (nTimeout! = 0)
            nReleaseTime = макс (nReleaseTime, GetTime () + nTimeout);
        еще
            nRefCount ++;
    }

    аннулируются Release ()
    {
        nRefCount--;
    }



    недействительным AddInventoryKnown (Const CINV& и)
    {
        CRITICAL_BLOCK (cs_inventory)
            setInventoryKnown.insert (INV);
    }

    аннулированию AskFor (константный CINV& и)
    {
        // Мы используем mapAskFor в качестве приоритетной очереди,
        // ключ самое раннее время запрос может быть отправлен
        int64& nRequestTime = mapAlreadyAskedFor [INV];
        Е ("askfor% s% I64d \ п", Inv.ToString () c_str (), nRequestTime).
        nRequestTime = макс (nRequestTime + 2 * 60, GetTime ());
        mapAskFor.insert (make_pair (nRequestTime, INV));
    }



    аннулированию BeginMessage (Const символ * pszCommand)
    {
        EnterCriticalSection (&cs_vSend);
        если (nPushPos! = -1)
            AbortMessage ();
        nPushPos = vSend.size ();
        vSend << CMessageHeader (pszCommand, 0);
        Е ("отправка:% -12s ", PszCommand);
    }

    аннулированию AbortMessage ()
    {
        если (nPushPos == -1)
            вернуть;
        vSend.resize (nPushPos);
        nPushPos = -1;
        LeaveCriticalSection (&cs_vSend);
        Е ("(Прерванный) \ п");
    }

    EndMessage недействительными ()
    {
        если (nPushPos == -1)
            вернуть;

        // Patch в размере
        без знака INT nРазмер: = vSend.size () - nPushPos - SizeOf (CMessageHeader);
        тетср ((символ *)&vSend [nPushPos] + offsetof (CMessageHeader, nMessageSize), &nРазмер:, SizeOf (nРазмер:));

        Е ("(% D байт)  ", NРазмер:);
        // для (INT I = nPushPos + SizeOf (CMessageHeader); я < мин (vSend.size (), nPushPos + SizeOf (CMessageHeader) + 20U); я ++)
        // Е ("% 02x ", VSend [я] & 0xff);
        Е ("\ п");

        nPushPos = -1;
        LeaveCriticalSection (&cs_vSend);
    }

    аннулированию EndMessageAbortIfEmpty ()
    {
        если (nPushPos == -1)
            вернуть;
        INT nРазмер: = vSend.size () - nPushPos - SizeOf (CMessageHeader);
        если (nРазмер: > 0)
            EndMessage ();
        еще
            AbortMessage ();
    }

    Const символ * GetMessageCommand () Const
    {
        если (nPushPos == -1)
            вернуть "";
        вернуть &vSend [nPushPos] + offsetof (CMessageHeader, pchCommand);
    }




    недействительным PushMessage (Const символ * pszCommand)
    {
        пытаться
        {
            BeginMessage (pszCommand);
            EndMessage ();
        }
        поймать (...)
        {
            AbortMessage ();
            бросить;
        }
    }

    шаблон<имяТипа T1>
    недействительный PushMessage (Const символ * pszCommand, Const Т1& a1)
    {
        пытаться
        {
            BeginMessage (pszCommand);
            vSend << a1;
            EndMessage ();
        }
        поймать (...)
        {
            AbortMessage ();
            бросить;
        }
    }

    шаблон<Ьурепате Т1, Т2 Ьурепате>
    недействительный PushMessage (Const символ * pszCommand, Const Т1& a1, Const T2& a2)
    {
        пытаться
        {
            BeginMessage (pszCommand);
            vSend << a1 << a2;
            EndMessage ();
        }
        поймать (...)
        {
            AbortMessage ();
            бросить;
        }
    }

    шаблон<Ьурепате Т1, Т2 Ьурепата, Ьурепате Т3>
    недействительный PushMessage (Const символ * pszCommand, Const Т1& a1, Const T2& a2, Const T3& a3)
    {
        пытаться
        {
            BeginMessage (pszCommand);
            vSend << a1 << a2 << a3;
            EndMessage ();
        }
        поймать (...)
        {
            AbortMessage ();
            бросить;
        }
    }

    шаблон<Ьурепате Т1, Т2 Ьурепата, Ьурепате Т3, Т4 Ьурепате>
    недействительный PushMessage (Const символ * pszCommand, Const Т1& a1, Const T2& a2, Const T3& a3, Const T4& a4)
    {
        пытаться
        {
            BeginMessage (pszCommand);
            vSend << a1 << a2 << a3 << a4;
            EndMessage ();
        }
        поймать (...)
        {
            AbortMessage ();
            бросить;
        }
    }


    аннулированию PushRequest (Const символ * pszCommand,
                     недействительный (* п) (пустота *, CDataStream&), Аннулирует * param1)
    {
        uint256 hashReply;
        RAND_bytes ((неподписанные символ *)&hashReply, SizeOf (hashReply));

        CRITICAL_BLOCK (cs_mapRequests)
            mapRequests [hashReply] = CRequestTracker (п, param1);

        PushMessage (pszCommand, hashReply);
    }

    шаблон<имяТипа T1>
    аннулированию PushRequest (Const символ * pszCommand, константный T1& a1,
                     недействительный (* п) (пустота *, CDataStream&), Аннулирует * param1)
    {
        uint256 hashReply;
        RAND_bytes ((неподписанные символ *)&hashReply, SizeOf (hashReply));

        CRITICAL_BLOCK (cs_mapRequests)
            mapRequests [hashReply] = CRequestTracker (п, param1);

        PushMessage (pszCommand, hashReply, a1);
    }

    шаблон<Ьурепате Т1, Т2 Ьурепате>
    аннулированию PushRequest (Const символ * pszCommand, константный T1& a1, Const T2& a2,
                     недействительный (* п) (пустота *, CDataStream&), Аннулирует * param1)
    {
        uint256 hashReply;
        RAND_bytes ((неподписанные символ *)&hashReply, SizeOf (hashReply));

        CRITICAL_BLOCK (cs_mapRequests)
            mapRequests [hashReply] = CRequestTracker (п, param1);

        PushMessage (pszCommand, hashReply, a1, a2);
    }



    BOOL IsSubscribed (беззнаковое INT nChannel);
    аннулируются Подписаться (беззнаковое целочисленное значение nChannel, беззнаковое целочисленное значение nHops = 0);
    недействительный CancelSubscribe (беззнаковый INT nChannel);
    Отключить недействительными ();
};










рядный недействительным RelayInventory (Const CINV& и)
{
    // Помещаем в списки, чтобы предложить другие узлы
    CRITICAL_BLOCK (cs_vNodes)
        Еогеасп (CNode * pnode, vNodes)
            CRITICAL_BLOCK (pnode->cs_inventory)
                если (! pnode->setInventoryKnown.count (INV))
                    pnode->vInventoryToSend.push_back (INV);
}

шаблон<Ьурепате Т>
недействительным RelayMessage (Const CINV& INV, сопзЬ Т& а)
{
    CDataStream сс (SER_NETWORK);
    сс << а;
    RelayMessage (INV, сс);
}

шаблон<>
рядный недействительным RelayMessage<>(Const CINV& и, Const CDataStream& сс)
{
    CRITICAL_BLOCK (cs_mapRelay)
    {
        // Сохранить оригинальное сериализованное сообщение так новые версии сохраняются
        mapRelay [INV] = сс;

        // Expire старых сообщений реле
        vRelayExpiration.push_back (make_pair (GetTime () + 10 * 60, INV));
        в то время как (! vRelayExpiration.empty () && vRelayExpiration.front (). первый < GetTime ())
        {
            mapRelay.erase (vRelayExpiration.front () второй.);
            vRelayExpiration.pop_front ();
        }
    }

    RelayInventory (INV);
}
[/ Предварительно]
Cryddit сейчас офлайн Пожаловаться на Cryddit   Ответить с цитированием Мультицитирование сообщения от Cryddit Быстрый ответ на сообщение Cryddit

23 декабря 2013, 7:36:17 PM   # 6
 
 
Сообщения: 840
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

А вот содержимое файла node.cpp.


Код:
// Copyright (с) 2008 Сатоси Накамото
//
// Разрешение Настоящим предоставляется бесплатно, любому лицу, приобретающему копию
// это программное обеспечение и связанные с ним файлы документации ( "Программного обеспечения"), иметь дело
// Программного обеспечения без ограничений, в том числе, без ограничения прав
// использовать, копировать, изменять, объединять, публиковать, распространять, сублицензировать и / или продавать
// копии программного обеспечения, а также разрешать лицам, которым данное программное обеспечение
// обставленная сделать так, при соблюдении следующих условий:
//
// выше уведомление об авторских правах и данное разрешение должно быть включено в
// все копии или существенные части Программного обеспечения.
//
// ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ "КАК ЕСТЬ", БЕЗ КАКИХ, ЯВНЫХ ИЛИ
// ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИИ КОММЕРЧЕСКОЙ,
// ПРИГОДНОСТИ ДЛЯ КОНКРЕТНЫХ ЦЕЛЕЙ И ОТСУТСТВИЯ НАРУШЕНИЙ. НИ В КОЕМ СЛУЧАЕ
// АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ ОТВЕТСТВЕННОСТИ ЗА Claim, УБЫТКОВ ИЛИ
// ДРУГОЙ ОТВЕТСТВЕННОСТИ, НЕЗАВИСИМО ОТ ДЕЙСТВИЯ ДОГОВОРА, ГРАЖДАНСКОГО ПРАВОНАРУШЕНИЯ ИЛИ ИНАЧЕ, ВОЗНИКАЮЩИЕ
// ИЗ, ИЗ ИЛИ В СВЯЗИ С ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ
// В ПРОГРАММЕ.

#включают "headers.h"
#включают

аннулированию ThreadMessageHandler2 (недействительный * PARG);
аннулированию ThreadSocketHandler2 (недействительный * PARG);
аннулированию ThreadOpenConnections2 (недействительный * PARG);






//
// Глобальные переменные состояния
//
BOOL fClient = ложь;
UInt64 nLocalServices = (fClient 0: NODE_NETWORK);
CAddress addrLocalHost (0, DEFAULT_PORT, nLocalServices);
CNode nodeLocalHost (INVALID_SOCKET, CAddress ("127.0.0.1", NLocalServices));
CNode * pnodeLocalHost = &nodeLocalHost;
BOOL fShutdown = ложь;
массив vfThreadRunning;
вектор vNodes;
CCriticalSection cs_vNodes;
карта<вектор<неподписанные символ>, CAddress> mapAddresses;
CCriticalSection cs_mapAddresses;
карта mapRelay;
Deque<пара > vRelayExpiration;
CCriticalSection cs_mapRelay;
карта mapAlreadyAskedFor;






BOOL AddAddress (CAddrDB& addrdb, Const CAddress& адр)
{
    CRITICAL_BLOCK (cs_mapAddresses)
    {
        карта<вектор<неподписанные символ>, CAddress>:: итератора он = mapAddresses.find (addr.GetKey ());
        если (== это mapAddresses.end ())
        {
            // Новый адрес
            mapAddresses.insert (make_pair (addr.GetKey (), ADDR));
            addrdb.WriteAddress (адрес);
            возвращает истину;
        }
        еще
       
            CAddress& addrFound = (* его) .second;
            если ((addrFound.nServices
    }
    вернуться ложным;
}





недействительный AbandonRequests (недействительный (* п) (пустота *, CDataStream&), Аннулирует * param1)
{
    // Если диалог может свернут до ответа возвращается,
    // называют это в деструкторе, чтобы он не дозвонился после его удаления.
    CRITICAL_BLOCK (cs_vNodes)
    {
        Еогеасп (CNode * pnode, vNodes)
        {
            CRITICAL_BLOCK (pnode->cs_mapRequests)
            {
                для (показать на карте:: итератор миль = pnode->mapRequests.begin (); ми! = pnode->mapRequests.end ();)
                {
                    CRequestTracker& трекер = (* мили) .second;
                    если (tracker.fn == п && tracker.param1 == param1)
                        pnode->mapRequests.erase (миль ++);
                    еще
                        ми ++;
                }
            }
        }
    }
}









CNode * FindNode (беззнаковое целочисленное значение ф)
{
    CRITICAL_BLOCK (cs_vNodes)
    {
        Еогеасп (CNode * pnode, vNodes)
            если (pnode->addr.ip == ф)
                возвращать (pnode);
    }
    возвращать NULL;
}

CNode * FindNode (CAddress адр)
{
    CRITICAL_BLOCK (cs_vNodes)
    {
        Еогеасп (CNode * pnode, vNodes)
            если (pnode->адр == адр)
                возвращать (pnode);
    }
    возвращать NULL;
}

CNode * ConnectNode (CAddress addrConnect, int64 nTimeout)
{
    если (addrConnect.ip == addrLocalHost.ip)
        возвращать NULL;

    // Поиск существующего соединения
    CNode * pnode = FindNode (addrConnect.ip);
    если (pnode)
    {
        если (nTimeout! = 0)
            pnode->AddRef (nTimeout);
        еще
            pnode->AddRef ();
        вернуться pnode;
    }

    // Connect
    РАЗЪЕМ hSocket = сокет (AF_INET, SOCK_STREAM, 0);
    если (hSocket == INVALID_SOCKET)
    {
        Е ("сокет не удалось \ п");
        возвращать NULL;
    }

    структура sockaddr_in SOCKADDR;
    sockaddr.sin_family = AF_INET;
    sockaddr.sin_addr.s_addr = addrConnect.ip;
    sockaddr.sin_port = addrConnect.port;

        /// отлаживать печать
        статическая карта<неподписанных INT, неподписанные INT> mapPrintLimit;
        если (mapPrintLimit [addrConnect.ip]% 20 == 0)
            Е ("подключение к% D.% d.% d.% d \ п"((Неподписанные символ *)&sockaddr.sin_addr.s_addr) [0], ((неподписанные символ *)&sockaddr.sin_addr.s_addr) [1], ((неподписанные символ *)&sockaddr.sin_addr.s_addr) [2], ((неподписанные символ *)&sockaddr.sin_addr.s_addr) [3]);

    если (подключение (hSocket (структура SOCKADDR *)&SOCKADDR, SizeOf (SOCKADDR))! = SOCKET_ERROR)
    {
            /// отлаживать печать
            mapPrintLimit [addrConnect.ip] = 0;
            Е ("% связано д.% d.% d.% d \ п"((Неподписанные символ *)&sockaddr.sin_addr.s_addr) [0], ((неподписанные символ *)&sockaddr.sin_addr.s_addr) [1], ((неподписанные символ *)&sockaddr.sin_addr.s_addr) [2], ((неподписанные символ *)&sockaddr.sin_addr.s_addr) [3]);

        // Добавить узел
        CNode * pnode = новый CNode (hSocket, addrConnect);
        если (nTimeout! = 0)
            pnode->AddRef (nTimeout);
        еще
            pnode->AddRef ();
        CRITICAL_BLOCK (cs_vNodes)
            vNodes.push_back (pnode);
        вернуться pnode;
    }
    еще
    {
        //// TODO: необходимо установить последнее не удалось время соединения, и увеличивают неудачный для подключения счетчика
        /// отлаживать печать
        если ((mapPrintLimit [addrConnect.ip] ++),% 20 == 0)
            Е ("соединение не удалось% d \ п", WSAGetLastError ());
        возвращать NULL;
    }
}

аннулируются CNode :: Disconnect ()
{
    Е ("Узел отсоединение% S \ N", Addr.ToString () c_str ()).

    closesocket (hSocket);

    // все из узлов вещания и подписки автоматически снесены
    // когда она идет вниз, так что узел должен остаться, чтобы сохранить его вещание происходит.

    // Отменить удаление Ссылок передач
    CRITICAL_BLOCK (cs_mapTables)
        для (показать на карте:: итератор мили = mapTables.begin (); ! Ми = mapTables.end ();)
            AdvertRemoveSource (это, MSG_TABLE, 0, (* (миль ++)) второй.);
    CRITICAL_BLOCK (cs_mapProducts)
        для (показать на карте:: итератор мили = mapProducts.begin (); ! Ми = mapProducts.end ();)
            AdvertRemoveSource (это, MSG_PRODUCT, 0, (* (миль ++)) второй.);

    // Отмена подписки
    для (без знака Int nChannel = 0; nChannel < vfSubscribe.size (); nChannel ++)
        если (vfSubscribe [nChannel])
            CancelSubscribe (nChannel);
}













аннулированию ThreadSocketHandler (пустоту * PARG)
{
    IMPLEMENT_RANDOMIZE_STACK (ThreadSocketHandler (PARG));

    петля
    {
        vfThreadRunning [0] = TRUE;
        CheckForShutdown (0);
        пытаться
        {
            ThreadSocketHandler2 (PARG);
        }
        CATCH_PRINT_EXCEPTION ("ThreadSocketHandler ()")
        vfThreadRunning [0] = FALSE;
        Sleep (5000);
    }
}

аннулированию ThreadSocketHandler2 (пустоту * PARG)
{
    Е ("ThreadSocketHandler начал \ п");
    РАЗЪЕМ hListenSocket = * (РАЗЪЕМ *) PARG;
    список vNodesDisconnected;
    INT nPrevNodeCount = 0;

    петля
    {
        //
        // Отключить узлы
        //
        CRITICAL_BLOCK (cs_vNodes)
        {
            // Отключить повторяющиеся соединения
            карта<неподписанных INT, CNode *> mapFirst;
            Еогеасп (CNode * pnode, vNodes)
            {
                беззнаковое целочисленное значение ф = pnode->addr.ip;
                если (mapFirst.count (ф) && addrLocalHost.ip < ф)
                {
                    // В случае, если два узла соединяются друг с другом одновременно,
                    // нижний IP разъединяет его исходящее соединение
                    CNode * pnodeExtra = mapFirst [ф];

                    если (pnodeExtra->GetRefCount () > (pnodeExtra->fNetworkNode? 1: 0))
                        подкачки (pnodeExtra, pnode);

                    если (pnodeExtra->GetRefCount () <= (PnodeExtra->fNetworkNode? 1: 0))
                    {
                        Е ("(% D узлы) разъединение двух экземплярах:% S", VNodes.size (), pnodeExtra->. Addr.ToString () c_str ());
                        если (pnodeExtra->fNetworkNode && ! pnode->fNetworkNode)
                        {
                            pnode->AddRef ();
                            своп (pnodeExtra->fNetworkNode, pnode->fNetworkNode);
                            pnodeExtra->Выпуск();
                        }
                        pnodeExtra->fDisconnect = TRUE;
                    }
                }
                mapFirst [ф] = pnode;
            }

            // Отключите неиспользуемые узлы
            вектор vNodesCopy = vNodes;
            Еогеасп (CNode * pnode, vNodesCopy)
            {
                если (pnode->ReadyToDisconnect () && pnode->vRecv.empty () && pnode->vSend.empty ())
                {
                    // удалить из vNodes
                    vNodes.erase (удалить (vNodes.begin (), vNodes.end (), pnode), vNodes.end ());
                    pnode->Отключить();

                    // держать в отключенном бассейне, пока все рефы не будут освобождены
                    pnode->nReleaseTime = макс (pnode->nReleaseTime, GetTime () + 5 * 60);
                    если (pnode->fNetworkNode)
                        pnode->Выпуск();
                    vNodesDisconnected.push_back (pnode);
                }
            }

            // Удалить отключенные узлы
            список vNodesDisconnectedCopy = vNodesDisconnected;
            Еогеасп (CNode * pnode, vNodesDisconnectedCopy)
            {
                // ждать, пока потоки не выполняются, используя его
                если (pnode->GetRefCount () <= 0)
                {
                    BOOL fDelete = ложь;
                    TRY_CRITICAL_BLOCK (pnode->cs_vSend)
                     TRY_CRITICAL_BLOCK (pnode->cs_vRecv)
                      TRY_CRITICAL_BLOCK (pnode->cs_mapRequests)
                       TRY_CRITICAL_BLOCK (pnode->cs_inventory)
                        fDelete = TRUE;
                    если (fDelete)
                    {
                        vNodesDisconnected.remove (pnode);
                        удалить pnode;
                    }
                }
            }
        }
        если (vNodes.size ()! = nPrevNodeCount)
        {
            nPrevNodeCount = vNodes.size ();
            MainFrameRepaint ();
        }


        //
        // Найти, какие разъемы есть данные для приема
        //
        Тайм-аут структуры формата: первый формат;
        timeout.tv_sec = 0;
        timeout.tv_usec = 50000; // Частота опроса pnode->vSend

        структура fd_set fdsetRecv;
        структура fd_set fdsetSend;
        FD_ZERO (&fdsetRecv);
        FD_ZERO (&fdsetSend);
        РАЗЪЕМ hSocketMax = 0;
        FD_SET (hListenSocket, &fdsetRecv);
        hSocketMax = макс (hSocketMax, hListenSocket);
        CRITICAL_BLOCK (cs_vNodes)
        {
            Еогеасп (CNode * pnode, vNodes)
            {
                FD_SET (pnode->hSocket, &fdsetRecv);
                hSocketMax = макс (hSocketMax, pnode->hSocket);
                TRY_CRITICAL_BLOCK (pnode->cs_vSend)
                    если (! pnode->vSend.empty ())
                        FD_SET (pnode->hSocket, &fdsetSend);
            }
        }

        vfThreadRunning [0] = FALSE;
        INT nВыберите пункт = выберите (hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &Тайм-аут);
        vfThreadRunning [0] = TRUE;
        CheckForShutdown (0);
        если (== nВыберите пункт SOCKET_ERROR)
        {
            INT nErr = WSAGetLastError ();
            Е ("выбрать не удалось:% d \ N", NErr);
            для (INT I = 0; я <= HSocketMax; я ++)
            {
                FD_SET (я, &fdsetRecv);
                FD_SET (я, &fdsetSend);
            }
            Sleep (timeout.tv_usec / 1000);
        }
        LARGE_INTEGER PerformanceCount;
        QueryPerformanceCounter (&PerformanceCount);
        RAND_add (&PerformanceCount.LowPart, SizeOf (PerformanceCount.LowPart), 1,0);

        //// отладки
        // Еогеасп (CNode * pnode, vNodes)
        // {
        // Е ("vRecv =% -5d ", pnode->vRecv.size ());
        // Е ("vSend =% -5d    ", pnode->vSend.size ());
        //}
        // Е ("\ п");


        //
        // Принять новые связи
        //
        если (FD_ISSET (hListenSocket, &fdsetRecv))
        {
            структура sockaddr_in SOCKADDR;
            INT Len = SizeOf (SOCKADDR);
            SOCKET hSocket = принять (hListenSocket (структура SOCKADDR *)&SOCKADDR, &длина);
            CAddress адр (sockaddr.sin_addr.s_addr, sockaddr.sin_port);
            если (hSocket == INVALID_SOCKET)
            {
                если (WSAGetLastError ()! = WSAEWOULDBLOCK)
                    Е ("ОШИБКА ThreadSocketHandler принимают не удалось:% d \ п", WSAGetLastError ());
            }
            еще
            {
                Е ("% S принимается соединение с% s \ п", AddrLocalHost.ToString () c_str (), addr.ToString () c_str ())..;
                CNode * pnode = новый CNode (hSocket, адр);
                pnode->AddRef ();
                pnode->fInbound = TRUE;
                CRITICAL_BLOCK (cs_vNodes)
                    vNodes.push_back (pnode);
            }
        }


        //
        // Служба каждого гнезда
        //
        вектор vNodesCopy;
        CRITICAL_BLOCK (cs_vNodes)
            vNodesCopy = vNodes;
        Еогеасп (CNode * pnode, vNodesCopy)
        {
            CheckForShutdown (0);
            SOCKET hSocket = pnode->hSocket;

            //
            // Получать
            //
            если (FD_ISSET (hSocket, &fdsetRecv))
            {
                TRY_CRITICAL_BLOCK (pnode->cs_vRecv)
                {
                    CDataStream& vRecv = pnode->vRecv;
                    без знака INT НСС = vRecv.size ();

                    // Типичный буфер сокета 8K-64K
                    сопзИ неподписанный INT nBufSize = 0x10000;
                    vRecv.resize (НСС + nBufSize);
                    INT = RECV-байт (hSocket, &vRecv [НСС], nBufSize, 0);
                    vRecv.resize (НСС + макс (число-байт, 0));
                    если (== 0 число-байт)
                    {
                        // сокет закрыт корректно
                        если (! pnode->fDisconnect)
                            Е ("RECV: гнездо закрыто \ п");
                        pnode->fDisconnect = TRUE;
                    }
                    иначе если (число-байт < 0)
                    {
                        // ошибка сокета
                        INT nErr = WSAGetLastError ();
                        если (nErr! = WSAEWOULDBLOCK && nErr! = WSAEMSGSIZE && nErr! = WSAEINTR && nErr! = WSAEINPROGRESS)
                        {
                            если (! pnode->fDisconnect)
                                Е ("RECV не удалось:% d \ п", NErr);
                            pnode->fDisconnect = TRUE;
                        }
                    }
                }
            }

            //
            // Послать
            //
            если (FD_ISSET (hSocket, &fdsetSend))
            {
                TRY_CRITICAL_BLOCK (pnode->cs_vSend)
                {
                    CDataStream& vSend = pnode->vSend;
                    если (! vSend.empty ())
                    {
                        INT = отправить-байт (hSocket, &vSend [0], vSend.size (), 0);
                        если (число-байт > 0)
                        {
                            vSend.erase (vSend.begin (), vSend.begin () + число-байт);
                        }
                        иначе если (== 0-байт)
                        {
                            если (pnode->ReadyToDisconnect ())
                                pnode->vSend.clear ();
                        }
                        еще
                        {
                            Е ("отправить ошибка% d \ N", Число-байт);
                            если (pnode->ReadyToDisconnect ())
                                pnode->vSend.clear ();
                        }
                    }
                }
            }
        }


        Сон (10);
    }
}










недействительный ThreadOpenConnections (недействительный * pärg)
{
    IMPLEMENT_RANDOMIZE_STACK (ThreadOpenConnections (PARG));

    петля
    {
        vfThreadRunning [1] = TRUE;
        CheckForShutdown (1);
        пытаться
        {
            ThreadOpenConnections2 (PARG);
        }
        CATCH_PRINT_EXCEPTION ("ThreadOpenConnections ()")
        vfThreadRunning [1] = FALSE;
        Sleep (5000);
    }
}

аннулированию ThreadOpenConnections2 (пустоту * PARG)
{
    Е ("ThreadOpenConnections начал \ п");
    без знака INT nTries = 0;
    петля
    {
        //// количество соединений все еще может потребоваться увеличить до выхода
        // Инициировать сетевые соединения
        если (vNodes.size () < 5 && vNodes.size () < mapAddresses.size ())
        {
            // Составьте список уникального класса Кассиопеяне
            символ без знака pchIPCMask [4] = {0xff, 0xff, 0xff, 0x00};
            неподписанный INT nIPCMask = * (беззнаковый INT *) pchIPCMask;
            вектор<неподписанных INT> vIPC;
            CRITICAL_BLOCK (cs_mapAddresses)
            {
                vIPC.reserve (mapAddresses.size ());
                беззнаковая INT nPrev = 0;
                Еогеасп (Const PAIRTYPE (вектор<неподписанные символ>, CAddress)& пункт, mapAddresses)
                {
                    Const CAddress& адр = item.second;
                    если (! addr.IsIPv4 ())
                        Продолжать;

                    // Пользуясь mapAddresses быть в отсортированном порядке,
                    // с IP-адреса одного и того же класса C, сгруппированных вместе.
                    неподписанный INT Ipc = addr.ip & nIPCMask;
                    если (Ipc! = nPrev)
                        vIPC.push_back (nPrev = IPC);
                }
            }

            //
            // Процесс выбора IP предназначен для ограничения уязвимости для решения затопления.
            // Любой класс C (A.B.C.?) Имеет равные шансы быть выбранным, затем ИС
            // выбрана в классе С. Злоумышленник может иметь возможность выделять множество IP-адресов, но
            // они, как правило, сосредоточены в блоках класса С-х. Они могут боры
            // внимание в своем классе С, но не все адресное пространство IP в целом.
            // одинокий узел в классе C получит столько внимания, как кто-то держит все 255
            // IP-адрес в другом классе C.
            //
            BOOL fSuccess = ложь;
            INT nLimit = vIPC.size ();
            в то время как (! fSuccess && nLimit-- > 0)
            {
                // Выбираем случайный класс C
                uint64 nRand;
                RAND_bytes ((неподписанные символ *)&nRand, SizeOf (nRand));
                беззнаковое INT = Ipc vIPC [nRand% vIPC.size ()];

                // Организовать все адреса класса С по IP
                карта<неподписанных INT, вектор > mapIP;
                CRITICAL_BLOCK (cs_mapAddresses)
                {
                    для (показать на карте<вектор<неподписанные символ>, CAddress>:: итератора миль = mapAddresses.lower_bound (CAddress (МПК, 0) .GetKey ());
                         ми = mapAddresses.upper_bound (CAddress (Ipc | ~ nIPCMask, 0xffff) .GetKey (!));
                         ++мили)
                    {
                        Const CAddress& адр = (* миля) .second;
                        mapIP [addr.ip] .push_back (адрес);
                    }
                }

                // Выбираем случайный IP в классе C
                RAND_bytes ((неподписанные символ *)&nRand, SizeOf (nRand));
                карта<неподписанных INT, вектор >:: итератор мили = mapIP.begin ();
                заранее (мили, nRand% mapIP.size ());

                // После того, как мы выбрали IP, мы будем стараться каждый данный порт, прежде чем двигаться дальше
                Еогеасп (Const CAddress& addrConnect (* мили) .second)
                !addrConnect.IsIPv4 ()
            }

            nTries ++;
        }

        // Ожидание
        vfThreadRunning [1] = FALSE;
        Sleep (100 + nTries * 5);
        vfThreadRunning [1] = TRUE;
        CheckForShutdown (1);
    }
}








аннулированию ThreadMessageHandler (пустоту * PARG)
{
    IMPLEMENT_RANDOMIZE_STACK (ThreadMessageHandler (PARG));

    петля
    {
        vfThreadRunning [2] = TRUE;
        CheckForShutdown (2);
        пытаться
        {
            ThreadMessageHandler2 (PARG);
        }
        CATCH_PRINT_EXCEPTION ("ThreadMessageHandler ()")
        vfThreadRunning [2] = FALSE;
        Sleep (5000);
    }
}

аннулированию ThreadMessageHandler2 (пустоту * PARG)
{
    Е ("ThreadMessageHandler начал \ п");
    петля
    {
        // опрос подключенных узлов для сообщений
        вектор vNodesCopy;
        CRITICAL_BLOCK (cs_vNodes)
            vNodesCopy = vNodes;
        Еогеасп (CNode * pnode, vNodesCopy)
        {
            pnode->AddRef ();

            // Получение сообщений
            TRY_CRITICAL_BLOCK (pnode->cs_vRecv)
                ProcessMessages (pnode);

            // Отправка сообщений
            TRY_CRITICAL_BLOCK (pnode->cs_vSend)
                SendMessages (pnode);

            pnode->Выпуск();
        }

        // Ждать и разрешить сообщения в кучу вверх
        vfThreadRunning [2] = FALSE;
        Сон (200);
        vfThreadRunning [2] = TRUE;
        CheckForShutdown (2);
    }
}









//// TODO: запустить один поток для каждого процессора, использование GETENV ("NUMBER_OF_PROCESSORS")
недействительный ThreadBitcoinMiner (недействительный * PARG)
{
    vfThreadRunning [3] = TRUE;
    CheckForShutdown (3);
    пытаться
    {
        BOOL ладу = BitcoinMiner ();
        Е ("BitcoinMiner вернулся% S \ N \ N \ п", Лада? "правда" : "ложный");
    }
    CATCH_PRINT_EXCEPTION ("BitcoinMiner ()")
    vfThreadRunning [3] = FALSE;
}











BOOL StartNode (строка& strError)
{
    strError = "";


    // запуск Sockets
    WSADATA WSADATA;
    INT RET = WSAStartup (MAKEWORD (2,2), &WSADATA);
    если (RET! = NO_ERROR)
    {
        strError = strprintf ("Ошибка: TCP / IP, библиотека сокет не удалось запустить (WSAStartup возвращается ошибка% d)", RET);
        Е ("% S \ п", StrError.c_str ());
        вернуться ложным;
    }

    // Получить локальный IP-хоста
    символ pszHostName [255];
    если (gethostname (pszHostName, 255) == SOCKET_ERROR)
    {
        strError = strprintf ("Ошибка: Не удается получить IP-адрес этого компьютера (gethostname возвращается ошибка% d)", WSAGetLastError ());
        Е ("% S \ п", StrError.c_str ());
        вернуться ложным;
    }
    структура hostent * pHostEnt = gethostbyname (pszHostName);
    если (! pHostEnt)
    {
        strError = strprintf ("Ошибка: Не удается получить IP-адрес этого компьютера (gethostbyname возвращается ошибка% d)", WSAGetLastError ());
        Е ("% S \ п", StrError.c_str ());
        вернуться ложным;
    }
    addrLocalHost = CAddress (* (длинный *) (pHostEnt->h_addr_list [0]),
                             DEFAULT_PORT,
                             nLocalServices);
    Е ("addrLocalHost =% s \ п", AddrLocalHost.ToString () c_str ()).

    // Создать сокет для прослушивания входящих соединений
    РАЗЪЕМ hListenSocket = сокет (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    если (hListenSocket == INVALID_SOCKET)
    {
        strError = strprintf ("Ошибка: Не удалось открыть сокет для входящих соединений (сокет возвращается ошибка% D)", WSAGetLastError ());
        Е ("% S \ п", StrError.c_str ());
        вернуться ложным;
    }

    // Установка для неблокирующего, Incomming соединения будут также наследовать этот
    не u_long NONE = 1;
    если (ioctlsocket (hListenSocket, FIONBIO, &нет) == SOCKET_ERROR)
    {
        strError = strprintf ("Ошибка: Не удалось установить свойства сокета для входящих соединений (ioctlsocket возвращается ошибка% d)", WSAGetLastError ());
        Е ("% S \ п", StrError.c_str ());
        вернуться ложным;
    }

    // Структура sockaddr_in указывает адрес семьи,
    // IP-адрес и порт для сокета, который связывался
    INT nRetryLimit = 15;
    структура sockaddr_in SOCKADDR;
    sockaddr.sin_family = AF_INET;
    sockaddr.sin_addr.s_addr = addrLocalHost.ip;
    sockaddr.sin_port = addrLocalHost.port;
    если (привязка (hListenSocket (структура SOCKADDR *)&SOCKADDR, SizeOf (SOCKADDR)) == SOCKET_ERROR)
    {
        INT nErr = WSAGetLastError ();
        если (nErr == WSAEADDRINUSE)
            strError = strprintf ("Ошибка: Не удалось выполнить привязку к порту% с на этом компьютере. Программа, вероятно, уже работает.", AddrLocalHost.ToString () c_str ()).
        еще
            strError = strprintf ("Ошибка: Не удалось выполнить привязку к порту% S на этом компьютере (привязка возвращается ошибка% d)", AddrLocalHost.ToString () c_str (), nErr).
        Е ("% S \ п", StrError.c_str ());
        вернуться ложным;
    }
    Е ("связан с addrLocalHost =% s \ N \ N", AddrLocalHost.ToString () c_str ()).

    // Прослушивание входящих соединений
    если (слушать (hListenSocket, SOMAXCONN) == SOCKET_ERROR)
    {
        strError = strprintf ("Ошибка: Прослушивание входящих соединений не удалось (слушать возвращается ошибка% d)", WSAGetLastError ());
        Е ("% S \ п", StrError.c_str ());
        вернуться ложным;
    }


    //
    // Начало темы
    //
    если (_beginthread (ThreadSocketHandler, 0, новый РАЗЪЕМ (hListenSocket)) == -1)
    {
        strError = "Ошибка: _beginthread (ThreadSocketHandler) не";
        Е ("% S \ п", StrError.c_str ());
        вернуться ложным;
    }

    если (_beginthread (ThreadOpenConnections, 0, NULL) == -1)
    {
        strError = "Ошибка: _beginthread (ThreadOpenConnections) не";
        Е ("% S \ п", StrError.c_str ());
        вернуться ложным;
    }

    если (_beginthread (ThreadMessageHandler, 0, NULL) == -1)
    {
        strError = "Ошибка: _beginthread (ThreadMessageHandler) не";
        Е ("% S \ п", StrError.c_str ());
        вернуться ложным;
    }

    возвращает истину;
}

BOOL StopNode ()
{
    Е ("StopNode () \ п");
    fShutdown = TRUE;
    nTransactionsUpdated ++;
    в то время как (количество (vfThreadRunning.begin (), vfThreadRunning.end (), правда))
        Сон (10);
    Сон (50);

    // Sockets выключение
    WSACleanup ();
    возвращает истину;
}

недействительный CheckForShutdown (Int N)
{
    если (fShutdown)
    {
        если (п! = -1)
            vfThreadRunning [п] = FALSE;
        _endthread ();
    }
}
[/ Предварительно]
Cryddit сейчас офлайн Пожаловаться на Cryddit   Ответить с цитированием Мультицитирование сообщения от Cryddit Быстрый ответ на сообщение Cryddit

23 декабря 2013, 7:37:33 PM   # 7
 
 
Сообщения: 840
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.


Я просто подумал, что я должен поставить эти туда, где сообщество будет иметь доступ к ним. Это небольшое окно в истории.

Одно интересное замечание о том, что блок генезиса в этом коде имеет другой хэш. 

Cryddit сейчас офлайн Пожаловаться на Cryddit   Ответить с цитированием Мультицитирование сообщения от Cryddit Быстрый ответ на сообщение Cryddit

23 декабря 2013, 7:38:48 PM   # 8
 
 
Сообщения: 1106
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Интересно.

Какой контекст Вы получаете их от Satoshi? (Я предполагаю)

Редактирование: может быть полезно иметь точные файлы, а не вырезания и вставки, чтобы получить "официальный" копия. Не стесняйтесь, напишите их мне, я могу поставить их где-то для вас: pete@petertodd.org
Peter Todd сейчас офлайн Пожаловаться на Питер Тодд   Ответить с цитированием Мультицитирование сообщения от Peter Todd Быстрый ответ на сообщение Peter Todd

23 декабря 2013, 7:41:29 PM   # 9
 
 
Сообщения: 840
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Я был в списке криптографической Metzdowd в то время.

Satoshi отправил просить профессиональные криптографические вундеркинд пересмотреть свой проект.

Hal Финни и я был два из тех, кто ответил, и он отправил в архив некоторые из нас.

Hal, вероятно, имеет тот же самый архив в своей почте, а также, если он спас его.
Cryddit сейчас офлайн Пожаловаться на Cryddit   Ответить с цитированием Мультицитирование сообщения от Cryddit Быстрый ответ на сообщение Cryddit

23 декабря 2013, 7:47:18 PM   # 10
 
 
Сообщения: 1106
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Круто!

То, что я сразу заметил, как scriptPubKey и все начать с OP_CODESEPARATOR; для меня это интересно посмотреть, как я прокомментировал несколько месяцев назад о том, как это позволило бы право подписи на сделки, которые будут делегированы.
Peter Todd сейчас офлайн Пожаловаться на Питер Тодд   Ответить с цитированием Мультицитирование сообщения от Peter Todd Быстрый ответ на сообщение Peter Todd

23 декабря 2013, 7:47:45 PM   # 11
 
 
Сообщения: 1106
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Это все, что источник у вас есть? Нет script.cpp?
Peter Todd сейчас офлайн Пожаловаться на Питер Тодд   Ответить с цитированием Мультицитирование сообщения от Peter Todd Быстрый ответ на сообщение Peter Todd

23 декабря 2013, 7:55:25 PM   # 12
 
 
Сообщения: 840
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

То есть весь источник. Там не было script.cpp в то время.  
Cryddit сейчас офлайн Пожаловаться на Cryddit   Ответить с цитированием Мультицитирование сообщения от Cryddit Быстрый ответ на сообщение Cryddit

23 декабря 2013, 8:00:46 PM   # 13
 
 
Сообщения: 1512
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.


Сатоши Накамото Satoshi в vistomail.com
Пн 17 ноября 12:24:43 EST 2008

    Предыдущее сообщение: Bitcoin P2P электронных денег бумага
    Следующее сообщение: Bitcoin P2P электронных денег бумага
    Сообщения, упорядоченные по: [дате] [дискуссии] [теме] [автору]

...(СНИП) ...

Я считаю, что я работал через все эти маленькие подробности по
в прошлом году полтора при кодировании, и там было много из них.
Функциональные детали не распространяется в работе, но
Исходный код скоро.  Я послал вам основные файлы.
(Предоставляется по запросу на данный момент, полный выпуск в ближайшее время)


Сатоши Накамото
deepceleron сейчас офлайн Пожаловаться на deepceleron   Ответить с цитированием Мультицитирование сообщения от deepceleron Быстрый ответ на сообщение deepceleron

23 декабря 2013, 8:07:38 PM   # 14
 
 
Сообщения: 1106
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Также интересно, как есть "getmywtxes" Команда в ProcessMessage, которая выглядит, как он разработан, чтобы получить Транзакции тонкого клиента для них. Кажется, что он извлекает все операции, связанные с указанным scriptPubKey хэш в определенном блоке.

Там также "WTX" Команда, которая, кажется, добавить CWalletTx к локальному бумажнику узла! Bizzare - вполне возможно, просто некоторый код для тестирования.

Принять блок завораживает, просто посмотрите на воздаем "Добавить атомы отзывов пользователей для монет, созданных" (?!)


То есть весь источник. Там не было script.cpp в то время.  

Вы имеете в виду это все, что он послал вас; источник, очевидно, отсутствуют функции, которые вызываются и не было бы скомпилированные. Жалко, интересно посмотреть, Bitcoin в этой промежуточной стадии развития.
Peter Todd сейчас офлайн Пожаловаться на Питер Тодд   Ответить с цитированием Мультицитирование сообщения от Peter Todd Быстрый ответ на сообщение Peter Todd

23 декабря 2013, 8:13:32 PM   # 15
 
 
Сообщения: 840
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.


То есть весь источник. Там не было script.cpp в то время.  

Вы имеете в виду это все, что он послал вас; источник, очевидно, отсутствуют функции, которые вызываются и не было бы скомпилированные. Жалко, интересно посмотреть, Bitcoin в этой промежуточной стадии развития.

Вы правы; Сам источник относится к нескольким файлам заголовков, которые не были в архиве источника я получил. Это вещи, я думаю, что Satoshi чувствовал, что ему нужен плюсы для обзора. 



Cryddit сейчас офлайн Пожаловаться на Cryddit   Ответить с цитированием Мультицитирование сообщения от Cryddit Быстрый ответ на сообщение Cryddit

23 декабря 2013, 8:30:45 PM   # 16
 
 
Сообщения: 1526
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

OP_CODESEPARATOR был в первой выпущенной версии тоже. Это была часть его сломанный метода запуска скриптов с помощью конкатенации.

Отзывы пользователей, потому что он изначально предназначен Bitcoin иметь интегрированный P2P eBay рынок стиль. Идея заключалась в том, что оценки пользователей / обзоры будут взвешены, насколько добыча вы сделали. Она не была закончена, и в конечном итоге код, чтобы поддержать его вынимали - он понял, что JSON-RPC API было более важным.
Майк Хирн сейчас офлайн Пожаловаться на Mike Хирн   Ответить с цитированием Мультицитирование сообщения от Mike Хирн Быстрый ответ на сообщение Mike Хирн

23 декабря 2013, 8:39:54 PM   # 17
 
 
Сообщения: 1106
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

OP_CODESEPARATOR был в первой выпущенной версии тоже. Это была часть его сломанный метода запуска скриптов с помощью конкатенации.

В релиз v0.1 OP_CODESEPARATOR Bitcoin всегда был вставлен между scriptSig и scriptPubKey до вызова EvalScript () Этот предварительный релиз исходный код означает, что не было сделано автоматически, что позволяет скриптам воспользоваться тем, что после того, как тот факт, делегировать право подписи после того, как факт. (Хотя в полной мере воспользоваться преимуществами этой идеи вам нужно понятие OP_CODESEPARATOR "стек")

Идея заключается в том "сломанный" только в этом OP_RETURN изначально может вызвать скрипт для возврата действителен преждевременно; теперь OP_RETURN только не сценарий преждевременно явный дизайн OP_CODESEPARATOR будет работать нормально.
Peter Todd сейчас офлайн Пожаловаться на Питер Тодд   Ответить с цитированием Мультицитирование сообщения от Peter Todd Быстрый ответ на сообщение Peter Todd

23 декабря 2013, 8:52:32 PM   # 18
 
 
Сообщения: 1512
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Cryddit пересылается по электронной почте и исходный файл, прикрепленный:
Цитата: Satoshi
> Вместо того, чтобы вы, ребята, пытаясь угадать, и заполнить пробелы
> и изобретать колесо, вот исходные ядер прикрепленных файлов
> (Bitcoin_src1.rar), так что вы можете увидеть, как я его реализации.

> main.h и main.cpp являются система Bitcoin
> node.h и node.cpp являются равноправными инфраструктурами сети связи

> Satoshi
http://we.lovebitco.in/bitcoin_src1.rar



Это выглядит как весело место, чтобы оставлять немного больше историй:

http://sourceforge.net/users/nakamoto2 - Регистрация: 2008-10-05

Благодаря robots.txt, нет исходного кода для восстановления от SourceForge через Internet Archive, но вот скриншот от 3 января 2009 года (дата же, как генезис), с неизданным blockchain в блоке 213 и три других соединений.

deepceleron сейчас офлайн Пожаловаться на deepceleron   Ответить с цитированием Мультицитирование сообщения от deepceleron Быстрый ответ на сообщение deepceleron

23 декабря 2013, 9:45:09 PM   # 19
 
 
Сообщения: 164
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Это очень странно. Взгляни: https://blockchain.info/address/19CncWdnU57yq4QHBNVPdScFB54JkPGu28
Valle сейчас офлайн Пожаловаться на Valle   Ответить с цитированием Мультицитирование сообщения от Valle Быстрый ответ на сообщение Valle

23 декабря 2013, 9:49:33 PM   # 20
 
 
Сообщений: 80
Цитировать по имени
цитировать ответ
по умолчанию Re: Bitcoin источник с ноября 2008 года.

Это очень странно. Взгляни: https://blockchain.info/address/19CncWdnU57yq4QHBNVPdScFB54JkPGu28
Что странно об этом? Это просто: этот адрес не был использован, пока кто-то послал тысячу satoshis к нему несколько месяцев назад.
michagogo сейчас офлайн Пожаловаться на michagogo   Ответить с цитированием Мультицитирование сообщения от michagogo Быстрый ответ на сообщение michagogo



Как заработать Биткоины?

Bitcoin Wallet * Portefeuille Bitcoin * Monedero Bitcoin * Carteira Bitcoin * Portafoglio Bitcoin * Bitcoin Cüzdan * 比特币钱包

bitcoin-zarabotat.ru
Почта для связи: bitcoin-zarabotat.ru@yandex.ru

3HmAQ9FkRFk6HZGuwExYxL62y7C1B9MwPW