欢迎光临散文网 会员登陆 & 注册

肖臻区块链b站网课笔记——06-10

2022-09-18 22:50 作者:苦茶今天断更了吗  | 我要投稿

视频链接:【北京大学肖臻老师《区块链技术与应用》公开课】 https://www.bilibili.com/video/BV1Vt411X7JF?p=6&;;share_source=copy_web&vd_source=33abd457d9415a4317112e8206e5360e

【笔记的内容也结合了评论区里其他同学的笔记】 


06-BTC-网络

Application layer(应用层):运行Bitcoin Block Chain

Network layer(底层):运行P2P Overlay Network(P2P覆盖网络)

 

比特币系统中所有节点完全平等,不像一些其他网络存在超级节点(super node)。要加入网络,至少需要知道一个种子节点,通过种子节点告知自己它所知道的节点。节点之间的通信采用了TCP协议,便于穿透防火墙。当节点离开时,只需要自行退出即可,其他节点在一定时间后仍然没有收到该节点消息,便会将其删掉。

 

比特币网络设计原则:simple,robust but not efficient,flooding。

每个节点维护一个邻居节点集合,消息传播在网络中采用洪泛法,某个节点在收到一条消息会将其发送给所有邻居节点并标记,下次再收到便不会再发送该消息。邻居节点选取随机,未考虑网络底层拓扑结构,也与现实世界物理地址无关。该网络具有极强鲁棒性,但牺牲了网络效率。

 

比特币系统中,每个节点要维护一个等待上链的交易集合。第一次听到交易,若是合法交易,则将其加入该交易集合并转发给邻居节点,以后再收到该交易就不再转发(避免网络上交易无线传输)。假如网络中存在两个冲突交易,具体接收哪个取决于节点先接收到哪个交易,之后收到另一个交易会将其放弃。

新发布区块在网络中传播方式与新发布交易传播方式类似,每个节点除检查该区块内容是否合法,还要检查是否位于最长合法链上。区块越大,则网络上传输越慢。

比特币网络传播属于 Best effort(尽力而为) ,不能保证一定传输成功。以一个交易发布到网络上,未必所有节点都能收到,也未必所有节点收到交易顺序都一致

 

 

07-BTC-挖矿难度调整算法

挖矿本质上就是不断调整block header中的nonce值,使H(block header)<=target.(target是目标阈值,target越小,目标难度就越大,挖矿越难)。挖矿难度的调整,可以视为调整目标空间在整个输出空间中所占比例大小

 

比特币系统采用的哈希算法为SHA-256,整个输出空间大小为2^256,调整目标空间所占比例,简单的说需要目标值前需要多少个0。

挖矿难度和目标阈值成反比, difficulty_1_target是挖矿难度为1时候的target,即最小挖矿难度。

问题:

1.如果不调整挖矿难度会怎么样?

系统总算力越来越强,若挖矿难度保持不变,则出块时间会越来越短。

 

2.出块时间越来越短是好事吗?

好处:交易可很快被写入区块链,提高系统响应时间,增加区块链系统效率。

坏处:区块在网络上传播具有时延,使得系统中节点经常性处于不一致的状态,增加了系统不稳定性;系统经常性位于分叉状态。分叉过多,不利于系统达成共识,会造成算力分散,使得黑客攻击成本大大降低(不再需要整个系统51%的算力)。

 

3.10min的出块间隔是最优吗?

不是,但系统出块时间需要维持在一个定值附近。以太坊平均出块时间为15秒左右,15s的时间明显会产生经常性的分叉,以太坊设计了新的共识协议Ghost。

对于一个交易系统来说,10min这样一个交易时间是比较长的。对于跨国交易来说,这个时间反而大大缩短了交易时间,减少了相应成本。

 

4.BTC系统如何调整挖矿难度:

BTC协议中规定,每隔2016个区块需要调整一次难度。

实际实际比较长,target会比较大,相应的挖矿难度会降低。

