365 lines
9.7 KiB
JavaScript
365 lines
9.7 KiB
JavaScript
/*
|
|
* @project: TERA
|
|
* @version: Development (beta)
|
|
* @license: MIT (not for evil)
|
|
* @copyright: Yuriy Ivanov 2017-2019 [progr76@gmail.com]
|
|
* Web: https://terafoundation.org
|
|
* Twitter: https://twitter.com/terafoundation
|
|
* Telegram: https://web.telegram.org/#/im?p=@terafoundation
|
|
*/
|
|
|
|
var MAX_SUPER_VALUE_POW = (1 << 30) * 2;
|
|
window.TYPE_TRANSACTION_CREATE = 100;
|
|
|
|
function GetHashWithValues(hash0,value1,value2,bNotCopy)
|
|
{
|
|
var hash;
|
|
if(bNotCopy)
|
|
hash = hash0;
|
|
else
|
|
hash = hash0.slice();
|
|
hash[0] = value1 & 0xFF;
|
|
hash[1] = (value1 >>> 8) & 0xFF;
|
|
hash[2] = (value1 >>> 16) & 0xFF;
|
|
hash[3] = (value1 >>> 24) & 0xFF;
|
|
hash[4] = value2 & 0xFF;
|
|
hash[5] = (value2 >>> 8) & 0xFF;
|
|
hash[6] = (value2 >>> 16) & 0xFF;
|
|
hash[7] = (value2 >>> 24) & 0xFF;
|
|
var arrhash = shaarr(hash);
|
|
return arrhash;
|
|
};
|
|
|
|
function GetPowPower(arrhash)
|
|
{
|
|
var SumBit = 0;
|
|
for(var i = 0; i < arrhash.length; i++)
|
|
{
|
|
var CurSum = Math.clz32(arrhash[i]) - 24;
|
|
SumBit += CurSum;
|
|
if(CurSum !== 8)
|
|
break;
|
|
}
|
|
return SumBit;
|
|
};
|
|
|
|
function GetPowValue(arrhash)
|
|
{
|
|
var value = (arrhash[0] << 23) * 2 + (arrhash[1] << 16) + (arrhash[2] << 8) + arrhash[3];
|
|
value = value * 256 + arrhash[4];
|
|
value = value * 256 + arrhash[5];
|
|
return value;
|
|
};
|
|
|
|
function CreateNoncePOWExtern(arr0,BlockNum,count,startnone)
|
|
{
|
|
var arr = [];
|
|
for(var i = 0; i < arr0.length; i++)
|
|
arr[i] = arr0[i];
|
|
if(!startnone)
|
|
startnone = 0;
|
|
var maxnonce = 0;
|
|
var supervalue = MAX_SUPER_VALUE_POW;
|
|
for(var nonce = startnone; nonce <= startnone + count; nonce++)
|
|
{
|
|
var arrhash = GetHashWithValues(arr, nonce, BlockNum, true);
|
|
var value = GetPowValue(arrhash);
|
|
if(value < supervalue)
|
|
{
|
|
maxnonce = nonce;
|
|
supervalue = value;
|
|
}
|
|
}
|
|
return maxnonce;
|
|
};
|
|
window.TR_TICKET_HASH_LENGTH = 10;
|
|
|
|
function CreateHashBody(body,Num,Nonce)
|
|
{
|
|
var length = body.length - 12;
|
|
body[length + 0] = Num & 0xFF;
|
|
body[length + 1] = (Num >>> 8) & 0xFF;
|
|
body[length + 2] = (Num >>> 16) & 0xFF;
|
|
body[length + 3] = (Num >>> 24) & 0xFF;
|
|
body[length + 4] = 0;
|
|
body[length + 5] = 0;
|
|
length = body.length - 6;
|
|
body[length + 0] = Nonce & 0xFF;
|
|
body[length + 1] = (Nonce >>> 8) & 0xFF;
|
|
body[length + 2] = (Nonce >>> 16) & 0xFF;
|
|
body[length + 3] = (Nonce >>> 24) & 0xFF;
|
|
body[length + 4] = 0;
|
|
body[length + 5] = 0;
|
|
var HASH = sha3(body);
|
|
var FullHashTicket = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
for(var i = 0; i < TR_TICKET_HASH_LENGTH; i++)
|
|
FullHashTicket[i] = HASH[i];
|
|
WriteUintToArrOnPos(FullHashTicket, Num, TR_TICKET_HASH_LENGTH);
|
|
return sha3(FullHashTicket);
|
|
};
|
|
window.DELTA_POWER_POW_TR = 0;
|
|
window.DELTA_FOR_TIME_TX = 0;
|
|
window.MIN_POWER_POW_TR = 0;
|
|
window.MIN_POWER_POW_ACC_CREATE = 0;
|
|
window.CONSENSUS_PERIOD_TIME = 1000;
|
|
window.FIRST_TIME_BLOCK = 1530446400000;
|
|
window.SetBlockChainConstant = function (Data)
|
|
{
|
|
var DeltaServerClient = new Date() - Data.CurTime;
|
|
if(!Data.DELTA_CURRENT_TIME)
|
|
Data.DELTA_CURRENT_TIME = 0;
|
|
window.DELTA_CURRENT_TIME2 = Data.DELTA_CURRENT_TIME - DeltaServerClient;
|
|
window.MIN_POWER_POW_TR = DELTA_POWER_POW_TR + Data.MIN_POWER_POW_TR;
|
|
window.MIN_POWER_POW_ACC_CREATE = Data.MIN_POWER_POW_ACC_CREATE + 3;
|
|
window.FIRST_TIME_BLOCK = Data.FIRST_TIME_BLOCK;
|
|
window.CONSENSUS_PERIOD_TIME = Data.CONSENSUS_PERIOD_TIME;
|
|
window.GetCurrentBlockNumByTime = function ()
|
|
{
|
|
var CurrentTime = Date.now() + DELTA_CURRENT_TIME2;
|
|
var CurTimeNum = CurrentTime - FIRST_TIME_BLOCK;
|
|
var StartBlockNum = Math.floor((CurTimeNum + CONSENSUS_PERIOD_TIME) / CONSENSUS_PERIOD_TIME);
|
|
return StartBlockNum;
|
|
};
|
|
window.NWMODE = Data.NWMODE;
|
|
};
|
|
window.GetCurrentBlockNumByTime = function ()
|
|
{
|
|
return 0;
|
|
};
|
|
|
|
function GetBlockNumTr(arr)
|
|
{
|
|
var BlockNum = window.DELTA_FOR_TIME_TX + GetCurrentBlockNumByTime();
|
|
if(arr[0] === TYPE_TRANSACTION_CREATE)
|
|
{
|
|
var BlockNum2 = Math.floor(BlockNum / 10) * 10;
|
|
if(BlockNum2 < BlockNum)
|
|
BlockNum2 = BlockNum2 + 10;
|
|
BlockNum = BlockNum2;
|
|
}
|
|
return BlockNum;
|
|
};
|
|
var LastCreatePOWTrType = 0;
|
|
var LastCreatePOWBlockNum = 0;
|
|
var LastCreatePOWHash = [255, 255, 255, 255];
|
|
|
|
function CreateHashBodyPOWInnerMinPower(arr,MinPow)
|
|
{
|
|
var TrType = arr[0];
|
|
var BlockNum = GetBlockNumTr(arr);
|
|
if(MinPow === undefined)
|
|
{
|
|
MinPow = MIN_POWER_POW_TR + Math.log2(arr.length / 128);
|
|
}
|
|
var nonce = 0;
|
|
while(1)
|
|
{
|
|
var arrhash = CreateHashBody(arr, BlockNum, nonce);
|
|
var power = GetPowPower(arrhash);
|
|
if(power >= MinPow)
|
|
{
|
|
if(LastCreatePOWBlockNum === BlockNum && LastCreatePOWTrType === TrType && CompareArr(LastCreatePOWHash, arrhash) > 0)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
LastCreatePOWBlockNum = BlockNum;
|
|
LastCreatePOWTrType = TrType;
|
|
LastCreatePOWHash = arrhash;
|
|
return nonce;
|
|
}
|
|
}
|
|
nonce++;
|
|
if(nonce % 2000 === 0)
|
|
{
|
|
BlockNum = GetBlockNumTr(arr);
|
|
}
|
|
}
|
|
};
|
|
|
|
function CalcHashFromArray(ArrHashes,bOriginalSeq)
|
|
{
|
|
if(bOriginalSeq === undefined)
|
|
ArrHashes.sort(CompareArr);
|
|
var Buf = [];
|
|
for(var i = 0; i < ArrHashes.length; i++)
|
|
{
|
|
var Value = ArrHashes[i];
|
|
for(var n = 0; n < Value.length; n++)
|
|
Buf.push(Value[n]);
|
|
}
|
|
if(Buf.length === 0)
|
|
return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
else
|
|
if(Buf.length === 32)
|
|
return Buf;
|
|
var Hash = shaarr(Buf);
|
|
return Hash;
|
|
};
|
|
|
|
function GetArrFromValue(Num)
|
|
{
|
|
var arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
arr[0] = Num & 0xFF;
|
|
arr[1] = (Num >>> 8) & 0xFF;
|
|
arr[2] = (Num >>> 16) & 0xFF;
|
|
arr[3] = (Num >>> 24) & 0xFF;
|
|
var NumH = Math.floor(Num / 4294967296);
|
|
arr[4] = NumH & 0xFF;
|
|
arr[5] = (NumH >>> 8) & 0xFF;
|
|
return arr;
|
|
};
|
|
|
|
function LoadLib(Path)
|
|
{
|
|
var item = document.createElement('script');
|
|
item.type = "text/javascript";
|
|
item.src = Path;
|
|
document.getElementsByTagName('head')[0].appendChild(item);
|
|
};
|
|
|
|
function IsMS()
|
|
{
|
|
var ua = window.navigator.userAgent;
|
|
var msie = ua.indexOf("MSIE ");
|
|
if(msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./))
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
function LoadSignLib()
|
|
{
|
|
if(window.SignLib)
|
|
return ;
|
|
LoadLib("./JS/sign-lib-min.js");
|
|
};
|
|
|
|
function ComputeSecretWithCheck(PubKey,StrPrivKey,F)
|
|
{
|
|
if(!window.SignLib)
|
|
{
|
|
SetError("Error - SignLib not installed");
|
|
return ;
|
|
}
|
|
if(!IsHexStr(StrPrivKey) || StrPrivKey.length !== 64)
|
|
{
|
|
SetError("Error set PrivKey");
|
|
return ;
|
|
}
|
|
var PrivKey = Buffer.from(GetArrFromHex(StrPrivKey));
|
|
if(typeof PubKey === "string")
|
|
{
|
|
if(!IsHexStr(PubKey) || PubKey.length !== 66)
|
|
{
|
|
SetError("Error PubKey");
|
|
return ;
|
|
}
|
|
PubKey = Buffer.from(GetArrFromHex(PubKey));
|
|
}
|
|
var Result = SignLib.ecdh(PubKey, PrivKey);
|
|
F(sha3(Result));
|
|
};
|
|
|
|
function ComputeSecret(PubKey,F)
|
|
{
|
|
if(localStorage["idPrivKey"])
|
|
{
|
|
ComputeSecretWithCheck(PubKey, localStorage["idPrivKey"], F);
|
|
}
|
|
else
|
|
{
|
|
GetData("GetWalletInfo", {}, function (Data)
|
|
{
|
|
if(!Data || !Data.result)
|
|
return ;
|
|
ComputeSecretWithCheck(PubKey, Data.PrivateKey, F);
|
|
});
|
|
}
|
|
};
|
|
|
|
function Encrypt(ArrSecret,StartEncrypt,StrName,StrValue)
|
|
{
|
|
var arrRnd = sha3arr2(ArrSecret, sha3(StrName + StartEncrypt));
|
|
var Arr = toUTF8Array(StrValue);
|
|
return DoSecret(Arr, arrRnd);
|
|
};
|
|
|
|
function Decrypt(ArrSecret,StartEncrypt,StrName,Arr)
|
|
{
|
|
if(!ArrSecret)
|
|
return "".padEnd(Arr.length / 2, ".");
|
|
if(typeof Arr === "string")
|
|
Arr = GetArrFromHex(Arr);
|
|
var arrRnd = sha3arr2(ArrSecret, sha3(StrName + StartEncrypt));
|
|
var Arr2 = DoSecret(Arr, arrRnd);
|
|
var Str = Utf8ArrayToStr(Arr2);
|
|
return Str;
|
|
};
|
|
|
|
function DoSecret(Arr,arrRnd)
|
|
{
|
|
var Arr2 = [];
|
|
var CryptID = 0;
|
|
var Pos = 0;
|
|
while(Pos < Arr.length)
|
|
{
|
|
CryptID++;
|
|
WriteUintToArrOnPos(arrRnd, CryptID, 0);
|
|
var CurBuf = sha3(arrRnd);
|
|
for(var i = 0; i < 32 && Pos < Arr.length; i++, Pos++)
|
|
{
|
|
Arr2[Pos] = Arr[Pos] ^ CurBuf[i];
|
|
}
|
|
}
|
|
return Arr2;
|
|
};
|
|
var glEncryptInit = 0;
|
|
|
|
function EncryptInit()
|
|
{
|
|
glEncryptInit++;
|
|
var Time = Date.now() - new Date(2019, 0, 1);
|
|
return Math.floor(Time * 100 + Math.random() * 100) * 100 + glEncryptInit;
|
|
};
|
|
|
|
function EncryptID(ArrSecret,StartEncrypt,id)
|
|
{
|
|
var Value = $(id).value;
|
|
Value = Value.padEnd(Value.length + random(5), " ");
|
|
return GetHexFromArr(Encrypt(ArrSecret, StartEncrypt, id, Value));
|
|
};
|
|
|
|
function EncryptFields(ArrSecret,Params,ArrName)
|
|
{
|
|
if(!Params.Crypto)
|
|
Params.Crypto = EncryptInit();
|
|
for(var i = 0; i < ArrName.length; i++)
|
|
{
|
|
var Name = ArrName[i];
|
|
var Value = Params[Name];
|
|
Value = Value.padEnd(Value.length + random(5), " ");
|
|
Params[Name] = GetHexFromArr(Encrypt(ArrSecret, Params.Crypto, Name, Value));
|
|
}
|
|
};
|
|
|
|
function DecryptFields(ArrSecret,Params,ArrName)
|
|
{
|
|
for(var i = 0; i < ArrName.length; i++)
|
|
{
|
|
var Name = ArrName[i];
|
|
if(Params[Name])
|
|
{
|
|
Params[Name] = Decrypt(ArrSecret, Params.Crypto, Name, GetArrFromHex(Params[Name]));
|
|
}
|
|
else
|
|
{
|
|
Params[Name] = "";
|
|
}
|
|
}
|
|
};
|