TxBuilder: remove initialized field from signature inputs
This commit is contained in:
parent
fd2311bda4
commit
3a371fccec
2 changed files with 58 additions and 65 deletions
|
@ -33,21 +33,32 @@ function extractInput(txIn) {
|
|||
}
|
||||
|
||||
// Extract hashType, pubKeys and signatures
|
||||
var hashType, initialized, parsed, pubKeys, signatures
|
||||
var hashType, parsed, pubKeys, signatures
|
||||
|
||||
switch (scriptType) {
|
||||
case 'pubkeyhash':
|
||||
case 'pubkeyhash': {
|
||||
parsed = ECSignature.parseScriptSignature(scriptSig.chunks[0])
|
||||
hashType = parsed.hashType
|
||||
pubKeys = [ECPubKey.fromBuffer(scriptSig.chunks[1])]
|
||||
signatures = [parsed.signature]
|
||||
|
||||
initialized = true
|
||||
prevOutScript = pubKeys[0].getAddress().toOutputScript()
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'multisig':
|
||||
case 'pubkey': {
|
||||
parsed = ECSignature.parseScriptSignature(scriptSig.chunks[0])
|
||||
hashType = parsed.hashType
|
||||
signatures = [parsed.signature]
|
||||
|
||||
if (redeemScript) {
|
||||
pubKeys = [ECPubKey.fromBuffer(redeemScript.chunks[0])]
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'multisig': {
|
||||
signatures = scriptSig.chunks.slice(1).map(function(chunk) {
|
||||
if (chunk === ops.OP_0) return chunk
|
||||
|
||||
|
@ -62,31 +73,11 @@ function extractInput(txIn) {
|
|||
}
|
||||
|
||||
break
|
||||
|
||||
case 'pubkey':
|
||||
parsed = ECSignature.parseScriptSignature(scriptSig.chunks[0])
|
||||
hashType = parsed.hashType
|
||||
signatures = [parsed.signature]
|
||||
|
||||
initialized = true
|
||||
|
||||
if (redeemScript) {
|
||||
pubKeys = [ECPubKey.fromBuffer(redeemScript.chunks[0])]
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
default:
|
||||
if (redeemScript) {
|
||||
initialized = true
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
hashType: hashType,
|
||||
initialized: initialized,
|
||||
prevOutScript: prevOutScript,
|
||||
prevOutType: prevOutType,
|
||||
pubKeys: pubKeys,
|
||||
|
@ -222,38 +213,40 @@ TransactionBuilder.prototype.__build = function(allowIncomplete) {
|
|||
var scriptSig
|
||||
|
||||
if (!allowIncomplete) {
|
||||
assert(input.initialized, 'Transaction is not complete')
|
||||
assert(!!scriptType, 'Transaction is not complete')
|
||||
assert(scriptType in canSignTypes, scriptType + ' not supported')
|
||||
assert(input.signatures, 'Transaction is missing signatures')
|
||||
}
|
||||
|
||||
switch (scriptType) {
|
||||
case 'pubkeyhash':
|
||||
var pkhSignature = input.signatures[0].toScriptSignature(input.hashType)
|
||||
scriptSig = scripts.pubKeyHashInput(pkhSignature, input.pubKeys[0])
|
||||
break
|
||||
if (input.signatures) {
|
||||
switch (scriptType) {
|
||||
case 'pubkeyhash':
|
||||
var pkhSignature = input.signatures[0].toScriptSignature(input.hashType)
|
||||
scriptSig = scripts.pubKeyHashInput(pkhSignature, input.pubKeys[0])
|
||||
break
|
||||
|
||||
case 'multisig':
|
||||
// Array.prototype.map is sparse-compatible
|
||||
var msSignatures = input.signatures.map(function(signature) {
|
||||
return signature.toScriptSignature(input.hashType)
|
||||
})
|
||||
case 'multisig':
|
||||
// Array.prototype.map is sparse-compatible
|
||||
var msSignatures = input.signatures.map(function(signature) {
|
||||
return signature.toScriptSignature(input.hashType)
|
||||
})
|
||||
|
||||
// fill in blanks with OP_0
|
||||
for (var i = 0; i < msSignatures.length; ++i) {
|
||||
if (msSignatures[i]) continue
|
||||
// fill in blanks with OP_0
|
||||
for (var i = 0; i < msSignatures.length; ++i) {
|
||||
if (msSignatures[i]) continue
|
||||
|
||||
msSignatures[i] = ops.OP_0
|
||||
}
|
||||
msSignatures[i] = ops.OP_0
|
||||
}
|
||||
|
||||
var redeemScript = allowIncomplete ? undefined : input.redeemScript
|
||||
scriptSig = scripts.multisigInput(signatures, redeemScript)
|
||||
break
|
||||
var redeemScript = allowIncomplete ? undefined : input.redeemScript
|
||||
scriptSig = scripts.multisigInput(msSignatures, redeemScript)
|
||||
break
|
||||
|
||||
case 'pubkey':
|
||||
var pkSignature = input.signatures[0].toScriptSignature(input.hashType)
|
||||
scriptSig = scripts.pubKeyInput(pkSignature)
|
||||
break
|
||||
case 'pubkey':
|
||||
var pkSignature = input.signatures[0].toScriptSignature(input.hashType)
|
||||
scriptSig = scripts.pubKeyInput(pkSignature)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// if we built a scriptSig, wrap as scriptHash if necessary
|
||||
|
@ -277,18 +270,19 @@ TransactionBuilder.prototype.sign = function(index, privKey, redeemScript, hashT
|
|||
assert.equal(input.hashType, hashType, 'Inconsistent hashType')
|
||||
}
|
||||
|
||||
var initialized = input.prevOutScript &&
|
||||
input.prevOutType &&
|
||||
input.hashType &&
|
||||
input.pubKeys &&
|
||||
input.signatures
|
||||
|
||||
// are we already initialized?
|
||||
if (input.initialized) {
|
||||
if (initialized) {
|
||||
// redeemScript only needed to initialize, but if provided again, enforce consistency
|
||||
if (redeemScript) {
|
||||
assert.deepEqual(input.redeemScript, redeemScript, 'Inconsistent redeemScript')
|
||||
}
|
||||
|
||||
// if signatures already exist, enforce multisig scriptType
|
||||
if (input.signatures.length > 0) {
|
||||
assert.equal(input.scriptType, 'multisig', input.scriptType + ' doesn\'t support multiple signatures')
|
||||
}
|
||||
|
||||
// initialize it
|
||||
} else {
|
||||
if (redeemScript) {
|
||||
|
@ -344,26 +338,24 @@ TransactionBuilder.prototype.sign = function(index, privKey, redeemScript, hashT
|
|||
}
|
||||
|
||||
input.hashType = hashType
|
||||
input.initialized = true
|
||||
input.signatures = input.signatures || []
|
||||
}
|
||||
|
||||
// do we know how to sign this?
|
||||
assert(input.scriptType in canSignTypes, input.scriptType + ' not supported')
|
||||
|
||||
var signatureScript = input.redeemScript || input.prevOutScript
|
||||
var signatureHash = this.tx.hashForSignature(index, signatureScript, hashType)
|
||||
var signature = privKey.sign(signatureHash)
|
||||
|
||||
// enforce signing in order of public keys
|
||||
// enforce in order signing of public keys
|
||||
assert(input.pubKeys.some(function(pubKey, i) {
|
||||
if (!privKey.pub.Q.equals(pubKey.Q)) return false
|
||||
|
||||
assert(!input.signatures[i], 'Signature already exists')
|
||||
var signatureScript = input.redeemScript || input.prevOutScript
|
||||
var signatureHash = this.tx.hashForSignature(index, signatureScript, hashType)
|
||||
var signature = privKey.sign(signatureHash)
|
||||
input.signatures[i] = signature
|
||||
|
||||
return true
|
||||
}), 'privateKey cannot sign for this input')
|
||||
}, this), 'privateKey cannot sign for this input')
|
||||
}
|
||||
|
||||
module.exports = TransactionBuilder
|
||||
|
|
7
test/fixtures/transaction_builder.json
vendored
7
test/fixtures/transaction_builder.json
vendored
|
@ -206,7 +206,7 @@
|
|||
},
|
||||
{
|
||||
"description": "Incomplete transaction w/ prevTxScript defined",
|
||||
"exception": "Transaction is not complete",
|
||||
"exception": "Transaction is missing signatures",
|
||||
"alwaysThrows": true,
|
||||
"inputs": [
|
||||
{
|
||||
|
@ -240,7 +240,8 @@
|
|||
],
|
||||
"sign": [
|
||||
{
|
||||
"exception": "pubkeyhash doesn\\'t support multiple signatures",
|
||||
"description": "Too many signatures - pubKeyHash",
|
||||
"exception": "Signature already exists",
|
||||
"inputs": [
|
||||
{
|
||||
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
|
@ -406,6 +407,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "Too many signatures - scriptHash(multisig 1-of-1)",
|
||||
"exception": "Signature already exists",
|
||||
"inputs": [
|
||||
{
|
||||
|
@ -418,7 +420,6 @@
|
|||
},
|
||||
{
|
||||
"privKey": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
|
||||
"redeemScript": "OP_1 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 OP_1 OP_CHECKMULTISIG",
|
||||
"throws": true
|
||||
}
|
||||
]
|
||||
|
|
Loading…
Add table
Reference in a new issue