待更新北京大学肖臻老师《区块链技术与应用》公开课笔记04-BTC-协议

Posted 如何科学杀正能量的猪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了待更新北京大学肖臻老师《区块链技术与应用》公开课笔记04-BTC-协议相关的知识,希望对你有一定的参考价值。

北大肖臻老师《区块链技术与应用》课程链接:点击这里

全系列文章链接:点击这里

主要补充内容及图片来源:《区块链:技术驱动金融》

该系列文章如中有任何侵权内容,或者有链接无法打开、图片加载上传失败等情况,请及时与我个人联系删除或修改。


一、双花攻击(double spending attack)

怎么设计出一个加密货币出来?

假设央行发行数字货币。我们知道,央行发的人民币上有各种防伪标志。同样,央行发的数字货币上也要有央行的私钥签名。而央行公钥是公开的,我们用密码学中的公私钥原理,就可以验证数字货币是不是真的。

大家觉得上面这个方案怎么样?但其实这个例子根本没用到区块链。

而且问题在于:私钥容易泄露。如果央行私钥都发生泄露,那普通百姓的私钥更容易泄露,这样比特币就没法用。

数字货币其实就是个文件。虽然文件上有央行的签名,100元面值就是100元,但数字货币是可以复制的,它可以无限复制下去,这一点和人民币不一样。

A把人民币给B,A的那张钱就没了,没办法再花一次。但如果A花出去一个数字货币,他可以再复制第二次,再花一次,这就叫“双花攻击”。

数字货币主要挑战就是怎么防止双花攻击。

举例

央行发行的每个数字货币上都有一个编号,就和人民币一样,比如017、092等。此外,央行还要维护一个数据库,上面记录着每个编号的数字货币在谁手里。

比如017在A手里,A把017给B,B不仅需要验证这个数字货币有没有央行签名(即验证下币的真假),还要跟央行核实一下017这个数字货币,A之前有没有花出去过。

央行确认后说017之前确实是在A手里,所以A支付017给B是合法的,交易发生后,央行的数据库也需要改一下,将币改为017-B.

此时,如果A想再花一次017,想把它支付给C,C就能跟央行核实查到017已经花出去,已经在B手里了,此时这个交易就不能成立,这样就能防止017花两次。

以上交易方法,正确性没问题,实践中也可操作。但这是中心化的方案,由央行统一控制,而且每次交易都需要央行确认其合法性,这就太慢了。

我们需要一个去中性化的方案,让所有用户共同承担央行的职能,用一个数据结构来检测比特币交易,这个数据结构就是区块链。

区块链有两个核心问题:①数字货币的发行;②如何验证交易的有效性。

如何验证交易的有效性,实际就是怎么防范双花攻击。

举例

 (4.1 小型区块链,source: 课程截图)

比特币每个交易都包含输入和输出两部分。输入要说明币的来源,输出要给出收款人的公钥的哈希。

假设,A获得铸币权(CreateCoin),A发行10个比特币。

A把钱平均分给B和C,一人5个比特币,这个交易需要有A的签名,证明是经过A同意的。

同时这个交易还要说明花掉的10个比特币从哪儿来,这里A花掉的币是由铸币交易来的。

A转给B,要说明B公钥哈希是什么,B又把钱转给C和D,也要说明币的来源。

此时,C一共有7个比特币,C又决定把7个币给E。

...

这就是构成了一个小型的区块链。

这里有两种哈希指针,一种把区块串起来构成一个链表,另一种指向前面某个交易来说明币的来源。这样就能证明这个币不是凭空捏造,并且防止双花。

举例

现在B要转给F5个币,签名还是有B的签名。

单纯验证签名币好像合法,但还要知道B从哪儿来。

B的来源回溯一下,这时候就不对了,因为B的币之前已经花出去了,这就能证明不合法,就能检测double spending.

  (4.1 小型区块链,source: 课程截图)

转账交易中,A转给B,需要有A的签名,B的地址。

收款的地址是通过公钥推算出来的,B的公钥取哈希通过某些转换得来。

和银行转账一样,A要给B转钱,A需要知道B的地址,可是A怎样知道B的地址呢?

很多比特币地址在网上以二维码形式呈现

B不需要任何信息,但A要证明币的来源信息。B要知道A的公钥,A的公钥代表A的身份,所有节点都要知道A的身份。这个交易要合法得有A的签名。区块链上每个节点都要独立证明。旁观者也得验证一笔交易。

那么怎么才能知道A的公钥?这跟买东西还不一样,买东西需要通过购物网站

这是A和B做交易

A给B转账中,A的公钥是交易中自己给出来的,输入中要说明币的来源,还要说明A的公钥是什么

这不能让自己说,假如如果B的同伙C,伪造A到B转账交易,用自己的公钥在输入中伪造成A的公钥,又用自己的私钥来签名,那别的节点用这个假造的公钥验证这个签名,肯定是对的呀,这就把A账上的钱偷走了

我们知道,每个交易分为输入和输出两部分,在A转账给B的交易中,输入部分说出币的来源和A的公钥,输出要给出收款人的公钥的哈希,就类似于B的地址

这里A与B的交易的币是从铸币交易来的。

铸币交易中(coinbase tx),它的输出里面有A的公钥的哈希,所以A与B转账交易里,A的公钥,要和铸币交易里A的公钥的哈希对得上才行。

