blockchain/routes/index.js

166 lines
4.2 KiB
JavaScript
Raw Normal View History

2022-01-26 19:20:35 +00:00
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;