区块链学习笔记

2019-10-27

近期学习极客时间上的左耳听风专栏,有一个区块链小章节,结合自己的体验和了解记录一下。

学习专栏章节说明

左耳朵耗子,很早之前看耗子叔写的《跟我一起写Makefile》,这是最早的接触。后面接触微博,酷壳上关于加班的讨论,到现在的专栏,在我的印象里是越来越高大,散发着很多很多干货。

鉴于是收费专栏(但绝对物超所值,推荐),我只简要记录一下自己的一些学习记录和理解。

学习笔记

参考:区块链技术的本质

  • 概要
    • 说区块链必然要谈比特币,比特币是一种数字货币。
      • 去中心化
      • 数据防篡改
      • 固定的发行量
    • 对于支持和不支持区块链的观点
      • 支持的人相信其可以实现:人们可以通过一个不受任何人控制和操作的 P2P 金融系统,进行完全自由和可信的交易。
      • 反区块链的人的观点也很明确。他们认为,所谓的去中心化看似很美好,但实则不可能。而且从目前的区块链的应用来看,也没有颠覆什么,连迹象都没有。反而,大家都在疯狂地炒作概念,没有实质的价值。像 ICO 和交易所这样的东西里面充满了大量的投机主义,泡沫非常大。
    • 去中心化的比特币交易处理流程
      • 用户把交易传到网络
      • 记账结点(网络上的机器)通过比拼计算力的方式竞争记账权。这也叫“挖矿”。
      • 获得记账权的结点,会把待记账的交易进行计算打包,并向全网广播。收到新的记账包的结点会对其进行验证,验证通过后加入自己的区块。
    • 比特币这个分布式的账本系统:
      • 任何人都可以拿到所有的数据
      • 数据要能很容易被验证是合法的没有被修改过的,而且也要是很难被人修改的。
      • 基于这个设计,比特币使用了两个比较大的技术:“区块链技术”和“工作量证明共识机制”。
  • 区块链
    • blockchain
    • 其中有一个一个的区块,,每个区块中包括着一组交易信息
    • 每一个区块都会有一个 ID(或是一个地址),这些区块通过记录前一个区块的 ID 来形成一条链。
    • 每个块的 ID 都是通过其内容生成的,所以,只要是内容有一丁点儿的变化,这个 ID 都会完全不一样。
      • 一个块被修改,后续的所有块都要跟着一起改。于是导致了修改成本的提升。
      • 越旧的区块的篡改会造成越大面积的修改,于是越旧的区块就不容易篡改,就越安全。
  • 工作量证明共识机制(POW, Proof-of-Work)
    • 一个公司内的分布式系统中的结点是被假设成可信任的,而在去中心化的网络下,结点要被假设成不可信任的
    • 即“挖矿,其实就是用大规模的计算来找到一个符合系统要求的区块 ID(即上面提到的ID)
    • 要找到符合条件的区块 ID 只能通过暴力穷举的方式,所以要付出大量的系统计算资源和电力。
    • 别看 Proof-of-Work 成本这么高,还这么耗电不环保,但是,这是目前去中心化系统中最安全的玩法。

参考:区块链技术细节:哈希算法

  • 对于计算机来说,区块链就像一个单向链表,一个数据块中保存着三个信息。
    • 真正的数据
    • 自己的地址(或ID),地址使用Secure Hash(安全哈希、安全散列)算法进行计算得到。
      • 有两个很著名的hash算法,MD5 和 SHA-2,区块链用的是SHA-256算法
      • 通过hash对数据做“数字签名”
    • 前一个数据块的地址
  • 比特币的hash算法

区块链协议格式图示

