了解区块链-用JS建造你自己的区块链

了解区块链-用JS建造你自己的区块链

00-1010区块链太复杂了,说点简单的吧。用JS构建自己的区块系统。只用几行代码就能解释区块链的底层数据结构、POW挖掘思想事务处理流程等。当然,真实场景远比这复杂。这篇文章目的只是让你对区块链有一个初步的了解。

文章主要参考了视频:用JavaScript构建区块链(https://www.youtube.com/playlist?list=plzvrqmj 9 hditqzmbtfisdxfxul 5k 0 f-Q4)

感谢原作者,本文在原视频的基础上进行了修改和补充,增加了个人理解。

00-1010区块链顾名思义就是由块组成的链,所以最基本的数据结构就是块。每个块都包含时间戳、数据、散列、先前散列和其他信息。其中data用于存储数据,previousHash是前一个块的哈希值。示意图如下:

哈希是块信息的汇总存储。hash的优点是任何长度的信息都可以通过hash映射成固定长度的字符串,比如sha256:

calculateHash() {

返回sha 256(this . previous hash this . timestamp JSON . stringify(this . data))。toString();

}

块的数据结构

块的最基本数据结构如下:

类块{

构造函数(时间戳,数据,先前哈希=\'\') {

this.timestamp=时间戳;

this.data=data

this . previous hash=previous hash;

hash的计算必须放在最后,计算前必须将所有数据赋值正确。

this . hash=this . calculate hash();

}

calculateHash() {

返回sha 256(this . previous hash this . timestamp JSON . stringify(this . data))。toString();

}

}

区块链的数据结构

多个块组成的区块链显然可以用数组或链表来表示,例如:

区块链级

构造函数(){

this . chain=[];

}

}

基础块

所谓万事开头难,区块链的第一块总是需要人手工打造的。该块的previousHash为空,例如:

createGenesisBlock() {

返回新块(\' 2018-11-11 00:00:00 \',\'简单链的创世块\',\' \');

}

区块链的施工方法也应改为:

区块链级

构造函数(){

this . chain=[this . creategenesisblock()];

}

}

添加块

每增加一个新的块,它必须与原来的区块链连接,即:

区块链级

getLatestBlock() {

返回this . chain[this . chain . length-1];

}

addBlock(newBlock) {

//新块的前一个哈希值是现有区块链的最后一个块的哈希值;

new block . previous hash=this . getlatest block()。哈希;

//重新计算新块的哈希值(因为previous hash);是指定的);

new block . hash=new block . calculate hash();

//将新块添加到链中

this . chain . push(new block);

}

.

}

检查区块链

区块链数据结构的核心是保证它是来回链接的,不能被篡改。但是如果真的有人篡改了一个区块,我们怎么去验证这个发现呢?最愚蠢和自然的想法是遍历所有情况并逐一检查,例如:

