1 package txscript
2 3 import (
4 "bytes"
5 "encoding/binary"
6 "fmt"
7 "time"
8 9 "github.com/p9c/p9/pkg/chainhash"
10 "github.com/p9c/p9/pkg/wire"
11 )
12 13 // Bip16Activation is the timestamp where BIP0016 is valid to use in the blockchain. To be used to determine if BIP0016
14 // should be called for or not. This timestamp corresponds to Sun Apr 1 00:00:00 UTC 2012.
15 var Bip16Activation = time.Unix(1333238400, 0)
16 17 type // SigHashType represents hash type bits at the end of a signature.
18 SigHashType uint32
19 20 const ( // Hash type bits from the end of a signature.
21 SigHashOld SigHashType = 0x0
22 SigHashAll SigHashType = 0x1
23 SigHashNone SigHashType = 0x2
24 SigHashSingle SigHashType = 0x3
25 SigHashAnyOneCanPay SigHashType = 0x80
26 // sigHashMask defines the number of bits of the hash type which is used to identify which outputs are signed.
27 sigHashMask = 0x1f
28 29 // These are the constants specified for maximums in individual scripts.
30 31 MaxOpsPerScript = 201 // Max number of non-push operations.
32 MaxPubKeysPerMultiSig = 20 // Multisig can't have more sigs than this.
33 MaxScriptElementSize = 520 // Max bytes pushable to the stack.
34 )
35 36 // isSmallInt returns whether or not the opcode is considered a small integer, which is an OP_0, or OP_1 through OP_16.
37 func isSmallInt(op *opcode) bool {
38 if op.value == OP_0 || (op.value >= OP_1 && op.value <= OP_16) {
39 return true
40 }
41 return false
42 }
43 44 // isScriptHash returns true if the script passed is a pay-to-script -hash transaction, false otherwise.
45 func isScriptHash(pops []parsedOpcode) bool {
46 return len(pops) == 3 &&
47 pops[0].opcode.value == OP_HASH160 &&
48 pops[1].opcode.value == OP_DATA_20 &&
49 pops[2].opcode.value == OP_EQUAL
50 }
51 52 // IsPayToScriptHash returns true if the script is in the standard pay -to-script-hash (P2SH) format, false otherwise.
53 func IsPayToScriptHash(script []byte) bool {
54 pops, e := parseScript(script)
55 if e != nil {
56 return false
57 }
58 return isScriptHash(pops)
59 }
60 61 // isWitnessScriptHash returns true if the passed script is a pay-to
62 // -witness-script-hash transaction, false otherwise.
63 func isWitnessScriptHash(pops []parsedOpcode) bool {
64 return len(pops) == 2 &&
65 pops[0].opcode.value == OP_0 &&
66 pops[1].opcode.value == OP_DATA_32
67 }
68 69 // IsPayToWitnessScriptHash returns true if the is in the standard pay
70 // -to-witness-script-hash (P2WSH) format, false otherwise.
71 func IsPayToWitnessScriptHash(script []byte) bool {
72 pops, e := parseScript(script)
73 if e != nil {
74 return false
75 }
76 return isWitnessScriptHash(pops)
77 }
78 79 // IsPayToWitnessPubKeyHash returns true if the is in the standard pay
80 // -to-witness-pubkey-hash (P2WKH) format, false otherwise.
81 func IsPayToWitnessPubKeyHash(script []byte) bool {
82 pops, e := parseScript(script)
83 if e != nil {
84 return false
85 }
86 return isWitnessPubKeyHash(pops)
87 }
88 89 // isWitnessPubKeyHash returns true if the passed script is a pay-to
90 // -witness-pubkey-hash, and false otherwise.
91 func isWitnessPubKeyHash(pops []parsedOpcode) bool {
92 return len(pops) == 2 &&
93 pops[0].opcode.value == OP_0 &&
94 pops[1].opcode.value == OP_DATA_20
95 }
96 97 // IsWitnessProgram returns true if the passed script is a valid witness program
98 // which is encoded according to the passed witness program version. A witness
99 // program must be a small integer (from 0-16), followed by 2-40 bytes of pushed
100 // data.
101 func IsWitnessProgram(script []byte) bool {
102 // The length of the script must be between 4 and 42 bytes. The smallest program
103 // is the witness version, followed by a data push of 2 bytes. The largest
104 // allowed witness program has a data push of 40-bytes.
105 if len(script) < 4 || len(script) > 42 {
106 return false
107 }
108 pops, e := parseScript(script)
109 if e != nil {
110 return false
111 }
112 return isWitnessProgram(pops)
113 }
114 115 // isWitnessProgram returns true if the passed script is a witness program, and
116 // false otherwise. A witness program MUST adhere to the following constraints:
117 // there must be exactly two pops (program version and the program itself), the
118 // first opcode MUST be a small integer (0-16), the push data MUST be canonical,
119 // and finally the size of the push data must be between 2 and 40 bytes.
120 func isWitnessProgram(pops []parsedOpcode) bool {
121 return len(pops) == 2 &&
122 isSmallInt(pops[0].opcode) &&
123 canonicalPush(pops[1]) &&
124 (len(pops[1].data) >= 2 && len(pops[1].data) <= 40)
125 }
126 127 // // ExtractWitnessProgramInfo attempts to extract the witness program version, as
128 // // well as the witness program itself from the passed script.
129 // func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) {
130 // pops, e := parseScript(script)
131 // if e != nil {
132 // return 0, nil, e
133 // }
134 // // If at this point, the scripts doesn't resemble a witness program, then we'll
135 // // exit early as there isn't a valid version or program to extract.
136 // if !isWitnessProgram(pops) {
137 // return 0, nil, fmt.Errorf(
138 // "script is not a witness program, " +
139 // "unable to extract version or witness program",
140 // )
141 // }
142 // witnessVersion := asSmallInt(pops[0].opcode)
143 // witnessProgram := pops[1].data
144 // return witnessVersion, witnessProgram, nil
145 // }
146 147 func isPushOnly(pops []parsedOpcode) bool {
148 // isPushOnly returns true if the script only pushes data, false otherwise. NOTE: This function does NOT verify
149 // opcodes directly since it is internal and is only called with parsed opcodes for scripts that did not have any
150 // parse errors. Thus, consensus is properly maintained.
151 for _, pop := range pops {
152 // All opcodes up to OP_16 are data push instructions. NOTE: This does consider OP_RESERVED to be a data push
153 // instruction but execution of OP_RESERVED will fail anyways and matches the behavior required by consensus.
154 if pop.opcode.value > OP_16 {
155 return false
156 }
157 }
158 return true
159 }
160 161 func IsPushOnlyScript(script []byte) bool {
162 // IsPushOnlyScript returns whether or not the passed script only pushes data. False will be returned when the
163 // script does not parse.
164 pops, e := parseScript(script)
165 if e != nil {
166 return false
167 }
168 return isPushOnly(pops)
169 }
170 171 // ParseScriptTemplate is the same as parseScript but allows the passing of the template list for testing purposes. When
172 // there are parse errors, it returns the list of parsed opcodes up to the point of failure along with the error.
173 func ParseScriptTemplate(script []byte, opcodes *[256]opcode) ([]parsedOpcode, error) {
174 retScript := make([]parsedOpcode, 0, len(script))
175 for i := 0; i < len(script); {
176 instr := script[i]
177 op := &opcodes[instr]
178 pop := parsedOpcode{opcode: op}
179 // Parse data out of instruction.
180 switch {
181 // No additional data. Note that some of the opcodes,
182 // notably OP_1NEGATE, OP_0,
183 // and OP_[1-16] represent the data themselves.
184 case op.length == 1:
185 i++
186 // Data pushes of specific lengths -- OP_DATA_[1-75].
187 case op.length > 1:
188 if len(script[i:]) < op.length {
189 str := fmt.Sprintf(
190 "opcode %s requires %d "+
191 "bytes, but script only has %d remaining",
192 op.name, op.length, len(script[i:]),
193 )
194 return retScript, scriptError(
195 ErrMalformedPush,
196 str,
197 )
198 }
199 // Slice out the data.
200 pop.data = script[i+1 : i+op.length]
201 i += op.length
202 // Data pushes with parsed lengths -- OP_PUSHDATAP{1,2,4}.
203 case op.length < 0:
204 var l uint
205 off := i + 1
206 if len(script[off:]) < -op.length {
207 str := fmt.Sprintf(
208 "opcode %s requires %d "+
209 "bytes, but script only has %d remaining",
210 op.name, -op.length, len(script[off:]),
211 )
212 return retScript, scriptError(
213 ErrMalformedPush,
214 str,
215 )
216 }
217 // Next -length bytes are little endian length of data.
218 switch op.length {
219 case -1:
220 l = uint(script[off])
221 case -2:
222 l = (uint(script[off+1]) << 8) |
223 uint(script[off])
224 case -4:
225 l = (uint(script[off+3]) << 24) |
226 (uint(script[off+2]) << 16) |
227 (uint(script[off+1]) << 8) |
228 uint(script[off])
229 default:
230 str := fmt.Sprintf(
231 "invalid opcode length %d",
232 op.length,
233 )
234 return retScript, scriptError(
235 ErrMalformedPush,
236 str,
237 )
238 }
239 // Move offset to beginning of the data.
240 off += -op.length
241 // Disallow entries that do not fit script or were sign extended.
242 if int(l) > len(script[off:]) || int(l) < 0 {
243 str := fmt.Sprintf(
244 "opcode %s pushes %d bytes, "+
245 "but script only has %d remaining",
246 op.name, int(l), len(script[off:]),
247 )
248 return retScript, scriptError(
249 ErrMalformedPush,
250 str,
251 )
252 }
253 pop.data = script[off : off+int(l)]
254 i += 1 - op.length + int(l)
255 }
256 retScript = append(retScript, pop)
257 }
258 return retScript, nil
259 }
260 261 // parseScript preparses the script in bytes into a list of parsedOpcodes while applying a number of sanity checks.
262 func parseScript(script []byte) ([]parsedOpcode, error) {
263 return ParseScriptTemplate(script, &OpcodeArray)
264 }
265 266 // unparseScript reversed the action of parseScript and returns the parsedOpcodes as a list of bytes
267 func unparseScript(pops []parsedOpcode) ([]byte, error) {
268 script := make([]byte, 0, len(pops))
269 for _, pop := range pops {
270 b, e := pop.bytes()
271 if e != nil {
272 return nil, e
273 }
274 script = append(script, b...)
275 }
276 return script, nil
277 }
278 279 // DisasmString formats a disassembled script for one line printing. When the script fails to parse, the returned string
280 // will contain the disassembled script up to the point the failure occurred along with the string '[error]' appended.
281 // In addition, the reason the script failed to parse is returned if the caller wants more information about the
282 // failure.
283 func DisasmString(buf []byte) (string, error) {
284 var disbuf bytes.Buffer
285 opcodes, e := parseScript(buf)
286 for _, pop := range opcodes {
287 disbuf.WriteString(pop.print(true))
288 disbuf.WriteByte(' ')
289 }
290 if disbuf.Len() > 0 {
291 disbuf.Truncate(disbuf.Len() - 1)
292 }
293 if e != nil {
294 disbuf.WriteString("[error]")
295 }
296 return disbuf.String(), e
297 }
298 299 // removeOpcode will remove any opcode matching ``opcode'' from the
300 // opcode stream in pkscript
301 func removeOpcode(pkscript []parsedOpcode, opcode byte) []parsedOpcode {
302 retScript := make([]parsedOpcode, 0, len(pkscript))
303 for _, pop := range pkscript {
304 if pop.opcode.value != opcode {
305 retScript = append(retScript, pop)
306 }
307 }
308 return retScript
309 }
310 311 // canonicalPush returns true if the object is either not a push instruction or the push instruction contained wherein
312 // is matches the canonical form or using the smallest instruction to do the job. False otherwise.
313 func canonicalPush(pop parsedOpcode) bool {
314 opcode := pop.opcode.value
315 data := pop.data
316 dataLen := len(pop.data)
317 if opcode > OP_16 {
318 return true
319 }
320 if opcode < OP_PUSHDATA1 && opcode > OP_0 && (dataLen == 1 && data[0] <= 16) {
321 return false
322 }
323 if opcode == OP_PUSHDATA1 && dataLen < OP_PUSHDATA1 {
324 return false
325 }
326 if opcode == OP_PUSHDATA2 && dataLen <= 0xff {
327 return false
328 }
329 if opcode == OP_PUSHDATA4 && dataLen <= 0xffff {
330 return false
331 }
332 return true
333 }
334 335 // removeOpcodeByData will return the script minus any opcodes that would push the passed data to the stack.
336 func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode {
337 retScript := make([]parsedOpcode, 0, len(pkscript))
338 for _, pop := range pkscript {
339 if !canonicalPush(pop) || !bytes.Contains(pop.data, data) {
340 retScript = append(retScript, pop)
341 }
342 }
343 return retScript
344 }
345 346 // calcHashPrevOuts calculates a single hash of all the previous outputs (txid:index) referenced within the passed
347 // transaction. This calculated hash can be re-used when validating all inputs spending segwit outputs, with a signature
348 // hash type of SigHashAll. This allows validation to re-use previous hashing computation, reducing the complexity of
349 // validating SigHashAll inputs from O(N^2) to O(N).
350 func calcHashPrevOuts(tx *wire.MsgTx) chainhash.Hash {
351 var b bytes.Buffer
352 for _, in := range tx.TxIn {
353 // First write out the 32-byte transaction ID one of whose outputs are being referenced by this input.
354 b.Write(in.PreviousOutPoint.Hash[:])
355 // Next, we'll encode the index of the referenced output as a little endian integer.
356 var buf [4]byte
357 binary.LittleEndian.PutUint32(buf[:], in.PreviousOutPoint.Index)
358 b.Write(buf[:])
359 }
360 return chainhash.DoubleHashH(b.Bytes())
361 }
362 363 // calcHashSequence computes an aggregated hash of each of the sequence numbers within the inputs of the passed
364 // transaction. This single hash can be re-used when validating all inputs spending segwit outputs, which include
365 // signatures using the SigHashAll sighash type. This allows validation to re-use previous hashing computation, reducing
366 // the complexity of validating SigHashAll inputs from O(N^2) to O(N).
367 func calcHashSequence(tx *wire.MsgTx) chainhash.Hash {
368 var b bytes.Buffer
369 for _, in := range tx.TxIn {
370 var buf [4]byte
371 binary.LittleEndian.PutUint32(buf[:], in.Sequence)
372 b.Write(buf[:])
373 }
374 return chainhash.DoubleHashH(b.Bytes())
375 }
376 377 // calcHashOutputs computes a hash digest of all outputs created by the
378 // transaction encoded using the wire format. This single hash can be re-used
379 // when validating all inputs spending witness programs, which include
380 // signatures using the SigHashAll sighash type. This allows computation to be
381 // cached, reducing the total hashing complexity from O(N^2) to O(N).
382 func calcHashOutputs(tx *wire.MsgTx) chainhash.Hash {
383 var b bytes.Buffer
384 for _, out := range tx.TxOut {
385 e := wire.WriteTxOut(&b, 0, 0, out)
386 if e != nil {
387 }
388 }
389 return chainhash.DoubleHashH(b.Bytes())
390 }
391 392 // calcWitnessSignatureHash computes the sighash digest of a transaction's
393 // segwit input using the new optimized digest calculation algorithm defined in
394 // BIP0143: https://github.// com/bitcoin/bips/blob/master/bip-0143.mediawiki
395 // This function makes use of pre-calculated sighash fragments stored within the
396 // passed HashCache to eliminate duplicate hashing computations when calculating
397 // the final digest, reducing the complexity from O(N^2) to O(N). Additionally,
398 // signatures now cover the input value of the referenced unspent output. This
399 // allows offline or hardware wallets to compute the exact amount being spent in
400 // addition to the final transaction fee. In the case the wallet if fed an
401 // invalid input amount, the real sighash will differ causing the produced
402 // signature to be invalid.
403 func calcWitnessSignatureHash(
404 subScript []parsedOpcode,
405 sigHashes *TxSigHashes,
406 hashType SigHashType,
407 tx *wire.MsgTx,
408 idx int,
409 amt int64,
410 ) ([]byte, error) {
411 // As a sanity check,
412 // ensure the passed input index for the transaction is valid.
413 if idx > len(tx.TxIn)-1 {
414 return nil, fmt.Errorf("idx %d but %d txins", idx, len(tx.TxIn))
415 }
416 // We'll utilize this buffer throughout to incrementally calculate the signature hash for this transaction.
417 var sigHash bytes.Buffer
418 // First write out, then encode the transaction's version number.
419 var bVersion [4]byte
420 binary.LittleEndian.PutUint32(bVersion[:], uint32(tx.Version))
421 sigHash.Write(bVersion[:])
422 // Next write out the possibly pre-calculated hashes for the sequence numbers of all inputs, and the hashes of the
423 // previous outs for all outputs.
424 var zeroHash chainhash.Hash
425 // If anyone can pay isn't active, then we can use the cached hashPrevOuts, otherwise we just write zeroes for the
426 // prev outs.
427 if hashType&SigHashAnyOneCanPay == 0 {
428 sigHash.Write(sigHashes.HashPrevOuts[:])
429 } else {
430 sigHash.Write(zeroHash[:])
431 }
432 // If the sighash isn't anyone can pay, single, or none, the use the cached hash sequences, otherwise write all
433 // zeroes for the hashSequence.
434 if hashType&SigHashAnyOneCanPay == 0 &&
435 hashType&sigHashMask != SigHashSingle &&
436 hashType&sigHashMask != SigHashNone {
437 sigHash.Write(sigHashes.HashSequence[:])
438 } else {
439 sigHash.Write(zeroHash[:])
440 }
441 txIn := tx.TxIn[idx]
442 // Next, write the outpoint being spent.
443 sigHash.Write(txIn.PreviousOutPoint.Hash[:])
444 var bIndex [4]byte
445 binary.LittleEndian.PutUint32(bIndex[:], txIn.PreviousOutPoint.Index)
446 sigHash.Write(bIndex[:])
447 if isWitnessPubKeyHash(subScript) {
448 // The script code for a p2wkh is a length prefix varint for the next 25 bytes, followed by a re-creation of the
449 // original p2pkh pk script.
450 sigHash.Write([]byte{0x19})
451 sigHash.Write([]byte{OP_DUP})
452 sigHash.Write([]byte{OP_HASH160})
453 sigHash.Write([]byte{OP_DATA_20})
454 sigHash.Write(subScript[1].data)
455 sigHash.Write([]byte{OP_EQUALVERIFY})
456 sigHash.Write([]byte{OP_CHECKSIG})
457 } else {
458 // For p2wsh outputs, and future outputs, the script code is the original script, with all code separators
459 // removed, serialized with a var int length prefix.
460 rawScript, _ := unparseScript(subScript)
461 e := wire.WriteVarBytes(&sigHash, 0, rawScript)
462 if e != nil {
463 }
464 }
465 // Next, add the input amount, and sequence number of the input being signed.
466 var bAmount [8]byte
467 binary.LittleEndian.PutUint64(bAmount[:], uint64(amt))
468 sigHash.Write(bAmount[:])
469 var bSequence [4]byte
470 binary.LittleEndian.PutUint32(bSequence[:], txIn.Sequence)
471 sigHash.Write(bSequence[:])
472 // If the current signature mode isn't single, or none, then we can re-use the pre-generated hashoutputs sighash
473 // fragment. Otherwise, we'll serialize and add only the target output index to the signature pre-image.
474 if hashType&SigHashSingle != SigHashSingle &&
475 hashType&SigHashNone != SigHashNone {
476 sigHash.Write(sigHashes.HashOutputs[:])
477 } else if hashType&sigHashMask == SigHashSingle && idx < len(tx.TxOut) {
478 var b bytes.Buffer
479 e := wire.WriteTxOut(&b, 0, 0, tx.TxOut[idx])
480 if e != nil {
481 }
482 sigHash.Write(chainhash.DoubleHashB(b.Bytes()))
483 } else {
484 sigHash.Write(zeroHash[:])
485 }
486 // Finally, write out the transaction's locktime, and the sig hash type.
487 var bLockTime [4]byte
488 binary.LittleEndian.PutUint32(bLockTime[:], tx.LockTime)
489 sigHash.Write(bLockTime[:])
490 var bHashType [4]byte
491 binary.LittleEndian.PutUint32(bHashType[:], uint32(hashType))
492 sigHash.Write(bHashType[:])
493 return chainhash.DoubleHashB(sigHash.Bytes()), nil
494 }
495 496 // CalcWitnessSigHash computes the sighash digest for the specified input of the
497 // target transaction observing the desired sig hash type.
498 func CalcWitnessSigHash(
499 script []byte,
500 sigHashes *TxSigHashes,
501 hType SigHashType,
502 tx *wire.MsgTx,
503 idx int,
504 amt int64,
505 ) ([]byte, error) {
506 parsedScript, e := parseScript(script)
507 if e != nil {
508 return nil, fmt.Errorf("cannot parse output script: %v", e)
509 }
510 return calcWitnessSignatureHash(
511 parsedScript, sigHashes, hType, tx, idx,
512 amt,
513 )
514 }
515 516 // shallowCopyTx creates a shallow copy of the transaction for use when calculating the signature hash. It is used over
517 // the Copy method on the transaction itself since that is a deep copy and therefore does more work and allocates much
518 // more space than needed.
519 func shallowCopyTx(tx *wire.MsgTx) wire.MsgTx {
520 // As an additional memory optimization, use contiguous backing arrays for the copied inputs and outputs and point
521 // the final slice of pointers into the contiguous arrays. This avoids a lot of small allocations.
522 txCopy := wire.MsgTx{
523 Version: tx.Version,
524 TxIn: make([]*wire.TxIn, len(tx.TxIn)),
525 TxOut: make([]*wire.TxOut, len(tx.TxOut)),
526 LockTime: tx.LockTime,
527 }
528 txIns := make([]wire.TxIn, len(tx.TxIn))
529 for i, oldTxIn := range tx.TxIn {
530 txIns[i] = *oldTxIn
531 txCopy.TxIn[i] = &txIns[i]
532 }
533 txOuts := make([]wire.TxOut, len(tx.TxOut))
534 for i, oldTxOut := range tx.TxOut {
535 txOuts[i] = *oldTxOut
536 txCopy.TxOut[i] = &txOuts[i]
537 }
538 return txCopy
539 }
540 541 // CalcSignatureHash will given a script and hash type for the current script engine instance calculate the signature
542 // hash to be used for signing and verification.
543 func CalcSignatureHash(script []byte, hashType SigHashType, tx *wire.MsgTx, idx int) ([]byte, error) {
544 parsedScript, e := parseScript(script)
545 if e != nil {
546 return nil, fmt.Errorf("cannot parse output script: %v", e)
547 }
548 return calcSignatureHash(parsedScript, hashType, tx, idx), nil
549 }
550 551 // calcSignatureHash will given a script and hash type for the current script engine instance calculate the signature
552 // hash to be used for signing and verification.
553 func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.MsgTx, idx int) []byte {
554 // The SigHashSingle signature type signs only the corresponding input and output (the output with the same index
555 // number as the input). Since transactions can have more inputs than outputs, this means it is improper to use
556 // SigHashSingle on input indices that don't have a corresponding output. A bug in the original Satoshi client
557 // implementation means specifying an index that is out of range results in a signature hash of 1 ( as a uint256
558 // little endian). The original intent appeared to be to indicate failure, but unfortunately, it was never checked
559 // and thus is treated as the actual signature hash. This buggy behavior is now part of the consensus and a hard
560 // fork would be required to fix it. Due to this, care must be taken by software that creates transactions which
561 // make use of SigHashSingle because it can lead to an extremely dangerous situation where the invalid inputs will
562 // end up signing a hash of 1. This in turn presents an opportunity for attackers to cleverly construct transactions
563 // which can steal those coins provided they can reuse signatures.
564 if hashType&sigHashMask == SigHashSingle && idx >= len(tx.TxOut) {
565 var hash chainhash.Hash
566 hash[0] = 0x01
567 return hash[:]
568 }
569 // Remove all instances of OP_CODESEPARATOR from the script.
570 script = removeOpcode(script, OP_CODESEPARATOR)
571 // Make a shallow copy of the transaction, zeroing out the script for all inputs that are not currently being
572 // processed.
573 txCopy := shallowCopyTx(tx)
574 for i := range txCopy.TxIn {
575 if i == idx {
576 // UnparseScript cannot fail here because removeOpcode above only returns a valid script.
577 sigScript, _ := unparseScript(script)
578 txCopy.TxIn[idx].SignatureScript = sigScript
579 } else {
580 txCopy.TxIn[i].SignatureScript = nil
581 }
582 }
583 switch hashType & sigHashMask {
584 case SigHashNone:
585 txCopy.TxOut = txCopy.TxOut[0:0] // Empty slice.
586 for i := range txCopy.TxIn {
587 if i != idx {
588 txCopy.TxIn[i].Sequence = 0
589 }
590 }
591 case SigHashSingle:
592 // Resize output array to up to and including requested index.
593 txCopy.TxOut = txCopy.TxOut[:idx+1]
594 // All but current output get zeroed out.
595 for i := 0; i < idx; i++ {
596 txCopy.TxOut[i].Value = -1
597 txCopy.TxOut[i].PkScript = nil
598 }
599 // Sequence on all other inputs is 0, too.
600 for i := range txCopy.TxIn {
601 if i != idx {
602 txCopy.TxIn[i].Sequence = 0
603 }
604 }
605 default:
606 // Consensus treats undefined hashtypes like normal SigHashAll for purposes of hash generation.
607 fallthrough
608 case SigHashOld:
609 fallthrough
610 case SigHashAll:
611 // Nothing special here.
612 }
613 if hashType&SigHashAnyOneCanPay != 0 {
614 txCopy.TxIn = txCopy.TxIn[idx : idx+1]
615 }
616 // The final hash is the double sha256 of both the serialized modified transaction and the hash type ( encoded as a
617 // 4-byte little-endian value) appended.
618 wbuf := bytes.NewBuffer(make([]byte, 0, txCopy.SerializeSizeStripped()+4))
619 e := txCopy.SerializeNoWitness(wbuf)
620 if e != nil {
621 }
622 e = binary.Write(wbuf, binary.LittleEndian, hashType)
623 if e != nil {
624 }
625 return chainhash.DoubleHashB(wbuf.Bytes())
626 }
627 628 // asSmallInt returns the passed opcode which must be true according to isSmallInt(), as an integer.
629 func asSmallInt(op *opcode) int {
630 if op.value == OP_0 {
631 return 0
632 }
633 return int(op.value - (OP_1 - 1))
634 }
635 636 // getSigOpCount is the implementation function for counting the number of signature operations in the script provided
637 // by pops. If precise mode is requested then we attempt to count the number of operations for a multisig op. Otherwise
638 // we use the maximum.
639 func getSigOpCount(pops []parsedOpcode, precise bool) int {
640 nSigs := 0
641 for i, pop := range pops {
642 switch pop.opcode.value {
643 case OP_CHECKSIG:
644 fallthrough
645 case OP_CHECKSIGVERIFY:
646 nSigs++
647 case OP_CHECKMULTISIG:
648 fallthrough
649 case OP_CHECKMULTISIGVERIFY:
650 // If we are being precise then look for familiar patterns for multisig, for now all we recognize is OP_1 -
651 // OP_16 to signify the number of pubkeys. Otherwise, we use the max of 20.
652 if precise && i > 0 &&
653 pops[i-1].opcode.value >= OP_1 &&
654 pops[i-1].opcode.value <= OP_16 {
655 nSigs += asSmallInt(pops[i-1].opcode)
656 } else {
657 nSigs += MaxPubKeysPerMultiSig
658 }
659 default:
660 // Not a sigop.
661 }
662 }
663 return nSigs
664 }
665 666 // GetSigOpCount provides a quick count of the number of signature operations in a script. a CHECKSIG operations counts
667 // for 1, and a CHECK_MULTISIG for 20. If the script fails to parse, then the count up to the point of failure is
668 // returned.
669 func GetSigOpCount(script []byte) int {
670 // Don't check error since parseScript returns the parsed-up-to-error list of pops.
671 pops, _ := parseScript(script)
672 return getSigOpCount(pops, false)
673 }
674 675 // GetPreciseSigOpCount returns the number of signature operations in scriptPubKey. If bip16 is true then scriptSig may
676 // be searched for the Pay -To-Script-Hash script in order to find the precise number of signature operations in the
677 // transaction. If the script fails to parse, then the count up to the point of failure is returned.
678 func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, bip16 bool) int {
679 // Don't check error since parseScript returns the parsed-up-to-error
680 // list of pops.
681 pops, _ := parseScript(scriptPubKey)
682 // Treat non P2SH transactions as normal.
683 if !(bip16 && isScriptHash(pops)) {
684 return getSigOpCount(pops, true)
685 }
686 // The public key script is a pay-to-script-hash, so parse the signature script to get the final item. Scripts that
687 // fail to fully parse count as 0 signature operations.
688 sigPops, e := parseScript(scriptSig)
689 if e != nil {
690 return 0
691 }
692 // The signature script must only push data to the stack for P2SH to be a valid pair, so the signature operation
693 // count is 0 when that is not the case.
694 if !isPushOnly(sigPops) || len(sigPops) == 0 {
695 return 0
696 }
697 // The P2SH script is the last item the signature script pushes to the stack. When the script is empty, there are no
698 // signature operations.
699 shScript := sigPops[len(sigPops)-1].data
700 if len(shScript) == 0 {
701 return 0
702 }
703 // Parse the P2SH script and don't check the error since parseScript returns the parsed-up-to-error list of pops and
704 // the consensus rules dictate signature operations are counted up to the first parse failure.
705 shPops, _ := parseScript(shScript)
706 return getSigOpCount(shPops, true)
707 }
708 709 // // GetWitnessSigOpCount returns the number of signature operations generated by
710 // // spending the passed pkScript with the specified witness, or sigScript. Unlike
711 // // GetPreciseSigOpCount, this function is able to accurately count the number of
712 // // signature operations generated by spending witness programs, and nested p2sh
713 // // witness programs. If the script fails to parse, then the count up to the
714 // // point of failure is returned.
715 // func GetWitnessSigOpCount(sigScript, pkScript []byte, witness wire.TxWitness) int {
716 // // If this is a regular witness program, then we can proceed directly to
717 // // counting its signature operations without any further processing.
718 // if IsWitnessProgram(pkScript) {
719 // return getWitnessSigOps(pkScript, witness)
720 // }
721 // // Next, we'll check the sigScript to see if this is a nested p2sh witness
722 // // program. This is a case wherein the sigScript is actually a datapush of a
723 // // p2wsh witness program.
724 // sigPops, e := parseScript(sigScript)
725 // if e != nil {
726 // return 0
727 // }
728 // if IsPayToScriptHash(pkScript) && isPushOnly(sigPops) &&
729 // IsWitnessProgram(sigScript[1:]) {
730 // return getWitnessSigOps(sigScript[1:], witness)
731 // }
732 // return 0
733 // }
734 735 // // getWitnessSigOps returns the number of signature operations generated by
736 // // spending the passed witness program wit the passed witness. The exact
737 // // signature counting heuristic is modified by the version of the passed witness
738 // // program. If the version of the witness program is unable to be extracted,
739 // // then 0 is returned for the sig op count.
740 // func getWitnessSigOps(pkScript []byte, witness wire.TxWitness) int {
741 // // Attempt to extract the witness program version.
742 // witnessVersion, witnessProgram, e := ExtractWitnessPrograminfo(
743 // pkScript,
744 // )
745 // if e != nil {
746 // return 0
747 // }
748 // switch witnessVersion {
749 // case 0:
750 // switch {
751 // case len(witnessProgram) == payToWitnessPubKeyHashDataSize:
752 // return 1
753 // case len(witnessProgram) == payToWitnessScriptHashDataSize &&
754 // len(witness) > 0:
755 // witnessScript := witness[len(witness)-1]
756 // pops, _ := parseScript(witnessScript)
757 // return getSigOpCount(pops, true)
758 // }
759 // }
760 // return 0
761 // }
762 763 // IsUnspendable returns whether the passed public key script is unspendable, or guaranteed to fail at execution. This
764 // allows inputs to be pruned instantly when entering the UTXO set.
765 func IsUnspendable(pkScript []byte) bool {
766 pops, e := parseScript(pkScript)
767 if e != nil {
768 return true
769 }
770 return len(pops) > 0 && pops[0].opcode.value == OP_RETURN
771 }
772