其中 Version,Previous Block Hash,Merkle Root,Timestamp,Difficulty Target 和 Nonce 这六个数据字段是区块链的区块数据协议头。后面的数据是交易数据,分别是:本块中的交易笔数 H 和交易列表(最多不能超过 1MB,中本聪未做说明。。)

  • 区块数据协议头
    • Version, 当前区块链协议的版本号,4 个字节。
    • Previous Block Hash, 前面那个区块的 hash 地址。32 个字节。
    • Merkle Root, 简单理解为是后面交易信息的 hash 值,32 个字节。
      • 比特币的每一笔交易会有三个字段:转出方、转入方、金额。把交易数据类似二叉树分成若干个组,两两合并再求hash,得到每个父节点hash(最后算得一个块的hash即Merkle Root)
        • 有利于我们整合数据和校验数据
        • 这样的开销在存储和内存上并不大,便于提高校验一组数据的难易程度
        • 在 P2P 的无中心化网络上,拆分传输可以提高网络传输速度
      • (以太坊有三个不同的 Merkle Root 树,因为以太坊要玩智能合约,所以需要更多的 Merkle Root。)
    • Timestamp, 区块生成的时间。
    • Difficulty Target, Bits 表明了当前的 hash 生成的难度, 4 个字节。
    • Nonce, 一个随机值,用于找到满足某个条件的 hash 值。4 字节。

对这六字段进行 hash 计算,就可以得到本区块的 hash 值,也就是其 ID 或是地址。对区块头做两次hash:
SHA-256(SHA-256 (Block Header))

在比特币中,一个交易可以有多个 output,也就是说我可以把一笔钱汇给多个人,但一个 output 只能对应一个源的 input,还有一个条件就是,output 跟 input 的总数要吻合。

比特币中没有余额的概念,多个交易计算后留下来的数量在比特币中叫 UTXO(Unspent Transaction Output)

UTXO因为没有账户和余额的概念,所以可以并行进行多笔交易。假如你有多个UTXO,你可以进行多笔交易而不需要并行锁。然后其还有匿名性的特征,你可以隐藏自己的交易目的地(通过设置的多个 output),而且没有余额意味着是没有状态的。
要知道你有多少个比特币,只需要把 UTXO 的交易记录统计一下就可以知道了。(以太坊则使用了余额的方式)

参考:区块链技术细节:加密和挖矿

  • 比特币的加密方法
    • 密钥对 / 签名 / 证书的概念
      • 所谓密钥对,也就是一种非对称加密技术。这种技术,在对信息进行加密和解密时,使用两个不同的密钥。这样一来,我们就可以把其中一个密钥公布出去,称之为公钥,另一个密钥私密地保管好,称之为私钥。
      • 数字签名:
        • 没有签名时会有这个问题:e.g.所有人都有我的公钥,别人可以截获Mike发给我的信息,然后用公钥加密别的信息伪装称Mike发给我,这样我就被黑了
        • Mike把想发的信息做hash得到hash串(也叫Digest 摘要),再用他的私钥把Digest加密,就叫数字签名(Signature)
        • 然后,Mike把想发的信息用我的公钥加密后,连同他的数字签名一同发给我
        • 我用我的私钥解密收到的密文(假设X)得到解开的信息(假设Y),同时用Mike的公钥解密数字签名(假设S)得到Digest(假设D),然后用hash对解开的信息(Y)做hash,再跟摘要(D)比较,一样则说明信息未被人更改。
      • 证书
        • 中间人攻击:上面的情况还是可能存在问题,黑客用ta自己的公钥替换掉Mike的公钥伪装成Mike,但是对我来说还是以为在跟Mike通信,这就是中间人攻击
        • 为了解决这种情况,需要有个权威可信机构认证这个公钥确实是Mike的。这个权威机构,用自己的私钥把 Mike 的公钥和其相关信息一起加密,生成一个证书
        • Mike发布信息时,放上这个权威机构发的数字证书,然后我收到信息时用机构的公钥解密证书得到Mike的公钥,再用Mike的公钥验证数字签名
    • 比特币的世界里,每一笔交易的 From 和 To 都是每个用户的公钥(Public Key)。也就是说,使用用户的公钥来做交易的账户。
    • 并且比特币不需要证书,不用认证公钥确实就是Mike的,不怕中间人攻击。
      • “这是因为,如果黑客想要伪造一笔别人的交易,那么他需要换掉半数以上结点上的被攻击者的公钥,这不太现实。与其这样做,还不如去偷被攻击者的私钥,可能还简单一些。”
  • 挖矿
    • 在比特币的区块 hash 算法中,要确保下面这个公式成立:SHA-256(SHA-256 (Block Header)) < Target,要找出一个数字是hash值小于Target
      • 这个 Target 是一个数,其决定了,我们计算出来的 hash 值的字符串最前面有几个零(由协议头中Difficulty Target定义个数)。
        • 前面需要的 0 越多,难度也就越大
        • 这个难度系数,会在每出 2016 个区块后就调整一次。现在,这个难度是要在前面找到有 18 个零 e.g. “000000000000000000424118cc80622cb26c07b69fbe2bdafe57fea7d5f59d68”
      • hash 值本身就是一串相对比较随机的字符串。但是要让这个随机的字符串有规律,是一件很困难的事,除了使用暴力破解,没有其他办法。
      • 在计算机世界里,我们把这个事叫 “哈希碰撞“(hash collision),碰撞前几个位都是 0 的哈希值。
    • 所以一般挖矿流程如下
      • 从网络上取得之前的区块信息。
      • 从 “待记账区” 中获取一组交易数据(有优先级,比如成长时间、矿工小费等)。
      • 形成区块头(计算 Merkle Root 并设置记账时间 Timestamp 等)。
      • 开始穷举 Nonce,来计算区块头的 hash 值。
        • 如果前面有 18 个零(小于 Target),那么记账成功。如果没有,则从第一步重新开始。
      • 一旦某矿工成功打包一个区块,他就会告诉其他矿工。收到消息的矿工会停下手上的工作,开始验证,验证通过后,广播给其他矿工。
    • 所以,满足条件的这个难度系数成为了挖矿的关键。设置这个难度系数就是为了让全网产生的区域名平均在 10 分钟一块。
      • 为了保证每 10 分钟产生一个区块,当算力不足的时候,难度下降,当算力充足的时候,难度提高。
      • 今天的这 18 个零,基本上来说,一般的电脑和服务器就不用想了,必须要算力非常非常高的机器才能搞定。

