-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
134 lines (98 loc) · 3.01 KB
/
index.ts
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import * as crypto from 'crypto';
class Transaction {
constructor(
public amount: number,
public payer: string,
public payee: string,
){}
toString(){
return JSON.stringify(this)
}
}
class Block {
public nounce = Math.round(Math.random() * 9999999);
constructor(
public prevHash: string,
public transaction: Transaction,
public ts = Date.now()
){
}
get hash(){
const str = JSON.stringify(this);
const hash = crypto.createHash('SHA256');
hash.update(str).end();
return hash.digest('hex');
}
}
class Chain{
public static instance = new Chain();
chain: Block[];
constructor(){
this.chain = [new Block('', new Transaction(100, 'genesis', 'sheranBuckman'))]
}
get lastBlock(){
return this.chain[this.chain.length - 1];
}
mine(nounce: number){
let solution = 1;
console.log('Minining.....');
while(true){
const hash = crypto.createHash('MD5');
hash.update((nounce + solution).toString()).end();
const attempt = hash.digest('hex');
if(attempt.substring(0, 4) === '0000'){
console.log(`Solved: ${solution}`);
return solution;
}
solution = solution + 1;
}
}
addBlock(transaction: Transaction, senderPublicKey: string, signature: Buffer){
//verify SHA256 signature
const verify = crypto.createVerify('SHA256');
verify.update(transaction.toString());
const isValid = verify.verify(senderPublicKey, signature);
if(isValid){
const newBlock = new Block(this.lastBlock.hash, transaction);
this.mine(newBlock.nounce);
this.chain.push(newBlock);
}
}
}
class Wallte{
public publicKey: string;
public privateKey: string;
constructor(){
const keyPair = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem'
}
})
this.privateKey = keyPair.privateKey;
this.publicKey = keyPair.publicKey;
}
sendMoney(amout: number, payeePublicKey: string){
const transaction = new Transaction(amout, this.publicKey, payeePublicKey);
// sign money crypto
const sign = crypto.createSign('SHA256');
sign.update(transaction.toString()).end();
const signature = sign.sign(this.privateKey);
//add to block chain
Chain.instance.addBlock(transaction, this.publicKey, signature);
}
}
//example usage
const peer1 = new Wallte();
const peer2 = new Wallte();
const peer3 = new Wallte();
// send money
peer1.sendMoney(50, peer2.publicKey);
peer2.sendMoney(100, peer1.publicKey);
peer3.sendMoney(500, peer3.publicKey);
console.log(Chain.instance);