V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Ficelle
V2EX  ›  Bitcoin

对于区块链和比特币想请教一下问题

  •  
  •   Ficelle · 2020-10-22 14:42:09 +08:00 · 750 次点击
    这是一个创建于 1495 天前的主题,其中的信息可能已经有所发展或是发生改变。

    刚了解了下区块链,有问题想请教一下。

    1,按照区块链竞争记账的权利,讲道理在一个节点里,只有算力最强的人才能赢得竞争,但是为什么有些算力不如最强的人也可以获得偶尔收益。仅仅是 hash 计算时的运气吗?

    2,关于每个区块记账广播确认后获取记账奖励,12.5 个币。但是一个区块大小是 1m,里面会包含很多信息,所有记账过程是把其中所有的交易信息全部录入和计算?有看过相关代码的高人指点一下吗?或者告诉我有什么地方可以参考一下。

    3,当比特币奖励完毕后,链还会继续吗?怎么继续。没有奖励了,还有人会记账吗?

    有没有哪里有相关代码可以看看啊。

    16 条回复    2020-10-23 15:44:11 +08:00
    frienmo
        1
    frienmo  
       2020-10-22 16:27:42 +08:00
    1 。是,所以叫挖矿有运气成分,而不是伐木只看量。
    2 。是。然后就是算一个随机值使得整体区块数量的 hash 值小于当前目标值。
    3 。会。因为有手续费
    Ficelle
        2
    Ficelle  
    OP
       2020-10-22 18:15:44 +08:00
    非常感谢。但是还想请教一下,交易信息是谁发的?全球的 200 多个节点吗?
    这个东西怎么称呼我好百度一下。
    frienmo
        3
    frienmo  
       2020-10-22 19:59:31 +08:00
    @Ficelle google bitcoin utxo
    acess
        4
    acess  
       2020-10-22 23:03:55 +08:00
    1.我怀疑你是不是把 51%攻击的概念和正常的挖矿混淆了。51%攻击是挖分叉链,让原本较短的分叉链反超之前的长链;而不是延长已知的最长链(严格来说是积累工作量最大链)。
    正常情况下,所有矿工都会共同延长同一条区·块·链账本,“宏观”来看,有点像百家被,算力多的,挖出区块占比就多,算力少的,占比少;“微观”来看,当然是有运气成分了,算力多,挖到的概率就大,算力少,概率就小,但是并不是没有。
    这里还有一点要注意,挖矿是无记忆性的( memoryless ),无论全网在当前高度挖了多久、挖了“多少铲子”,是前一秒刚刚挖出一个新区块,还是等了一个小时也没挖出新区块,从此刻起下一个区块被挖出时间的数学期望都仍然是十分钟。
    (还有,如果算力非常非常低,比如一般的电脑 CPU,跟专业 ASIC 矿机有好几个数量级的差距,而且全网还有数以万计的 ASIC 矿机参与竞争,那在现有难度下,独立( solo )挖出区块的时间几乎是天文数字;如果再考虑到全网算力不断增长,那甚至可以认为永远也不能独立( solo )挖出区块)
    acess
        5
    acess  
       2020-10-22 23:32:08 +08:00
    2.最早定义的矿工=节点,节点会完整验证全网所有交易,这样才能确保账本里没有违规行为,比如打破 2100 万币总量上限凭空印 100 万币,再比如无视数字签名直接把别人的币抢过来划到自己头上。

    这些违规行为并不是受什么数学定理或者自然定律而做不到,想要制造此类非法区块,并没有任何难度,顶多就是挖矿要消耗算力。

    但是如果区块里有了这些违规行为,别的节点看到这样的区块,检验时就必定会发现违反规则,然后拒收,拒绝在这个非法区块上继续延长区·块·链账本。
    这样一来,虽然非法区块被挖出来了,但是没人承认,会被抛弃掉,然后在这个非法区块上付出的算力就付之东流了,这样等于是惩罚了挖非法区块的行为。

    每个节点都知道别人会这样验证,知道自己如果打破规则胡乱写交易,自己付出的算力(背后是货真价实的电费)会付之东流,所以最后的结果就是每个人都“老实”了。而且,这是通过博弈达成的,每个节点是出于自己利益的考虑而“老实”,而不是什么道德啦法律啦之类的原因。


    后来,矿工和节点实质上分离了。这个原因也挺复杂,有技术层面的原因,比如网络延迟,现在比特币自然产生的孤块分叉少其实是因为用了中心化的 FIBRE 服务器;还有挖矿 /共识规则本身,对小算力 solo 矿工极不友好,所以才有提出 GHOST 之类的机制试图缓解这个问题;也有经济层面的原因,也就是规模经济,马太效应,最后垄断。

    矿工加入矿池,甚至压根就不在乎矿池给他们发的任务是啥;
    (全)节点则失去了算力,只能监视网络,虽然这样不会跟随非法链(因为全节点可以检验出来是否违反规则),但是如果算力搞事了(比如 51%攻击,注意,这里认为 51%攻击并不能打破规则、把非法的变成合法的),或者干脆跑路了、没算力挖矿延续区·块·链账本了,那从技术上讲全节点只能干瞪眼,或者就“耍流氓”改规则改挖矿 /共识算法。


    还有,你应该也注意到了,“规则”这个东西本来就是中本聪钦定的,是人为的,所以某种程度上也是主观的。
    这里其实就有争议,算是“政治话语权”上的争议吧。
    有人认为只有跑了全节点的用户才是真正的用户,基于这个前提假设,51%攻击也是不能打破规则的(但攻击方看不爽的链,51%攻击可以扰乱其正常运作,使其停摆、陷入混乱),所以,持有比特币 /愿意接受比特币支付,同时又自己跑全节点验证交易的用户,也就是所谓的“经济上的大多数”,才是说话算数的;
    有人就不同意,认为按照白皮书和中本聪本人的发言,用户不需要跑全节点,SPV (其实 SPV 并没有能力验证交易有效性,它是盲目跟随算力的)才是真正的用户,只有矿工 /算力才是真正说话算数的;全节点没有算力、不能出块,所以只能干瞪眼。
    acess
        6
    acess  
       2020-10-22 23:44:11 +08:00
    第 2 个问题,还有一点,很显然,验证全网所有交易(尤其是历史交易)负担非常重,显得很浪费。
    但是这个问题据我所知几乎无解。
    众所周知区·块·链最鸡肋的地方,就是它对外部真实世界无能为力,如果输入了假数据,它无法明辨是非。
    如果你觉得多条链就能解决问题,我想说,对于链 A 来说,只要它不去跑 B 全节点验证 B 链的内容,那 B 链对他来说就是“外部”,然后 B 链上发生违规行为,A 链就无能为力。

    除此之外还有一个概念“欺诈证明”( fraud proofs ),可以追溯到白皮书本身,白皮书描述 SPV 时,不是提到可以用警告机制,来引导 SPV 、让它们不要跟随非法链(哪怕非法链积累工作量更大)么?所以说,只要把非法链里面具体违反规则的证据亮出来,SPV 看到了,就可以自己得出毋庸置疑的结论,知道这条链是非法的,就不会跟随了。
    比如一条链里如果把一个币花了两次,这样其实就是另一种形式的通胀、凭空造币,那只要把这两个交易的内容,还有 Merkle proof (还有区块头链)拿出来,SPV 看到这个证明就会确信这条链有非法内容,不能跟随。
    但是这个概念在很多年前就被比特币核心开发者弃坑了,理由是如果制造非法链的人把违反规则的地方藏起来,那就拿不出对应的欺诈证明。如果要把类似于“某个高度的区块无法完整下载”这个消息本身作为欺诈证明 /警告消息,那也是没有意义的,因为收到这个警告消息的人,必须自己亲自去试试看那个区块能不能完整下载,然后,就产生了拒绝服务攻击,可以恶意生成假警告、让其他人去尝试下载本来完全能正常下载的区块,这样最终的、最坏的结果,就是 SPV 还是把整条区·块·链下载回来了,这样还叫什么轻量级客户端呢,还不如从一开始就老老实实跑全节点。
    acess
        7
    acess  
       2020-10-22 23:53:35 +08:00
    关于 2 楼的问题,交易是谁发送的?

    答案是任何人都可以发送,都可以转发,不需要是全节点(别人也没办法知道你是不是全节点),哪怕你就是调用 netcat 直接连接上比特币 P2P 网络的一个节点也可以,但是正常的全节点会检验交易是否合法,拒绝转发非法交易。但是很显然,只有掌控私钥的人能签名交易。

    不过,给矿工发奖励的 coinbase 交易是特殊的,它没有输入,内容是矿工自己写的——当然,这里也必须符合规则,奖励总额不能超过新币(被叫做“区块补贴”block subsidy,当前是 6.25BTC )+手续费。
    奖励可以少于新币+手续费,但是正常情况下追求利益最大化的矿工很显然不会这样挖,只有偶尔软件出问题的时候会产生这种区块(仍然是合法区块),然后这样也等于是让对应量的比特币被永久销毁了。

    另外,交易除了“合法性规则”之外,还有“标准性规则”( standardness rule ),违反标准性规则的交易(也就是非标准交易),仍然可以是合法的,这种交易,全节点不会转发,(对于矿池或 solo 矿工来说)默认也不会打包进自己要挖的区块,但是如果别人打包进去了,也不会拒收相应的区块。
    acess
        8
    acess  
       2020-10-23 00:02:10 +08:00
    3.上面已经说了,奖励不止是新币,还有交易手续费。
    但是理论上(考虑矿工只是单纯逐利、甚至“不择手段”)貌似是只要有交易手续费参与,就不稳定,很多年前 Arvind Narayanan 有篇论文说了这个问题。我了解不多,只看了摘要图,简单说,如果内存池里可以被打包进区块赚到的交易手续费太少,而前一个区块里已经被别人打包赚走的交易手续费又很多,那逐利的矿工就可能把别人已经打包的交易重新拿出来,自己挖一条分叉链,把本属于别人的手续费收入据为己有,同时为了笼络其他矿工和自己同流合污,他可以只拿一部分手续费,另一部分分给愿意同流合污的其他矿工,由此让自己的分叉链获得算力支持。
    这样一来,理论上,矿工就不会老老实实地正常延长区·块·链账本了,导致整个网络的动荡不稳。
    acess
        9
    acess  
       2020-10-23 00:20:29 +08:00
    看到第 2 个问题,还有楼上说的 UTXO,感觉我可能说得很罗嗦、又没有 get 到你要问的点。

    其实《精通比特币第二版》第十章“挖矿与共识”,尤其是“交易的独立检验”这一节应该就是你要找的答案。
    Ficelle
        10
    Ficelle  
    OP
       2020-10-23 10:35:20 +08:00
    @acess 大神,感谢!阅读过两遍,我需要多看两遍。
    第 2 个问题我想问的应该是,你描述里提到的“内存池”是被什么东西操作和管理。
    我刚才随便搜索了下你说的书,是一本英文,我水平低下,觉得我无法阅读,哈哈。
    只是对这个东西很好奇,感谢你,一边自己巩固,一边帮助我探索到未知的内容。
    不过我还有一个额外问题,是我阅读你们的帖子的时候我想问的。
    utxo 是一个模型,他引用和存储的内容,都是关于区块验证后的奖励(比特里就奖励比特币?),他的挖矿内容也是内存池里提供的交易信息。
    那么发明中本聪的第一笔交易,第一个区块,第一次挖矿。他存了什么东西? 因为这个时候“内存池”里没有内容供他上链不是吗。
    还是我对比特币对某个基础概念仍然有错误认知。
    Ficelle
        11
    Ficelle  
    OP
       2020-10-23 10:36:27 +08:00
    @Ficelle 那么中本聪的第一笔交易,第一个区块,第一次挖矿。他存了什么东西? 因为这个时候“内存池”里没有内容供他上链不是吗。
    改了一句话少删两个字。
    acess
        12
    acess  
       2020-10-23 14:16:08 +08:00
    @Ficelle
    《精通比特币》第二版是有中文版的,随便一搜就能找到。

    内存池里面是待打包的交易,虽然一般全节点没有对接算力、不能独立挖矿出块,但是默认也会接受、验证、转发网络上广播的交易,交易在(被矿工)打包进区块之前,就暂存在内存池里。(所以说实际上交易数据在网络上会被重复传播两遍,然后才有 compact block 之类的技术,只给其他节点传输一个“骨架”,让其他节点从内存池里自己把对应的交易找出来、把完整区块重新组装出来,这样就可以设法大幅省掉重复传播第二次的开销、加快区块传播、避免出现带宽占用峰值)

    内存池是每个节点各自维护的,很显然全节点完全可以自由选择要让哪些交易进入内存池(当然,一般不会选择非法交易,原因楼上说过了)、还可以选择优先打包哪些交易(一般是按照矿工费率 sat/vB 排序,优先打包矿工费付得多的;有些矿池提供“加速”,就是在付费后专门把对应的交易“插队”到前面,不过对于用户来说,我觉得加速器价格太贵,还是直接用 RBF 来追加手续费比较好);而且很显然不同节点的内存池内容完全可以不一样。
    内存池里面的“零确认”交易不进链确认就是不作数的,只有进链确认了才算数。

    内存池里面积压的交易,默认是有过期时间的,过期了就会丢弃出去。不过每一笔交易本身是没有过期时间的,所以即便因为长时间拥堵暂时被某些节点丢弃了,也随时可以重新广播出去,然后又会进入内存池、等待打包进链。
    acess
        13
    acess  
       2020-10-23 14:26:25 +08:00
    没有供打包的交易,当然也可以挖矿出块,这个时候区块里只有一个给矿工自己发奖励的 coinbase 交易,一般被叫做空块。

    创世区块比较特殊,它是直接硬编码写到全节点软件代码里的,而且创世 coinbase 交易生成的 50BTC 并没有进入 UTXO 集合,这 50BTC 等于不存在。

    coinbase 交易实际上没有输入,它的输入内容是可以随便写的,中本聪就写了那句著名的报纸头版头条,有人说这是对金融危机的回应,也有人说这可能就是个时间戳而已,证明这个区块是那天之后才挖出来的,所以可以证明比特币挖矿是公平的、证明中本聪没有在发布比特币之前私自偷偷预挖币。

    这里还有两个梗,都是关于创世地址。首先,有些比特币开发者认为 1A1z 开头的那个创世地址其实是一种误解,认为创世区块并没有地址,因为创世交易的输出是一个裸公钥 P2PK 输出,而不是现在常见的公钥哈希 P2PKH 输出,虽然这两种输出都是同一个私钥控制,币的所有权一模一样,但是技术细节并不一样。其次,创世区块里的 50BTC 等于不存在,不能被花掉,但是原则上创世地址如果用私钥签名交易,它收到的其他币都是可以花掉的。不过也有人猜测,创世区块里的那个公钥也许(只是也许)并不是从某个私钥推导出来的,所以没有对应私钥。

    Sergio Demian Lerner 在这方面做过一些研究,可以去 bitcointalk 论坛搜搜他的帖子。
    acess
        14
    acess  
       2020-10-23 14:50:06 +08:00
    实际上即便内存池里有交易,有的时候矿工仍然会挖空块。一般是因为 SPY mining,也就是 A 矿池假装成 B 矿池的矿工,从 B 矿池接收区块头、coinbase 交易等信息,这些信息不足以判断前一个区块是否合法,但是足够矿机暴力试错挖矿。然后 A 矿池的矿工就可以和 B 矿工站在同一个区块高度共同竞争挖下一个区块了。

    完整下载、验证一个区块需要比较长的时间,只下载区块头等信息需要的时间就非常短,于是这里就有一个空当。这个时候,因为 A 矿池不知道前一个区块里有什么交易,所以不能更新 UTXO 集合、不知道内存池里哪些交易可以打包(要排除双花的情况,否则挖出来的区块就非法了),这个时候就只能挖空块了。

    一般情况下这样不会出什么问题,如果 A 矿池不采取这个挖空块的策略,那他就不能在最新的区块后面延续挖新的区块,只能在同一个高度挖一个分叉,所以很显然 A 矿池还是采取挖空块的策略对自己更有利。
    不过 2015 年的时候,BIP66 软分叉升级在部署时出了一点问题,SPY mining 因为没有完整验证上一个区块的内容就抢先挖,就放大了问题,导致网络出现比较长的分叉。

    ( BitMEX 博客上有篇文章总结了比特币的软分叉、硬分叉历史。不过我觉得“软分叉”“硬分叉”的概念本来就很混乱,一般是从共识规则被放宽还是被收紧来定义的,但是也有从其他角度定义的,比如兼容性改变,或者是网络实际状况等等;甚至还有人认为“共识规则放宽 /收紧”这个定义是 Blockstream 公司 /比特币核心开发组为了维护自己的利益才刻意强调的说辞)
    acess
        15
    acess  
       2020-10-23 15:29:20 +08:00
    回头看 4 楼的帖子,我感觉“51%攻击是挖分叉链,让原本较短的分叉链反超之前的长链”这个有点不严谨……实际上 51%攻击还可以隐蔽地进行,可以私下里偷偷先挖好,等到明面上的交易完成(攻击方完成付款),再把更长的分叉链(攻击链)公开放出去,然后别的节点就会被迫丢弃之前的链,接受攻击链(首先是因为攻击链也没有违反规则;其次,如果不接受,对于当时没有在线、后来才上线加入网络的节点来说,它们无从分辨哪条链才是诚实链、哪条链是攻击链),最后攻击方的付款被强制撤回,收款方钱货两空。
    acess
        16
    acess  
       2020-10-23 15:44:11 +08:00
    提到 UTXO,我又想到白皮书里的 Merkle 树剪枝,实际上那个 Merkle 树剪枝是没意义的。

    从根本上讲,比特币的区·块·链账本里只登记了“交易记录”,并没有登记“当前余额”,“当前余额”是从“交易记录”重放、推算出来的。中本聪的白皮书里把比特币的交易叫做“币”,听起来就好像与众不同了——“比特币没有账户!”
    但是很显然,换一个名字叫,并不能绕过本质问题,比特币只是形式上没有账户而已,本质上并没有多大区别。全节点还是必须自己想办法把“当前余额”给重放、重建出来,也就是 UTXO 集合,这样才能对后续的交易进行验证。

    从安全 /信任层面讲,如果新上线的节点不完整下载、验证整条区·块·链账本,那就可能受到恶意节点欺骗(回到白皮书本身去抠字眼,白皮书写的也只是“回收磁盘空间”,而不是“节约下载带宽”)。即使一个恶意节点没有挖矿算力,它也完全可以恶意地挑选 Merkle 树分支来进行恶意的裁剪,把本来没被花掉的币裁掉,或者把本来已经被花掉的币加回来(根据情况,可以直接加回来,也可以把当时直接花掉这个币的交易裁掉),等等,然后受骗的节点在验证交易时就会出错,和其他(没受骗的)节点出现不一致。如果恶意节点有挖矿算力,它还可以花掉从来就没存在过的币(实质上等于凭空造币,也就是通胀),然后这种交易也没有什么特征,因为有很多其他的交易也是来自于“不存在(整个分支都被裁掉)的交易”。

    从效律上讲,很显然,维护一个独立的 UTXO 集合数据库,验证交易时就只需要对这个 UTXO 集合数据库进行查询、增删,不再需要回溯读取历史区块的内容。如果需要回溯读取历史区块内容,很显然效律相比而言就非常低下。(这里也可以看出来,UTXO 集合数据库在记录了区块高度的情况下,其实还是一个方便查询的索引,可以直接查到某个币 /交易是在哪个区块里面;只不过是在验证交易的时候,UTXO 集合本身就提供了需要的数据,所以就不太像是个索引了)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1061 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 19:52 · PVG 03:52 · LAX 11:52 · JFK 14:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.