美文网首页区块链研习社程序员
比特币探究之MerkleTree

比特币探究之MerkleTree

作者: 魏兆华 | 来源:发表于2018-07-22 10:25 被阅读36次

在比特币区块里,所有交易都按照Merkle Tree的格式组织起来,再跟区块头里的hashMerkleTreeRoot对应起来,就可以保证本区块交易信息的不可篡改。关于Merkle Tree的解释和具体算法,可以参见Merkle Tree学习这篇文章,讲得很好,这里不重复了,仅贴张图示意一下:

MerkleTree结构图
比特币源码当中,关于Merkle Tree的实现,是在src/consensus/merkle.cpp里。Merkle树的建立,是通过IncrementExtraNonce函数(在miner.cpp)被调用:
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);

下面是BlockMerkleRoot的实现:

//mutated用于报告是否有重复交易,其默认值是nullptr
uint256 BlockMerkleRoot(const CBlock& block, bool* mutated)
{
    std::vector<uint256> leaves;
    leaves.resize(block.vtx.size());
    //用交易哈希值去填充叶子
    for (size_t s = 0; s < block.vtx.size(); s++) {
        leaves[s] = block.vtx[s]->GetHash();
    }
    return ComputeMerkleRoot(std::move(leaves), mutated);
}

ComputeMerkleRoot用于计算树根的哈希:

uint256 ComputeMerkleRoot(std::vector<uint256> hashes, bool* mutated) {
    bool mutation = false;
    //从叶子向根逐层循环计算
    while (hashes.size() > 1) {
        if (mutated) {
            for (size_t pos = 0; pos + 1 < hashes.size(); pos += 2) {
                //发现相邻的重复交易
                if (hashes[pos] == hashes[pos + 1]) mutation = true;
            }
        }
        //叶子总数是单数,就把最后一个哈希复制一次
        if (hashes.size() & 1) {
            hashes.push_back(hashes.back());
        }
        //每算完一层,节点数减一半
        SHA256D64(hashes[0].begin(), hashes[0].begin(), hashes.size() / 2);
        hashes.resize(hashes.size() / 2);
    }
    if (mutated) *mutated = mutation;
    if (hashes.size() == 0) return uint256();
    //返回最终的根节点
    return hashes[0];
}

这里的SHA256D64函数定义在sha256.cpp里:

void SHA256D64(unsigned char* out, const unsigned char* in, size_t blocks)
{
    //... 去除了部分无用代码
    while (blocks) {
        TransformD64(out, in);
        out += 32;
        in += 64;
        --blocks;
    }
}

对照上面的调用,可以看到out和in指向同一块地址,这个实际上不影响,TransformD64函数是在全部读取完毕,完成加密计算之后再写入的。这个加密算法的源码很长,网上标准教程也多,这里就不贴了。


欢迎转载,请注明出处。

相关文章

  • 比特币探究之MerkleTree

    在比特币区块里,所有交易都按照Merkle Tree的格式组织起来,再跟区块头里的hashMerkleTreeRo...

  • 区块链的java实现

    概述 MerkleTree被广泛的应用在比特币技术中,本文旨在通过代码实现一个简单的MerkleTree,并计算出...

  • 比特币探究之挖矿

    源码部分解析如下,其中的中文注释为笔者添加。 相关源码如下: 下一讲继续解析交易打包和POW工作量证明。 本文欢迎...

  • 比特币源码研读

    forest21000版 比特币源码研读之一比特币源码研读之二比特币源码研读之三比特币源码研读之四比特币源码研读之...

  • 比特币探究之脚本执行

    本来打算接着写交易签名的,研究半天发现不搞清楚脚本,就没办法讲签名。那还是先讲脚本吧。 比特币脚本的详细介绍和运作...

  • 互联网校招技术面试解析

    比特币入门之获取,消费和特点 如何获取比特币 比特币通过公开的复杂算法 生成。任何人都可以下载软件制造 比特币,但...

  • 比特币入门之获取,消费和特点

    比特币入门之获取,消费和特点 如何获取比特币 比特币通过公开的复杂算法 生成。任何人都可以下载软件制造 比特币,但...

  • 比特币现金(Bitcoin Cash)分叉是个危险的伎俩

    新创立的比特币现金(BCH)是比特币(BTC)的一个仓促的衍生品,比特币过去曾经有许多克隆品,比特币现金也是其中之...

  • 小白杨学区块链003认识区块链P2P网络

    本文探究一下比特币区块链网络: OKcoin网站信息中选择一个区块来研究一下: 点开比特币区块链472221区块:...

  • 比特币探究之工作量证明

    比特币采用工作量证明(POW)的方式来确保取得共识。在解析之前,先看一下比特币定义的arith_uint256类,...

网友评论

    本文标题:比特币探究之MerkleTree

    本文链接:https://www.haomeiwen.com/subject/mkklmftx.html