Bitcoin比特币的优秀设计详解

说说比特币用到的一些精妙的设计:

1、UTXO模型。正常人去设计一个货币系统,通常会用帐号系统,也就是一个帐号对应一个余额。为了方便介绍,下面给交易的数据结构。

class COutPoint
{
public:
    uint256 hash; //上一个交易的hash
    uint32_t n;   //hash对应的这个交易的vout的index
}
class CTxIn
{
public:
    COutPoint prevout; //这个输入使用的那个交易的输出
    CScript scriptSig; //签名
    uint32_t nSequence;
    CScriptWitness scriptWitness; // 隔离见证的签名
}
class CTxOut
{
public:
    CAmount nValue;
    CScript scriptPubKey; //输出锁定脚本
}
class CTransaction
{
public:
    const std::vector<CTxIn> vin; // vin.size() >= 1
    const std::vector<CTxOut> vout; // vout.size() >= 1
    const int32_t nVersion;
    const uint32_t nLockTime;
}

CTxOut代表一笔转账,有金额和锁定脚本。锁定脚本有好几种,这里可以简单的认为是支付到某个比特币地址,谁能提供这个地址对应的签名就能创建一个交易,并用它作为输入把转到任意的输出。一个UTXO有点类似现实中的一个硬币,只不过UTXO有任意的面值(正确是大于粉尘值且小于比特币上限)。好处是易于跟踪,当然也是它的缺点,不具匿名性。另外一个优点是锁定脚本多样性。

2、区块头。区块和区块体分开,方便同步传输。

class CBlockHeader
{
public:
    // header
    int32_t nVersion;
    uint256 hashPrevBlock;
    uint256 hashMerkleRoot;
    uint32_t nTime;
    uint32_t nBits;
    uint32_t nNonce;
}
class CBlock : public CBlockHeader
{
public:
    std::vector<CTransactionRef> vtx;
}

区块的主要数据在交易,区块头的数据只占80字节。区块头的hash包含算力验证,仅依据区块头就能判断是否数据合法、根据算力选择最长链,进而决定是否要下对应区块数据(具体的交易)。区块头数据小,即便传输几千个区块头,也能在很短时间内完成。

3、BlockChain。区块通过字段hashPrevBlock链接起来,形成链状,hashPrevBlock指向前一个区块。链越长,累加的算力越大,要想篡改也就越难。

4、MerkleTree。区块头并没有包含具体交易的数据,它是如何保证交易数据不被修改?是的,就是hashMerkleRoot这个字段。它是交易数组vtx中所有交易的hash,相邻两两再hash,得到新的数组,对这个新数组重复前面操作,直到只剩一个值。有兴趣的可以看 https://www.cnblogs.com/fengzhiwu/p/5524324.html

5、CoinBase交易。既然一笔交易需要包含输入输出,那第一笔交易的输入哪里来?比特币规定,矿工可以在区块中构造一个没有输入的交易,输出的值等于区块奖励+区块其他交易的手续费(输入减输出的差值为手续费),并且放在vtx数组的第一个位置。CoinBase交易的输出需要满足100个高度才能使用。

6、pow。挖矿共识Proof of work。矿工那么多,谁作为话事人呢?毕竟挖到区块有笔不菲的收入。pow共识就是为了确定矿工而产生的。谁能最快提供一个区块,它的hash值小于目标值,这个区块就是他的。hash值目前只能依靠硬碰,不断的修改nNonce的值去偿试。目标值会不断调整,当算力增时,出块时间变快了,目标值为了控制出块时间间隔在10分钟左右,目标值变小。用区块的方式还可以解决双花的问题。

7、区块链公理:一切依赖经济惩罚的共识都是垃圾。比特币的优点是利用数学保证区块链数据正确。有些区块链往往为了区块安全加入经济惩罚机制,这洽洽导致区块不安全。

发布了12 篇原创文章 · 获赞 1 · 访问量 910

猜你喜欢

转载自blog.csdn.net/huafable007/article/details/90708877
今日推荐