Friday, April 13, 2018

Blockchain



https://yeasy.gitbooks.io/blockchain_guide/content/born/what.html
http://www.ruanyifeng.com/blog/2017/12/blockchain-tutorial.html
一、非对称加密
首先,区块链的主要作用是储存信息。任何需要保存的信息,都可以写入区块链,也可以从里面读取,所以它是数据库。
其次,任何人都可以架设服务器,加入区块链网络,成为一个节点。区块链的世界里面,没有中心节点,每个节点都是平等的,都保存着整个数据库。你可以向任何一个节点,写入/读取数据,因为所有节点最后都会同步,保证区块链一致。

区块链没有管理员,它是彻底无中心的。其他的数据库都有管理员,但是区块链没有。如果有人想对区块链添加审核,也实现不了,因为它的设计目标就是防止出现居于中心地位的管理当局。
正是因为无法管理,区块链才能做到无法被控制。否则一旦大公司大集团控制了管理权,他们就会控制整个平台,其他使用者就都必须听命于他们了。
区块链由一个个区块(block)组成。区块很像数据库的记录,每次写入数据,就是创建一个区块。

每个区块包含两个部分。
  • 区块头(Head):记录当前区块的特征值
  • 区块体(Body):实际数据
区块头包含了当前区块的多项特征值。
  • 生成时间
  • 实际数据(即区块体)的哈希
  • 上一个区块的哈希
  • 推论1:每个区块的哈希都是不一样的,可以通过哈希标识区块。
  • 推论2:如果区块的内容变了,它的哈希一定会改变。

四、 Hash 的不可修改性

区块与哈希是一一对应的,每个区块的哈希都是针对"区块头"(Head)计算的。也就是说,把区块头的各项特征值,按照顺序连接在一起,组成一个很长的字符串,再对这个字符串计算哈希。
Hash = SHA256( 区块头 )
上面就是区块哈希的计算公式,SHA256是区块链的哈希算法。注意,这个公式里面只包含区块头,不包含区块体,也就是说,哈希由区块头唯一决定,
前面说过,区块头包含很多内容,其中有当前区块体的哈希,还有上一个区块的哈希。这意味着,如果当前区块体的内容变了,或者上一个区块的哈希变了,一定会引起当前区块的哈希改变。
这一点对区块链有重大意义。如果有人修改了一个区块,该区块的哈希就变了。为了让后面的区块还能连到它(因为下一个区块包含上一个区块的哈希),该人必须依次修改后面所有的区块,否则被改掉的区块就脱离区块链了。由于后面要提到的原因,哈希的计算很耗时,短时间内修改多个区块几乎不可能发生,除非有人掌握了全网51%以上的计算能力。
正是通过这种联动机制,区块链保证了自身的可靠性,数据一旦写入,就无法被篡改。这就像历史一样,发生了就是发生了,从此再无法改变。

每个区块都连着上一个区块,这也是"区块链"这个名字的由来。

五、采矿

由于必须保证节点之间的同步,所以新区块的添加速度不能太快。试想一下,你刚刚同步了一个区块,准备基于它生成下一个区块,但这时别的节点又有新区块生成,你不得不放弃做了一半的计算,再次去同步。因为每个区块的后面,只能跟着一个区块,你永远只能在最新区块的后面,生成下一个区块。所以,你别无选择,一听到信号,就必须立刻同步。
所以,区块链的发明者中本聪(这是假名,真实身份至今未知)故意让添加新区块,变得很困难。他的设计是,平均每10分钟,全网才能生成一个新区块,一小时也就六个。
这种产出速度不是通过命令达成的,而是故意设置了海量的计算。也就是说,只有通过极其大量的计算,才能得到当前区块的有效哈希,从而把新区块添加到区块链。由于计算量太大,所以快不起来。
这个过程就叫做采矿(mining),因为计算有效哈希的难度,好比在全世界的沙子里面,找到一粒符合条件的沙子。计算哈希的机器就叫做矿机,操作矿机的人就叫做矿工。

