TxBuilder: add support for RSBuffer type keyPairs and .publicKey

This commit is contained in:
Daniel Cousens 2017-10-19 11:22:17 +11:00
parent b94da10e6c
commit a868d27407
2 changed files with 22 additions and 4 deletions

View file

@ -667,7 +667,8 @@ function canSign (input) {
} }
TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashType, witnessValue, witnessScript) { TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashType, witnessValue, witnessScript) {
if (keyPair.network !== this.network) throw new Error('Inconsistent network') // TODO: remove keyPair.network matching in 4.0.0
if (keyPair.network && keyPair.network !== this.network) throw new TypeError('Inconsistent network')
if (!this.inputs[vin]) throw new Error('No input at index: ' + vin) if (!this.inputs[vin]) throw new Error('No input at index: ' + vin)
hashType = hashType || Transaction.SIGHASH_ALL hashType = hashType || Transaction.SIGHASH_ALL
@ -680,7 +681,7 @@ TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashTy
throw new Error('Inconsistent redeemScript') throw new Error('Inconsistent redeemScript')
} }
var kpPubKey = keyPair.getPublicKeyBuffer() var kpPubKey = keyPair.publicKey || keyPair.getPublicKeyBuffer()
if (!canSign(input)) { if (!canSign(input)) {
if (witnessValue !== undefined) { if (witnessValue !== undefined) {
if (input.value !== undefined && input.value !== witnessValue) throw new Error('Input didn\'t match witnessValue') if (input.value !== undefined && input.value !== witnessValue) throw new Error('Input didn\'t match witnessValue')
@ -699,14 +700,18 @@ TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashTy
} else { } else {
signatureHash = this.tx.hashForSignature(vin, input.signScript, hashType) signatureHash = this.tx.hashForSignature(vin, input.signScript, hashType)
} }
// enforce in order signing of public keys // enforce in order signing of public keys
var signed = input.pubKeys.some(function (pubKey, i) { var signed = input.pubKeys.some(function (pubKey, i) {
if (!kpPubKey.equals(pubKey)) return false if (!kpPubKey.equals(pubKey)) return false
if (input.signatures[i]) throw new Error('Signature already exists') if (input.signatures[i]) throw new Error('Signature already exists')
if (!keyPair.compressed && if (kpPubKey.length !== 33 &&
input.signType === scriptTypes.P2WPKH) throw new Error('BIP143 rejects uncompressed public keys in P2WPKH or P2WSH') input.signType === scriptTypes.P2WPKH) throw new Error('BIP143 rejects uncompressed public keys in P2WPKH or P2WSH')
input.signatures[i] = keyPair.sign(signatureHash).toScriptSignature(hashType) var signature = keyPair.sign(signatureHash)
if (Buffer.isBuffer(signature)) signature = ECSignature.fromRSBuffer(signature)
input.signatures[i] = signature.toScriptSignature(hashType)
return true return true
}) })

View file

@ -294,6 +294,19 @@ describe('TransactionBuilder', function () {
}) })
describe('sign', function () { describe('sign', function () {
it('supports the alternative abstract interface { publicKey, sign }', function () {
var keyPair = {
publicKey: Buffer.alloc(33, 0x03),
sign: function (hash) { return Buffer.alloc(64) }
}
var txb = new TransactionBuilder()
txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
txb.addOutput('1111111111111111111114oLvT2', 100000)
txb.sign(0, keyPair)
assert.equal(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000002c0930060201000201000121030303030303030303030303030303030303030303030303030303030303030303ffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
})
fixtures.invalid.sign.forEach(function (f) { fixtures.invalid.sign.forEach(function (f) {
it('throws on ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), function () { it('throws on ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), function () {
var txb = construct(f, true) var txb = construct(f, true)