上调和下调都是有4倍的限制。例如:(正常2个星期),实际最近2016个区块出块时间>8个星期,按8个星期计算;<0.5个星期,按0.5个星期计算。防止网络中出现黑天鹅事件。

 

5.如何让所有矿工都愿意调整这个挖矿难度呢?

调整算法已写入代码,若有恶意节点故意不调,其产生的区块不会承认。

在block header中有一个nbits的域,它是对target的编码存储(target为256位,nbits为32位,block header并未直接存储target),其他节点在进行合法性验证时候会验证nbits域是否合法,不合法则对该区块不予以承认。


比特币系统中的实际情况:



08-BTC-挖矿

在挖矿过程中,如果监听到别人已经挖出区块延申了最长合法链,应立刻放弃当前区块,在本地重新组装一个指向最后这个新合法区块的候选区块,重新开始挖矿。挖矿本身具有无记忆性,前面无论挖多久,对后续继续挖矿没有影响。

 

比特币系统如何安全性?

密码学:没有私钥,无法伪造签名,无法转走账户上BTC。(前提:系统中大多数算力掌握在好人手中)

共识机制:保证了恶意交易不被系统承认。


挖矿设备:

经历了三个过程,总体趋势从通用到越来越专用。

普通CPU  GPU  ASIC芯片(application specific indergrated circuit)(挖矿专用矿机)

 

CPU:挖矿本身就是计算,挖矿过程中大多数内存、硬盘、CPU中大多数部件(用到指令较少)等都是闲置的。随着挖矿难度提高,用通用计算机挖矿很快变得无利可图。


第二代——GPU(主要用于大规模并行计算,如:深度学习)。仍有浪费(如:挖矿过程只使用整数操作,根本不会用到浮点数运算部件)。

GPU价格上涨,仅仅是深度学习火热导致的吗?实际上,很多GPU被用于了挖矿。

 

第三代设备:ASIC芯片,专门为挖矿设计,只能用于特定币种的挖矿。

但ASIC芯片设计、流片流程很长,假如BTC价格剧烈变化,前期投入很可能会血本无归。所以,ASIC芯片需要提前预订。假如BTC系统中,算力突然很猛烈增加,一般是一个大的厂商生产出新的ASIC矿机。

ASIC芯片只能用于挖矿,一旦其过时,便完全作废。

 

思考:ASIC芯片的出现是好事吗?

ASIC芯片并不是普通人可以参与的,一定程度上提升了挖矿的门槛,违背了比特币系统去中心化的初衷。后续有一些货币便考虑到了这个问题,设计了抗ASIC芯片化的解决方案绍。

如果大家都用ASIC矿机挖矿,有人想要颠覆BTC系统,必然会导致BTC价格跳水, ASIC矿机作废,投入成本血本无归。所以,很多人反倒认为ASIC芯片出现,一定程度上并不是坏事。

 

大型矿池:

单个矿工的算力在整个系统中只占据很少一部分,有利可图,但收入很不稳定。还要承担全节点其他责任,造成了算力的消耗。

 

矿池,通常是一个全节点驱动多台矿机。矿工只需要不停计算哈希值,而全节点其他职责由矿主来承担。ASIC芯片只能计算哈希值,不能实现全节点其他功能。

当获得收益后,所有矿工对收益进行分配,从而保证了收益的稳定性。

矿池一般具有两种组织形式:

类似大型数据中心(同一机构),集中成千上万矿机进行哈希计算。

分布式。矿工与矿主不认识(不同机构),矿工与矿主联系,自愿加入其矿池,矿主分配任务,矿工进行计算,获得收益后整个矿池中所有矿工进行利益分配。

 

矿池利益分配方法:

平均分配:

需要进行按劳分配,需要一个工作量证明的方案。如何证明每个矿工所作的工作量呢?

 

降低挖矿难度(可行方案):

