区块链笔记-(肖臻)(二刷自用笔记)
密码学
crypto-currency 加密货币
cryptographic hash function 密码学
hash
collision resistance(不可篡改,经验证明) hiding puzzle friendly
1.H(m) m为内容,没有办法修改内容 变为m’ 使得H(m’)为原来的值 可以用hash值比较看原来的内容有没有被篡改
没有哪一个可以被证明----人为检验 MD5可以人为碰撞
X------>H(X) 不可逆推 ,输入空间大,且分布比较均匀
2.digital commitment/ digital equivalent of sealed envelope 我们可以用hiding的性质,公布出hash值,检验是否正确
x值比较小可以加一个nonce拼接起来
3.hash值的计算,是不可预测的(落在哪个空间)
应用(比特币)H(block header)<=target pow工作量证明 没有捷径-大量工作找出nonce 但是证明很容易
签名
怎样开账户?
创建一个公私钥的对(public key,private key) 非对称加密体系
我用你的公钥加密,你用你的私钥解密 A用B的公钥对内容进行加密,B用自己的私钥解密(用的同一个人的公私钥)
A发布一笔交易,用A的私钥签名,其他人可以用A的公钥验证,是否是A发起的交易
公私钥对创建相同-(概率极小) a good source of randomness (好的随机缘)
数据结构
hash pointer
p指向结构点的指针,存放结构体的位置 H()->不仅存放结构体的位置,还有hash值-能检测内容有没有被篡改
区块链 Block chain is a linked list using hash pointers
[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ]
| |
genesis block most recent block
区块链第一个区块叫作创世纪块(genesis block) 最后一个区块 是最近产生的区块(most recent block) 每一个区块都包含指向前一个区块的哈希指针
一个区块的哈希指针怎么算:是把前面整个区块的内容,包括里面的hash pointer ,合在一起取哈希值。通过这种结构,可以实现tamper-evident log。如果有人改变了一个区块的内容,后面一个区块的哈希指针就对不上,因为后一个区块哈希指针是根据前一个区块的内容算出来的,所以后一个哈希指针也得改,以此类推,我们保留的是最后一个哈希值也会变化。
Merkle tree
其中最下面一层是数据块(data blocks),上面三层内部节点都是哈希指针(hash pointers),第一层是根节点,根节点的区块也可以取个哈希,叫根哈希(root hash))-------这种结构的好处:只要记住根哈希值,就能检测出对树中任何部位的修改。
比特币当中各区块之间用哈希指针连接在一起,每个区块所包含的交易组织成一个merkle tree的形式,最下面一行data blocks每个区块实际上是一个交易,每个区块分为两部分,分别是块头和块身(block header ,block body)。块头里面有根哈希值,每个区块所包含的所有交易组成的merkle tree的根哈希值存在于区块的块头里面,但是,块头里没有交易的具体内容,只有一个根哈希值,块身里面是有交易的列表的。
全节点:包含block header -block body
轻节点:只有block header
Merkle Proof
这时存在一个问题:如何向一个轻节点证明某个交易是写入区块链的?
这时需要用到merkle proof :找到交易所在的位置(最底行的其中一个区块),这时该区块一直往上到根节点的路径就叫merkle proof
proof of membership 复杂度 log(n)
proof of non-membership 把整个树给轻节点,查看每一层变化,复杂度就是n
对交易内容取Hash 排序,看在哪个之间 log(n)
轻节点中没包含具体的交易信息,就给交易证明带来一些困难。在比特币系统中采用Merkle proof方法。轻节点想要证明图中tx(黄色框代表的某一笔)交易,轻节点保存了区块头信息,需要向全节点请求区中三个红色H()哈希信息,并在本地计算三个绿色H()哈希信息,并最终计算Merkle root信息,如果计算得到的Merkle root信息和轻节点保存在区块头中的Merkle root信息一致,那么证实了区块中确实记录了该笔交易。
sorted Merkle tree 比特币不需要证明不在
无环都可以用hash指针,由环的就可以
BTC协议
交易
double spending attack(双花攻击 )
谁发行货币?
怎么防范double spending attack-区块链(类似于央行数字货币的大型数据库)
1.A给B转钱 -币的来源 ,A的公钥 -输出 收款人公钥的hash
2.A需要干什么,要什么?A的签名,B的地址 比特币系统里收款的地址是通过公钥推算出来的。比如B的地址就是B的公钥取哈希然后经过一些转换得到的。
3.B?B需要知道A的公钥(身份)–所有都要知道A的公钥 怎么才能知道A的公钥?1.
那就存在了安全漏洞,假如B的同伙伪造了这次交易呢?其实第一个方框里铸币交易的输出就有A的公钥的哈希,所以第二个方框交易里A的公钥要跟前面哈希对的上。
注意:coinbase tx 要和交易中A的公钥说明要和币的来源的hash要对的上
在比特币系统当中,前面这些验证过程,是通过执行脚本来实现的。每个交易的输入提一段脚本,包括给出公钥的过程,公钥也是在输入的脚本里指定的。每个交易的输出也是一段脚本,验证其的合法性,就需要把当前交易的输入脚本跟前面交易(提供币来源的交易)的输出脚本拼在一起,然后看看能不能顺利执行,如果能执行说明是合法的。比特币脚本(BitCoin Script)。
实际上每个区块(对应图中的每个方框)可以有很多交易,这些交易就组成merkle tree。每个区块分为块头和块身。
块头包含的是区块的宏观信息,比如:用的是比特币哪个版本(version)的协议,区块链当中指向前一个区块的指针(hash of previous block header),整颗merkle tree 的根哈希值(merkle root hash),还有两个域是跟挖矿相关的,一个是挖矿的难度目标预值(target),另一个是随机数nonce。
这里的target,就是前面讲到的,整个块头的哈希要小于这个预值,即H(block header)≤target。block header里存的就是这个目标预值的编码(nBits)。这里需要注意,前一个区块的哈希只算的是前一个区块的块头,所以前面画的,一个区块引出一个剪头指向另一个区块中间,是不正确的,所以有的书剪头是指向一个区块的上面。取哈希时是把块头的所有部分都取哈希。
块身里面有交易列表(transaction list)。
全节点-轻节点
每个节点都需要验证所有的交易,实际上系统中的节点分全节点(full node)和轻节点(light node),全节点是保存区块链所有的信息的,验证每一个交易,所以全节点又叫fully validating node。轻节点只保存block header的信息,一般来说轻节点没法独立验证交易的合法性。
比如一个交易是不是double spending,轻节点没有存以前的交易信息所以它没法验证。系统中大多数节点是轻节点,这节课内容主要针对全节点,因为轻节点没有参与区块链的构造和维护,只是利用了区块链的一些信息做一些查询。
写入区块链
区块链里的内容是如何写到区块链里面的呢:每个节点,每个账户都可以发布交易,交易是广播给所有节点的。有些交易是合法的,有些是非法的。谁来决定哪些交易应该被写入下一个区块中呢?按照什么顺序写呢?如果每个节点自己决定可以吗?如果每个人在本地维护一个区块链,那区块链的统一性得不到保证,而账本的内容是要取得分布式的共识(distributed consensus)。
下面的笔记跟比特币的应用关系不大,可以作为了解:
分布式的共识一个简单的例子就是分布式的哈希表(distributed hash table),比如系统里有很多台机器,共同维护一个全局的哈希表。
这里需要取得共识的内容是什么?哈希表中包含了哪些键值对key valve pair。假如有人在自己电脑上插入一个键值对,'xiao’这个pair对应的是12345,即’xiao’→12345。那么别人在另一台读的时候也要能把这个读出来,这就叫一个全局的哈希表。
关于分布式系统有很多不可能结论(impossibility result),其中最著名的是FLP。这三个字母是三个专家的名字缩写,他们的结论是:在一个异步的(asynchronous)系统里,(网络传输迟延没有上限就叫异步系统),即使只有一个成员是有问题的(faulty),也不可能取得共识。
还有一个著名结论:CAP Theorem。(CAP是指分布式系统的三个我们想要的性质,Consistency【系统状态的一致性】 Availability【别人都可以用】 Partition tolerance)。该理论内容是:任何一个分布式系统,比如分布式哈希表,这三个性质中,最多只能满足两个,假如想要前两个性质,那么就不会得到第三个性质。
分布式共识一个著名的协议是Paxos,该协议能够保证一致性,即第一个性质。如果该协议打成了共识,那么这个共识一定是一致的,即每个成员所认为的共识都是相同的。但是,某些情况下,该协议可能永远无法达成共识,这种可能性比较小但是客观存在的。
比特币中的共识协议(consensus in BitCoin):
比特币中共识要解决的一个问题是,有些节点可能是有恶意的。我们假设系统中大多数节点是好的,那么该如何取得共识协议?
第一种方案是投票,首先应该确定哪些区块有投票权,有些membership是有严格要求的,这种情况下基于投票的方案是可行的。但比特币系统创建账户是很容易的,甚至一个人产生了公私钥对别人都无法得知,只有转账时别人才知道。所以有些人可以不停的创建账户,当超过账户总数的一半时就有了控制权,这种称为女巫攻击(sybil attack)。因此投票方法不可取。
比特币账户巧妙的解决了这个问题,不是按照账户数目投票,而是按照计算力来投票。每个节点都可以在本地组装出一个候选区块,把它认为合法的交易放在里面,然后开始尝试各种nonce值(占4 byte),看哪一个能满足不等式H(block header)≤target的要求。如果某个节点找到了符合要求的nonce,它就获得了记账权。
所谓的记账权,就是往比特币账本里写入下一个区块的权利。只有找到这个nonce,获得记账权的节点才有权利发布下一个区块。其他节点收到这个区块之后,要验证这个区块的合法性。
假如生成了一个新区块,怎么知道新区块插在了哪里呢?根据生成区块的指针。有可能就存在一个问题,这两个交易指A转账给B,以及A转账给自己。这种情况不是double spending,判断一个交易是不是double spending ,是看这个区块所在的分支上币又没有被花掉。如图,一直到第三个区块,币都没有花过,所以这个交易是合法的。虽然该交易是合法的,但是它不在最长合法链(longest valid chain)上。这种称为分叉攻击(forking attack)。所以接收的区块应该是扩展最长合法链。
区块链在正常情况下也可能出现分岔:两个节点同时获得记账权。每个节点在本地自己组装一个它认为合适的区块,然后去试各种nonce,如果两个节点在差不多同一个时间找到了符合要求的nonce,就都可以把区块发布,这时会出现两个等长的分岔。这两条都是最长合法链,那该接受那条呢?比特币协议当中,在缺省(默认的意思)情况下,每个节点是接受它最早收到的那个。所以不同节点根据在网络上的位置不同,有的节点先听到新生成的其中一个区块,那就接受这个区块;有些节点先听到另一个区块,那就接受另一个区块。
block reward 发行货币
那么能造多少币呢?开始时比特币刚上线的时候,每一个发布的区块可以产生50BTC(BTC就是比特币的符号)。协议中规定,21万个区块以后,初块奖励就要减半,就变成了25BTC。再过21万个区块,又要减半。
因此当一个区块胜出后,另一个作废的区块得到的比特币是没有作用的,其他诚实的区块是不会承认的。
比特币系统中要取得什么共识?去中心化的账本要取得共识。谁又能决定账本的内容呢?只有获得记账权的节点才能写东西。怎么获得记账权呢?就是解pow(挖矿)。按照算力记票,算力可以用每秒能试多少nonce数值表示。那怎样防范女巫攻击呢?按算力记票,即使创建再多的账户,也无法使算力增强。
比特币争夺记账权的过程叫作挖矿(mining),比特币被称为数字黄金(digital gold),争夺记账权的节点被称为矿工(miner)