对不上,则你说的币的来源是不对的,这个币当初不是给你的。如果有人茂名顶底把自己的公钥说是A的公钥,那假的公钥就和铸币交易里A的指定的公钥的哈希就对不上,验证不通过。

实际上,这些哈希指针是很有作用的。

在比特币系统单中,这些验证过程是通过执行脚本来实现的。

每个交易的输入是一段脚本,公钥也是在输入的脚本里指定的。每个交易的输出也是一段脚本。验证是否合法,就是把当前交易的输入脚本,和前面那个提供币的来源的交易的输出脚本,拼在一起,合成一段程序,看能不能顺利执行,能执行才是合法的。

这叫做比特币脚本(Bitcoin Script)

以上这个图里好像每个区块只有一个交易,实际系统中每个区块可以包含很多交易,这些交易就组织成梅克尔树,每个区块分成块头和块身两部分。

Block header里包含区块的宏观信息,比如用的比特币哪个版本的协议(version)、区块链当中指向前一个区块的指针(hash of previous block header)、整棵梅克尔树的跟哈希值(Merkle root hash)、挖矿的难度目标阈值(target)、随机数(nonce)

上节课提到,挖矿求的puzzle,H(block header)≤target,整个块头的哈希要小于目标阈值,block header里存的就是目标阈值的一个编码nBits

前一个区块的哈希,只算得是区块的块头,block body是不管的

Block body

有交易列表(transaction list)

实际当中,节点分为全节点(full node)、轻节点(light node)。

全节点保护所有信息,验证所有交易,也叫做fully validating node。

轻节点只保存block header的信息,一般来说,无法验证独立验证交易的合法性,比如是不是double spending,轻节点不知道,因为它没存以前的交易信息,它查不出来。系统中大多数节点是轻节点。

这节课主要针对全节课来讲。

每个节点每个账户都可以发布交易,这些交易是广播给所有节点的,有些交易可能合法,有些非法,那么谁来决定哪些交易能写进下一个交易中呢,按照什么顺序呢?

区块链是一个去中心化的账本,这个账本内容要有同意的说法,

这叫做账本的内容要取得分布式的共识(distributed consensus)

简单来例子:分布式的哈希表(distributed hash table)

系统有很多台机器,共同维护一个全局的哈希表,这里需要取得共识的内容是什么?

需要取得的是哈希表中包含哪些键值对(key-value pair)

比如 'xiao'→12345,xiao这个key对应的是12345

另一台机器要能把它读出来

比特币中的共识协议(Consensus in Bitcoin)

假设系统中大多数节点都是好的,有恶意的是小部分,这种情况下怎样设计一个共识协议呢?

直接投票行不行?

更大的问题:

任何基于投票的方案,首先要确定谁有投票权(membership)

如果这个区块链的membership是有严格定义的,不是谁都能加入,比如联盟链(hyperledger)只有大公司才能加入。

比特币系统中,创建一个账户是很容易的,本地产生一个公私钥对儿就是一个账户,不参与交易外界是不知道账户存在的。

当有恶意的节点用超级计算机不停的产生账户,当账户超过总数一半,就有控制权了,就能操纵投票结果,这叫做女巫攻击(sybil attack)

这样投票不行,或者说简单的直接的投票是不行的。

比特币系统中用一个巧妙机制解决这个问题:

也是投票,但不按照账户数目,而是按照计算力来投票。

每个节点都可以在本地组装一个候选区块,把它认为合法的交易放在区块里,然后就开始尝试各种nonce值

我们之前提到的 H(block header)≤target,这个block header里有一个域,是一个随机数nonce。

组装好区块后就开始试各种随机数,(这是个4 bytes),看哪一个能满足不等式要求,求出来的哈希落在指定范围内,如果某个节点找到了符合要求的nonce,即获得了记账权。

记账权即有权力发布下一个区块。

其他节点收到区块后也要验证区块合法性。

比如:

先验证下 block header 的内容填的对不对,里面有一个nBits域(目标阈值的一个编码),检查一下这个 nBits域设置是否符合比特币协议规定的难度要求;

查一下nonce,选出的Nonce是不是符合上面不等式,即是否真的有权利发布区块,是否真的获得了记账权

把block header里面的那几项都查一遍,假设都符合要求,然后看一下block body里面的交易列表,验证一下每个交易都是合法的,1合法的签名,2以前没有被花过,任何一个条件不符合要求,区块不能接收。

假设一个区块全都查过是符合要求,那是不是就可以接受它呢?

hash of prev block header

验证一个分叉交易是否合法,不会查到另一个分叉上。

这个分叉上交易虽然合法,但不在最长合法链上。

分叉攻击,

回滚已经发生过的交易

 

 

以上是关于待更新北京大学肖臻老师《区块链技术与应用》公开课笔记04-BTC-协议的主要内容,如果未能解决你的问题,请参考以下文章

区块链与比特币基础知识——北京大学肖臻老师《区块链技术与应用》公开课笔记

北京大学肖臻老师《区块链技术与应用》公开课-ETH

北京大学肖臻老师《区块链技术与应用》公开课-ETH

北京大学肖臻老师《区块链技术与应用》公开课-ETH

北京大学肖臻老师《区块链技术与应用》公开课笔记-BTC

北京大学肖臻老师《区块链技术与应用》公开课笔记-BTC