Browse Source

TxBuilder: remove initialized field from signature inputs

hk-custom-address
Daniel Cousens 10 years ago
parent
commit
3a371fccec
  1. 116
      src/transaction_builder.js
  2. 7
      test/fixtures/transaction_builder.json

116
src/transaction_builder.js

@ -33,60 +33,51 @@ 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':
signatures = scriptSig.chunks.slice(1).map(function(chunk) {
if (chunk === ops.OP_0) return chunk
var parsed = ECSignature.parseScriptSignature(chunk)
hashType = parsed.hashType
return parsed.signature
})
if (redeemScript) {
pubKeys = redeemScript.chunks.slice(1, -2).map(ECPubKey.fromBuffer)
}
break
case 'pubkey':
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
}
case 'multisig': {
signatures = scriptSig.chunks.slice(1).map(function(chunk) {
if (chunk === ops.OP_0) return chunk
var parsed = ECSignature.parseScriptSignature(chunk)
hashType = parsed.hashType
return parsed.signature
})
default:
if (redeemScript) {
initialized = true
pubKeys = redeemScript.chunks.slice(1, -2).map(ECPubKey.fromBuffer)
}
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

@ -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…
Cancel
Save