参考:区块链技术细节:去中心化的共识机制

  • 拜占庭将军问题(The Byzantine Generals Problem)
    • 其实,去中心化的共识机制也是要解决拜占庭将军问题(The Byzantine Generals Problem),它是莱斯利·兰伯特(Leslie Lamport)于 1982 年提出来的,用来解释一致性问题的一个虚构模型。
    • 同时,它也是分布式领域中最复杂、最严格的容错模型。
    • “拜占庭的将军们没有一个中心化的领导机构,所以,如果他们需要攻击某个城市,所有将军需要对任何将军可能提出的攻击时间达成共识。这时,可能会有多个将军同时发出不同的攻击计划,而且这些将军中还有叛徒。那么,将军们怎样达成共识呢?”

拜占庭问题之所以难解,在于任何时候系统中都可能存在多个提案(因为提案成本很低),并且要完成最终的一致性确认过程十分困难,容易受干扰。但一旦确认,即为最终确认。

  • 比特币的区块链网络在设计时使用的 PoW(Proof of Work)算法思路。
    • 一方面是限制一段时间内整个网络中出现提案的个数(增加提案成本)
    • 另外一个是放宽对最终一致性确认的需求,约定好大家都确认并沿着已知最长的链进行拓宽。
  • 如果比特币系统在某一个时刻同时出现了两个都合法的区块,那么两个都承认。于是,区块链上会出现两个合法的分支(术语叫 “分叉”)。此时矿工可以选择任何一个分支继续,在某个分支的长度超过了另一个分支时,短的那个分支马上作废。
  • 对于比特币 / 以太坊来说,其前提假设(加入其网络/集群的结点)都是不受信的,它们只相信,超过一半的结点所同意的东西。
  • 系统中暂时的不一致是可以被修正的

  • 无论你是搞区块链,还是搞分布式,你都需要知道拜占庭容错系统研究中的三个重要理论:CAP、FLP 和 DLS。
    • CAP理论: “在网络发生阻断(partition)时,你只能选择数据的一致性(consistency)或可用性(availability),无法两者兼得”。
    • FLP impossibility: 在异步环境中,如果节点间的网络延迟没有上限,只要有一个恶意节点存在,就没有算法能在有限的时间内达成共识。
    • DLS: 说明了不同网络情况下对拜占庭故障的容错上限
  • 工作量证明(Proof-of-Work,简称为 PoW)
    • 比特币的挖矿算法并不是比特币开创的,其原型叫 Hashcash,一开始这个算法是用来限制垃圾邮件的
      • Hashcash 一开始要求邮件发送方对邮件头(其中包括时间和收件人地址)计算一个 160bit 的 SHA-1 哈希值。其前面需要有 5 个零,也就是 20bit 的 0。接收端会检查这个事。
      • 这点算力对于普通发送方来说,没有什么。对于需要大量发送垃圾邮件的人来说,这就是一个很大的成本了。就算是那些控制着用户的僵尸网络的黑客来说,发送垃圾邮件时,会导致 CPU 使用率过高
      • 对于一些受信的邮件服务器,我们可以把其放进白名单中,这样,就不需要它们接受 Hashcash 挑战,它们也不用为之付出成本。
    • PoW 有两种协议。
      • 一种叫 Challenge-Response 协议,用于 Client-Server。
        • 如果 Client 需要使用服务,那么需要被 Challenge 去花费一些资源。如果证明自己的资源已被花费了,则通过认证,授权使用。
      • 另一种叫 Solution-Verification 协议,用于验证使用。Hashcash 就是这种协议。
    • 通过挖矿——PoW 这样的协议来大幅度地提高修改成本,使得有恶意的人要改一个地方,需要花很大很大的成本来修改。这几乎是一件不可能的事情。
    • 工作量证明实现了:提高对数据篡改的成本、提高网络中有不同声音的成本、解决分歧(这让整个去中心化系统的一致性,不再以人数多认可的数据为准,而是以算力多的人认可的数据为准。)
    • 也有严重问题:越来越中心化地记账(算力问题一般人几乎无法参与)、越来越跑不动(链越来越长,导致要验证数据是否正确的成本越来越高)。
  • 股权证明协议(PoS: Proof of Stake)
    • PoW 这个机制,要找到符合条件的 Hash 值,在目前来看,其耗费的电力和时间成本是越来越大了。所以,为了每个 Block 更快的生成,出现了 PoS (Proof of Stake)协议,中文翻译为股权证明协议。
    • 在 PoS 机制下,矿工不在叫矿工,而是叫 Validator(校验者)。假设现在有一个区域需要被生成,而现在有 4 个 Validator,每一个 Validator 需要以 “交押金” 的方式来取得记账权。按照股权的比权来获得记账权。
      • 如果你发起恶意攻击的话,你的钱就会被系统没收充公。而 Validator 记账后没有奖金,只有手续费。
      • 也就是说,在 PoS 机制下,记账权不再像 PoW 那样由谁的算力大谁就越有机会来记账,而是由谁的财富多,谁就越有可能来记账。于是,记账权按大家财富的比例来分配。
    • 在以太坊下,是根据拥有以太币的总量,来决定成为 Validator 的机率
    • 问题:攻击者可以发起 Nothin-At-Stake 攻击、两个分支发展还可以发起双重支付、甚至可以发起 “贿赂攻击(Bribe Attack)”
  • DPoS 机制
    • PoS 的问题也很多,所以有人又提出来了一个进化版,叫 DPoS(Delegated Proof of Stake,委托股权证明)。它是 PoS 的进化方案。
    • DPoS 优化方案在于:通过不同的策略,不定时地选中一小群节点,这一小群节点做新区块的创建、验证、签名和相互监督。这样就大幅度减少了区块创建和确认所需要消耗的时间和算力成本。
    • EOS

