166 lines
4.2 KiB
JavaScript
166 lines
4.2 KiB
JavaScript
|
var express = require('express');
|
||
|
var router = express.Router();
|
||
|
var KyotoTycoon = require('kyoto-tycoon').KyotoTycoon;
|
||
|
|
||
|
var CryptoJS = require('crypto-js');
|
||
|
|
||
|
var kt = new KyotoTycoon();
|
||
|
|
||
|
function randomString(length) {
|
||
|
chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||
|
var result = '';
|
||
|
for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
function mineBlock(block, requirement) {
|
||
|
rand = '';
|
||
|
i = 0;
|
||
|
|
||
|
while(CryptoJS.SHA512(JSON.stringify(block.content)).toString().substring(0, requirement.length) != requirement) {
|
||
|
rand = randomString(32);
|
||
|
block.content.rand = rand;
|
||
|
i++;
|
||
|
console.log(i + ': ' + rand + ' : ' + CryptoJS.SHA512(JSON.stringify(block.content)).toString());
|
||
|
}
|
||
|
block.hash = CryptoJS.SHA512(JSON.stringify(block.content)).toString();
|
||
|
}
|
||
|
|
||
|
function checkBlock(id, badId, goodId) {
|
||
|
kt.get(id, function(err, data) {
|
||
|
if(err) {
|
||
|
console.log('Error getting block id ' + id);
|
||
|
return -1;
|
||
|
} else {
|
||
|
kt.get(id - 1, function(err, prevData){
|
||
|
if(err) {
|
||
|
console.log('Error getting block id ' + id - 1);
|
||
|
}
|
||
|
block = JSON.parse(data);
|
||
|
if((CryptoJS.SHA512(JSON.stringify(block.content)).toString() === block.hash) && (block.content.prevhash === JSON.parse(prevData).hash)) {
|
||
|
console.log('Block ' + block.content.id + ' is OK');
|
||
|
if(goodId) {
|
||
|
goodId(block.content.id);
|
||
|
}
|
||
|
} else {
|
||
|
console.log('Block ' + block.content.id + ' is bad');
|
||
|
if(badId) {
|
||
|
badId(block.content.id);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function checkChain() {
|
||
|
j = 0;
|
||
|
kt.status(':', async function (err, data) {
|
||
|
if(err) {
|
||
|
console.log('Error getting chain data.');
|
||
|
return -1;
|
||
|
} else {
|
||
|
for(i = 1; i < data.count; i++) {
|
||
|
await checkBlock(i, function(id) {
|
||
|
console.log('Handle badId: ' + id);
|
||
|
deleteChain(id, data.count - 1);
|
||
|
}, function(id) {
|
||
|
console.log('Handle goodId: ' + id)
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function deleteChain(firstId, lastId) {
|
||
|
for(i = firstId; i <= lastId; i++) {
|
||
|
console.log('Deleteing block id ' + i);
|
||
|
kt.remove(i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function getLastTransactions(count, next) {
|
||
|
result = [];
|
||
|
j = 0;
|
||
|
kt.status(':', async function(err, data) {
|
||
|
if(err) {
|
||
|
console.log('Error getting chain data.');
|
||
|
return -1;
|
||
|
}
|
||
|
for(i = data.count - count; i < data.count; i++) {
|
||
|
result.push(new Promise((resolve, reject) => {
|
||
|
kt.get(i, async function(err, block) {
|
||
|
if(err) reject(err);
|
||
|
resolve(JSON.parse(block));
|
||
|
});
|
||
|
}));
|
||
|
}
|
||
|
if(next) {
|
||
|
next(await Promise.all(result));
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/* GET home page. */
|
||
|
router.get('/', function(req, res, next) {
|
||
|
getLastTransactions(15, async function(data) {
|
||
|
await console.log(JSON.stringify(data));
|
||
|
breadcrumb = [{title:'home', url:'/', stat:'active'}]
|
||
|
await res.render('index', { title: 'mCoin', data: data, breadcrumb: breadcrumb });
|
||
|
});
|
||
|
});
|
||
|
|
||
|
router.get('/new', function(req, res, next) {
|
||
|
block = {
|
||
|
content: {
|
||
|
message: {
|
||
|
from: 'Simona',
|
||
|
to: 'Matjaz',
|
||
|
amount: '200',
|
||
|
timestamp: '1234',
|
||
|
},
|
||
|
id: 1,
|
||
|
previd: 0,
|
||
|
prevhash: 'abc',
|
||
|
rand: '',
|
||
|
timestamp: '',
|
||
|
unixtime: '',
|
||
|
},
|
||
|
hash: '',
|
||
|
difficulty: '',
|
||
|
version: '0.01',
|
||
|
};
|
||
|
difficulty = '000';
|
||
|
|
||
|
kt.status(':', function(err, data) {
|
||
|
if(err) {
|
||
|
console.log(err);
|
||
|
}
|
||
|
kt.get(data.count - 1, function(err, prevData) {
|
||
|
if(err) {
|
||
|
console.log(err);
|
||
|
}
|
||
|
const utcDate = new Date();
|
||
|
block.content.timestamp = utcDate.toUTCString();
|
||
|
block.content.unixtime = Math.floor(new Date().getTime() / 1000);
|
||
|
block.content.prevhash = JSON.parse(prevData).hash;
|
||
|
block.content.id = data.count;
|
||
|
block.content.previd = data.count - 1;
|
||
|
block.difficulty = difficulty;
|
||
|
mineBlock(block, difficulty);
|
||
|
console.log(JSON.stringify(block));
|
||
|
kt.set(block.content.id.toString(), JSON.stringify(block), function() {
|
||
|
console.log('Block Written');
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
router.get('/check', function(req, res, next) {
|
||
|
badBlock = 0;
|
||
|
console.log('Checking the chain');
|
||
|
checkChain();
|
||
|
});
|
||
|
|
||
|
module.exports = router;
|