继续改进兼容性:浏览器目前不支持 string.padStart; HBuilderX打包app不能够 crypto 的 setPrivateKey(...)

This commit is contained in:
陆柯 2020-03-13 16:00:47 +08:00
parent 0eaed0f118
commit 7e1d2ef6e1

View File

@ -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')
}
}