参考:区块链技术细节:智能合约

  • 银行的资金托管业务(类比为什么出现智能合约)
    • 当业务大到一定程度的时候,个人的信用是不足以来当中间公证人这个角色了。这时,你要找更为靠谱的机构,这个机构叫银行,银行的信用等级至少在这几方面上要比个人高。
    • 银行的受信程度很高,可以来做担保
    • e.g. 二手房买卖时双方都担心纠纷。于是买家先到银行开个户,把购房款全额存进去。这个账户和一般的账户不一样,这叫资金托管账户,钱一旦进入后,你就取不出来了,除非满足了某个条件。在开户时,房屋的买卖方和银行三方约定,一旦房产证从卖家过户到买家 30 天后没有纠纷,钱就划给卖家了。
  • 以太坊的智能合约
    • 对于以太坊来说,智能合约其实就是一段可执行的程序片段,由发布人使用一种类似于 JavaScript 或是 Python 的编程语言来编写。
      • 就像最开始那个民间担保的案例,定义好顺序逻辑
      • 把合约代码在本地编译成功后发布到区块链上,可以理解为一个特殊的交易(包括可执行代码),然后会被矿工打包记录在某一个区块中。当需要调用这个智能合约的方法时,只需要向这个智能合约的地址发送一笔交易即可。
    • 另外,我们要小心智能合同。有程序的地方就会有 Bug,现实生活中会有 Bug,合同也会有 Bug。出现了 Bug 后,大家可以相互协商,给合同打补丁(附加条款,或是重新签合同)。然而,代码合同则不一样,Bug 也会被残酷无情地执行,一旦执行就很难补救了。
      • 最著名的例子就是以太坊一个叫 The DAO 的应用,黑客在其智能合约里找到 Bug,把所有的钱给调走了,大约 7000 多万美刀。这成为有史以来最大宗的数字劫案,而且 FBI 也找不到人。
      • 这个项目因为钱被偷走而倒闭以后,引起了以太坊的强行分叉,变成 ETH 和 ETC。