原来不是任意一个哈希都可以,只有满足条件的哈希才会被区块链接受。这个条件特别苛刻,使得绝大部分哈希都不满足要求,必须重算。
原来,区块头包含一个难度系数(difficulty),这个值决定了计算哈希的难度。举例来说,第100000个区块的难度系数是 14484.16236122。

区块链协议规定,使用一个常量除以难度系数,可以得到目标值(target)。显然,难度系数越大,目标值就越小。
哈希的有效性跟目标值密切相关,只有小于目标值的哈希才是有效的,否则哈希无效,必须重算。由于目标值非常小,哈希小于该值的机会极其渺茫,可能计算10亿次,才算中一次。这就是采矿如此之慢的根本原因。
前面说过,当前区块的哈希由区块头唯一决定。如果要对同一个区块反复计算哈希,就意味着,区块头必须不停地变化,否则不可能算出不一样的哈希。区块头里面所有的特征值都是固定的,为了让区块头产生变化,中本聪故意增加了一个随机项,叫做 Nonce。
Nonce 是一个随机值,矿工的作用其实就是猜出 Nonce 的值,使得区块头的哈希可以小于目标值,从而能够写入区块链。Nonce 是非常难猜的,目前只能通过穷举法一个个试错。根据协议,Nonce 是一个32位的二进制值,即最大可以到21.47亿。第 100000 个区块的 Nonce 值是274148111,可以理解成,矿工从0开始,一直计算了 2.74 亿次,才得到了一个有效的 Nonce 值,使得算出的哈希能够满足条件。
运气好的话,也许一会就找到了 Nonce。运气不好的话,可能算完了21.47亿次,都没有发现 Nonce,即当前区块体不可能算出满足条件的哈希。这时,协议允许矿工改变区块体,开始新的计算。

七、难度系数的动态调节

正如上一节所说,采矿具有随机性,没法保证正好十分钟产出一个区块,有时一分钟就算出来了,有时几个小时可能也没结果。总体来看,随着硬件设备的提升,以及矿机的数量增长,计算速度一定会越来越快。
为了将产出速率恒定在十分钟,中本聪还设计了难度系数的动态调节机制。他规定,难度系数每两周(2016个区块)调整一次。如果这两周里面,区块的平均生成速度是9分钟,就意味着比法定速度快了10%,因此接下来的难度系数就要调高10%;如果平均生成速度是11分钟,就意味着比法定速度慢了10%,因此接下来的难度系数就要调低10%。
难度系数越调越高(目标值越来越小),导致了采矿越来越难。

八、区块链的分叉

即使区块链是可靠的,现在还有一个问题没有解决:如果两个人同时向区块链写入数据,也就是说,同时有两个区块加入,因为它们都连着前一个区块,就形成了分叉。这时应该采纳哪一个区块呢?
现在的规则是,新节点总是采用最长的那条区块链。如果区块链有分叉,将看哪个分支在分叉点后面,先达到6个新区块(称为"六次确认")。按照10分钟一个区块计算,一小时就可以确认。
由于新区块的生成速度由计算能力决定,所以这条规则就是说,拥有大多数计算能力的那条分支,就是正宗的区块链。

但是,为了保证数据的可靠性,区块链也有自己的代价。一是效率,数据写入区块链,最少要等待十分钟,所有节点都同步数据,则需要更多的时间;二是能耗,区块的生成需要矿工进行无数无意义的计算,这是非常耗费能源的。
因此,区块链的适用场景,其实非常有限。
  1. 不存在所有成员都信任的管理当局
  2. 写入的数据不要求实时使用
  3. 挖矿的收益能够弥补本身的成本
https://www.quora.com/Why-would-you-use-blockchain-over-a-distributed-consensus-protocol-like-Paxos-or-Raft



