今天我们通过 JS 实现一个区块链应用, 帮助您更好地理解区块链技术原理
创建区块链
区块链验证
工作量证明防纂改
我们先创建一个 JS 项目, 然后创建 main.JS 作为项目主文件也是入口文件. 区块链本质是密码学, 我们需要将信息进行加密, 这里我们用 crypto-JS 提供加密算法来进行加密, 所以先加载一下 crypto-JS 这个库.
先创建 Block(块)这个类, 在其构造函数对块的各个属性进行初始化赋值, 之所以叫做区块链, 那么这条链是靠什么链接的呢, 看一下构造函数, 可以看出答案是每个块都拥有前一个块的 hash 值的方式来实现一条链的. calculateHash 方法作用就是将所有信息进行 hash 算法来加密成一个字符串.
然后我们来创建 BlockChain 区块链这个类, 我需要在构造函数中初始化区块链, 创建区块链的第一个块的工作是由 createGenesisBlock 来做的. getLatesBlock 用户获取区块链的上一个块, addBlock 则负责添加块.
修改构造函数, 将第一个块添加到区块链中.
然后我们来实现 getLatesBlock 和 addBlock 方法, 这里内容很简单, 大家一看就会, 我就不做过多解释了.
然后我们创建一个区块链, 添加两个块.
大家注意每一个块的 previousHash 都是上一个块的 hash 值, 这就是区块链的模样.
为了防止有人恶意篡改一个块的信息, 我们需要对区块链进行校验, 检验的方法很简单, 就是验证每个区块链的块的 previoushash 值与上一个块的 hash 是否相等. 这里我们在验证时不需要考虑第一个块, 因为他比较特殊, 没有前一个块.
测试一下 没有问题, 验证通过
我们来尝试篡改一个块, 篡改时我们不但需要修改数据, 还需要重新计算他的 hash 值, 然后再次进行校验, 发现报错.
大家都知道区块链一般在十分左右创建一个块, 这是因为现在的计算机速度快到可以很短的时间内篡改区块链上所有块来实现篡改块的信息, 如果是这样, 我们校验方法也就失效了. 为了防止提出 POW 工作量证明的方式来解决此问题, 我们通过提高计算 hash 值难度来增加创建新块 (也就是挖矿) 的时间, 来防止篡改. 是如何增加计算难度的呢, 也就是如何来要求更高计算速度的呢. 我们是通过判断计算出值是否满足一定格式来实现.
我们通过判断计算出的 hash 值前几位是否为 0 来不断提高难度的, 如果我们要求前面必须是两个 0 才有效, 这样就有一定难度, 0 个数越多要求算力就越高, 具体看代码吧.
这里定义 mineBlock 接受一个参数来定义难度 - 也就是要求 hash 前几位为零, difficulty 值越大, 计算难度越大, 要计算力也越高.
如果计算值没有满足我们要求, 也就是 hash 值, 我们需要调整值继续计算, 我们知道 index ,timestamp data 这些值是无法改变, 所以我们需要添加一个变量来调整值, 所以这里我们引入 nonce .
我们对 addBlock 方法进行修改, 将对块的赋值移到 mineBlock
在 BlockChain 我们将难度定义为 2
大家注意 hash 值前两位为 0. 并花费一定的时间.
这里我修改为 5 时, 由于等待时间过长我就放弃了
这是修改为 3 的情况, 还可以接受
来源: http://www.jianshu.com/p/2385b8fe5d7e