diff --git a/index.js b/index.js index cb90407..1080caf 100644 --- a/index.js +++ b/index.js @@ -11,7 +11,7 @@ const keyman = require('js-crypto-key-utils') // 转换原始密钥和 PER/DER const bip39 = require('bip39') // https://github.com/bitcoinjs/bip39 // 有更多语言,但不方便选择语言,也不能使用 pass const hdkey = require('hdkey') // https://github.com/cryptocoinjs/hdkey // 或者用 bitcore-mnemonic 或者 ethers 里的相同功能 // const bitcorelib = require('bitcore-lib') -// const secp256k1 = require('secp256k1') +const secp256k1 = require('secp256k1') // 全部以hex为默认输入输出格式,方便人的阅读,以及方便函数之间统一接口 @@ -290,7 +290,12 @@ module.exports = { option.coin=my.COIN_LIST.indexOf(option.coin)>=0?option.coin:my.COIN let kp=this.secword2keypair(secword, option) if (kp) { - kp.address=this.seckey2address(kp.seckey, option) + if (option.coin === 'ETH') { + let uncompressedPubkey = this.decompressPubkey(kp.pubkey) + kp.address = this.pubkey2address(uncompressedPubkey,{coin:'ETH'}) + }else { + kp.address=this.pubkey2address(kp.pubkey, option) + } return kp } return null @@ -301,7 +306,14 @@ module.exports = { option.coin=my.COIN_LIST.indexOf(option.coin)>=0?option.coin:my.COIN let kp=this.secword2keypair(secword, option) if (kp) { - return this.seckey2address(kp.seckey,option) + let address + if (option.coin === 'ETH') { + let uncompressedPubkey = this.decompressPubkey(kp.pubkey) + address = this.pubkey2address(uncompressedPubkey,{coin:'ETH'}) + }else { + address = this.pubkey2address(kp.pubkey, option) + } + return address } return null } @@ -310,9 +322,9 @@ module.exports = { option.coin=my.COIN_LIST.indexOf(option.coin)>=0?option.coin:my.COIN if (this.isSeckey(seckey) && seckey.length===64){ // 只能用于32字节的私钥(BTC, ETH)。也就是不能用于 TIC 的私钥。 let curve = my.CURVE_LIST.indexOf(option.curve)>=0?option.curve:my.CURVE // 默认为 secp256k1 - return new crypto.createECDH(curve).setPrivateKey(seckey,'hex').getPublicKey('hex', option.compress===false?'uncompressed':'compressed') // ecdh.getPublicKey(不加参数) 默认为 'uncompressed' + // return new crypto.createECDH(curve).setPrivateKey(seckey,'hex').getPublicKey('hex', option.compress===false?'uncompressed':'compressed') // ecdh.getPublicKey(不加参数) 默认为 'compressed'。用 HBuilderX 2.6.4 打包成 app 后 setPrivateKey() 报错:TypeError: null is not an object (evaluating 'this.rand.getBytes') // 从 nodejs 10.0 开始,还有 crypto.ECDH.convertKey 方法,更直接。但可惜,浏览器里不存在 crypto.ECDH。 - // 或者 return this.buf2hex(require('secp256k1').publicKeyCreate(Buffer.from(seckey, 'hex'), option.compress!==false)) // 可用于浏览器。secp256k1缺省或true时输出压缩公钥,false时输出非压缩公钥。 + return this.buf2hex(require('secp256k1').publicKeyCreate(Buffer.from(seckey, 'hex'), option.compress!==false)) // 可用于浏览器。secp256k1缺省或true时输出压缩公钥,false时输出非压缩公钥。 // 或者 bitcorelib.PublicKey.fromPrivateKey(new bitcorelib.PrivateKey(seckey)).toString('hex') // 可用于浏览器 // 或者 const ecc = require('eccrypto') // if (option.compress===false){ @@ -362,7 +374,7 @@ module.exports = { return null } , - position2address(position, {coin, net, format}={}){ + position2address(position, {coin, net}={}){ if (!/^[\da-fA-F]{40}$/.test(position)) return null // 不论 tic, btc, eth,其 position 都是 40字符的。 coin = my.COIN_LIST.indexOf(coin)>=0?coin:my.COIN let address @@ -530,19 +542,29 @@ module.exports = { } , randomNumber({length, min, max}={}){ // 长度为 length 的随机数字,或者 (min||0) <= num < max - var num=0 + var num = 0 if (typeof length === 'number' && length>0){ - num=parseInt(Math.random()*Math.pow(10,length)) - num.toString().padStart(length, '0') + num = parseInt(Math.random()*Math.pow(10,length)) + num = this.padStart(num.toString(), length, '0') }else if (typeof max === 'number' && max>0){ min = (typeof min === 'number' && min>=0) ? min : 0 - num=parseInt(Math.random()*(max-min))+min + num = parseInt(Math.random()*(max-min))+min }else{ // 如果 option 为空 - num=Math.random() + num = Math.random() } return num } , + padStart(string, targetLength, symbol){ // 2020-03: 发现在浏览器里,还不支持 string.padStart(),只好自己写个暂代。 + let stringLength = string.length + if (stringLength < targetLength) { + for (let index = 1; index <= targetLength-stringLength; index++) { + string = symbol + string + } + } + return string + } + , randomUuid:uuid.v4 , getMerkleHash(hashList, option){ @@ -758,6 +780,6 @@ module.exports = { if( y.mod(2).toJSNumber() !== signY ) { // If the parity doesn't match it's the *other* root y = prime.subtract( y ) // y = prime - y } - return '04' + x.toString(16).padStart(64, '0') + y.toString(16).padStart(64, '0') + return '04' + this.padStart(x.toString(16), 64, '0') + this.padStart(y.toString(16), 64, '0') } } \ No newline at end of file