From c3dc3fbc45bfd2c19023f301ca5a1fee39f0fc5f Mon Sep 17 00:00:00 2001 From: "luk.lu" Date: Thu, 18 Apr 2019 18:04:25 +0800 Subject: [PATCH] [netConfig.js] node.server port changed from 8888 to 60000. [eth.js] lint it to remove semicolons at line endings. --- eth.js | 256 +++++++++++++++++++++++++-------------------------- netConfig.js | 2 +- 2 files changed, 129 insertions(+), 129 deletions(-) diff --git a/eth.js b/eth.js index 0e9aa27..e49c3c0 100644 --- a/eth.js +++ b/eth.js @@ -1,22 +1,22 @@ 'use strict' -const eth = require('etherscan-api').init('E3ZFFAEMNN33KX4HHVUZ4KF8XY1FXMR4BI'); -const secretStorage = require('./utils/secret-storage'); -const SigningKey = require('./utils/signing-key.js'); -const Ticrypto = require('tic.crypto'); -const HDNode = require('./utils/hdnode'); -const utils = require('./util.js'); -const axios = require('axios'); +const eth = require('etherscan-api').init('E3ZFFAEMNN33KX4HHVUZ4KF8XY1FXMR4BI') +const secretStorage = require('./utils/secret-storage') +const SigningKey = require('./utils/signing-key.js') +const Ticrypto = require('tic.crypto') +const HDNode = require('./utils/hdnode') +const utils = require('./util.js') +const axios = require('axios') -require('setimmediate'); +require('setimmediate') -const GAS_UNIT_WEI = 1e18; //1wei -const GAS_UNIT_GWEI = 1e9; //1gwei = 1e9 wei -const GAS_Fee = 0.000021; -const GAS_Fee_ERC20 = 0.000060; -const GAS_LIMIT = 21000; -const GAS_LIMIT_ERC20 = 60000; -const defaultPath = "m/44'/60'/0'/0/0"; -const ETH_NODE = require('./netConfig').ETH_NODE; +const GAS_UNIT_WEI = 1e18 //1wei +const GAS_UNIT_GWEI = 1e9 //1gwei = 1e9 wei +const GAS_Fee = 0.000021 +const GAS_Fee_ERC20 = 0.000060 +const GAS_LIMIT = 21000 +const GAS_LIMIT_ERC20 = 6e4 +const defaultPath = "m/44'/60'/0'/0/0" +const ETH_NODE = require('./netConfig').ETH_NODE const transactionFields = [ {name: 'nonce', maxLength: 32, }, @@ -25,15 +25,15 @@ const transactionFields = [ {name: 'to', length: 20, }, {name: 'value', maxLength: 32, }, {name: 'data'}, -]; +] class ETH { constructor(privateKey){ if(privateKey.length == 64 && !(privateKey.split('x')[1] && privateKey.split('x')[0] === '0')) - privateKey = '0x'+privateKey; - var signingKey = privateKey; + privateKey = '0x'+privateKey + var signingKey = privateKey if (!(privateKey instanceof SigningKey)) { - signingKey = new SigningKey(privateKey); + signingKey = new SigningKey(privateKey) } Object.defineProperties(this, { 'privateKey' : { @@ -48,27 +48,27 @@ class ETH { }, 'url' : { enumerable: true, - get: function() { return this._url; }, + get: function() { return this._url }, set: function(url) { - if (typeof(url) !== 'string') { throw new Error('invalid url'); } - this._url = url; + if (typeof(url) !== 'string') { throw new Error('invalid url') } + this._url = url }, }, 'defaultGasFee' : { enumerable: true, - get: function() { return this._defaultGasFee; }, + get: function() { return this._defaultGasFee }, set: function(value) { - if (typeof(value) !== 'number') { throw new Error('invalid defaultGasFee'); } - this._defaultGasFee = value; + if (typeof(value) !== 'number') { throw new Error('invalid defaultGasFee') } + this._defaultGasFee = value } } }) - this._defaultGasFee = GAS_Fee; - this._url = ETH_NODE; + this._defaultGasFee = GAS_Fee + this._url = ETH_NODE } static generateNewAccount(option = {path:defaultPath}){ //major path as default path >/0'/0/0 - var mnemonic = Ticrypto.randomSecword(); + var mnemonic = Ticrypto.randomSecword() return Object.assign(ETH.fromMnemonic(mnemonic, option),{mnemonic,mnemonic}) } static fromMnemonic(mnemonic, option = {path:defaultPath}){ @@ -77,7 +77,7 @@ class ETH { return new ETH(HDNode.fromSeed(seed).derivePath(option.path).privateKey) } static async getBalance(address){ - if(!address){ throw new Error('Address is required'); } + if(!address){ throw new Error('Address is required') } let res = (await axios.post(ETH_NODE,{ "jsonrpc":"2.0","method":"eth_getBalance","params":[address, "latest"],"id":1 })).data @@ -87,114 +87,114 @@ class ETH { } static async getActions(address){ let tx = await eth.account.txlist(address, 0 ,'latast') - if(tx && tx.message === "OK") + if(tx && tx.message === 'OK') return tx.result else return [] } static fromEncryptedWallet(json, password, progressCallback) { if (progressCallback && typeof(progressCallback) !== 'function') { - throw new Error('invalid callback'); + throw new Error('invalid callback') } return new Promise(function(resolve, reject) { if (secretStorage.isCrowdsaleWallet(json)) { try { - var privateKey = secretStorage.decryptCrowdsale(json, password); - resolve(new ETH(privateKey)); + var privateKey = secretStorage.decryptCrowdsale(json, password) + resolve(new ETH(privateKey)) } catch (error) { - reject(error); + reject(error) } } else if (secretStorage.isValidWallet(json)) { secretStorage.decrypt(json, password, progressCallback).then(function(signingKey) { - var wallet = new ETH(signingKey); + var wallet = new ETH(signingKey) if (signingKey.mnemonic && signingKey.path) { - utils.defineProperty(wallet, 'mnemonic', signingKey.mnemonic); - utils.defineProperty(wallet, 'path', signingKey.path); + utils.defineProperty(wallet, 'mnemonic', signingKey.mnemonic) + utils.defineProperty(wallet, 'path', signingKey.path) } - resolve(wallet); - return null; + resolve(wallet) + return null }, function(error) { - reject(error); - }).catch(function(error) { reject(error); }); + reject(error) + }).catch(function(error) { reject(error) }) } else { - reject('invalid wallet JSON'); + reject('invalid wallet JSON') } - }); + }) } static parseTransaction(rawTransaction){ - rawTransaction = utils.hexlify(rawTransaction, 'rawTransaction'); - var signedTransaction = utils.RLP.decode(rawTransaction); - if (signedTransaction.length !== 9) { throw new Error('invalid transaction'); } + rawTransaction = utils.hexlify(rawTransaction, 'rawTransaction') + var signedTransaction = utils.RLP.decode(rawTransaction) + if (signedTransaction.length !== 9) { throw new Error('invalid transaction') } - var raw = []; + var raw = [] - var transaction = {}; + var transaction = {} transactionFields.forEach(function(fieldInfo, index) { - transaction[fieldInfo.name] = signedTransaction[index]; - raw.push(signedTransaction[index]); - }); + transaction[fieldInfo.name] = signedTransaction[index] + raw.push(signedTransaction[index]) + }) if (transaction.to) { if (transaction.to == '0x') { - delete transaction.to; + delete transaction.to } else { - transaction.to = utils.getAddress(transaction.to); + transaction.to = utils.getAddress(transaction.to) } } ['gasPrice', 'gasLimit', 'nonce', 'value'].forEach(function(name) { - if (!transaction[name]) { return; } + if (!transaction[name]) { return } if (transaction[name].length === 0) { - transaction[name] = utils.bigNumberify(0); + transaction[name] = utils.bigNumberify(0) } else { - transaction[name] = utils.bigNumberify(transaction[name]); + transaction[name] = utils.bigNumberify(transaction[name]) } - }); + }) if (transaction.nonce) { - transaction.nonce = transaction.nonce.toNumber(); + transaction.nonce = transaction.nonce.toNumber() } else { - transaction.nonce = 0; + transaction.nonce = 0 } - var v = utils.arrayify(signedTransaction[6]); - var r = utils.arrayify(signedTransaction[7]); - var s = utils.arrayify(signedTransaction[8]); + var v = utils.arrayify(signedTransaction[6]) + var r = utils.arrayify(signedTransaction[7]) + var s = utils.arrayify(signedTransaction[8]) if (v.length >= 1 && r.length >= 1 && r.length <= 32 && s.length >= 1 && s.length <= 32) { - transaction.v = utils.bigNumberify(v).toNumber(); - transaction.r = signedTransaction[7]; - transaction.s = signedTransaction[8]; + transaction.v = utils.bigNumberify(v).toNumber() + transaction.r = signedTransaction[7] + transaction.s = signedTransaction[8] - var chainId = (transaction.v - 35) / 2; - if (chainId < 0) { chainId = 0; } - chainId = parseInt(chainId); + var chainId = (transaction.v - 35) / 2 + if (chainId < 0) { chainId = 0 } + chainId = parseInt(chainId) - transaction.chainId = chainId; + transaction.chainId = chainId - var recoveryParam = transaction.v - 27; + var recoveryParam = transaction.v - 27 if (chainId) { - raw.push(utils.hexlify(chainId)); - raw.push('0x'); - raw.push('0x'); - recoveryParam -= chainId * 2 + 8; + raw.push(utils.hexlify(chainId)) + raw.push('0x') + raw.push('0x') + recoveryParam -= chainId * 2 + 8 } - var digest = utils.keccak256(utils.RLP.encode(raw)); + var digest = utils.keccak256(utils.RLP.encode(raw)) try { - transaction.from = SigningKey.recover(digest, r, s, recoveryParam); + transaction.from = SigningKey.recover(digest, r, s, recoveryParam) } catch (error) { - console.log(error); + console.log(error) } } - return transaction; + return transaction } static encrypt(data, key){ if(!data || !key) throw new Error('Required Params Missing') @@ -228,67 +228,67 @@ class ETH { return ETH.getActions(this.address) } async getTransactionCount(){ - if(!this._url){ throw new Error('Base url required'); } - var self = this; + if(!this._url){ throw new Error('Base url required') } + var self = this return (await axios.post(this._url,{ "jsonrpc":"2.0","method":"eth_getTransactionCount","params":[self.address, "latest"],"id":1 })).data.result||null } signTransaction(transaction){ - var chainId = transaction.chainId; - if (chainId == null && this.provider) { chainId = this.provider.chainId; } - if (!chainId) { chainId = 0; } + var chainId = transaction.chainId + if (chainId == null && this.provider) { chainId = this.provider.chainId } + if (!chainId) { chainId = 0 } - var raw = []; + var raw = [] transactionFields.forEach(function(fieldInfo) { - var value = transaction[fieldInfo.name] || ([]); - value = utils.arrayify(utils.hexlify(value), fieldInfo.name); + var value = transaction[fieldInfo.name] || ([]) + value = utils.arrayify(utils.hexlify(value), fieldInfo.name) // Fixed-width field if (fieldInfo.length && value.length !== fieldInfo.length && value.length > 0) { - var error = new Error('invalid ' + fieldInfo.name); - error.reason = 'wrong length'; - error.value = value; - throw error; + var error = new Error('invalid ' + fieldInfo.name) + error.reason = 'wrong length' + error.value = value + throw error } // Variable-width (with a maximum) if (fieldInfo.maxLength) { - value = utils.stripZeros(value); + value = utils.stripZeros(value) if (value.length > fieldInfo.maxLength) { - var error = new Error('invalid ' + fieldInfo.name); - error.reason = 'too long'; - error.value = value; - throw error; + var error = new Error('invalid ' + fieldInfo.name) + error.reason = 'too long' + error.value = value + throw error } } - raw.push(utils.hexlify(value)); - }); + raw.push(utils.hexlify(value)) + }) if (chainId) { - raw.push(utils.hexlify(chainId)); - raw.push('0x'); - raw.push('0x'); + raw.push(utils.hexlify(chainId)) + raw.push('0x') + raw.push('0x') } - var digest = utils.keccak256(utils.RLP.encode(raw)); - var signingKey = new SigningKey(this.privateKey); - var signature = signingKey.signDigest(digest); + var digest = utils.keccak256(utils.RLP.encode(raw)) + var signingKey = new SigningKey(this.privateKey) + var signature = signingKey.signDigest(digest) var v = 27 + signature.recoveryParam if (chainId) { - raw.pop(); - raw.pop(); - raw.pop(); - v += chainId * 2 + 8; + raw.pop() + raw.pop() + raw.pop() + v += chainId * 2 + 8 } - raw.push(utils.hexlify(v)); - raw.push(utils.stripZeros(utils.arrayify(signature.r))); - raw.push(utils.stripZeros(utils.arrayify(signature.s))); + raw.push(utils.hexlify(v)) + raw.push(utils.stripZeros(utils.arrayify(signature.r))) + raw.push(utils.stripZeros(utils.arrayify(signature.s))) - return utils.RLP.encode(raw); + return utils.RLP.encode(raw) } async sendTransaction(toAddress, amount, option = {gasFee : GAS_Fee}){ /**************************************************************** @@ -297,17 +297,17 @@ class ETH { *GWei as the unit of gasPrice, minimum gasPrice is 1Gwei *unit of amount is ether,should be translate to wei ****************************************************************/ - let nonce = await this.getTransactionCount(); + let nonce = await this.getTransactionCount() if(!nonce) nonce = '0x0' - var gasPrice, gasLimit; + var gasPrice, gasLimit if(!option.gasPrice || !option.gasLimit){ //Normal Mode:use customized gasFee( ether ) to caculate gasPrice( wei ), gasLimit use default value - gasLimit = GAS_LIMIT; - gasPrice = String(option.gasFee * GAS_UNIT_WEI / gasLimit); + gasLimit = GAS_LIMIT + gasPrice = String(option.gasFee * GAS_UNIT_WEI / gasLimit) } else{ //Advance Mode:specified the gasLimit and gasPrice( gwei ) - gasLimit = option.gasLimit; + gasLimit = option.gasLimit gasPrice = String(GAS_UNIT_GWEI * option.gasPrice) } let transaction = { @@ -317,9 +317,9 @@ class ETH { to: toAddress, value: utils.parseEther(String(amount)), - }; + } try{ - let signedTransaction = this.signTransaction(transaction); + let signedTransaction = this.signTransaction(transaction) let ethTxRes = (await axios.post(ETH_NODE,{ "jsonrpc":"2.0", "method":"eth_sendRawTransaction", @@ -342,7 +342,7 @@ class ETH { class ERC20 extends ETH{ constructor(privateKey, contractAddress){ if(!contractAddress) throw new Error('Missing contractAddress') - super(privateKey); + super(privateKey) Object.defineProperty(this, 'contractAddress',{ enumerable:true, writable:false, @@ -410,19 +410,19 @@ class ERC20 extends ETH{ 1 Ether = 1e18 wei 1 Gwei = 1e9 wei *GWei as the unit of gasPrice, minimum gasPrice is 1Gwei - minimum gaslimit for erc20transaction is 60000 + minimum gaslimit for erc20transaction is 6e4 ****************************************************************/ - var nonce = await this.getTransactionCount(); - var gasPrice, gasLimit, decimals, contractAddress = this.contractAddress; + var nonce = await this.getTransactionCount() + var gasPrice, gasLimit, decimals, contractAddress = this.contractAddress if(!nonce) nonce = '0x0' if(!option.gasPrice || !option.gasLimit){ //Normal Mode:use customized gasFee( ether ) to caculate gasPrice( wei ), gasLimit use default value - gasLimit = GAS_LIMIT_ERC20; - gasPrice = String(option.gasFee * GAS_UNIT_WEI / gasLimit); + gasLimit = GAS_LIMIT_ERC20 + gasPrice = String(option.gasFee * GAS_UNIT_WEI / gasLimit) } else{ //Advance Mode:specified the gasLimit and gasPrice( gwei ) - gasLimit = option.gasLimit; + gasLimit = option.gasLimit gasPrice = String(GAS_UNIT_GWEI * option.gasPrice) } if(!option.decimals) decimals = await ERC20.getDecimals(contractAddress) @@ -434,8 +434,8 @@ class ERC20 extends ETH{ to: contractAddress, value : 0, data : txBody - }; - let signedTransaction = this.signTransaction(transaction); + } + let signedTransaction = this.signTransaction(transaction) try{ let erc20TxRes = (await axios.post(ETH_NODE, { "jsonrpc":"2.0", diff --git a/netConfig.js b/netConfig.js index 508e92a..826a7bf 100644 --- a/netConfig.js +++ b/netConfig.js @@ -1,5 +1,5 @@ -const TIC_NODE = 'https://bank.bittic.net:8888/api'; +const TIC_NODE = 'https://bank.bittic.net:60000/api'; const BTC_NODE = 'https://api.blockcypher.com/v1/btc/main'; const BTC_NODE2 = 'https://blockchain.info'//https://blockchain.info/unspent?active=12HnmPpLomtPL53Q4s6xEqRB4wkMHi5GEZ const ETH_NODE = 'https://mainnet.infura.io/8284219b092f4cc69f3de29e532b1eb2';