Skip to content

Commit 22f8c8a

Browse files
committed
TxBuilder: re-order functions to project standard
1 parent 4f88980 commit 22f8c8a

File tree

1 file changed

+116
-114
lines changed

1 file changed

+116
-114
lines changed

src/transaction_builder.js

+116-114
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,90 @@ function TransactionBuilder() {
1515
this.tx = new Transaction()
1616
}
1717

18+
// Static constructors
19+
TransactionBuilder.fromTransaction = function(transaction) {
20+
var txb = new TransactionBuilder()
21+
22+
// Extract/add inputs
23+
transaction.ins.forEach(function(txin) {
24+
txb.addInput(txin.hash, txin.index, txin.sequence)
25+
})
26+
27+
// Extract/add outputs
28+
transaction.outs.forEach(function(txout) {
29+
txb.addOutput(txout.script, txout.value)
30+
})
31+
32+
// Extract/add signatures
33+
transaction.ins.forEach(function(txin) {
34+
// Ignore empty scripts
35+
if (txin.script.buffer.length === 0) return
36+
37+
var redeemScript
38+
var scriptSig = txin.script
39+
var scriptType = scripts.classifyInput(scriptSig)
40+
41+
// Re-classify if P2SH
42+
if (scriptType === 'scripthash') {
43+
redeemScript = Script.fromBuffer(scriptSig.chunks.slice(-1)[0])
44+
scriptSig = Script.fromChunks(scriptSig.chunks.slice(0, -1))
45+
46+
scriptType = scripts.classifyInput(scriptSig)
47+
assert.equal(scripts.classifyOutput(redeemScript), scriptType, 'Non-matching scriptSig and scriptPubKey in input')
48+
}
49+
50+
// Extract hashType, pubKeys and signatures
51+
var hashType, pubKeys, signatures
52+
53+
switch (scriptType) {
54+
case 'pubkeyhash':
55+
var parsed = ECSignature.parseScriptSignature(scriptSig.chunks[0])
56+
var pubKey = ECPubKey.fromBuffer(scriptSig.chunks[1])
57+
58+
hashType = parsed.hashType
59+
pubKeys = [pubKey]
60+
signatures = [parsed.signature]
61+
62+
break
63+
64+
case 'multisig':
65+
var scriptSigs = scriptSig.chunks.slice(1) // ignore OP_0
66+
var parsed = scriptSigs.map(function(scriptSig) {
67+
return ECSignature.parseScriptSignature(scriptSig)
68+
})
69+
70+
hashType = parsed[0].hashType
71+
pubKeys = []
72+
signatures = parsed.map(function(p) { return p.signature })
73+
74+
break
75+
76+
case 'pubkey':
77+
var parsed = ECSignature.parseScriptSignature(scriptSig.chunks[0])
78+
79+
hashType = parsed.hashType
80+
pubKeys = []
81+
signatures = [parsed.signature]
82+
83+
break
84+
85+
default:
86+
assert(false, scriptType + ' not supported')
87+
}
88+
89+
txb.signatures[txin.index] = {
90+
hashType: hashType,
91+
pubKeys: pubKeys,
92+
redeemScript: redeemScript,
93+
scriptType: scriptType,
94+
signatures: signatures
95+
}
96+
})
97+
98+
return txb
99+
}
100+
101+
// Operations
18102
TransactionBuilder.prototype.addInput = function(prevTx, index, sequence, prevOutScript) {
19103
var prevOutHash
20104

@@ -63,55 +147,6 @@ TransactionBuilder.prototype.addOutput = function(scriptPubKey, value) {
63147
return this.tx.addOutput(scriptPubKey, value)
64148
}
65149

66-
TransactionBuilder.prototype.sign = function(index, privKey, redeemScript, hashType) {
67-
assert(this.tx.ins.length >= index, 'No input at index: ' + index)
68-
hashType = hashType || Transaction.SIGHASH_ALL
69-
70-
var prevOutScript = this.prevOutScripts[index]
71-
var prevOutType = this.prevOutTypes[index]
72-
73-
var scriptType, hash
74-
if (redeemScript) {
75-
prevOutScript = prevOutScript || scripts.scriptHashOutput(redeemScript.getHash())
76-
prevOutType = prevOutType || 'scripthash'
77-
78-
assert.equal(prevOutType, 'scripthash', 'PrevOutScript must be P2SH')
79-
80-
scriptType = scripts.classifyOutput(redeemScript)
81-
82-
assert.notEqual(scriptType, 'scripthash', 'RedeemScript can\'t be P2SH')
83-
assert.notEqual(scriptType, 'nonstandard', 'RedeemScript not supported (nonstandard)')
84-
85-
hash = this.tx.hashForSignature(index, redeemScript, hashType)
86-
87-
} else {
88-
prevOutScript = prevOutScript || privKey.pub.getAddress().toOutputScript()
89-
scriptType = prevOutType || 'pubkeyhash'
90-
91-
assert.notEqual(scriptType, 'scripthash', 'PrevOutScript requires redeemScript')
92-
93-
hash = this.tx.hashForSignature(index, prevOutScript, hashType)
94-
}
95-
96-
if (!(index in this.signatures)) {
97-
this.signatures[index] = {
98-
hashType: hashType,
99-
pubKeys: [],
100-
redeemScript: redeemScript,
101-
scriptType: scriptType,
102-
signatures: []
103-
}
104-
}
105-
106-
var input = this.signatures[index]
107-
assert.equal(input.hashType, hashType, 'Inconsistent hashType')
108-
assert.deepEqual(input.redeemScript, redeemScript, 'Inconsistent redeemScript')
109-
110-
var signature = privKey.sign(hash)
111-
input.pubKeys.push(privKey.pub)
112-
input.signatures.push(signature)
113-
}
114-
115150
TransactionBuilder.prototype.build = function() {
116151
return this.__build(false)
117152
}
@@ -173,86 +208,53 @@ TransactionBuilder.prototype.__build = function(allowIncomplete) {
173208
return tx
174209
}
175210

176-
TransactionBuilder.fromTransaction = function(transaction) {
177-
var txb = new TransactionBuilder()
178-
179-
// Extract/add inputs
180-
transaction.ins.forEach(function(txin) {
181-
txb.addInput(txin.hash, txin.index, txin.sequence)
182-
})
183-
184-
// Extract/add outputs
185-
transaction.outs.forEach(function(txout) {
186-
txb.addOutput(txout.script, txout.value)
187-
})
188-
189-
// Extract/add signatures
190-
transaction.ins.forEach(function(txin) {
191-
// Ignore empty scripts
192-
if (txin.script.buffer.length === 0) return
193-
194-
var redeemScript
195-
var scriptSig = txin.script
196-
var scriptType = scripts.classifyInput(scriptSig)
197-
198-
// Re-classify if P2SH
199-
if (scriptType === 'scripthash') {
200-
redeemScript = Script.fromBuffer(scriptSig.chunks.slice(-1)[0])
201-
scriptSig = Script.fromChunks(scriptSig.chunks.slice(0, -1))
202-
203-
scriptType = scripts.classifyInput(scriptSig)
204-
assert.equal(scripts.classifyOutput(redeemScript), scriptType, 'Non-matching scriptSig and scriptPubKey in input')
205-
}
206-
207-
// Extract hashType, pubKeys and signatures
208-
var hashType, pubKeys, signatures
209-
210-
switch (scriptType) {
211-
case 'pubkeyhash':
212-
var parsed = ECSignature.parseScriptSignature(scriptSig.chunks[0])
213-
var pubKey = ECPubKey.fromBuffer(scriptSig.chunks[1])
211+
TransactionBuilder.prototype.sign = function(index, privKey, redeemScript, hashType) {
212+
assert(this.tx.ins.length >= index, 'No input at index: ' + index)
213+
hashType = hashType || Transaction.SIGHASH_ALL
214214

215-
hashType = parsed.hashType
216-
pubKeys = [pubKey]
217-
signatures = [parsed.signature]
215+
var prevOutScript = this.prevOutScripts[index]
216+
var prevOutType = this.prevOutTypes[index]
218217

219-
break
218+
var scriptType, hash
219+
if (redeemScript) {
220+
prevOutScript = prevOutScript || scripts.scriptHashOutput(redeemScript.getHash())
221+
prevOutType = prevOutType || 'scripthash'
220222

221-
case 'multisig':
222-
var scriptSigs = scriptSig.chunks.slice(1) // ignore OP_0
223-
var parsed = scriptSigs.map(function(scriptSig) {
224-
return ECSignature.parseScriptSignature(scriptSig)
225-
})
223+
assert.equal(prevOutType, 'scripthash', 'PrevOutScript must be P2SH')
226224

227-
hashType = parsed[0].hashType
228-
pubKeys = []
229-
signatures = parsed.map(function(p) { return p.signature })
225+
scriptType = scripts.classifyOutput(redeemScript)
230226

231-
break
227+
assert.notEqual(scriptType, 'scripthash', 'RedeemScript can\'t be P2SH')
228+
assert.notEqual(scriptType, 'nonstandard', 'RedeemScript not supported (nonstandard)')
232229

233-
case 'pubkey':
234-
var parsed = ECSignature.parseScriptSignature(scriptSig.chunks[0])
230+
hash = this.tx.hashForSignature(index, redeemScript, hashType)
235231

236-
hashType = parsed.hashType
237-
pubKeys = []
238-
signatures = [parsed.signature]
232+
} else {
233+
prevOutScript = prevOutScript || privKey.pub.getAddress().toOutputScript()
234+
scriptType = prevOutType || 'pubkeyhash'
239235

240-
break
236+
assert.notEqual(scriptType, 'scripthash', 'PrevOutScript requires redeemScript')
241237

242-
default:
243-
assert(false, scriptType + ' not supported')
244-
}
238+
hash = this.tx.hashForSignature(index, prevOutScript, hashType)
239+
}
245240

246-
txb.signatures[txin.index] = {
241+
if (!(index in this.signatures)) {
242+
this.signatures[index] = {
247243
hashType: hashType,
248-
pubKeys: pubKeys,
244+
pubKeys: [],
249245
redeemScript: redeemScript,
250246
scriptType: scriptType,
251-
signatures: signatures
247+
signatures: []
252248
}
253-
})
249+
}
254250

255-
return txb
251+
var input = this.signatures[index]
252+
assert.equal(input.hashType, hashType, 'Inconsistent hashType')
253+
assert.deepEqual(input.redeemScript, redeemScript, 'Inconsistent redeemScript')
254+
255+
var signature = privKey.sign(hash)
256+
input.pubKeys.push(privKey.pub)
257+
input.signatures.push(signature)
256258
}
257259

258260
module.exports = TransactionBuilder

0 commit comments

Comments
 (0)