区块链由一个一个区块组成,通过 chain 来将一个个 block 区块链接起来
人们可以把区块链看成人人都可以信任的分布式账簿
区块 block
一个区块大体上面可以被分为三个部分:
一旦数据被更改,那么哈希值就会发生变化,这样人们就能通过哈希值来发现数据的更改。
区块链的第一个区块没有前哈希值,可以被叫做祖先区块(Genesis Block)。
是的,区块链这样说就和链表很像了
区块链为了放置区块被篡改,引入了一个 Proof of Work(POW)工作量证明机制
区块链还引入了 Peer to Peer(P2P)的网络,形成了分布式存储
一旦有一个区块需要被加入,需要 P2P 网络中所有人达成共识,这个区块才能被加入。
区块链防篡改并不是让数据不能被篡改,而是让做这件事(窜改数据)的成本变的极高。
哈希(散列)函数 Hash Function
F(x) = y (y 为定长)
已知 x,求 y ==》 容易
已知 y,求 x ==》 困难
例如:x^18 + x^5 + x^0.5 + x - 5 = y
我们可以尝试猜数字
猜 = 穷举/试值 = WORK
穷举的越快(算力越高),理论上就能越快得到结果的
复制代码
crypto-js
crypto 模块的目的是为了提供通用的加密和哈希算法。用纯 JavaScript 代码实现这些功能不是不可能,但速度会非常慢。Nodejs 用 C/C++实现这些算法后,通过 cypto 这个模块暴露为 JavaScript 接口,这样用起来方便,运行速度也快。
crypto-js 的安装下载和使用
const sha256 = require("crypto-js/sha256");
console.log(sha256('hello').toString());
console.log(sha256('world').toString());
复制代码
测试结果: 对于不同的输入,哪怕只是一个很微小的改动,输出都是不一样的
得到的结果就是哈希值
对于同一个输入,输出结果是一样的。
function proofOfWork() {
let data = "hello world";
let x = 1;
while (true) {
if(sha256(data + x).toString()[0]!== "0") {
x = x + 1;
} else {
console.log(sha256(data + x).toString());
console.log(x);
break;
}
}
}
proofOfWork();
复制代码
结果:
function proofOfWork() {
let data = "hello world";
let x = 1;
while (true) {
if (
sha256(data + x).toString()
// 可以通过调整字符串长度来控制难度,自己可以试一下。
// 也可以用自己喜欢的语言,来实现这个函数。
// 这个函数真的不复杂。
.substring(0, 4) !== "0000"
) {
x = x + 1;
} else {
console.log(sha256(data + x).toString());
console.log(x);
break;
}
}
}
proofOfWork();
复制代码
结果:
创建一个区块的类
const sha256 = require("crypto-js/sha256");
/**区块
* data
* 之前区块的哈希值
* 自己的哈希值——由存储在区块里的信息算出来的(data + 之前区块的哈希值)
*/
//写一个区块的类
class Block{
constructor(data, previousHash) {
this.data = data;
this.previousHash = previousHash;
this.hash = this.computeHash()
}
computeHash(){
return sha256(this.data + this.previousHash).toString()
}
}
const block = new Block("转账10元","KLOP");
console.log(block)
复制代码
运行之后:
编写一个链的类
class Block{
constructor(data, previousHash) {
this.data = data;
this.previousHash = previousHash;
this.hash = this.computeHash()
}
computeHash(){
return sha256(this.data + this.previousHash).toString()
}
}
// const block = new Block("转账10元","KLOP");
// console.log(block)
class Chain {
constructor(){
this.chain = [this.bigBang()];
}
bigBang(){
//定义一个祖先区块
const genesisBlock = new Block("我是祖先区块","");
return genesisBlock;
}
}
const chain = new Chain();
console.log(chain);
复制代码
输出的一个具有祖先区块的链
添加一个区块到区块链上
class Chain {
constructor(){
this.chain = [this.bigBang()];
}
bigBang(){
//定义一个祖先区块
const genesisBlock = new Block("我是祖先区块","");
return genesisBlock;
}
//找到最近一个block的hash
getLatestBlock(){
return this.chain[this.chain.length - 1];
}
//添加区块到区块链上
addBlocktoChain(newBlock){
//找到最近一个block的hash
//这个hash就是新区块的previousHash
newBlock.previousHash = this.getLatestBlock().hash;
newBlock.hash = newBlock.computeHash();
this.chain.push(newBlock);
}
}
const chain = new Chain();
const block1 = new Block("转账10元","");
chain.addBlocktoChain(block1);
console.log(chain);
复制代码
效果:
验证区块链中数据是否被篡改
class Chain {
constructor(){
this.chain = [this.bigBang()];
}
bigBang(){
//定义一个祖先区块
const genesisBlock = new Block("我是祖先区块","");
return genesisBlock;
}
//找到最近一个block的hash
getLatestBlock(){
return this.chain[this.chain.length - 1];
}
//添加区块到区块链上
addBlocktoChain(newBlock){
//找到最近一个block的hash
//这个hash就是新区块的previousHash
newBlock.previousHash = this.getLatestBlock().hash;
newBlock.hash = newBlock.computeHash();
this.chain.push(newBlock);
}
//验证这个当前的区块链是否合法
//当前的数据有没有被篡改
//我们要验证区块的previousHash是否等于previous区块的hash
validateChain() {
if (this.chain.length === 1) {
if (this.chain[0].hash !== this.chain[0].computeHash()) {
return false;
}
return true;
}
// this.chain[1] 是第二个区块
// 我们从第二个区块开始 验证
// 验证到最后一个区块 this.chain.length -1
for (let i = 1; i <= this.chain.length - 1; i++) {
const blockToValidate = this.chain[i];
//当前的数据有没有被篡改
if (blockToValidate.hash !== blockToValidate.computeHash()) {
console.log("数据篡改");
return false;
}
//我们要验证区块的previousHash是否等于previous区块的hash
const previousBlock = this.chain[i - 1];
if (blockToValidate.previousHash !== previousBlock.hash) {
console.log("前后区块链接断裂");
return false;
}
}
return true;
}
}
const chain = new Chain();
const block1 = new Block("转账10元","");
const block2 = new Block("转账20元","");
const block3 = new Block("转账30元","");
const block4 = new Block("转账40元","");
chain.addBlocktoChain(block1);
chain.addBlocktoChain(block2);
chain.addBlocktoChain(block3);
chain.addBlocktoChain(block4);
//尝试篡改这个区块链
chain.chain[1].data = "转账一百个十元";
console.log(chain);
console.log(chain.validateChain())
复制代码
效果:
学习来源
https://www.bilibili.com/video/av78391502
评论