Paxos requires coordination, which requires leader election, which requires monitoring of processes, which implies in a lot of communication. Even if the communication required for monitoring was ok, it would be hard to set appropriate timeouts to detect failures; large timeout lead to slow detection and small timeouts lead to wrong detections.
After a detection, the coordinator steps in and messages all acceptors (the nodes in the core of the system), waits for their replies (a majority), then messages them again, which in turn message the learners (those learning the outcome of transactions). If the coordinator fails, a new one must be elected, but if multiple are elected in parallel (which is allowed by the protocol), then the protocol will not make progress. This leads us to the byzantine failures: if a malicious node wants, it can prevent progress by acting as coordinator to start a new round of the protocol and then disappearing, repeatedly, in a sort of Denial of Service attack. Worse, it could simply become the coordinator and not respect the protocol rules, leading processes to inconsistent decisions.
Byzantine Paxos can prevent these attacks, but they require more processing (digital signing) and communication (decisions cannot be made based on simple majorities).

https://blockgeeks.com/guides/what-is-blockchain-technology/

http://www.ruanyifeng.com/blog/2018/01/bitcoin-tutorial.html
公钥是公开的,任何人都可以获取。私钥是保密的,只有拥有者才能使用。他人使用你的公钥加密信息,然后发送给你,你用私钥解密,取出信息。反过来,你也可以用私钥加密信息,别人用你的公钥解开,从而证明这个信息确实是你发出的,且未被篡改,这叫做数字签名(更详细的介绍请看《什么是数字签名》)。
现在请设想,如果公钥加密的不是普通的信息,而是加密了一笔钱,发送给你,这会怎样?
首先,你能解开加密包,取出里面的钱,因为私钥在你手里。其次,别人偷不走这笔钱,因为他们没有你的私钥。因此,支付可以成功。
这就是比特币(以及其他数字货币)的原理:非对称加密保证了支付的可靠性。
由于支付的钱必须通过私钥取出,所以你是谁并不重要,重要的是谁拥有私钥。只有拥有了私钥,才能取出支付给你的钱

对于比特币来说,钱不是支付给个人的,而是支付给某一把私钥。这就是交易匿名性的根本原因,因为没有人知道,那些私钥背后的主人是谁。
所以,比特币交易的第一件事,就是你必须拥有自己的公钥和私钥。
你去网上那些比特币交易所开户,它们会让你首先生成一个比特币钱包(wallet)。这个钱包不是用来存放比特币,而是存放你的公钥和私钥。软件会帮你生成这两把钥匙,然后放在钱包里面

根据协议,公钥的长度是512位。这个长度不太方便传播,因此协议又规定,要为公钥生成一个160位的指纹。所谓指纹,就是一个比较短的、易于传播的哈希值。160位是二进制,写成十六进制,大约是26到35个字符,比如 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2。这个字符串就叫做钱包的地址,它是唯一的,即每个钱包的地址肯定都是不一样的。

问题出在怎么防止其他人,冒用你的名义申报交易。举例来说,有人申报了一笔交易:地址 A 向地址 B 支付10个比特币。我怎么知道这个申报是真的,申报人就是地址 A 的主人?
比特币协议规定,申报交易的时候,除了交易金额,转出比特币的一方还必须提供以下数据。
  • 上一笔交易的 Hash(你从哪里得到这些比特币)
  • 本次交易双方的地址
  • 支付方的公钥
  • 支付方的私钥生成的数字签名
验证这笔交易是否属实,需要三步。
第一步,找到上一笔交易,确认支付方的比特币来源。
第二步,算出支付方公钥的指纹,确认与支付方的地址一致,从而保证公钥属实。
第三步,使用公钥去解开数字签名,保证私钥属实。
确认交易的真实性以后,交易还不算完成。交易数据必须写入数据库,才算成立,对方才能真正收到钱。
比特币使用的是一种特殊的数据库,叫做区块链(blockchain),详细的介绍请看《区块链入门教程》。本文只讨论交易如何写入区块链。
首先,所有的交易数据都会传送到矿工那里。矿工负责把这些交易写入区块链。
根据比特币协议,一个区块的大小最大是 1MB,而一笔交易大概是500字节左右,因此一个区块最多可以包含2000多笔交易。矿工负责把这2000多笔交易打包在一起,组成一个区块,然后计算这个区块的哈希。

