tera/src/core/wallet.ts

234 lines
8.1 KiB
TypeScript

/*
* @project: TERA
* @version: Development (beta)
* @license: MIT (not for evil)
* @copyright: Yuriy Ivanov (Vtools) 2017-2019 [progr76@gmail.com]
* Web: https://terafoundation.org
* Twitter: https://twitter.com/terafoundation
* Telegram: https://t.me/terafoundation
*/
"use strict";
import { secp256k1 } from './library'
// const fs = require('fs');
import * as crypto from 'crypto';
require("./library");
require("./crypto-library");
const WalletPath = "WALLET";
// const DBRow = require("./db/db-row");
const CONFIG_NAME = global.GetDataPath(WalletPath + "/config.lst");
class CApp {
Password
WalletOpen
AccountMap
KeyPair
KeyXOR
PubKeyArr
constructor() {
global.CheckCreateDir(global.GetDataPath(WalletPath))
var bReadOnly = (global.PROCESS_NAME !== "TX");
this.Password = ""
this.WalletOpen = undefined
var Params = global.LoadParams(CONFIG_NAME, undefined);
if (!Params) {
Params = {}
if (global.TEST_NETWORK) {
Params.Key = global.ARR_PUB_KEY[0]
}
else {
Params.Key = global.GetHexFromArr(crypto.randomBytes(32))
}
Params.AccountMap = {}
Params.MiningAccount = 0
}
if (Params.MiningAccount)
global.GENERATE_BLOCK_ACCOUNT = Params.MiningAccount
this.AccountMap = Params.AccountMap
this.KeyPair = crypto.createECDH('secp256k1')
if (Params.Protect) {
global.ToLogClient("Wallet protect by password")
this.KeyXOR = global.GetArrFromHex(Params.KeyXOR)
this.WalletOpen = false
this.SetPrivateKey(Params.PubKey)
}
else {
this.SetPrivateKey(Params.Key)
}
}
SetMiningAccount(Account) {
global.GENERATE_BLOCK_ACCOUNT = Account
this.SaveWallet()
}
AddTransaction(Tr) {
if (!global.TX_PROCESS.Worker)
return 0;
var StrHex = global.GetHexFromArr(global.sha3(Tr.body));
global.TX_PROCESS.Worker.send({ cmd: "FindTX", TX: StrHex })
return global.SERVER.AddTransaction(Tr, 1);
}
SetPrivateKey(KeyStr, bSetNew?) {
var bGo = 1;
if (this.WalletOpen === false) {
bGo = 0
}
if (KeyStr && KeyStr.length === 64 && bGo) {
this.KeyPair.setPrivateKey(global.GetArr32FromHex(KeyStr))
this.KeyPair.PubKeyArr = this.KeyPair.getPublicKey('', 'compressed')
this.KeyPair.PubKeyStr = global.GetHexFromArr(this.KeyPair.PubKeyArr)
this.KeyPair.PrivKeyStr = KeyStr.toUpperCase()
this.KeyPair.addrArr = this.KeyPair.PubKeyArr.slice(1)
this.KeyPair.addrStr = global.GetHexAddresFromPublicKey(this.KeyPair.addrArr)
this.KeyPair.addr = this.KeyPair.addrArr
this.KeyPair.WasInit = 1
this.PubKeyArr = this.KeyPair.PubKeyArr
}
else {
this.KeyPair.WasInit = 0
if (KeyStr) {
this.PubKeyArr = global.GetArrFromHex(KeyStr)
this.KeyPair.PubKeyStr = global.GetHexFromArr(this.PubKeyArr)
}
else {
this.PubKeyArr = []
this.KeyPair.PubKeyStr = ""
}
this.KeyPair.PrivKeyStr = ""
}
if (bSetNew) {
this.AccountMap = {}
}
this.FindMyAccounts(0)
if (bGo)
this.SaveWallet()
}
CloseWallet() {
this.Password = ""
this.WalletOpen = false
this.KeyPair = crypto.createECDH('secp256k1')
this.SetPrivateKey(global.GetHexFromArr(this.PubKeyArr), false)
global.ToLogClient("Wallet close")
return 1;
}
OpenWallet(StrPassword) {
if (this.WalletOpen !== false) {
global.ToLogClient("Wallet was open")
}
var Hash = this.HashProtect(StrPassword);
var TestPrivKey = this.XORHash(this.KeyXOR, Hash, 32);
if (!global.IsZeroArr(TestPrivKey)) {
this.KeyPair.setPrivateKey(Buffer.from(TestPrivKey))
var TestPubKey = this.KeyPair.getPublicKey('', 'compressed');
if (global.CompareArr(TestPubKey, this.PubKeyArr) !== 0) {
global.ToLogClient("Wrong password")
return 0;
}
this.Password = StrPassword
this.WalletOpen = true
this.SetPrivateKey(global.GetHexFromArr(TestPrivKey), false)
}
else {
this.Password = StrPassword
this.WalletOpen = true
this.SetPrivateKey(global.GetHexFromArr(this.PubKeyArr), false)
}
global.ToLogClient("Wallet open")
return 1;
}
SetPasswordNew(StrPassword) {
if (this.WalletOpen === false) {
global.ToLogClient("Wallet is close by password")
return;
}
this.Password = StrPassword
if (StrPassword)
this.WalletOpen = true
else
this.WalletOpen = undefined
this.SaveWallet()
}
HashProtect(Str) {
var arr = global.shaarr(Str);
for (var i = 0; i < 10000; i++) {
arr = global.shaarr(arr)
}
return arr;
}
XORHash(arr1, arr2, length) {
var arr3 = [];
for (var i = 0; i < length; i++) {
arr3[i] = arr1[i] ^ arr2[i]
}
return arr3;
}
SaveWallet() {
if (this.WalletOpen === false) {
return;
}
var Params: any = {};
if (this.Password) {
Params.Protect = true
var Hash = this.HashProtect(this.Password);
if (this.KeyPair.WasInit) {
Params.KeyXOR = global.GetHexFromArr(this.XORHash(this.KeyPair.getPrivateKey(), Hash, 32))
}
else {
var Key2 = [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];
Params.KeyXOR = global.GetHexFromArr(this.XORHash(Key2, Hash, 32))
}
Params.PubKey = global.GetHexFromArr(this.PubKeyArr)
this.KeyXOR = global.GetArrFromHex(Params.KeyXOR)
}
else {
if (this.KeyPair.WasInit)
Params.Key = this.KeyPair.PrivKeyStr
else
Params.Key = global.GetHexFromArr(this.PubKeyArr)
}
Params.AccountMap = this.AccountMap
Params.MiningAccount = global.GENERATE_BLOCK_ACCOUNT
global.SaveParams(CONFIG_NAME, Params)
}
OnCreateAccount(Data) {
this.AccountMap[Data.Num] = 0
}
FindMyAccounts(bClean) {
if (global.IsZeroArr(this.PubKeyArr))
return;
if (bClean)
this.AccountMap = {}
global.DApps.Accounts.FindAccounts([this.PubKeyArr], this.AccountMap, 0)
}
GetAccountKey(Num) {
if (this.KeyPair.WasInit && global.TestTestWaletMode) {
}
return this.KeyPair;
}
GetPrivateKey(Num) {
if (!this.KeyPair.WasInit)
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];
var KeyPair;
if (Num) {
KeyPair = this.GetAccountKey(Num)
}
else {
KeyPair = this.KeyPair
}
return KeyPair.getPrivateKey();
}
GetSignFromArr(Arr, Num) {
if (!this.KeyPair.WasInit)
return "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
var PrivKey = this.GetPrivateKey(Num);
var sigObj = secp256k1.sign(global.SHA3BUF(Arr), Buffer.from(PrivKey));
return global.GetHexFromArr(sigObj.signature);
}
GetSignTransaction(TR) {
if (!this.KeyPair.WasInit)
return "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
var PrivKey = this.GetPrivateKey(this.AccountMap[TR.FromID]);
var Arr = global.DApps.Accounts.GetSignTransferTx(TR, PrivKey);
return global.GetHexFromArr(Arr);
}
};
global.WALLET = new CApp;