区块链
什么是区块链
区块链是一种特殊的分布式数据库。是一个由多个节点组成的区块链网络。任何人都可以架设服务器成为区块链的一个节点。节点之间没有权值高低每个节点都是平等的,都保存着整个数据库。你可以向任何一个节点,写入/读取数据,所有节点最后都会通过同步来保证区块链一致。正因为区块链的全局同步性,于是区块链便可以通过自身的安全机制实现了无人管理。
具体组成
我们说了既然叫区块链,其实我们可以简单的想象成链表,区块链由一个个区块(block)组成,每次写入数据就是在创建一个区块。
一个区块包含以下内容
区块大小信息(4字节)
区块头(80字节)
版本号(4字节)
上一个区块的SHA256 Hash值,要求链接到一个合法的块(32字节)
包含所有校验过的交易的Merkle树根的Hash值(32字节)
时间戳(4字节)
难度指标(4字节)
Nonce:PoW问题的答案(4字节)
交易个数计数器(1-9字节)
所有交易的具体内容(字节数不确定)
Hash是个什么鬼
这里首先解释下hash(散列、杂凑)函数,是将任意长度的数据映射到有限长度的域上。直观解释起来,就是对一串数据m进行杂糅,输出另一段固定长度的数据h,作为这段数据的特征(指纹)。
了解了散列的概念,然后久了解下安全散列算法SHA,是美国国家安全局 (NSA) 设计,美国国家标准与技术研究院(NIST) 发布的一系列密码散列函数,主要用途还是用于数字签名。对任何长度的报文(就是你要加密的信息),计算出来都是一个32 byte的结果,称之为摘要。等你拿到报文和摘要之后,对报文进行SHA-256算法,把计算出的结果和收到的摘要比对,如果一样,就说明报文在传输过程中没有被改。
SHA-256算法输入报文的最大长度不超过2^64 bit,输入按512-bit分组进行处理,产生的输出是一个256-bit的报文摘要。
@(举个栗子——SHA256算法?)
有一个字符串”abc“,他有三个字节(一个字两个字节,一个字节8位),也就是24位,那么按照ascii码,这个就该转化为一个位串:0110 0001 0110 0010 0110 0011,它也可以被表示成16进制字符串:0x616263。然后我们要计算这个位串的MD5。
- 补位:首先补一个1,然后一直补0,直到补位后的总长度%512=448(补位操作具有强制性:如果补位前的长度%512=448那必须进行补位一个周期回到次状态)
- 补长·度:所谓的补长度就是将原始的数据长度(补位前)补到已经进行补位操作的后面,这个原始数据长度为64位
- 初始缓存:使用一个256-bit 的缓存来存放该散列函数的中间及最终结果该缓存表示(十六进制)为:
A=0x6A09E667
B=0xBB67AE85
C=0x3C6EF372
D=0xA54FF53A
E=0x510E527F
F=0x9B05688C
G=0x1F83D9AB
H=0x5BE0CD19
-
处理512-bit(16 个字)报文分组序列:处理512-bit(16 个字)报文分组序列。
该算法使用了六种基本逻辑函数,由64 步迭代运算组成。每步都以256-bit 缓存值ABCDEFGH 为输入,然后更新缓存内容。
每步使用一个32-bit 常数值Kt
和一个32-bit Wt。
总结起来说就是Hash通过Hash256(data)函数得到一个很长的指纹,这个指纹拥有很强的不可逆性,使得可破解度几乎低到0(理论上,其他字符串也有可能得到这个哈希,但是概率极低,可以近似认为不可能发生)。因此:
- 推论1:要求一种安全的标识算法唯一标识区块,hash是一个很好的选择。实现的方式为Hash = SHA256(区块头),这个公式里面只包含区块头,不包含区块体,也就是说,哈希由区块头唯一决定,
- 推论2:如果区块的内容改变,那么区块的hash一定改变
通过推论2其实我们可以得出,区块的数据一旦写入就难以再被篡改了。因为如果有人修改了一个区块,该区块的哈希就变了。为了让后面的区块还能连到它(因为下一个区块包含上一个区块的哈希),该人必须依次修改后面所有的区块,否则被改掉的区块就脱离区块链了。但是由于哈希的计算很耗时,短时间内修改多个区块几乎不可能发生,除非有人掌握了全网51%以上的计算能力。
- 为什么哈希的计算很慢
我前面在讲区块的组成的时候说了区块头包含一个四个字节的难度指标,这个难度指标的值确定了哈希计算的难度。区块链协议规定,使用一个常量除以难度系数,可以得到目标值(target)。显然,难度系数越大,目标值就越小。
举个栗子——区块的难度系数
第100000个区块的难度系数是 14484.16236122。由计算公式我们可知
target = targetMax / difficulty
那么就有
targetMax = 0x00000000FFFF0000000000000000000000000000000000000000000000000
difficulty = 14484.16236122
只有当计算的hash小于目标值的时候才是有效的,必须重算,。由于目标值非常小,哈希小于该值的机会极其渺茫,可能计算10亿次,才算中一次。如果要对同一个区块反复计算哈希,就意味着,区块头必须不停地变化,否则不可能算出不一样的哈希。区块头里面所有的特征值都是固定的,为了让区块头产生变化,中本聪故意增加了一个随机项,叫做 'Nonce'。
Nonce 是一个随机值,矿工的作用其实就是猜出 Nonce 的值,使得区块头的哈希可以小于目标值,从而能够写入区块链。Nonce 是非常难猜的,目前只能通过穷举法一个个试错。根据协议,Nonce 是一个32位的二进制值,即最大可以到21.47亿。第 100000 个区块的 Nonce 值是274148111,可以理解成,矿工从0开始,一直计算了 2.74 亿次,才得到了一个有效的 Nonce 值,使得算出的哈希能够满足条件。可以理解成,矿工从0开始,一直计算了 2.74 亿次,才得到了一个有效的 Nonce 值,使得算出的哈希能够满足条件。不是每个区块体都能算出满足条件的hash,对于这种情况就玉虚矿工改变区块体,开始新的计算。
动态调节控制产出速率
正如上文所述,采矿的随机性导致了采矿的时间差,为了将产出速率恒定在十分钟,中本聪设计了难度系数的动态调节机制。他规定,难度系数每两周(2016个区块)调整一次。如果这两周里面,区块的平均生成速度是9分钟,就意味着比法定速度快了10%,因此接下来的难度系数就要调高10%;如果平均生成速度是11分钟,就意味着比法定速度慢了10%,因此接下来的难度系数就要调低10%。
区块链的分叉
我们这里第一次拿比特币举个栗子。我们说了既然每一笔交易都会被记录而且不可篡改,并且透明公开,最后一条,也就意味交易可以重用,比如说“Yank向Bill转移了8个比特币”。不管善意还是恶意,Yank我在上一笔没有写入区块链的间歇提交了另一笔交易“Yank向Gates转移了3个比特币”,那么是不是就意味着这句话可能被两次写入区块链?有着双重支出的可能?
以上栗子我们穷举:
- 情况一: 如果这两句话都是被一个矿工接受,那么矿工察觉到这两笔交易不会同时成立,第二次写入的时候,查询区块链可以发现Yank已经把这笔钱花掉了,从而认定这是不合法的交易,不能写入区块链。因此,复制交易是不可能的。
- 情况二: 这两句话同时被两个矿工接受。矿工 A 收到了第一笔交易,矿工 B 收到了第二笔交易,他们各自都会认定这是合法的交易,分别把这两笔交易写入了两个区块,这时区块链就出现了分叉。比特币协议规定,分叉点之后最先达到6个区块的那个分支,被认定为正式的区块链,其他分支都将被放弃。由于区块的生成速度由计算能力决定,所以到底哪一笔交易最后会被写入区块链,完全由它所在的分支能吸引多少计算能力决定。隐藏的逻辑是,如果大多数人(计算能力)选择相信某一笔交易,那么它就应该是真的。
需要区块链的地方
这里我只放一张图:
===
参考:http://www.ruanyifeng.com/blog/2017/12/blockchain-tutorial.html