计算哈希的过程叫做采矿,这需要大量的计算。矿工之间也在竞争,谁先算出哈希,谁就能第一个添加新区块进入区块链,从而享受这个区块的全部收益,而其他矿工将一无所获。
一笔交易一旦写入了区块链,就无法反悔了。这里需要建立一个观念:比特币不存放在钱包或其他别的地方,而是只存在于区块链上面。区块链记载了你参与的每一笔交易,你得到过多少比特币,你又支付了多少比特币,因此可以算出来你拥有多少资产。

交易的确认离不开矿工。为什么有人愿意做矿工呢?
比特币协议规定,挖到新区块的矿工将获得奖励,一开始(2008年)是50个比特币,然后每4年减半,目前(2018年)是12.5个比特币。这也是比特币的供给增加机制,流通中新增的比特币都是这样诞生的。
你可能看出来了,每4年奖励减半,由于比特币可以分割到小数点后八位,那么到了2140年,矿工将得不到任何奖励,比特币的数量也将停止增加。这时,矿工的收益就完全依靠交易手续费了。
所谓交易手续费,就是矿工可以从每笔交易抽成,具体的金额由支付方自愿决定。你完全可以一毛不拔,一分钱也不给矿工,但是那样的话,你的交易就会没人处理,迟迟无法写入区块链,得到确认。矿工们总是优先处理手续费最高的交易。
目前由于交易数量猛增,手续费已经水涨船高,一个区块2000多笔交易的手续费总额可以达到3~10个比特币。如果你的手续费给低了,很可能过了一个星期,交易还没确认。
一个区块的奖励金12.5个比特币,再加上手续费,收益是相当可观的。按照目前的价格,可以达到100万~200万人民币。想想看,运气好的话,几分钟就能挖到一个区块,拿到这样一大笔钱,怪不得人们对挖矿趋之若鹜。

比特币是一个全世界的开放网络,只要你有服务器,就能加入这个网络,成为一个节点。每个节点都包含了整个区块链(目前大概 100多 GB),并且节点之间时刻不停地在同步信息。
比特币要解决的核心问题,就是创造一种可信的数字凭证。由于这种凭证可信,所以能够当做货币。
比特币的技术基础是加密学,因为只有加密学才能保证它的可信性。一旦加密被破解,它就没法当作货币了。这也是这一类数字凭证被称为"加密货币"的原因。
比较麻烦的是另一种情况,就是张三把同一笔钱付给两个人。他先向区块链提交一个交易"张三向李四转移了1个比特币",然后又提交了另一个交易"张三向王五转移了1个比特币"。这两个交易都可能被认为是真实的交易,从而进入区块链。因此,必须有办法防止出现这种情况。
情况一:同一个矿工收到了这两个交易。那么他会察觉到,它们不可能同时成立,因此选择其中的一笔写入区块链。
情况二:矿工 A 收到了第一笔交易,矿工 B 收到了第二笔交易,他们各自都会认定这是合法的交易,分别把这两笔交易写入了两个区块,这时区块链就出现了分叉。

比特币协议规定,分叉点之后最先达到6个区块的那个分支,被认定为正式的区块链,其他分支都将被放弃。由于区块的生成速度由计算能力决定,所以到底哪一笔交易最后会被写入区块链,完全由它所在的分支能吸引多少计算能力决定。隐藏的逻辑是,如果大多数人(计算能力)选择相信某一笔交易,那么它就应该是真的。
综上所述,双重支出不可能发生。因为中央记账系统总有办法发现,你把同一笔钱花了两遍。但是,这也说明了比特币的一个代价,就是交易不能实时确认,必须等待至少一个小时。

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts