快讯:
1月21日消息,数字资产交易平台Blockex证实,近日公司在裁员,以减少成本。Blockex去年曾通过ICO募集到了2400万美元,后因币价下跌、基金投资失败屡受打击。
今日消息,从1月15日至3月31日,富士通正对宫古岛市约20家公司的约200名员工进行进行健康验证相关测试。该测试系统将使用区块链技术管理相关数据,旨在确保个人信息保护和防篡改。
1、播客主持人:美国政府关门对BTC来说或是个机会。 2、bitcoin.org网站公布比特币论文12种语言的翻译版本。 3、媒体:比特大陆称扩张存在问题,将回归核心业务、实现精细化运营。 4、财经评论员程智鹏:利益即得者矿工阻碍以太坊性能的提高。 5、Hyperledger执行董事:数据将成为石油一样的资产,区块链有助于防止泄漏。 6、对于基于EOS的侧链BOS上线,老猫发文提出质疑。 7、研究:Grin可选择XRP和XMR作为估值参照,对应的估值区间为1.89美元到33.14美元。 8、谷歌年度热搜词公布,“What is Bitcoin?”成为问题搜索排名第一。
1月21日消息,数字资产交易平台Blockex证实,近日公司在裁员,以减少成本。Blockex去年曾通过ICO募集到了2400万美元,后因币价下跌、基金投资失败屡受打击。
今日消息,从1月15日至3月31日,富士通正对宫古岛市约20家公司的约200名员工进行进行健康验证相关测试。该测试系统将使用区块链技术管理相关数据,旨在确保个人信息保护和防篡改。
1、播客主持人:美国政府关门对BTC来说或是个机会。 2、bitcoin.org网站公布比特币论文12种语言的翻译版本。 3、媒体:比特大陆称扩张存在问题,将回归核心业务、实现精细化运营。 4、财经评论员程智鹏:利益即得者矿工阻碍以太坊性能的提高。 5、Hyperledger执行董事:数据将成为石油一样的资产,区块链有助于防止泄漏。 6、对于基于EOS的侧链BOS上线,老猫发文提出质疑。 7、研究:Grin可选择XRP和XMR作为估值参照,对应的估值区间为1.89美元到33.14美元。 8、谷歌年度热搜词公布,“What is Bitcoin?”成为问题搜索排名第一。
1月21日消息,数字资产交易平台Blockex证实,近日公司在裁员,以减少成本。Blockex去年曾通过ICO募集到了2400万美元,后因币价下跌、基金投资失败屡受打击。
今日消息,从1月15日至3月31日,富士通正对宫古岛市约20家公司的约200名员工进行进行健康验证相关测试。该测试系统将使用区块链技术管理相关数据,旨在确保个人信息保护和防篡改。
1、播客主持人:美国政府关门对BTC来说或是个机会。 2、bitcoin.org网站公布比特币论文12种语言的翻译版本。 3、媒体:比特大陆称扩张存在问题,将回归核心业务、实现精细化运营。 4、财经评论员程智鹏:利益即得者矿工阻碍以太坊性能的提高。 5、Hyperledger执行董事:数据将成为石油一样的资产,区块链有助于防止泄漏。 6、对于基于EOS的侧链BOS上线,老猫发文提出质疑。 7、研究:Grin可选择XRP和XMR作为估值参照,对应的估值区间为1.89美元到33.14美元。 8、谷歌年度热搜词公布,“What is Bitcoin?”成为问题搜索排名第一。
比特币源码分析:utxo刷盘

比特币源码分析:utxo刷盘

姜家志 发布在 技术指南 14724

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循环,不断迭代,将值写入磁盘。

文章标签: UTXO
评论
登录 账号发表你的看法,还没有账号?立即免费 注册