TransactionBuilder: re-order in order of usage

This commit is contained in:
Daniel Cousens 2016-10-12 12:15:13 +11:00 committed by Daniel Cousens
parent 6056e7913e
commit 7059b177eb

View file

@ -84,6 +84,37 @@ function expandInput (scriptSig, redeemScript) {
}
}
function fixMultisigOrder (input, transaction, vin) {
if (input.redeemScriptType !== 'multisig' || !input.redeemScript) return
if (input.pubKeys.length === input.signatures.length) return
var unmatched = input.signatures.concat()
var hashType = input.hashType || Transaction.SIGHASH_ALL
var hash = transaction.hashForSignature(vin, input.redeemScript, hashType)
input.signatures = input.pubKeys.map(function (pubKey, y) {
var keyPair = ECPair.fromPublicKeyBuffer(pubKey)
var match
// check for a signature
unmatched.some(function (signature, i) {
// skip if undefined || OP_0
if (!signature) return false
// skip if signature does not match pubKey
if (!keyPair.verify(hash, signature)) return false
// remove matched signature from unmatched
unmatched[i] = undefined
match = signature
return true
})
return match
})
}
function expandOutput (script, scriptType, ourPubKey) {
typeforce(types.Buffer, script)
@ -122,50 +153,6 @@ function expandOutput (script, scriptType, ourPubKey) {
}
}
function buildInput (input, allowIncomplete) {
var signatures = input.signatures
var scriptType = input.redeemScriptType || input.prevOutType
var scriptSig
switch (scriptType) {
case 'pubkeyhash':
case 'pubkey':
if (signatures.length < 1 || !signatures[0]) throw new Error('Not enough signatures provided')
var pkSignature = signatures[0].toScriptSignature(input.hashType)
if (scriptType === 'pubkeyhash') {
scriptSig = bscript.pubKeyHashInput(pkSignature, input.pubKeys[0])
} else {
scriptSig = bscript.pubKeyInput(pkSignature)
}
break
// ref https://github.com/bitcoin/bitcoin/blob/d612837814020ae832499d18e6ee5eb919a87907/src/script/sign.cpp#L232
case 'multisig':
signatures = signatures.map(function (signature) {
return (signature && signature.toScriptSignature(input.hashType)) || ops.OP_0
})
if (!allowIncomplete) {
// remove blank signatures
signatures = signatures.filter(function (x) { return x !== ops.OP_0 })
}
scriptSig = bscript.multisigInput(signatures, allowIncomplete ? undefined : input.redeemScript)
break
default: return
}
// wrap as scriptHash if necessary
if (input.prevOutType === 'scripthash') {
scriptSig = bscript.scriptHashInput(scriptSig, input.redeemScript)
}
return scriptSig
}
function prepareInput (input, kpPubKey, redeemScript, hashType) {
if (redeemScript) {
var redeemScriptHash = bcrypto.hash160(redeemScript)
@ -212,35 +199,48 @@ function prepareInput (input, kpPubKey, redeemScript, hashType) {
input.hashType = hashType
}
function fixMultisigOrder (input, transaction, vin) {
if (input.redeemScriptType !== 'multisig' || !input.redeemScript) return
if (input.pubKeys.length === input.signatures.length) return
function buildInput (input, allowIncomplete) {
var signatures = input.signatures
var scriptType = input.redeemScriptType || input.prevOutType
var scriptSig
var unmatched = input.signatures.concat()
var hashType = input.hashType || Transaction.SIGHASH_ALL
var hash = transaction.hashForSignature(vin, input.redeemScript, hashType)
switch (scriptType) {
case 'pubkeyhash':
case 'pubkey':
if (signatures.length < 1 || !signatures[0]) throw new Error('Not enough signatures provided')
input.signatures = input.pubKeys.map(function (pubKey, y) {
var keyPair = ECPair.fromPublicKeyBuffer(pubKey)
var match
var pkSignature = signatures[0].toScriptSignature(input.hashType)
if (scriptType === 'pubkeyhash') {
scriptSig = bscript.pubKeyHashInput(pkSignature, input.pubKeys[0])
} else {
scriptSig = bscript.pubKeyInput(pkSignature)
}
// check for a signature
unmatched.some(function (signature, i) {
// skip if undefined || OP_0
if (!signature) return false
break
// skip if signature does not match pubKey
if (!keyPair.verify(hash, signature)) return false
// ref https://github.com/bitcoin/bitcoin/blob/d612837814020ae832499d18e6ee5eb919a87907/src/script/sign.cpp#L232
case 'multisig':
signatures = signatures.map(function (signature) {
return (signature && signature.toScriptSignature(input.hashType)) || ops.OP_0
})
// remove matched signature from unmatched
unmatched[i] = undefined
match = signature
if (!allowIncomplete) {
// remove blank signatures
signatures = signatures.filter(function (x) { return x !== ops.OP_0 })
}
return true
})
scriptSig = bscript.multisigInput(signatures, allowIncomplete ? undefined : input.redeemScript)
break
return match
})
default: return
}
// wrap as scriptHash if necessary
if (input.prevOutType === 'scripthash') {
scriptSig = bscript.scriptHashInput(scriptSig, input.redeemScript)
}
return scriptSig
}
function TransactionBuilder (network) {