假设原本挖矿难度要求,计算所得126位的哈希值前70位都必须为0,现在降低要求,只需要前60位为0。当然,这个哈希是不会被区块链所承认的,我们将其称为一个share,或almost valid share。矿工每挖到一个share,将其提交给矿主,矿主对其进行记录,作为矿工工作量的证明。等到某个矿工真正挖到符合要求的的区块后,根据所有矿工提交的share数量进行分配。

因为每个矿工尝试的nonce越多,挖到矿的可能性越大,所能得到的share也会越多,所以这种方案作为工作量证明方案是可行的。

 

 

思考:某个矿工平时正常提交share,但真正挖到区块后,自己偷偷发布出去?

不可能的。因为每个矿工挖矿任务是矿主分配的。矿主组装区块,交给矿工计算,而区块中铸币交易的收款人地址是矿主,如果矿工修改该地址,计算的nonce值也会作废。

 

矿池之间存在竞争关系。打击竞争对手,派出矿机加入竞争对手矿池挖矿,搞破坏。只参与其他矿工挖矿分红,自己挖到的区块却丢掉不给他人分。

 

矿池本身对BTC系统带来了较大威胁。某个恶意用户如果想发动攻击,只需要作为矿主,够吸引到足够多的不明真相的矿工,便可以用较低成本实现51攻击。

矿主经验管理矿池,也需要收取一定比例(出块奖励、交易费)作为管理费用。如果恶意者想要攻击系统,会将管理费降低甚至赔本吸引足够多矿工加入。这便使得发动51%攻击变得容易了起来。

 

51%算力矿池可以发动哪些攻击

分叉攻击 forking attack

对已经过6次确认的交易分叉,利用51%算力将交易记录回滚

矿工只能计算哈希值,并不知道区块包含哪些交易,区块链状况是什么,容易被利用。

51%攻击只是一个概率问题,并非达到51%算力就能发动攻击,不能达到就无法发动攻击。矿池本身算力也是在不断变化的。

 

封锁交易Boycott

假如攻击者不想让A的交易上区块链,在监听到有其他人将A的交易发布到区块链上时,立刻发动分叉攻击,使A所在链无法成为”最长合法链“。便实现了对A账户的封锁。

 

盗币(将他人账户BTC转走)

不可能,因为没有他人账户私钥。强行发布,也不会被认可。

 

矿池出现的优劣:

优点:解决了矿工收入不稳定的问题,减轻了矿工的负担。

缺点:威胁到了区块链系统的安全,使得51%攻击变得容易起来。

 

09-BTC-脚本

比特币系统中使用的语言很简单,唯一可以访问的内存空间只有,被称为“基于栈的语言”

如果存在一个交易有多个输入,那么每个输入都要说明币的来源并给出签名(BTC中一个交易可能需要多个签名)



B→C的交易中的txid和vout是指向A→B这个交易。

图为脚本执行流程。先执行input script,若无出错,再执行output script。

若脚本能顺利执行,栈顶结果为非零值(true),则验证通过,交易合法;否则交易非法。

如果一个交易有多个输入脚本,则每个输入脚本都要和对应的输出脚本匹配执行,全部验证通过才能说明该交易合法

 

 

输入输出脚本的形式:

1. P2PK(Pay to Public Key)

(1)脚本内容

特点:输出脚本中直接给出收款人的公钥。

(2)脚本执行

(3)实例

助理解【自编】:



