當前位置:
首頁 > 最新 > 比特幣源碼分析:utxo刷盤

比特幣源碼分析:utxo刷盤

utxo的刷盤邏輯主要在中實現,主要是 這個函數。下面我們來分析一下:

bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { CDBBatch batch(db); size_t count = 0; size_t changed = 0; for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) { if (it->second.flags & CCoinsCacheEntry::DIRTY) { CoinEntry entry(&it->first); if (it->second.coin.IsSpent()) { batch.Erase(entry); } else { batch.Write(entry, it->second.coin); } changed++; } count++; CCoinsMap::iterator itOld = it++; mapCoins.erase(itOld); } if (!hashBlock.IsNull()) { batch.Write(DB_BEST_BLOCK, hashBlock); } bool ret = db.WriteBatch(batch); LogPrint("coindb", "Committed %u changed transaction outputs (out of %u) " "to coin database...
", (unsigned int)changed, (unsigned int)count); return ret; }

在前面我們介紹過 主要是對 leveldb的一個簡單封裝,定義一個我們拿著 db 就可以實現相應的操作。

接下來迭代mapCoins,並填充其值,這裡最主要的就是作為k-v資料庫的leveldb中的key與value如何獲得:


CoinEntry是一個輔助工具類。

struct CoinEntry { COutPoint *outpoint; char key; CoinEntry(const COutPoint *ptr) : outpoint(const_cast(ptr)), key(DB_COIN) {} template void Serialize(Stream &s) const { shash; sn); } };

key指向的是outpoint,具體結構如下:

我們將序列化後的值當作key,作為entry的參數,同時作為的key。

關於db.write和db.WriteBatch二者之間的聯繫,前面已經詳細分析。


value的值就是 coin 序列化後的值,而 coin 又包含了txout,如下:

class Coin { //! Unspent transaction output. CTxOut out; //! Whether containing transaction was a coinbase and height at which the //! transaction was included into a block. uint32_t nHeightAndIsCoinBase;

同樣的,我們進行序列化並使用對txout進行壓縮,REF是一個宏定義,是非const轉換,我們首先斷言這個幣是否被消費:

template void Serialize(Stream &s) const { assert(!IsSpent()); ::Serialize(s, VARINT(nHeightAndIsCoinBase)); ::Serialize(s, CTxOutCompressor(REF(out))); }

txout主要包含:

class CTxOut { public: Amount nValue; CScript scriptPubKey;

對nValue和scriptPubKey採用了不同的壓縮方式來進行序列化,如下:

class CTxOutCompressor { private: CTxOut &txout; public: template inline void SerializationOp(Stream &s, Operation ser_action) { if (!ser_action.ForRead()) { uint64_t nVal = CompressAmount(txout.nValue); READWRITE(VARINT(nVal)); } else { uint64_t nVal = 0; READWRITE(VARINT(nVal)); txout.nValue = DecompressAmount(nVal); } CScriptCompressor cscript(REF(txout.scriptPubKey)); READWRITE(cscript); } };

這時候我們就拿到了的value值,這時候我們通過for循環,不斷迭代,將值寫入磁碟。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 巴比特資訊 的精彩文章:

墨西哥預計未來幾周內通過數字貨幣監管法案
馬來西亞成立特別工作組研究區塊鏈

TAG:巴比特資訊 |