风险提示:理性看待区块链,提高风险意识!
比特币源码分析:utxo刷盘
首页 > 币界资讯 > 区块链知识 2018-03-02 09:45:00

utxo的刷盘逻辑主要在txdb.cpp中实现,主要是 CoinsViewDB::batchwrite这个函数。下面我们来分析一下:

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...\n",
 (unsigned int)changed, (unsigned int)count);
 return ret;
 }

在前面我们介绍过 CDBWrapper主要是对 leveldb的一个简单封装,定义一个CDBWrapper db;我们拿着 db 就可以实现相应的操作。

1

接下来迭代mapCoins,并填充其值,这里最主要的就是作为k-v数据库的leveldb中的key与value如何获得:

key

CoinEntry是一个辅助工具类。

struct CoinEntry {
 COutPoint *outpoint;
 char key;
 CoinEntry(const COutPoint *ptr)
 : outpoint(const_cast(ptr)), key(DB_COIN) {}
 template void Serialize(Stream &s) const {
 s << key;
 s << outpoint->hash;
 s << VARINT(outpoint->n);
 }
 };

key指向的是outpoint,具体结构如下:

2

我们将序列化后的值当作key,作为entry的参数,同时作为db.write的key。

关于db.write和db.WriteBatch二者之间的联系,前面已经详细分析。

value

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;

同样的,我们进行序列化并使用CTxOutCompressor对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);
 }
 };

这时候我们就拿到了db.write的value值,这时候我们通过for循环,不断迭代,将值写入磁盘。

上一篇: 闪电网络入门:如何发送你的第一笔交易?
下一篇: 区块链技术(11):RLPx加密握手协议研究
推荐专栏
web3首席知识博主
一位相信价值投资的币圈KOL。稳定盈利的缠论野生交易员 #BTC行情分析师 #价值投资 #链上数据分析
爱Web 3,爱生活,爱科技,爱炒币的老韭菜
热门币种
更多
币种
价格
24H涨跌幅
BTC比特币
¥264,723.74
37,091.22 USDT
+0.1%
ETH以太坊
¥14,416.22
2,019.90 USDT
-0.12%
USDT泰达币
¥7.20
1.01 USDT
0%
BNB币安币
¥1,625.40
227.74 USDT
+0.36%
XRP瑞波币
¥4.32
0.60460 USDT
+0.37%
USDC
¥7.14
1.00 USDT
+0.03%
SOLSolana
¥398.85
55.89 USDT
+1.54%
OKBOK币
¥398.61
55.85 USDT
-1.64%
ADA艾达币
¥2.68
0.37580 USDT
-1.16%
DOGE狗狗币
¥0.55160
0.07730 USDT
-1.52%
热搜币种
更多
币种
价格
24H涨跌幅
Terra Classic
¥0.00
9.402E-5 USDT
-18.95%
Gala
¥0.18
0.025374 USDT
-4.66%
dYdX
¥22.58
3.1918 USDT
-0.91%
比特股
¥0.05
0.006964 USDT
+4.28%
PancakeSwap
¥15.52
2.1936 USDT
-2.74%
Conflux
¥1.08
0.1524 USDT
-2.87%
Filecoin
¥31.45
4.4454 USDT
-0.69%
FTX Token
¥29.82
4.2155 USDT
+16.96%
Yield Guild Games
¥2.55
0.3608 USDT
-0.52%
Shiba Inu
¥0.00
8.14E-6 USDT
-2.51%
比特币
¥262,381.44
37091.22 USDT
+0.1%
比原链
¥0.07
0.010011 USDT
-4.38%
最新快讯
更多
汇丰、恒生、渣打、富邦华一四家外资银行入围首批“数字人民币”业务试点名单
2023-11-28 19:06:57
摩根大通和Apollo计划建立代币化“企业主网”
2023-11-28 19:03:57
Nansen2公测版本上线,新增链上数据异动、智能搜索等功能
2023-11-28 18:59:52
西班牙公民需在明年3月底前申报其海外平台上加密货币持仓
2023-11-28 18:53:43
Nansen2已公开测试
2023-11-28 18:53:38
dYdX基金会:主网启动以来超过1645万DYDX被质押
2023-11-28 18:52:07
NicCarter等比特币倡导者发文:比特币挖矿是清洁能源和平衡电网的关键工具
2023-11-28 18:47:58
下载币界网APP