ischavalid(){

//遍历所有块

for(设I=1;I this . chain . length;i ) {

const current block=this . chain[I];

const previous block=this . chain[I-1];

//重新计算当前块的哈希值。如果哈希值不匹配,说明这个块中的数据被篡改了,哈希值没有重新计算。

if (currentBlock.hash!==current block . calculate hash()){

console.error(\'hash不等于: \' JSON . stringify(current block));

返回false

}

//判断当前块的previousHash是否真的等于前一块的。如果不是,则意味着前一个块已经被篡改。虽然哈希值重新计算正确,但后续块的哈希值没有重新计算,导致整个链断裂。

if (currentBlock.previousHash!==previous block . calculate hash){

console.error(\'以前的哈希不正确: \' JSON . stringify(current block));

返回false

}

}

返回true

}

运行它

跑上去一看,即:

设simpleChain=新区块链();

simpleChain.addBlock(新块(\' 2018-11-11 00:00:01 \',{ amount : 10 });

simpleChain.addBlock(新块(\' 2018-11-11 00:00:02 \',{金额: 20 });

控制台。log(JSON。stringify(简单链,null,4));

console.log(\'链有效吗?\'简单的链条。ischavalid());

结果如下:

阿里-186590 cc 4a 7f :单链山妖$ node main_1.js

{

链条\' : [

{

时间戳\' : \' 2018-11-11 00:00:00 \',

数据\":\"简单链的起源块,

以前哈希\' : \',

哈希: \' FD 56967 ff 621 a 4090 ff 71 ce 88 FDD 456547 D1 c 92d 2e 93766 B7 e 8791 f 7 a5 f 91 f 89 \'

},

{

时间戳\' : \' 2018-11-11 00:00:01 \',

数据\' : {

金额\' : 10

},

以前哈希: \' FD 56967 ff 621 a 4090 ff 71 ce 88 FDD 456547 D1 c 92d 2e 93766 b7e 8791 f 7 a5f 91f 89 \',

哈希: \' 150 b 196268 a 0152 e 9 f 0e 719 AC 131 a 722472 a 809 f 49 BD 507965029 a 78 c 7400529 \'

},

{

时间戳\' : \' 2018-11-11 00:00:02 \',

数据\' : {

金额\' : 20

},

以前哈希: \' 150 b 196268 a 0152 e 9 f 0e 719 AC 131 a 722472 a 809 f 49 BD 507965029 a 78 c 7400529 \',

哈希: \' 274 a7a 13 ed 20118 E8 CB 745654934 a7 e24 a4 d 59333 ba 17 DFB F5 d 4 cf E0 fa 8 a6 e 34 \'

}

]

}

链条有效吗?真实的

注意看其中的前一个哈希与哈希,确实是当前区块的前一个哈希指向前一个区块的哈希。

篡改下试试

都说区块链不可篡改,是真的吗?让我们篡改第2个区块试试,如:

设简单链=新区块链();

simpleChain.addBlock(新块(\' 2018-11-11 00:00:01 \',{金额: 10 });

simpleChain.addBlock(新块(\' 2018-11-11 00:00:02 \',{金额: 20 });

console.log(\'链有效吗?\'简单的链条。ischavalid());

//将第2个区块的数据,由10改为15

简单链.data={ amount : 15 };

console.log(\'链还有效吗?\'简单的链条。ischavalid());

控制台。log(JSON。stringify(简单链,null,4));

结果如下:

阿里-186590 cc 4a 7f :单链山妖$ node main_1.js

链条有效吗?真实的

哈希不等于:{ \'时间戳\' : \' 2018-11-11 003:00:01 \',\'数据\' : { \'金额\' :15},\'先前哈希D1 c 92d 2 e 93766 b 7 e 8791 f 7 a5 f 911

链条还有效吗?错误

{

链条\' : [

{

时间戳\' : \' 2018-11-11 00:00:00 \',

数据\":\"简单链的起源块,

以前哈希\' : \',

哈希: \' FD 56967 ff 621 a 4090 ff 71 ce 88 FDD 456547 D1 c 92d 2e 93766 B7 e 8791 f 7 a5 f 91 f 89 \'

},

{

时间戳\' : \' 2018-11-11 00:00:01 \',

数据\' : {

金额\' : 15

},

以前哈希: \' FD 56967 ff 621 a 4090 ff 71 ce 88 FDD 456547 D1 c 92d 2e 93766 b7e 8791 f 7 a5f 91f 89 \',

哈希: \' 150 b 196268 a 0152 e 9 f 0e 719 AC 131 a 722472 a 809 f 49 BD 507965029 a 78 c 7400529 \'

},

{

时间戳\' : \' 2018-11-11 00:00:02 \',

数据\' : {

金额\' : 20

},

以前哈希: \' 150 b 196268 a 0152 e 9 f 0e 719 AC 131 a 722472 a 809 f 49 BD 507965029 a 78 c 7400529 \',

哈希: \' 274 a7a 13 ed 20118 E8 CB 745654934 a7 e24 a4 d 59333 ba 17 DFB F5 d 4 cf E0 fa 8 a6 e 34 \'

}

]

}

显然,篡改了数据之后,哈希值并未重新计算,导致该区块的混杂值对不上。

再篡改下试试

那么,如果我们聪明点,篡改后把混杂值也重新计算会如何?

设简单链=新区块链();

simpleChain.addBlock(新块(\' 2018-11-11 00:00:01 \',{金额: 10 });

simpleChain.addBlock(新块(\' 2018-11-11 00:00:02 \',{金额: 20 });

console.log(\'链有效吗?\'简单的链条。ischavalid());

//篡改后重新计算混杂值

简单链.data={ amount : 15 };

简单链.hash=simpleChain.chain[1].计算hash();

console.log(\'链还有效吗?\'简单的链条。ischavalid());

控制台。log(JSON。stringify(简单链,null,4));

结果如下:

显然,第3个区块的前一个哈希并未指向第2个区块的哈希。

是真的无法篡改吗

其实并不是,如果我们再聪明一点,把后续区块的混杂值也重新计算一下,不就好了吗?确实如此,如:

设简单链=新区块链();

simpleChain.addBlock(新块(\' 2018-11-11 00:00:01 \',{金额: 10 });

simpleChain.addBlock(新块(\' 2018-11-11 00:00:02 \',{金额: 20 });

console.log(\'链有效吗?\'简单的链条。ischavalid());

//篡改第2个区块

简单链.data={ amount : 15 };

简单链.hash=simpleChain.chain[1].计算hash();

//并把第3个区块也重新计算

简单链.以前的哈希=简单链。链条,链条.哈希;

简单链.hash=simpleChain.chain[2].计算hash();

console.log(\'链还有效吗?\'简单的链条。ischavalid());

控制台。log(JSON。stringify(简单链,空,4

作者:扁鹊他大哥

版权声明:区块链数字货币交易平台 发表于 2022-04-26 6:05:14。
转载请注明:了解区块链-用JS建造你自己的区块链 | 零零洞洞

暂无评论

暂无评论...