TxBuilder: extract extractSignatures to free function
This commit is contained in:
parent
75ca355d48
commit
906accdc0f
1 changed files with 70 additions and 61 deletions
|
@ -16,6 +16,71 @@ function TransactionBuilder() {
|
||||||
this.tx = new Transaction()
|
this.tx = new Transaction()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extractSignature(txIn) {
|
||||||
|
assert(!Array.prototype.every.call(txIn.hash, function(x) {
|
||||||
|
return x === 0
|
||||||
|
}), 'coinbase inputs not supported')
|
||||||
|
|
||||||
|
var redeemScript
|
||||||
|
var scriptSig = txIn.script
|
||||||
|
var scriptType = scripts.classifyInput(scriptSig, true)
|
||||||
|
|
||||||
|
// Re-classify if P2SH
|
||||||
|
if (scriptType === 'scripthash') {
|
||||||
|
redeemScript = Script.fromBuffer(scriptSig.chunks.slice(-1)[0])
|
||||||
|
scriptSig = Script.fromChunks(scriptSig.chunks.slice(0, -1))
|
||||||
|
|
||||||
|
scriptType = scripts.classifyInput(scriptSig, true)
|
||||||
|
assert.equal(scripts.classifyOutput(redeemScript), scriptType, 'Non-matching scriptSig and scriptPubKey in input')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract hashType, pubKeys and signatures
|
||||||
|
var hashType, parsed, pubKeys, signatures
|
||||||
|
|
||||||
|
switch (scriptType) {
|
||||||
|
case 'pubkeyhash':
|
||||||
|
parsed = ECSignature.parseScriptSignature(scriptSig.chunks[0])
|
||||||
|
var pubKey = ECPubKey.fromBuffer(scriptSig.chunks[1])
|
||||||
|
|
||||||
|
hashType = parsed.hashType
|
||||||
|
pubKeys = [pubKey]
|
||||||
|
signatures = [parsed.signature]
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'multisig':
|
||||||
|
parsed = scriptSig.chunks.slice(1).filter(function(chunk) {
|
||||||
|
return chunk !== ops.OP_0
|
||||||
|
}).map(ECSignature.parseScriptSignature)
|
||||||
|
|
||||||
|
hashType = parsed[0].hashType
|
||||||
|
pubKeys = []
|
||||||
|
signatures = parsed.map(function(p) { return p.signature })
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'pubkey':
|
||||||
|
parsed = ECSignature.parseScriptSignature(scriptSig.chunks[0])
|
||||||
|
|
||||||
|
hashType = parsed.hashType
|
||||||
|
pubKeys = []
|
||||||
|
signatures = [parsed.signature]
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(false, scriptType + ' inputs not supported')
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
hashType: hashType,
|
||||||
|
pubKeys: pubKeys,
|
||||||
|
redeemScript: redeemScript,
|
||||||
|
scriptType: scriptType,
|
||||||
|
signatures: signatures
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Static constructors
|
// Static constructors
|
||||||
TransactionBuilder.fromTransaction = function(transaction) {
|
TransactionBuilder.fromTransaction = function(transaction) {
|
||||||
var txb = new TransactionBuilder()
|
var txb = new TransactionBuilder()
|
||||||
|
@ -35,72 +100,16 @@ TransactionBuilder.fromTransaction = function(transaction) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Extract/add signatures
|
// Extract/add signatures
|
||||||
transaction.ins.forEach(function(txIn, i) {
|
txb.signatures = transaction.ins.map(function(txIn) {
|
||||||
// Ignore empty scripts
|
// Coinbase inputs not supported
|
||||||
if (txIn.script.buffer.length === 0) return
|
|
||||||
|
|
||||||
assert(!Array.prototype.every.call(txIn.hash, function(x) {
|
assert(!Array.prototype.every.call(txIn.hash, function(x) {
|
||||||
return x === 0
|
return x === 0
|
||||||
}), 'coinbase inputs not supported')
|
}), 'coinbase inputs not supported')
|
||||||
|
|
||||||
var redeemScript
|
// Ignore empty scripts
|
||||||
var scriptSig = txIn.script
|
if (txIn.script.buffer.length === 0) return
|
||||||
var scriptType = scripts.classifyInput(scriptSig, true)
|
|
||||||
|
|
||||||
// Re-classify if P2SH
|
return extractSignature(txIn)
|
||||||
if (scriptType === 'scripthash') {
|
|
||||||
redeemScript = Script.fromBuffer(scriptSig.chunks.slice(-1)[0])
|
|
||||||
scriptSig = Script.fromChunks(scriptSig.chunks.slice(0, -1))
|
|
||||||
|
|
||||||
scriptType = scripts.classifyInput(scriptSig, true)
|
|
||||||
assert.equal(scripts.classifyOutput(redeemScript), scriptType, 'Non-matching scriptSig and scriptPubKey in input')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract hashType, pubKeys and signatures
|
|
||||||
var hashType, parsed, pubKeys, signatures
|
|
||||||
|
|
||||||
switch (scriptType) {
|
|
||||||
case 'pubkeyhash':
|
|
||||||
parsed = ECSignature.parseScriptSignature(scriptSig.chunks[0])
|
|
||||||
var pubKey = ECPubKey.fromBuffer(scriptSig.chunks[1])
|
|
||||||
|
|
||||||
hashType = parsed.hashType
|
|
||||||
pubKeys = [pubKey]
|
|
||||||
signatures = [parsed.signature]
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'multisig':
|
|
||||||
parsed = scriptSig.chunks.slice(1).filter(function(chunk) {
|
|
||||||
return chunk !== ops.OP_0
|
|
||||||
}).map(ECSignature.parseScriptSignature)
|
|
||||||
|
|
||||||
hashType = parsed[0].hashType
|
|
||||||
pubKeys = []
|
|
||||||
signatures = parsed.map(function(p) { return p.signature })
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'pubkey':
|
|
||||||
parsed = ECSignature.parseScriptSignature(scriptSig.chunks[0])
|
|
||||||
|
|
||||||
hashType = parsed.hashType
|
|
||||||
pubKeys = []
|
|
||||||
signatures = [parsed.signature]
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert(false, scriptType + ' inputs not supported')
|
|
||||||
}
|
|
||||||
|
|
||||||
txb.signatures[i] = {
|
|
||||||
hashType: hashType,
|
|
||||||
pubKeys: pubKeys,
|
|
||||||
redeemScript: redeemScript,
|
|
||||||
scriptType: scriptType,
|
|
||||||
signatures: signatures
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return txb
|
return txb
|
||||||
|
|
Loading…
Add table
Reference in a new issue