参考:区块链技术 - 传统金融和虚拟货币

  • 对传统金融和虚拟货币的思考。
    • 每个交易中,对于买方,其需要付出的是货币和信用,对于卖方,其需要支付的是商品、服务或金融资产。
    • 而支出方是整个经济的驱动力。
    • 一个社会的最基本的经济活动是交易,而经济状况好的好坏是受支出方影响的。
    • 整个人类世界的影响经济波动的东西就是“借贷”,也就是为了购买现在买不起的东西,向未来的自己去借钱,或是由未来的自己去还债。这种未来消费的方式并不一定是坏事。如果能还了,就是良性,如果还不了了,那就成了恶性的。
    • 如果整个社会的支出变多,于是就会出现一片繁荣的情况。大多数人都是目光短浅的,所以,大多数人都觉得经济形势很好,于是就出现更多的借贷。人们觉得挣钱好容易,于是就借钱来买其他金融产品,导致金融产品上涨,于是导致大家觉得应该花更多的钱来投资,那样就会借更多的钱……这样一来,就会出现巨大的泡沫……
    • 2008 年暴发的全球金融次贷危机,房贷的回报如此优秀,银行开始乱放贷款,把贷款放给好多根本没有能力还款的人,且相信房价将继续升值的前提下,鼓励了许多次级贷款借款人去取得浮动利率抵押贷款。最终,最底层的越来越多的人不还贷款了,越来越多的房子被拍卖。一方面导致房价下跌,另一方面,导致银行坏账,最终,像多米诺骨牌一样倒了一片……
    • 就像上面说的 2008 年金融危机一样,银行业过于快速地促成交易,加快货币、股票、债券的流通性,导致了各种“杠杆”以及“多杠杆”的出现。
    • 虚拟货币这种后台没有价值体现的玩法,如果不能提高效率,降低成本,没有风控和评级,总有一天会达到瓶颈的——就是支出不再能够维持下去的时候。也就是没有新人入场的时候,老人因为钱投进去了,也不会再有更多的钱投入的时候。那个时候可能就是泡沫破灭的时候。
    • 就像前面说的那个经济规律一样,只要有不停的支出,就会造就一种繁荣的景象。这种繁荣的景象,对于绝大多数不明真相的人来说是很容易让他们心动的,因为人性是想不劳而获且趋利避害的。于是就会引发更多的人进入,于是形成更大的繁荣。
    • 这种去中心化的技术难题并不是什么人都能 Hold,一方面是结点是不可信任的假设,另一方面,其中有太多的政治上的博弈问题不是技术能解的。
    • 思考问题:数字货币是在颠覆现有的传统金融体系,还是建立另外一个一模一样,但充满更多泡沫和投机的体系?

  • 本文作者: xiaodongQ
  • 本文链接: /2019/10/27/blockchain-note/
  • 版权声明: 本文可以自由拷贝,转载,请注明出处,谢谢! 🤝

Comments