2. P2PKH(Pay to Public Key Hash【最常用】

(1)脚本内容

输出脚本给出公钥的哈希值,输出脚本中其他还有一些为了验证签名正确性的操作。

输入脚本给出签名公钥

 (2)脚本执行

助理解【自编】:


3.P2SH(Pay to Script Hash)

(1)脚本内容

最复杂。输出脚本给出的是收款人提供的赎回脚本(Redeem Script)的哈希。相应交易的输入脚本要给出赎回脚本的具体内容,和能让赎回脚本能正确运行所需要的签名

input script要给出一些数目不定的签名及一段序列化的Redeem Script(赎回脚本)。验证分两步:

 验证redeemScript和redeemScriptHash是否匹配

 将赎回脚本的内容当作操作指令执行,看能否顺利执行。

 

(2) 用P2SH实现P2PK的功能

执行过程:

把输入脚本和输出脚本拼接到一起,前两行来自输入脚本,后面三行来自于输出脚本。

将第一阶段输入脚本中提供的序列化的赎回脚本进行反序列化,这个反序列操作,在代码部分没有展现出来,这个是每个节点需要自己完成的,然后再执行赎回脚本。


助理解【自编】:


多重签名

该方法通过CHECKMULTISIG来实现,其中输入脚本提供M个签名,输出脚本给出N个公钥和阈值M,表示N个人至少有M个签名即可实现转账(N>=M)。输入脚本只需要提供N个公钥中M个合法签名即可。【给出的M个签名顺序要和N个公钥中相对顺序一致】

X,是CHECKMULTISIG的实现存在一个bug,执行时会从堆栈上多弹出一个元素。这个bug现在已经无法修改(去中心化系统中软件升级代价极大,需要硬分叉修改)。实际采用的方案是往栈中多压入一个无用元素


一个特殊的脚本

该方法是销毁比特币的一种方法

Q:为什么要销毁比特币?

①部分小币种(AltCoin)要求销毁部分比特币才能得到。

②往区块链中写入内容。区块链是不可篡改的账本,有人(任何人)便利用该特性往其中添加想要永久保存的内容。例如:股票预测情况的哈希、知识产权保护——知识产权的哈希值。

 

Q:在铸币交易中,有一个CoinBase域,其中便可以写入任何内容。那么为什么不使用这种方法呢,不需要销毁BTC,可以直接写入。

因为这种方法只有获得记账权的节点才可以写入内容。【发布交易不需要有记账权,发布区块需要有记账权】

任何用户都可以使用这种方法,通过销毁很小一部分比特币,换取向区块链中写入数据的机会。实际上,很多交易并未销毁BTC,而是支付了交易费

例如下图为一个铸币交易,其包含两个交易,第二个交易便是仅仅想要往其中写入内容。



10-BTC-分叉

硬分叉hard fork:必须系统中所有节点新软件,系统才不会产生永久性分叉

对比特币协议增加新协议,扩展新功能,未升级软件的旧节点会不认可这些修改,会认为这些特性是非法的。这也就是对比特币协议内容产生分歧,从而导致分叉。

在BTC系统中,区块大小最大为1MB,可以包含的交易最大数量为4000笔左右。而一个区块产生大概需要10min左右。平均每10分钟最多只能处理4000笔交易(平均每秒7笔交易),严重影响吞吐率和交易处理(上链)时间(交易太多,无法写入只能等待下一个区块)。


假设系统中大多数节点更新了软件,少数节点仍然遵从1MB限制的协议(注意,这里大多数和少数是按照算力来区分的,和账户数量无关)。即:新节点认为区块大小最大4MB,旧节点认为区块大小最大1MB,且新节点占据大多数。

设1为当前区块链,有一个新节点挖出了一个区块如2。旧节点认为该区块为一个非法区块,不会认可,仍然从其前一个区块开始挖矿,如3。旧节点挖出的区块,新节点是认可的(并未超过4MB限制),所以对旧节点来说,3下面的链才是合法链,而对新节点来说,这两条链都是合法的链。因为新节点算力强,所以出现4中情况可能性大。对于新节点来说,上面的为最长合法链,新节点便都会沿着上面的链继续挖;旧节点就会沿着下面的链继续挖矿。

由于新节点算力足够强,所以形成两条永远都在延伸且平行的链。可见,这种分叉是持久性的。只要这部分旧节点永远不更新软件,下面的链便永远不会消失。

 

①BTC社区中有些人很保守,不愿意加大区块大小

②区块大小并非越大越好,比特币网络传输为"尽力而为",区块加大会造成传输变慢等问题。

③单纯增加区块大小,对交易数量的增加远不能达到数量级的提升。

 

目前看到的以太坊ETH已经不是最初的ETH了,以太坊在历史上发生过硬分叉,另一个链称为ETC。ETC才是以太坊设计原本的协议,而ETH是黑客攻击ETH上一个智能合约THE DAO后进行回滚的协议链(将黑客攻击偷取的以太币采用硬分叉方式回滚回到另一智能合约,然后退还给真正拥有者)。

但是这次硬分叉的后果,由于有人不愿意这么做,造成了以太坊社区的分裂。实际上,虽然ETC不如ETH有名,但实际它也是目前一种主流货币。

分叉之初,由于两个链分叉造成了互相影响,产生了很多麻烦。比如:在ETH链上有一笔转账B->C,有人便在ETC链上回放,将ETC链上的货币也转给了C(C收到两笔钱)。 后来,对两条链各添加了一个chainID,将两个链区分开,才使得这两条链真正分开。

 

 

 

软分叉soft fork:只要系统中拥有半数以上算力节点更新软件,系统就不会产生永久性分叉

如果对BTC协议添加限制,使得原本合法交易在新交易中不合法,便会形成软分叉。


假设将区块大小从1MB减小至0.5MB(实际中,1MB已经足够小,不会调小了).

由于参数修改方式不同,有可能会是硬分叉,也有可能是软分叉。

假设系统中大多数节点更新了软件,少数节点仍然遵从1MB限制的协议。即:新节点认为区块大小最大0.5MB,旧节点认为区块大小最大1MB,且新节点占据大多数。

设1为当前区块链,此时软件更新,有一个新节点挖出了一个区块如2。但对于旧节点来说,该区块符合1MB大小限制,旧节点对其认可,从而旧节点会沿着该新的小区块开始挖矿,如3但是新节点会认为该旧节点挖出区块超过0.5MB限制,为一个非法区块,不会认可该区块,会从其前一个小区块开始挖矿。如4所示。而旧节点认可新区块,最终会造成5中的效果(绿色大节点为旧节点),旧节点挖出的区块一直被抛弃,无法得到出块奖励(不在最长合法链上)。这就倒逼旧节点升级软件,最终会实现区块链上的所有矿工共同认可新协议,实现软件协议的升级。

旧节点如果不升级软件,挖出的区块可能就白挖了(大于0.5MB),但对于系统来说,不会存在永久性分叉


系统中可能出现软分叉的情况及其实例

给某些目前协议中未规定的域赋予新的含义或规则。

铸币交易中CoinBase域。在CoinBase域中写入任何内容都可以。挖矿本质是调整block header中的nonce,但其只有4个字节,搜索空间太小。所以实际使用中,将CoinBase域前8个字节作为另一个extra nonce,此时搜索空间从原本2^32 增长到2^96,对于目前挖矿难度来说已经足够。

但CoinBase中并不是只有8个字节,还剩下很多空间。有人便提出将其作为UTXO集合的根哈希值。目前UTXO是全节点自己在本地为了方便查询自行维护的,但UTXO内容并未写入区块链(还记得Merkle proof吗?Merkle proof用于验证某个交易是否在区块中,Merkle proof的交易信息是写入区块链的。)

由于UTXO存在本地,如果查询某账户余额,轻节点便需要询问全节点,全节点根据UTXO中信息可以计算得到账户余额,但如何确保全节点给的数据可信?由于直接修改block header会造成硬分叉,有人便提出了以上的方案(该域刚好无人用)。

可以看到,旧节点认可新节点的区块,但新节点对于旧节点CoinBase域检查时候,发现没有这个UTXO的根哈希值,不会认可其发布的区块,所以这是软分叉。

 

P2SH:Pay to Script Hash

最初比特币版本中没有该功能,后来通过软分叉方法加入了进去。

 


肖臻区块链b站网课笔记——06-10的评论 (共 条)

分享到微博请遵守国家法律