Created
March 14, 2019 21:44
-
-
Save matiu/3906be643eae2cf635c524c7ee510433 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// cryto exports: | |
return Bitcore.crypto.Hash.sha256(pk.toBuffer()).slice(0, 16).toString('base64'); | |
// priv key validation | |
$.checkArgument(Bitcore.PrivateKey.isValid(privKey), 'The private key received is invalid'); | |
// pub key validation | |
pubKey = new Bitcore.PublicKey.fromString(opts.pubKey); | |
// pub key derivation (from xpub) | |
var pub = (new Bitcore.HDPublicKey(xPubKey)).deriveChild(Constants.PATHS.REQUEST_KEY_AUTH).publicKey; | |
// xpub validation | |
xPubKey = Bitcore.HDPublicKey(opts.xPubKey); | |
// address validation and network extraction (live/testnet) | |
var A = Bitcore_[wallet.coin].Address; | |
var addrObj = {}; | |
try { | |
addrObj = new A(address); | |
} catch (ex) { | |
return cb(null,[]); | |
} | |
if (addrObj.network.name != wallet.network) { | |
return cb(null,[]); | |
} | |
// Address derivation | |
var bitcore = Bitcore_[coin]; | |
var publicKeys = _.map(publicKeyRing, function(item) { | |
var xpub = new bitcore.HDPublicKey(item.xPubKey); | |
return xpub.deriveChild(path).publicKey; | |
}); | |
var bitcoreAddress; | |
switch (scriptType) { | |
case Constants.SCRIPT_TYPES.P2SH: | |
bitcoreAddress = bitcore.Address.createMultisig(publicKeys, m, network); | |
break; | |
case Constants.SCRIPT_TYPES.P2PKH: | |
$.checkState(_.isArray(publicKeys) && publicKeys.length == 1); | |
bitcoreAddress = bitcore.Address.fromPublicKey(publicKeys[0], network); | |
break; | |
} | |
return { | |
address: coin == 'bch' ? bitcoreAddress.toLegacyAddress() : bitcoreAddress.toString(), | |
path: path, | |
publicKeys: _.invokeMap(publicKeys, 'toString'), | |
}; | |
// verify message | |
var crypto = Bitcore.crypto; | |
var pub = new PublicKey(pubKey); | |
var hash = Utils.hashMessage(text); | |
try { | |
var sig = new crypto.Signature.fromString(signature); | |
return crypto.ECDSA.verify(hash, sig, pub, 'little'); | |
// dust amount constant | |
Bitcore_[txp.coin].Transaction.DUST_AMOUNT | |
// create raw TX | |
var self = this; | |
var t = new Bitcore[self.coin].Transaction(); | |
$.checkState(Utils.checkValueInCollection(self.addressType, Constants.SCRIPT_TYPES)); | |
switch (self.addressType) { | |
case Constants.SCRIPT_TYPES.P2SH: | |
_.each(self.inputs, function(i) { | |
$.checkState(i.publicKeys, 'Inputs should include public keys'); | |
t.from(i, i.publicKeys, self.requiredSignatures); | |
}); | |
break; | |
case Constants.SCRIPT_TYPES.P2PKH: | |
t.from(self.inputs); | |
break; | |
} | |
_.each(self.outputs, function(o) { | |
$.checkState(o.script || o.toAddress, 'Output should have either toAddress or script specified'); | |
if (o.script) { | |
t.addOutput(new Bitcore[self.coin].Transaction.Output({ | |
script: o.script, | |
satoshis: o.amount | |
})); | |
} else { | |
t.to(o.toAddress, o.amount); | |
} | |
}); | |
t.fee(self.fee); | |
if (self.changeAddress) { | |
t.change(self.changeAddress.address); | |
} | |
// Shuffle outputs for improved privacy | |
if (t.outputs.length > 1) { | |
var outputOrder = _.reject(self.outputOrder, function(order) { | |
return order >= t.outputs.length; | |
}); | |
$.checkState(t.outputs.length == outputOrder.length); | |
t.sortOutputs(function(outputs) { | |
return _.map(outputOrder, function(i) { | |
return outputs[i]; | |
}); | |
}); | |
} | |
// Validate actual inputs vs outputs independently of Bitcore | |
var totalInputs = _.sumBy(t.inputs, 'output.satoshis'); | |
var totalOutputs = _.sumBy(t.outputs, 'satoshis'); | |
$.checkState(totalInputs > 0 && totalOutputs > 0 && totalInputs >= totalOutputs, 'not-enought-inputs'); | |
$.checkState(totalInputs - totalOutputs <= Defaults.MAX_TX_FEE, 'fee-too-high'); | |
return t; | |
// add signatures to a tx | |
TxProposal.prototype._addSignaturesToBitcoreTx = function(tx, signatures, xpub) { | |
var self = this; | |
var bitcore = Bitcore[self.coin]; | |
if (signatures.length != this.inputs.length) | |
throw new Error('Number of signatures does not match number of inputs'); | |
var i = 0, | |
x = new bitcore.HDPublicKey(xpub); | |
_.each(signatures, function(signatureHex) { | |
var input = self.inputs[i]; | |
try { | |
var signature = bitcore.crypto.Signature.fromString(signatureHex); | |
var pub = x.deriveChild(self.inputPaths[i]).publicKey; | |
var s = { | |
inputIndex: i, | |
signature: signature, | |
sigtype: bitcore.crypto.Signature.SIGHASH_ALL | bitcore.crypto.Signature.SIGHASH_FORKID, | |
publicKey: pub, | |
}; | |
tx.inputs[i].addSignature(tx, s); | |
i++; | |
} catch (e) {}; | |
}); | |
if (i != tx.inputs.length) | |
throw new Error('Wrong signatures'); | |
}; | |
<D-Bar> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment