目录
一、UTXO
二、区块链中的例子
1.Block #529709
(2)Block header
(3)交易信息
2.普通转账交易
3.概率分析
4.公平性保证
5.比特币区块总量
6.安全性分析
区块链是去中心化的账本,BTC采用的是基于交易的账本模式(Transaction-based Ledger),每个区块里记录的是交易信息,所以,我们并不能直接得到每个账户上有多少钱,而是需要根据区块链中的交易记录来推算。
一、UTXO
比特币中的全节点要维护一个叫UTXO(Unspent Transaction Output)的数据结构,即还没有被花出去的交易的输出。一个交易可能有多个输出,被花掉的就不在UTXO里了,如下图1-1所示。UTXO集合中的每个元素要给出产生这个输出的交易的哈希值,以及它在这个交易中是第几个输出。用这两个信息就可以定位到一个确定的交易中确定的输出。使用UTXO可以用来快速检测双花攻击,想知道新发布的交易是不是合法的,要查一下全节点存在内存中的UTXO。想要交易的币只有在这个UTXO这个集合里才算是合法的,否则要么是这个币是不存在的,要么是这笔钱已经花过了的。
没有花出的币有可能是拥有者不想花或者没办法花(忘记了自己的密钥),但是这些记录都会永远被保存在UTXO中。每个交易可以有多个输入,也可以有多个输出,但是需要满足“所有输入得金额=所有输出得金额”(Outputstotal Inputs = Total Outputs)。有些交易的总输入可能略微大于总输出,如:总输入是1个BTC,总输出是0.99个BTC,这之中的差额就作为记账费给了获得记账权的那个节点。这些差额被称为比特币系统中的交易费(Transaction Fee)。
除了基于交易的账本模式之外,还有一种模式,叫基于账户的账本模式(Account-based leger),以太坊系统用的就是这种模式。在这种模式下,系统需要显示地记录每个账户上确切有多少余额。
二、区块链中的例子
1.Block #529709
(1)基本信息
(2)Block header
class CBlockHeader{public://headerint32_t nVersion;//当前使用的比特币协议的版本号,没法修改(4字节)uint256 hashPrevBlock;//前一个区块块头哈希值(32字节),不能修改uint256 hashMerkleRoot;//Merkle Tree的根哈希值(32字节);//通过修改Merkle Tree中铸币交易的CoinBase域当作ExtraNonce来调整其根哈希值uint32_t nTime;//区块产生时间,有一定调整余地(4字节);//比特币系统并不要求非常精确的时间,这个时间可以在一定范围内调整uint32_t nBits;//挖矿后的目标阈值编码后的版本(4字节);//只能按照协议中的要求定期进行调整,不能随便改uint32_t nNonce;//(4字节)单纯靠调整nonce的值很大概率找不到符合难度要求的}
(3)交易信息
铸币交易是没有交易来源的,所以可以在其CoinBase域里随便写入内容,如下图2-2所示。
铸币交易的变化会使该交易的哈希发生变化,变化沿着Merkle Tree一路向上传递,最终使整棵Merkle Tree的根哈希值发生变化,间接地调整块头(Block Header)的哈希值,如图2-3所示。所以可以将这个字段当做一个Extra Nonce,块头的nonce字段不够用,就再拿着这个域的一部分字节一起调整,就增大了搜索空间。
2.普通转账交易
比特币系统中的输入和输出都是由脚本指定的。在比特币系统中,验证交易的合法性就是把交易的Input Scripts和Output Scripts配对后执行来完成的,如将本交易中的输入脚本和上一个交易中的输出脚本配对后执行,即可验证其合法性,如图2-4所示。
3.概率分析
伯努利试验(Bernoulli trial:a random experiment with binary outcome)。掷硬币就是一个最简单的伯努利试验,要么正面朝上要么反面朝上,这两个概率不一定一样大。对于挖矿而言,也是有成功和失败两种可能,但是成功和失败的概率相差非常悬殊,成功的概率微乎其微。
当进行了大量的伯努利试验,这些伯努利试验就构成了伯努利过程(Bernoulli process:a sequence of independent Bernoulli trails)。伯努利过程的一个性质是无记忆性(Memoryless),即做大量的试验,前面的试验结果对后面没有影响。例如,掷硬币很多次都是反面朝上,下一次掷硬币正面朝上的概率也不会增加,也就是说前面的实验结果对于后面实验结果不会产生影响,实验结果相对独立。
当伯努利过程的n(试验次数)很大而p(每次试验成功概率)很小时,可以近似为泊松分布。这里挖矿就是这样一个试验次数很多每次试验成功概率很小的伯努利过程,所以可以近似为泊松过程(Poisson process)。
4.公平性保证
这里的公平性保证又叫Progress Free。出块时间是服从指数分布(Exponential Distribution)的,整个系统的出块时间会按照比特币协议被调整在10分钟左右。其函数图像大致如图2-5所示,横轴表示出块时间(Time to Next Block),纵轴是概率密度(Probability Density)。
这里的出块时间是整个系统的出块时间并不是每个矿工的出块时间。矿工的出块时间取决于其算力占系统总算力的百分比。Progress Free中,过去做了多少工作不会让后续成功的概率变化。这个性质是必要的,它是挖矿公平性的保证。
5.比特币区块总量
出块奖励是系统中产生新的BTC的唯一途径,而且由协议可知,出块奖励每隔21万个区块要减半,所以新产生的BTC的总量就形成了一个几何序列(Geometric Series)。
求解比特币挖矿的puzzle除了比拼算力之外,没有任何实际意义,但对维护BTC系统的安全性是至关重要的。Bitcoin is security by mining。挖矿提供了一种凭借算力投票的有效手段。
6.安全性分析
假设在现在的比特币系统中,大部分算力掌握在诚实的节点手里,这只能说明有比较大的概率下一个区块是由诚实矿工发布的,并不能完全保证记账权不会落在有恶意的节点手里。
(1)偷走他人的钱
假设一个有恶意的节点M获得了记账权,它想把节点A的钱转走,但由于M没有A的私钥所以没有办法伪造A的签名。如果M任何写个不正确的签名上去,都会导致诚实的节点不会接受这个候选区块,而是继续沿着上一个区块扩展,如图2-6所示。因为这个区块是不合法的,所以多长都不是最长合法链,所以,这种攻击方式属于无效攻击。
(2)分叉攻击
假设M把想要把比特币转给A,然后就紧接着挖矿挖到了一个区块,在这里填写了M把比特币转给自己的交易,以希望沿着这个区块成为最长合法链,这样就能将转给A的区块挤掉,从而实现将花出去的比特币回滚,如下图2-7所示。
假设我们现在将A→M的区块认为是缺省的,把它认为是one confirmation,那么缺省的是要等6个confirmation(大约一小时),才认为one confirmation区块中的交易是不可篡改的。比特币中还存在着zero confirmation,即交易刚发布出去,还没有写入区块链中的时候,就认为交易已经不可篡改了,如图2-8中红线部分就可以认为是zero confirmation。
zero confirmation实际使用的比较广泛,有两个原因:(1)两个交易有冲突,节点接收最先听到的交易。上面分叉攻击的例子中M->A后的M->M’,大多诚实节点会将其拒绝。(2)除了区块链之外有其他手段来保护自己的交易。
如果觉得《北大肖臻老师《区块链技术与应用》系列课程学习笔记[3]BTC的具体实现》对你有帮助,请点赞、收藏,并留下你的观点哦!