0%

BTC四---实现

实现

transaction-based ledger

BTC(比特币):基于交易的账本模式(transaction-based ledger),每个区块记录交易信息,但是系统中没有统一的记录,比如需要知道某个账户有多少钱,这个还需要交易记录来推算

比特币的全节点要维护一个UTXO的数据结构

UTXO:Unspent Transaction Output,还没有被花出去的交易的输出,区块链中有很多交易,有些交易的输出可能被花掉了,有些还没有被花掉,没有被花掉的交易的输出的集合叫做UTXO

UTXO中的每个元素要给出产生这个输出的交易的hash值,以及他在这个交易里是第几个输出,就可以定位到这个UTXO中的输出,那么这个UTXO集合的作用是什么?为什么要维护这样一个数据结构

作用:防范double spending attack,所以全节点要在内存中维护UTXO数据结构,以便快速检测double spending attack,

随着交易的发布,每个交易要消耗UTXO中的输出,同时也会产生一些新的输出

每个交易所有输入的金额,要等于所有输出的金额:total inputs = total outputs

发布区块的那个结点为什么要把你的交易打包在区块里?这样做对她有什么好处吗?

如果只有出块奖励,那么自私的结点就只会打包他自己的交易,同时也节省带宽

所以比特币系统设定了第二个激励机制:交易费(transaction fee),你把我的交易打包在区块里,我给你点小费,所以就会出现total inputs >= total outputs的情况,多的比特币充当了小费

目前矿工去争取记账权,主要还是为了得到出块奖励,但是因为21个区块都会减少出块奖励

比特币系统中差不多10分钟会创建一个区块,计算下来差不多每四年就会减半(出块奖励)

区块的例子

account-based ledger

以太坊就是这种模式,在这种模式总,系统显式的记录每个账户上有多少个币,比特币的隐私保护就比较好一些

Height:是区块的序号,Difficulty:挖矿的难度(每隔2016个区块要调整这个难度,保持出块时间在10分钟左右)

注意:计算hash值都是计算block header的哈希值,不包含block body的哈希值

所谓的挖矿,就是不断地调整随机数nonce,使得整个block header的哈希值小于等于给定的目标阈值,这个目标阈值表示成16进制就是前面有一长串的0,所以凡是符合难度要求的区块,它的块头的哈希值,算出来都是要有一长串的0

每个发布的区块里都包含一个特殊的铸币交易

这个对Merkle tree的根哈希值有什么影响吗

coinbase中的前八个字节当作extra nonce来用nonce从2^32->2^96

所以真正挖矿的时候是有两层循环的,外层循环调整coinbase域的extra nonce ,算出block header中的根哈希值之后,内层循环在调整header里的nonce

概率分析

每次尝试nonce可以看作是Bernoulli trial:a random experiment with binary outcome

挖矿,每次尝试nonce,成功的概率是微乎其微的,大概率是不行的,如果我们做很多的Bernoulli trial,每个实验都是随机的,这些Bernoulli trial就构成了Bernoulli process:a sequence of independent Bernoulli trials,Bernoulli trial的一个性质是无记忆性:memory less,你做大量的实验,前面的结果和后面的结果是没有关系的

实验很多,每次成功的概率很小,多重伯努利可以用Poisson process来近似,我们关心的是,系统中产生下一个区块的时间,这个在概率中可以推导出来出块时间是服从指数分布的exponential distribution

整个系统平均的出块时间是十分钟,这个时间是比特币协议设计出来的

具体到每个矿工,他能够挖到下一个区块的时间,取决于这个矿工的算力占系统算力的百分比,比如说,你的算力占到系统算力的1%,平均下来,系统里每产生一百个区块,其中有一个区块就是你挖矿挖到的,平均你要等1000分钟才能产生一个区块

这个性质有时候也叫:process free,过去的process是不算数的

假设一下,如果有某个puzzle不满足process free,会出现什么情况:算力强的矿工具有不成比例的优势,因为算力强的矿工过去做的工作肯定是多的,比如有两个矿工,一个矿工的算力是另一个的十倍,那么他挖到矿的概率也是另一个的十倍,这样就满足process free,如果不满足,就会大于十倍!其实process free 恰恰是挖矿公平性的保证。

比特币的总量

挖矿获得的出矿奖励,是比特币长生的唯一途径,然而这个值每四年就会减半,比特币的总量呈现几何趋势

genmetric series

挖矿对维护比特币系统的安全是至关重要的:Bitcoin is secured by mining,只要大部分算力在诚实的结点手里,系统的安全就可以得到保证。出矿奖励随着出块会减半,那么人们的动力是否会减少呢?从过去的几年来看,恰恰是相反的,比特币的价格是飙升的,如果趋于0之后,是不是就没有动力挖矿了呢?还有第二种激励机制:交易费

比特币的安全性的分析,①假设大部分算力是掌握在诚实的矿工手里,我们能得到什么样的安全保证,能不能保证写入区块里的交易都是合法的?如果落在了10%的不诚实的结点手里,这个节点能不能偷币?能不能把别人账上的钱转给自己?不能,因为他无法伪造别人的签名(需要知道别人的私钥)。如果把这个交易硬写道区块链里呢?

②恶意的结点能不能double spending?

如果M->A存在某种不可逆的效果,那么M->M’就可以从中获得不当的利益,比如网上购物,M购买了一些商品,然后网站接受比特币支付,M把帐转给这个网站,网站监听到这个交易写入到区块链里了,以为, 支付成功了,所以把商品给了M,M拿到商品之后,又发起了一个交易M->M’把钱转给自己,然后按照下面这个区块扩展最长合法链,这样上面那个交易就作废了。

如何防范double spending?类似上面这种攻击

区块链是不可篡改的账本:irrevocable ledger,那是不是说凡是写入区块链的内容,永远改不了呢?根据上面的分析可知,这种不可篡改性,只是一种概率上的保证

其实,还有一种zero confirmation,0个确认,这个意思是说,这个转账交易发布出去了,但是还没有被写入区块链里,商家就确认了这个交易,这种在现实生活中还是比较普遍的,

原因:

①比特币协议缺省的设置是:结点接收最先听到的那个交易,两个交易有冲突,最先听到哪个,接收哪个,所以发布一个M->A,最先听到这个,在zero confirmation的这个位置,诚实的结点有比较大的几率是不会接收M->M’这个交易的

②很多购物网站,从你支付成功,到他把货品发给你,是有一定的时间间隔的,如果发现M->M’这个转账交易没有在最长合法链里,电商就可以选择取消发货。

假设某个有恶意的结点获得了记账权,他还能干什么坏事?

能不能不把某些合法的交易写道区块链里?这是可以的,但是会少交易费,比特币规定某个区块的大小是有限制的,最多不能超过1M字节,某个节点交易太多,这些交易就只能等到下个区块在发布

selfish mining:在商家等待6个区块的时候,M->M’先不发布,在私下偷偷的挖矿,但是不发布,等挖矿创建的区块比6个区块多的时候,一下子全部发布,M->M’这条链就成了最长合法链;正常的情况是,挖到区块,立马发布,要不然就被别人抢了,所以selfish mining有一个前提,恶意的结点的算力要超过诚实的结点的算力,但是是不可能的

selfish mining还有什么目的,上述是分叉攻击的目的,假设我们能不是为了回滚以前的交易,就是为了正常的挖矿,赚取出块奖励,selfish mining有没有什么好处?减少竞争:别人挖了一个,我已经挖了两个,然后直接抛出去两个,让别人做一些无用功。