To add a block in blockchain we should know the hash of the previous block and create the rest of the required content (= index, hash, data and timestamp). Block data will be provided by end user .
“Talk is cheap. Show me the code.” -Linus Torvalds
schema_name = "HELLOBLOCK";
namespace HelloBlock.DBARTIFACT;
@Schema: 'HELLOBLOCK'
context entity {
@Catalog.tableType: #COLUMN
Entity BlockChain{
key index : Integer;
data : LargeString;
commit_at : UTCTimestamp;
previous_hash : LargeString;
current_hash: LargeString;
};
PROCEDURE "HELLOBLOCK"."HelloBlock.Procedure::InsertBlock" (
IN block_index Integer,
IN block_data Nclob,
IN block_commit TIMESTAMP,
IN prevblock_hash Nclob,
IN Currblock_hash Nclob
)
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER AS
--DEFAULT SCHEMA <default_schema_name>
-- READS SQL DATA AS
BEGIN
/*************************************
Write your procedure logic
*************************************/
INSERT INTO "HELLOBLOCK"."HelloBlock.DBARTIFACT::entity.BlockChain"("index","data","commit_at","previous_hash","current_hash")
VALUES (:block_index,:block_data,:block_commit,:prevblock_hash,:Currblock_hash);
END
var acmd = $.request.parameters.get("action");
var BlockData = $.request.parameters.get("data");
var BlockIndex = $.request.parameters.get("index");
var PrevBlockHash = $.request.parameters.get("prevhash");
function DisplayBlockChain() {
try {
var conn = $.db.getConnection();
var output = {
results: []
};
var query = 'select * from "HELLOBLOCK"."HelloBlock.DBARTIFACT::entity.BlockChain"';
var myStatement = conn.prepareStatement(query);
var rs = myStatement.executeQuery();
while (rs.next()) {
var record = {};
record.Index = rs.getInteger(1);
record.Data = rs.getNClob(2);
record.CommitedTime = rs.getString(3);
record.PrevBlockHash = rs.getNClob(4);
record.CurrentHash = rs.getNClob(5);
output.results.push(record);
}
rs.close();
myStatement.close();
conn.close();
} catch (e) {
$.response.status = $.net.http.INTERNAL_SERVER_ERROR;
$.response.setBody(e.message);
return;
}
var body = JSON.stringify(output);
$.response.contentType = 'application/json';
$.response.setBody(body);
$.response.status = $.net.http.OK;
}
function CurrentTImeStamp() {
var date = new Date();
var utcout = date.getFullYear() + '-' +
('0' + (date.getMonth() + 1)).slice(-2) + '-' +
('0' + date.getDate()).slice(-2) + 'T' +
('0' + date.getHours()).slice(-2) + ':' +
('0' + date.getMinutes()).slice(-2) + ':' +
('0' + date.getSeconds()).slice(-2);
return (utcout);
}
function CalculateHash(s) {
var chrsz = 8;
var hexcase = 0;
function safe_add(x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
function S(X, n) {
return (X >>> n) | (X << (32 - n));
}
function R(X, n) {
return (X >>> n);
}
function Ch(x, y, z) {
return ((x & y) ^ ((~x) & z));
}
function Maj(x, y, z) {
return ((x & y) ^ (x & z) ^ (y & z));
}
function Sigma0256(x) {
return (S(x, 2) ^ S(x, 13) ^ S(x, 22));
}
function Sigma1256(x) {
return (S(x, 6) ^ S(x, 11) ^ S(x, 25));
}
function Gamma0256(x) {
return (S(x, 7) ^ S(x, 18) ^ R(x, 3));
}
function Gamma1256(x) {
return (S(x, 17) ^ S(x, 19) ^ R(x, 10));
}
function core_sha256(m, l) {
var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01,
0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F,
0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70,
0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A,
0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2);
var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
var W = new Array(64);
var a, b, c, d, e, f, g, h, i, j;
var T1, T2;
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >> 9) << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
a = HASH[0];
b = HASH[1];
c = HASH[2];
d = HASH[3];
e = HASH[4];
f = HASH[5];
g = HASH[6];
h = HASH[7];
for (var j = 0; j < 64; j++) {
if (j < 16) W[j] = m[j + i];
else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
T2 = safe_add(Sigma0256(a), Maj(a, b, c));
h = g;
g = f;
f = e;
e = safe_add(d, T1);
d = c;
c = b;
b = a;
a = safe_add(T1, T2);
}
HASH[0] = safe_add(a, HASH[0]);
HASH[1] = safe_add(b, HASH[1]);
HASH[2] = safe_add(c, HASH[2]);
HASH[3] = safe_add(d, HASH[3]);
HASH[4] = safe_add(e, HASH[4]);
HASH[5] = safe_add(f, HASH[5]);
HASH[6] = safe_add(g, HASH[6]);
HASH[7] = safe_add(h, HASH[7]);
}
return HASH;
}
function str2binb(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz) {
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i % 32);
}
return bin;
}
function Utf8Encode(string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
function binb2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +
hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF);
}
return str;
}
s = Utf8Encode(s);
return binb2hex(core_sha256(str2binb(s), s.length * chrsz));
}
function GetPreviousBlock() {
try {
var conn = $.db.getConnection();
var query = 'select COUNT(*) from "HELLOBLOCK"."HelloBlock.DBARTIFACT::entity.BlockChain"';
var myStatement = conn.prepareStatement(query);
var rs = myStatement.executeQuery();
if (rs.next()) {
var lv_index = rs.getString(1);
var index_int = parseInt(lv_index);
if (index_int < 1) {
var block = [];
block.push('1');
block.push('0000000X0');
} else {
var connhash = $.db.getConnection();
var query = 'select "current_hash" from \"HELLOBLOCK\".\"HelloBlock.DBARTIFACT::entity.BlockChain\" where "index" =?';
var pstmt = connhash.prepareStatement(query);
pstmt.setInteger(1, index_int);
var rec = pstmt.executeQuery();
if (rec.next()) {
var lv_prevhash = rec.getNClob(1);
var block = [];
block.push(lv_index);
block.push(lv_prevhash);
}
}
return (block);
} else {
$.response.status = $.net.http.INTERNAL_SERVER_ERROR;
$.response.setBody('Error in fetching Block Count');
}
} catch (e) {
var an = e.message;
}
}
function AddBlock(pdata, bindex, pbhash) {
var data;
var passed_index = parseInt(bindex);
var passed_pbhash = pbhash.toString();
var prevblock = GetPreviousBlock();
var prev_index = prevblock[0];
prev_index = parseInt(prev_index);
var index = prev_index + 1;
if (prev_index > 1){
data = pdata;
}else {
data = 'Genesis Block';
}
var prevHash = prevblock[1];
var timest = CurrentTImeStamp();
var actual_hash = CalculateHash(index.toString() + data.toString() + timest.toString() + prevHash.toString());
actual_hash = actual_hash.toUpperCase();
//Calling Procedure to add new Block
if (index !== passed_index) {
$.response.status = $.net.http.OK;
$.response.setBody("index is not valid");
} else if (pbhash !== prevHash) {
$.response.status = $.net.http.OK;
$.response.setBody("Previous hash is not valid");
} else {
var conn = $.db.getConnection();
var query = 'call \"HELLOBLOCK"."HelloBlock.Procedure::InsertBlock\"(?,?,?,?,?)';
var myStatement = conn.prepareCall(query);
myStatement.setInteger(1, index);
myStatement.setNClob(2, data);
myStatement.setString(3, timest);
myStatement.setNClob(4, prevHash);
myStatement.setNClob(5, actual_hash);
var rs = myStatement.execute();
conn.commit();
//Calling Procedure to add new Block
// Displaying Whole Block Chain
DisplayBlockChain();
// Displaying Whole Block Chain
}
}
function ValidCall() {
if (typeof BlockData === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter data");
} else if (typeof BlockIndex === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter index");
} else if (typeof PrevBlockHash === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter prevhash");
} else {
AddBlock(BlockData, BlockIndex, PrevBlockHash);
}
}
switch (acmd) {
case "addblock":
ValidCall()
break;
case "chaindisp":
DisplayBlockChain();
break;
default:
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter: " + acmd);
}
function ValidCall() {
if (typeof BlockData === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter data");
} else if (typeof BlockIndex === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter index");
} else if (typeof PrevBlockHash === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter prevhash");
} else {
AddBlock(BlockData, BlockIndex, PrevBlockHash);
}
}
function CurrentTImeStamp() {
var date = new Date();
var utcout = date.getFullYear() + '-' +
('0' + (date.getMonth() + 1)).slice(-2) + '-' +
('0' + date.getDate()).slice(-2) + 'T' +
('0' + date.getHours()).slice(-2) + ':' +
('0' + date.getMinutes()).slice(-2) + ':' +
('0' + date.getSeconds()).slice(-2);
return (utcout);
}
function DisplayBlockChain() {
try {
var conn = $.db.getConnection();
var output = {
results: []
};
var query = 'select * from "HELLOBLOCK"."HelloBlock.DBARTIFACT::entity.BlockChain"';
var myStatement = conn.prepareStatement(query);
var rs = myStatement.executeQuery();
while (rs.next()) {
var record = {};
record.Index = rs.getInteger(1);
record.Data = rs.getNClob(2);
record.CommitedTime = rs.getString(3);
record.PrevBlockHash = rs.getNClob(4);
record.CurrentHash = rs.getNClob(5);
output.results.push(record);
}
rs.close();
myStatement.close();
conn.close();
} catch (e) {
$.response.status = $.net.http.INTERNAL_SERVER_ERROR;
$.response.setBody(e.message);
return;
}
var body = JSON.stringify(output);
$.response.contentType = 'application/json';
$.response.setBody(body);
$.response.status = $.net.http.OK;
}
function GetPreviousBlock() {
try {
var conn = $.db.getConnection();
var query = 'select COUNT(*) from "HELLOBLOCK"."HelloBlock.DBARTIFACT::entity.BlockChain"';
var myStatement = conn.prepareStatement(query);
var rs = myStatement.executeQuery();
if (rs.next()) {
var lv_index = rs.getString(1);
var index_int = parseInt(lv_index);
if (index_int < 1) {
var block = [];
block.push('1');
block.push('0000000X0');
} else {
var connhash = $.db.getConnection();
var query = 'select "current_hash" from \"HELLOBLOCK\".\"HelloBlock.DBARTIFACT::entity.BlockChain\" where "index" =?';
var pstmt = connhash.prepareStatement(query);
pstmt.setInteger(1, index_int);
var rec = pstmt.executeQuery();
if (rec.next()) {
var lv_prevhash = rec.getNClob(1);
var block = [];
block.push(lv_index);
block.push(lv_prevhash);
}
}
return (block);
} else {
$.response.status = $.net.http.INTERNAL_SERVER_ERROR;
$.response.setBody('Error in fetching Block Count');
}
} catch (e) {
var an = e.message;
}
}
function AddBlock(pdata, bindex, pbhash) {
var data;
var passed_index = parseInt(bindex);
var passed_pbhash = pbhash.toString();
var prevblock = GetPreviousBlock();
var prev_index = prevblock[0];
prev_index = parseInt(prev_index);
var index = prev_index + 1;
if (prev_index > 1){
data = pdata;
}else {
data = 'Genesis Block';
}
var prevHash = prevblock[1];
var timest = CurrentTImeStamp();
var actual_hash = CalculateHash(index.toString() + data.toString() + timest.toString() + prevHash.toString());
actual_hash = actual_hash.toUpperCase();
//Calling Procedure to add new Block
if (index !== passed_index) {
$.response.status = $.net.http.OK;
$.response.setBody("index is not valid");
} else if (pbhash !== prevHash) {
$.response.status = $.net.http.OK;
$.response.setBody("Previous hash is not valid");
} else {
var conn = $.db.getConnection();
var query = 'call \"HELLOBLOCK"."HelloBlock.Procedure::InsertBlock\"(?,?,?,?,?)';
var myStatement = conn.prepareCall(query);
myStatement.setInteger(1, index);
myStatement.setNClob(2, data);
myStatement.setString(3, timest);
myStatement.setNClob(4, prevHash);
myStatement.setNClob(5, actual_hash);
var rs = myStatement.execute();
conn.commit();
//Calling Procedure to add new Block
// Displaying Whole Block Chain
DisplayBlockChain();
// Displaying Whole Block Chain
}
}
nonce
value. This is a number that gets incremented until a good hash is found. And because you cannot predict the output of a hash function, you simply have to try a lot of combinations before you get a hash that satisfies the difficulty. Looking for a valid hash (to create a new block) is also called “mining” in the cryptoworld. @Catalog.tableType: #COLUMN
Entity BlockChainPOW{
key index : Integer;
data : LargeString;
commit_at : UTCTimestamp;
previous_hash : LargeString;
current_hash: LargeString;
nonce : Integer;
};
PROCEDURE "HELLOBLOCK"."HelloBlock.Procedure::InsertBlockPOW" (
IN block_index Integer,
IN block_data Nclob,
IN block_commit TIMESTAMP,
IN prevblock_hash Nclob,
IN Currblock_hash Nclob,
IN BlockNonce Integer
)
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER AS
--DEFAULT SCHEMA <default_schema_name>
-- READS SQL DATA AS
BEGIN
/*************************************
Write your procedure logic
*************************************/
INSERT INTO "HELLOBLOCK"."HelloBlock.DBARTIFACT::entity.BlockChainPOW"("index","data","commit_at","previous_hash","current_hash","nonce")
VALUES (:block_index,:block_data,:block_commit,:prevblock_hash,:Currblock_hash,:BlockNonce);
END
var difficulty = 2 + (index / 10);
difficulty = parseInt(difficulty);
function MineBlock(pdifficulty, pindex, pdata, ptimest, prevhash, phash) {
var actdiff = parseInt(pdifficulty);
var actind = parseInt(pindex);
var genhash = phash.toString();
var actnonce = 0;
while (genhash.substring(0, actdiff) !== Array(actdiff + 1).join("0")) {
actnonce++;
genhash = CalculateHash(pindex.toString() + JSON.stringify(pdata.toString() + actnonce.toString()).toString() + ptimest.toString() +
prevhash.toString());
}
var mblock = [];
mblock.push(actnonce);
mblock.push(genhash);
return mblock;
}
function ValidCall() {
//jshint maxdepth:5;
/*eslint max-depth: [22, 22]*/
if (typeof BlockData === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter data");
} else if (typeof BlockIndex === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter index");
} else if (typeof PrevBlockHash === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter prevhash");
} else if (typeof MiningOP === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter mine , accepted value auto or manual");
} else if (typeof MiningOP !== 'undefined') {
if (MiningOP !== 'manual' && MiningOP !== 'auto') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter mine , accepted value auto or manual");
} else if (MiningOP === 'manual') {
if (typeof Nonce === 'undefined'){
$.response.status = $.net.http.OK;
$.response.setBody("In manual mining you have to pass parameter nonce,Better you go with auto because generating nonce is not everyone's cup of tea ");
} else {
AddBlock(BlockData, BlockIndex, PrevBlockHash, Nonce);
}
} else {
AddBlock(BlockData, BlockIndex, PrevBlockHash, 'auto');
}
}
}
function AddBlock(data, bindex, pbhash, psnonce) {
// var anonce = parseInt(pnonce);
var passed_index = parseInt(bindex);
var passed_pbhash = pbhash.toString();
var prevblock = GetPreviousBlock();
var prev_index = prevblock[0];
prev_index = parseInt(prev_index);
var index = prev_index + 1;
var difficulty = 2 + (index / 10);
difficulty = parseInt(difficulty);
var data = data;
var prevHash = prevblock[1];
var timest = CurrentTImeStamp();
var intnonce = 0;
function bmvalidation() {
//Calling Procedure to add new Block
if (index !== passed_index) {
$.response.status = $.net.http.OK;
$.response.setBody("index is not valid");
} else if (pbhash !== prevHash) {
$.response.status = $.net.http.OK;
$.response.setBody("Previous hash is not valid");
} else {
if (psnonce === 'auto') {
var initial_hash = CalculateHash(index.toString() + JSON.stringify(data.toString() + intnonce.toString()).toString() + timest.toString() +
prevHash.toString());
var minedblock = MineBlock(difficulty, index, data, timest, prevHash, initial_hash);
var minenonce = minedblock[0];
minenonce = parseInt(minenonce);
var minehash = minedblock[1];
minehash = minehash.toUpperCase();
var conn = $.db.getConnection();
var query = 'call \"HELLOBLOCK"."HelloBlock.Procedure::InsertBlockPOW\"(?,?,?,?,?,?)';
var myStatement = conn.prepareCall(query);
myStatement.setInteger(1, index);
myStatement.setNClob(2, data);
myStatement.setString(3, timest);
myStatement.setNClob(4, prevHash);
myStatement.setNClob(5, minehash);
myStatement.setInteger(6, minenonce);
var rs = myStatement.execute();
conn.commit();
//Calling Procedure to add new Block
// Displaying Whole Block Chain
DisplayBlockChain();
// Displaying Whole Block Chain
} else {
var initial_hash = CalculateHash(index.toString() + JSON.stringify(data.toString() + intnonce.toString()).toString() + timest.toString() +
prevHash.toString());
var minedblock = MineBlock(difficulty, index, data, timest, prevHash, initial_hash);
var minenonce = minedblock[0];
minenonce = parseInt(minenonce);
var minernonce = parseInt(psnonce);
var minehash = minedblock[1];
if (minenonce !== minernonce) {
$.response.status = $.net.http.OK;
$.response.setBody("Try with different nonce, your computed nonce is not enough to add block in Blockchain");
} else {
var conn = $.db.getConnection();
var query = 'call \"HELLOBLOCK"."HelloBlock.Procedure::InsertBlockPOW\"(?,?,?,?,?,?)';
var myStatement = conn.prepareCall(query);
myStatement.setInteger(1, index);
myStatement.setNClob(2, data);
myStatement.setString(3, timest);
myStatement.setNClob(4, prevHash);
myStatement.setNClob(5, minehash);
myStatement.setNClob(6, minenonce);
var rs = myStatement.execute();
conn.commit();
//Calling Procedure to add new Block
// Displaying Whole Block Chain
DisplayBlockChain();
// Displaying Whole Block Chain
}
}
}
}
bmvalidation();
}
var acmd = $.request.parameters.get("action");
var BlockData = $.request.parameters.get("data");
var BlockIndex = $.request.parameters.get("index");
var PrevBlockHash = $.request.parameters.get("prevhash");
var Nonce = $.request.parameters.get("nonce");
var MiningOP = $.request.parameters.get("mine");
function DisplayBlockChain() {
try {
var conn = $.db.getConnection();
var output = {
results: []
};
var query = 'select * from "HELLOBLOCK"."HelloBlock.DBARTIFACT::entity.BlockChainPOW"';
var myStatement = conn.prepareStatement(query);
var rs = myStatement.executeQuery();
while (rs.next()) {
var record = {};
record.Index = rs.getInteger(1);
record.Data = rs.getNClob(2);
record.CommitedTime = rs.getString(3);
record.PrevBlockHash = rs.getNClob(4);
record.CurrentHash = rs.getNClob(5);
record.Nonce = rs.getInteger(6);
output.results.push(record);
}
rs.close();
myStatement.close();
conn.close();
} catch (e) {
$.response.status = $.net.http.INTERNAL_SERVER_ERROR;
$.response.setBody(e.message);
return;
}
var body = JSON.stringify(output);
$.response.contentType = 'application/json';
$.response.setBody(body);
$.response.status = $.net.http.OK;
}
function CurrentTImeStamp() {
var date = new Date();
var utcout = date.getFullYear() + '-' +
('0' + (date.getMonth() + 1)).slice(-2) + '-' +
('0' + date.getDate()).slice(-2) + 'T' +
('0' + date.getHours()).slice(-2) + ':' +
('0' + date.getMinutes()).slice(-2) + ':' +
('0' + date.getSeconds()).slice(-2);
return (utcout);
}
function CalculateHash(s) {
var chrsz = 8;
var hexcase = 0;
function safe_add(x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
function S(X, n) {
return (X >>> n) | (X << (32 - n));
}
function R(X, n) {
return (X >>> n);
}
function Ch(x, y, z) {
return ((x & y) ^ ((~x) & z));
}
function Maj(x, y, z) {
return ((x & y) ^ (x & z) ^ (y & z));
}
function Sigma0256(x) {
return (S(x, 2) ^ S(x, 13) ^ S(x, 22));
}
function Sigma1256(x) {
return (S(x, 6) ^ S(x, 11) ^ S(x, 25));
}
function Gamma0256(x) {
return (S(x, 7) ^ S(x, 18) ^ R(x, 3));
}
function Gamma1256(x) {
return (S(x, 17) ^ S(x, 19) ^ R(x, 10));
}
function core_sha256(m, l) {
var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01,
0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F,
0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70,
0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A,
0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2);
var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
var W = new Array(64);
var a, b, c, d, e, f, g, h, i, j;
var T1, T2;
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >> 9) << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
a = HASH[0];
b = HASH[1];
c = HASH[2];
d = HASH[3];
e = HASH[4];
f = HASH[5];
g = HASH[6];
h = HASH[7];
for (var j = 0; j < 64; j++) {
if (j < 16) W[j] = m[j + i];
else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
T2 = safe_add(Sigma0256(a), Maj(a, b, c));
h = g;
g = f;
f = e;
e = safe_add(d, T1);
d = c;
c = b;
b = a;
a = safe_add(T1, T2);
}
HASH[0] = safe_add(a, HASH[0]);
HASH[1] = safe_add(b, HASH[1]);
HASH[2] = safe_add(c, HASH[2]);
HASH[3] = safe_add(d, HASH[3]);
HASH[4] = safe_add(e, HASH[4]);
HASH[5] = safe_add(f, HASH[5]);
HASH[6] = safe_add(g, HASH[6]);
HASH[7] = safe_add(h, HASH[7]);
}
return HASH;
}
function str2binb(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz) {
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i % 32);
}
return bin;
}
function Utf8Encode(string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
function binb2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +
hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF);
}
return str;
}
s = Utf8Encode(s);
return binb2hex(core_sha256(str2binb(s), s.length * chrsz));
}
function GetPreviousBlock() {
try {
var conn = $.db.getConnection();
var query = 'select COUNT(*) from "HELLOBLOCK"."HelloBlock.DBARTIFACT::entity.BlockChainPOW"';
var myStatement = conn.prepareStatement(query);
var rs = myStatement.executeQuery();
if (rs.next()) {
var lv_index = rs.getString(1);
var index_int = parseInt(lv_index);
if (index_int < 1) {
var block = [];
block.push('0');
block.push('0000000X0');
} else {
var connhash = $.db.getConnection();
var query = 'select "current_hash" from \"HELLOBLOCK\".\"HelloBlock.DBARTIFACT::entity.BlockChainPOW\" where "index" =?';
var pstmt = connhash.prepareStatement(query);
pstmt.setInteger(1, index_int);
var rec = pstmt.executeQuery();
if (rec.next()) {
var lv_prevhash = rec.getNClob(1);
var block = [];
block.push(lv_index);
block.push(lv_prevhash);
}
}
return (block);
} else {
$.response.status = $.net.http.INTERNAL_SERVER_ERROR;
$.response.setBody('Error in fetching Block Count');
}
} catch (e) {
var an = e.message;
}
}
function MineBlock(pdifficulty, pindex, pdata, ptimest, prevhash, phash) {
var actdiff = parseInt(pdifficulty);
var actind = parseInt(pindex);
var genhash = phash.toString();
var actnonce = 0;
while (genhash.substring(0, actdiff) !== Array(actdiff + 1).join("0")) {
actnonce++;
genhash = CalculateHash(pindex.toString() + JSON.stringify(pdata.toString() + actnonce.toString()).toString() + ptimest.toString() +
prevhash.toString());
}
var mblock = [];
mblock.push(actnonce);
mblock.push(genhash);
return mblock;
}
function AddBlock(data, bindex, pbhash, psnonce) {
// var anonce = parseInt(pnonce);
var passed_index = parseInt(bindex);
var passed_pbhash = pbhash.toString();
var prevblock = GetPreviousBlock();
var prev_index = prevblock[0];
prev_index = parseInt(prev_index);
var index = prev_index + 1;
var difficulty = 2 + (index / 10);
difficulty = parseInt(difficulty);
var data = data;
var prevHash = prevblock[1];
var timest = CurrentTImeStamp();
var intnonce = 0;
function bmvalidation() {
//Calling Procedure to add new Block
if (index !== passed_index) {
$.response.status = $.net.http.OK;
$.response.setBody("index is not valid");
} else if (pbhash !== prevHash) {
$.response.status = $.net.http.OK;
$.response.setBody("Previous hash is not valid");
} else {
if (psnonce === 'auto') {
var initial_hash = CalculateHash(index.toString() + JSON.stringify(data.toString() + intnonce.toString()).toString() + timest.toString() +
prevHash.toString());
var minedblock = MineBlock(difficulty, index, data, timest, prevHash, initial_hash);
var minenonce = minedblock[0];
minenonce = parseInt(minenonce);
var minehash = minedblock[1];
minehash = minehash.toUpperCase();
var conn = $.db.getConnection();
var query = 'call \"HELLOBLOCK"."HelloBlock.Procedure::InsertBlockPOW\"(?,?,?,?,?,?)';
var myStatement = conn.prepareCall(query);
myStatement.setInteger(1, index);
myStatement.setNClob(2, data);
myStatement.setString(3, timest);
myStatement.setNClob(4, prevHash);
myStatement.setNClob(5, minehash);
myStatement.setInteger(6, minenonce);
var rs = myStatement.execute();
conn.commit();
//Calling Procedure to add new Block
// Displaying Whole Block Chain
DisplayBlockChain();
// Displaying Whole Block Chain
} else {
var initial_hash = CalculateHash(index.toString() + JSON.stringify(data.toString() + intnonce.toString()).toString() + timest.toString() +
prevHash.toString());
var minedblock = MineBlock(difficulty, index, data, timest, prevHash, initial_hash);
var minenonce = minedblock[0];
minenonce = parseInt(minenonce);
var minernonce = parseInt(psnonce);
var minehash = minedblock[1];
if (minenonce !== minernonce) {
$.response.status = $.net.http.OK;
$.response.setBody("Try with different nonce, your computed nonce is not enough to add block in Blockchain");
} else {
var conn = $.db.getConnection();
var query = 'call \"HELLOBLOCK"."HelloBlock.Procedure::InsertBlockPOW\"(?,?,?,?,?,?)';
var myStatement = conn.prepareCall(query);
myStatement.setInteger(1, index);
myStatement.setNClob(2, data);
myStatement.setString(3, timest);
myStatement.setNClob(4, prevHash);
myStatement.setNClob(5, minehash);
myStatement.setNClob(6, minenonce);
var rs = myStatement.execute();
conn.commit();
//Calling Procedure to add new Block
// Displaying Whole Block Chain
DisplayBlockChain();
// Displaying Whole Block Chain
}
}
}
}
bmvalidation();
}
function ValidCall() {
//jshint maxdepth:5;
/*eslint max-depth: [22, 22]*/
if (typeof BlockData === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter data");
} else if (typeof BlockIndex === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter index");
} else if (typeof PrevBlockHash === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter prevhash");
} else if (typeof MiningOP === 'undefined') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter mine , accepted value auto or manual");
} else if (typeof MiningOP !== 'undefined') {
if (MiningOP !== 'manual' && MiningOP !== 'auto') {
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter mine , accepted value auto or manual");
} else if (MiningOP === 'manual') {
if (typeof Nonce === 'undefined'){
$.response.status = $.net.http.OK;
$.response.setBody("In manual mining you have to pass parameter nonce,Better you go with auto because generating nonce is not everyone's cup of tea ");
} else {
AddBlock(BlockData, BlockIndex, PrevBlockHash, Nonce);
}
} else {
AddBlock(BlockData, BlockIndex, PrevBlockHash, 'auto');
}
}
}
switch (acmd) {
case "addblock":
// AddBlock(BlockData, BlockIndex, PrevBlockHash, 'auto');
ValidCall();
break;
case "chaindisp":
DisplayBlockChain();
break;
default:
$.response.status = $.net.http.OK;
$.response.setBody("Pass Parameter: " + acmd);
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
8 | |
8 | |
7 | |
7 | |
5 | |
4 | |
4 | |
4 | |
3 | |
3 |