区块链入门学习(1)--基本原理和成链的个人理解
什么是区块链
生活中区块链小栗子
现在家里有三口人,爸爸,妈妈和儿子。他们开始约定由爸爸记账,妈妈买菜了花了20元,爸爸加了一升油花了50元,这些都会被爸爸记在本子上(集中式)。有一天,爸爸突然想私自买包烟抽,于是在本子上做了手脚,妈妈没有发现,却被儿子发现了,妈妈却无可奈何,因为账本在爸爸手上,没有纰漏。于是,妈妈提议,三口人每个人都要做账本,当发现异常时,校对一下就知道哪个是错误的了,于是,家里就有了三份账本(分布式),每个人的资金有变动,都要广播一下,让另外的人记账。那么问题来了,这样每次都要每个人记账,是不是很费力啊,要是我,肯定觉得麻烦。但是,如果妈妈说,每记一笔都会有金币奖励,且只给第一个记完的人。那大家都会踊跃记账,又有问题出现了,儿子为了得到奖励去买喜爱的零食,就写得很潦草,完全看不懂(医生们的笔记,哈哈),妈妈发现了,提出,我们需要达成共识,我们要用格子纸写,每格一个字,每行空两格,要用正楷。同时,为了保证数据同步,我们要把前一个人的消费和时间,签名进行核对,没有错误以后,我们才能写进去,一直按规范做到最新的状态。
这样,要想做假账的话,除非贿赂一个人和你一起篡改一模一样的账本,否则是就是做不到的。
栗子?小结
那以上的账本,我们就可以说是一条区块链。每一笔交易就是一个区块。记账的人,我们称之为旷工,为了获取奖励,我们采用格子纸和正楷规范地记账过程就是挖矿。最后,我们引用共识机制保证数据同步和正确地持续链接下去。
简单来说,区块链就是由一个一个的包含着信息的区块连接起来的信息链。其中,包含的信息主要包括主体信息data、时间戳timestamp、前hash,本身hash,随机值nonce和本身的序号index等。用js代码表示即为:
const firstBlock = {
timestamp: 1550155109024,//时间戳
prevHash: '0',//前一个hash
nonce:0, //随机值
hash: 'b788ba63a91f9fcbae92154679da5df7551939518e81aca280745c9eadb51fbd',//本身hash
index: 0, //序号
data: {
info:'I am a firstBlock in BlockChain'
},//信息主体
}
那么,我们可以对区块做一个简单的分解,分为区块头和区块体。区块头(时间戳timestamp、前hash,本身hash)和区块体(主体信息data)
每一个区块会根据自身区块里的其他值生成本身hash,后面的区块依据preHash来链接。一个一个地向前追溯,那么第一个就没有preHash,也就是我们常说的创世区块。
这里就会有了区块链的几个重要的特点,其本身不可被篡改、存储数据。那么,我们现在可以说,区块链是由一个个任何人都可以访问的区块构成的分布式的,且不可变的数据库。一旦一个区块被添加或者被篡改,除非让剩余的其余区块失效,否则它是不会再被改变的。但这是不可能的。对于要制作虚假交易,除非你说服了全网里超过51%的矿工都更改某一笔账目,否则你的篡改都是无效的。网络中参与人数越多,实现造假可能性越低。
hash
为了验证链的正确性,我们需要比对链中每个区块的信息,最后一一比对完,这样的工作量是非常大的。因此我们在区块链中,用到的hash算法是SHA256。为什么用hash算法呢?
因为hash有以下特点:
- 可以根据相同信息生成一组相同的串
- 根据串无法倒推出生成该串的信息
- 信息方发生细微变化,得到的值将会变得面目全非。
这里用到的Hash算法不仅起到了验证链的正确性以外,还提供了合理的工作量证明(pow)。这里的pow方式我们发放到第二章,用代码给大家讲解。
说到代码,额。该到正题了,我们就用js来实现下简单的区块链的成链及相关验证。
js实现简单的区块链的成链及相关验证
首先我们要创建一个区块类,来表示区块:
class EasyBlock {
constructor(index, timestamp, data, prevHash = '') {
this.index = index;
this.prevHash = prevHash;
this.timestamp = timestamp;
this.data = data;
this.hash = this.calHash();
}
calHash() {
return crypto
.createHash('sha256')
.update<