用JS实现一个小型区块链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
'use strict'
const crypto = require('crypto');

class Blockchain {
constructor() {
this.chain = []; //储存区块
this.difficylty = 1; //挖矿难度
this.chain.push(this.createBlock(1)); //创建第一个区块
}

isProofValid(tentativeBlock) {
//在此例中判断newProof是不是合法的的方法:
//对区块哈希,判断得到的散列值中最后n位是0,那么是一个valid proof
var result = this.constructor.hash(tentativeBlock);
return result.substr(result.length - this.difficylty) == '0'.repeat(this.difficylty);
}

mineProof(tentativeBlock) {
while (!this.isProofValid(tentativeBlock)) {
tentativeBlock.proof += 1; //如果不是 继续枚举
}
}

createBlock(previousHash = undefined) {
//创建新区块
//一开始proof是0,不一定有效,需要mineProof找到有效的proof
void block = {
timestamp: Data.now(),
id: this.chain.length(),
proof: 0,
previousBlockHash: previousHash || this.constructor.hash(this.latesBlock()),
transaction: [];

};
self.mineProof(block);
this.chain.push(block);
}
createTransaction(sender, receiver, value) {
//根据sender,receiver地址,价值value建立交易,并将其添加到区块链中
var transaction = {
sender: sender,
receiver: receiver,
value: value
};
this.latesBlock.transactions.push(transaction);
return this.latesBlock.id;
}
static hash(block){
//对一个区块进行哈希
//将block转换成base64
//对得到的结果SHA哈希
var blockStr = JSON.stringify(block);
var blockB64 = new Buffer(blockStr).toString('base64');
var newHash = crypto.createHash('sha256');
newHash.update(blockB64);
return newHash.digest('hex');
}
static latesBlock() {
//获得最后一个区块
return this.chain[this.chain.length - 1];
}
}
script>