github.com/btcsuite/btcd@v0.24.0/txscript/sighash.go (about) 1 // Copyright (c) 2013-2017 The btcsuite developers 2 // Copyright (c) 2015-2019 The Decred developers 3 // Use of this source code is governed by an ISC 4 // license that can be found in the LICENSE file. 5 6 package txscript 7 8 import ( 9 "bytes" 10 "crypto/sha256" 11 "encoding/binary" 12 "fmt" 13 "io" 14 "math" 15 16 "github.com/btcsuite/btcd/chaincfg/chainhash" 17 "github.com/btcsuite/btcd/wire" 18 ) 19 20 // SigHashType represents hash type bits at the end of a signature. 21 type SigHashType uint32 22 23 // Hash type bits from the end of a signature. 24 const ( 25 SigHashDefault SigHashType = 0x00 26 SigHashOld SigHashType = 0x0 27 SigHashAll SigHashType = 0x1 28 SigHashNone SigHashType = 0x2 29 SigHashSingle SigHashType = 0x3 30 SigHashAnyOneCanPay SigHashType = 0x80 31 32 // sigHashMask defines the number of bits of the hash type which is used 33 // to identify which outputs are signed. 34 sigHashMask = 0x1f 35 ) 36 37 const ( 38 // blankCodeSepValue is the value of the code separator position in the 39 // tapscript sighash when no code separator was found in the script. 40 blankCodeSepValue = math.MaxUint32 41 ) 42 43 // shallowCopyTx creates a shallow copy of the transaction for use when 44 // calculating the signature hash. It is used over the Copy method on the 45 // transaction itself since that is a deep copy and therefore does more work and 46 // allocates much more space than needed. 47 func shallowCopyTx(tx *wire.MsgTx) wire.MsgTx { 48 // As an additional memory optimization, use contiguous backing arrays 49 // for the copied inputs and outputs and point the final slice of 50 // pointers into the contiguous arrays. This avoids a lot of small 51 // allocations. 52 txCopy := wire.MsgTx{ 53 Version: tx.Version, 54 TxIn: make([]*wire.TxIn, len(tx.TxIn)), 55 TxOut: make([]*wire.TxOut, len(tx.TxOut)), 56 LockTime: tx.LockTime, 57 } 58 txIns := make([]wire.TxIn, len(tx.TxIn)) 59 for i, oldTxIn := range tx.TxIn { 60 txIns[i] = *oldTxIn 61 txCopy.TxIn[i] = &txIns[i] 62 } 63 txOuts := make([]wire.TxOut, len(tx.TxOut)) 64 for i, oldTxOut := range tx.TxOut { 65 txOuts[i] = *oldTxOut 66 txCopy.TxOut[i] = &txOuts[i] 67 } 68 return txCopy 69 } 70 71 // CalcSignatureHash will, given a script and hash type for the current script 72 // engine instance, calculate the signature hash to be used for signing and 73 // verification. 74 // 75 // NOTE: This function is only valid for version 0 scripts. Since the function 76 // does not accept a script version, the results are undefined for other script 77 // versions. 78 func CalcSignatureHash(script []byte, hashType SigHashType, tx *wire.MsgTx, idx int) ([]byte, error) { 79 const scriptVersion = 0 80 if err := checkScriptParses(scriptVersion, script); err != nil { 81 return nil, err 82 } 83 84 return calcSignatureHash(script, hashType, tx, idx), nil 85 } 86 87 // calcSignatureHash computes the signature hash for the specified input of the 88 // target transaction observing the desired signature hash type. 89 func calcSignatureHash(sigScript []byte, hashType SigHashType, tx *wire.MsgTx, idx int) []byte { 90 // The SigHashSingle signature type signs only the corresponding input 91 // and output (the output with the same index number as the input). 92 // 93 // Since transactions can have more inputs than outputs, this means it 94 // is improper to use SigHashSingle on input indices that don't have a 95 // corresponding output. 96 // 97 // A bug in the original Satoshi client implementation means specifying 98 // an index that is out of range results in a signature hash of 1 (as a 99 // uint256 little endian). The original intent appeared to be to 100 // indicate failure, but unfortunately, it was never checked and thus is 101 // treated as the actual signature hash. This buggy behavior is now 102 // part of the consensus and a hard fork would be required to fix it. 103 // 104 // Due to this, care must be taken by software that creates transactions 105 // which make use of SigHashSingle because it can lead to an extremely 106 // dangerous situation where the invalid inputs will end up signing a 107 // hash of 1. This in turn presents an opportunity for attackers to 108 // cleverly construct transactions which can steal those coins provided 109 // they can reuse signatures. 110 if hashType&sigHashMask == SigHashSingle && idx >= len(tx.TxOut) { 111 var hash chainhash.Hash 112 hash[0] = 0x01 113 return hash[:] 114 } 115 116 // Remove all instances of OP_CODESEPARATOR from the script. 117 sigScript = removeOpcodeRaw(sigScript, OP_CODESEPARATOR) 118 119 // Make a shallow copy of the transaction, zeroing out the script for 120 // all inputs that are not currently being processed. 121 txCopy := shallowCopyTx(tx) 122 for i := range txCopy.TxIn { 123 if i == idx { 124 txCopy.TxIn[idx].SignatureScript = sigScript 125 } else { 126 txCopy.TxIn[i].SignatureScript = nil 127 } 128 } 129 130 switch hashType & sigHashMask { 131 case SigHashNone: 132 txCopy.TxOut = txCopy.TxOut[0:0] // Empty slice. 133 for i := range txCopy.TxIn { 134 if i != idx { 135 txCopy.TxIn[i].Sequence = 0 136 } 137 } 138 139 case SigHashSingle: 140 // Resize output array to up to and including requested index. 141 txCopy.TxOut = txCopy.TxOut[:idx+1] 142 143 // All but current output get zeroed out. 144 for i := 0; i < idx; i++ { 145 txCopy.TxOut[i].Value = -1 146 txCopy.TxOut[i].PkScript = nil 147 } 148 149 // Sequence on all other inputs is 0, too. 150 for i := range txCopy.TxIn { 151 if i != idx { 152 txCopy.TxIn[i].Sequence = 0 153 } 154 } 155 156 default: 157 // Consensus treats undefined hashtypes like normal SigHashAll 158 // for purposes of hash generation. 159 fallthrough 160 case SigHashOld: 161 fallthrough 162 case SigHashAll: 163 // Nothing special here. 164 } 165 if hashType&SigHashAnyOneCanPay != 0 { 166 txCopy.TxIn = txCopy.TxIn[idx : idx+1] 167 } 168 169 // The final hash is the double sha256 of both the serialized modified 170 // transaction and the hash type (encoded as a 4-byte little-endian 171 // value) appended. 172 sigHashBytes := chainhash.DoubleHashRaw(func(w io.Writer) error { 173 if err := txCopy.SerializeNoWitness(w); err != nil { 174 return err 175 } 176 err := binary.Write(w, binary.LittleEndian, hashType) 177 if err != nil { 178 return err 179 } 180 return nil 181 }) 182 183 return sigHashBytes[:] 184 } 185 186 // calcWitnessSignatureHashRaw computes the sighash digest of a transaction's 187 // segwit input using the new, optimized digest calculation algorithm defined 188 // in BIP0143: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki. 189 // This function makes use of pre-calculated sighash fragments stored within 190 // the passed HashCache to eliminate duplicate hashing computations when 191 // calculating the final digest, reducing the complexity from O(N^2) to O(N). 192 // Additionally, signatures now cover the input value of the referenced unspent 193 // output. This allows offline, or hardware wallets to compute the exact amount 194 // being spent, in addition to the final transaction fee. In the case the 195 // wallet if fed an invalid input amount, the real sighash will differ causing 196 // the produced signature to be invalid. 197 func calcWitnessSignatureHashRaw(subScript []byte, sigHashes *TxSigHashes, 198 hashType SigHashType, tx *wire.MsgTx, idx int, amt int64) ([]byte, error) { 199 200 // As a sanity check, ensure the passed input index for the transaction 201 // is valid. 202 // 203 // TODO(roasbeef): check needs to be lifted elsewhere? 204 if idx > len(tx.TxIn)-1 { 205 return nil, fmt.Errorf("idx %d but %d txins", idx, len(tx.TxIn)) 206 } 207 208 sigHashBytes := chainhash.DoubleHashRaw(func(w io.Writer) error { 209 var scratch [8]byte 210 211 // First write out, then encode the transaction's version 212 // number. 213 binary.LittleEndian.PutUint32(scratch[:], uint32(tx.Version)) 214 w.Write(scratch[:4]) 215 216 // Next write out the possibly pre-calculated hashes for the 217 // sequence numbers of all inputs, and the hashes of the 218 // previous outs for all outputs. 219 var zeroHash chainhash.Hash 220 221 // If anyone can pay isn't active, then we can use the cached 222 // hashPrevOuts, otherwise we just write zeroes for the prev 223 // outs. 224 if hashType&SigHashAnyOneCanPay == 0 { 225 w.Write(sigHashes.HashPrevOutsV0[:]) 226 } else { 227 w.Write(zeroHash[:]) 228 } 229 230 // If the sighash isn't anyone can pay, single, or none, the 231 // use the cached hash sequences, otherwise write all zeroes 232 // for the hashSequence. 233 if hashType&SigHashAnyOneCanPay == 0 && 234 hashType&sigHashMask != SigHashSingle && 235 hashType&sigHashMask != SigHashNone { 236 237 w.Write(sigHashes.HashSequenceV0[:]) 238 } else { 239 w.Write(zeroHash[:]) 240 } 241 242 txIn := tx.TxIn[idx] 243 244 // Next, write the outpoint being spent. 245 w.Write(txIn.PreviousOutPoint.Hash[:]) 246 var bIndex [4]byte 247 binary.LittleEndian.PutUint32( 248 bIndex[:], txIn.PreviousOutPoint.Index, 249 ) 250 w.Write(bIndex[:]) 251 252 if isWitnessPubKeyHashScript(subScript) { 253 // The script code for a p2wkh is a length prefix 254 // varint for the next 25 bytes, followed by a 255 // re-creation of the original p2pkh pk script. 256 w.Write([]byte{0x19}) 257 w.Write([]byte{OP_DUP}) 258 w.Write([]byte{OP_HASH160}) 259 w.Write([]byte{OP_DATA_20}) 260 w.Write(extractWitnessPubKeyHash(subScript)) 261 w.Write([]byte{OP_EQUALVERIFY}) 262 w.Write([]byte{OP_CHECKSIG}) 263 } else { 264 // For p2wsh outputs, and future outputs, the script 265 // code is the original script, with all code 266 // separators removed, serialized with a var int length 267 // prefix. 268 wire.WriteVarBytes(w, 0, subScript) 269 } 270 271 // Next, add the input amount, and sequence number of the input 272 // being signed. 273 binary.LittleEndian.PutUint64(scratch[:], uint64(amt)) 274 w.Write(scratch[:]) 275 binary.LittleEndian.PutUint32(scratch[:], txIn.Sequence) 276 w.Write(scratch[:4]) 277 278 // If the current signature mode isn't single, or none, then we 279 // can re-use the pre-generated hashoutputs sighash fragment. 280 // Otherwise, we'll serialize and add only the target output 281 // index to the signature pre-image. 282 if hashType&sigHashMask != SigHashSingle && 283 hashType&sigHashMask != SigHashNone { 284 285 w.Write(sigHashes.HashOutputsV0[:]) 286 } else if hashType&sigHashMask == SigHashSingle && 287 idx < len(tx.TxOut) { 288 289 h := chainhash.DoubleHashRaw(func(tw io.Writer) error { 290 wire.WriteTxOut(tw, 0, 0, tx.TxOut[idx]) 291 return nil 292 }) 293 w.Write(h[:]) 294 } else { 295 w.Write(zeroHash[:]) 296 } 297 298 // Finally, write out the transaction's locktime, and the sig 299 // hash type. 300 binary.LittleEndian.PutUint32(scratch[:], tx.LockTime) 301 w.Write(scratch[:4]) 302 binary.LittleEndian.PutUint32(scratch[:], uint32(hashType)) 303 w.Write(scratch[:4]) 304 305 return nil 306 }) 307 308 return sigHashBytes[:], nil 309 } 310 311 // CalcWitnessSigHash computes the sighash digest for the specified input of 312 // the target transaction observing the desired sig hash type. 313 func CalcWitnessSigHash(script []byte, sigHashes *TxSigHashes, hType SigHashType, 314 tx *wire.MsgTx, idx int, amt int64) ([]byte, error) { 315 316 const scriptVersion = 0 317 if err := checkScriptParses(scriptVersion, script); err != nil { 318 return nil, err 319 } 320 321 return calcWitnessSignatureHashRaw(script, sigHashes, hType, tx, idx, amt) 322 } 323 324 // sigHashExtFlag represents the sig hash extension flag as defined in BIP 341. 325 // Extensions to the base sighash algorithm will be appended to the base 326 // sighash digest. 327 type sigHashExtFlag uint8 328 329 const ( 330 // baseSigHashExtFlag is the base extension flag. This adds no changes 331 // to the sighash digest message. This is used for segwit v1 spends, 332 // a.k.a the tapscript keyspend path. 333 baseSigHashExtFlag sigHashExtFlag = 0 334 335 // tapscriptSighashExtFlag is the extension flag defined by tapscript 336 // base leaf version spend define din BIP 342. This augments the base 337 // sighash by including the tapscript leaf hash, the key version, and 338 // the code separator position. 339 tapscriptSighashExtFlag sigHashExtFlag = 1 340 ) 341 342 // taprootSigHashOptions houses a set of functional options that may optionally 343 // modify how the taproot/script sighash digest algorithm is implemented. 344 type taprootSigHashOptions struct { 345 // extFlag denotes the current message digest extension being used. For 346 // top-level script spends use a value of zero, while each tapscript 347 // version can define its own values as well. 348 extFlag sigHashExtFlag 349 350 // annexHash is the sha256 hash of the annex with a compact size length 351 // prefix: sha256(sizeOf(annex) || annex). 352 annexHash []byte 353 354 // tapLeafHash is the hash of the tapscript leaf as defined in BIP 341. 355 // This should be h_tapleaf(version || compactSizeOf(script) || script). 356 tapLeafHash []byte 357 358 // keyVersion is the key version as defined in BIP 341. This is always 359 // 0x00 for all currently defined leaf versions. 360 keyVersion byte 361 362 // codeSepPos is the op code position of the last code separator. This 363 // is used for the BIP 342 sighash message extension. 364 codeSepPos uint32 365 } 366 367 // writeDigestExtensions writes out the sighash message extension defined by the 368 // current active sigHashExtFlags. 369 func (t *taprootSigHashOptions) writeDigestExtensions(w io.Writer) error { 370 switch t.extFlag { 371 // The base extension, used for tapscript keypath spends doesn't modify 372 // the digest at all. 373 case baseSigHashExtFlag: 374 return nil 375 376 // The tapscript base leaf version extension adds the leaf hash, key 377 // version, and code separator position to the final digest. 378 case tapscriptSighashExtFlag: 379 if _, err := w.Write(t.tapLeafHash); err != nil { 380 return err 381 } 382 if _, err := w.Write([]byte{t.keyVersion}); err != nil { 383 return err 384 } 385 err := binary.Write(w, binary.LittleEndian, t.codeSepPos) 386 if err != nil { 387 return err 388 } 389 } 390 391 return nil 392 } 393 394 // defaultTaprootSighashOptions returns the set of default sighash options for 395 // taproot execution. 396 func defaultTaprootSighashOptions() *taprootSigHashOptions { 397 return &taprootSigHashOptions{} 398 } 399 400 // TaprootSigHashOption defines a set of functional param options that can be 401 // used to modify the base sighash message with optional extensions. 402 type TaprootSigHashOption func(*taprootSigHashOptions) 403 404 // WithAnnex is a functional option that allows the caller to specify the 405 // existence of an annex in the final witness stack for the taproot/tapscript 406 // spends. 407 func WithAnnex(annex []byte) TaprootSigHashOption { 408 return func(o *taprootSigHashOptions) { 409 // It's just a bytes.Buffer which never returns an error on 410 // write. 411 var b bytes.Buffer 412 _ = wire.WriteVarBytes(&b, 0, annex) 413 414 o.annexHash = chainhash.HashB(b.Bytes()) 415 } 416 } 417 418 // WithBaseTapscriptVersion is a functional option that specifies that the 419 // sighash digest should include the extra information included as part of the 420 // base tapscript version. 421 func WithBaseTapscriptVersion(codeSepPos uint32, 422 tapLeafHash []byte) TaprootSigHashOption { 423 424 return func(o *taprootSigHashOptions) { 425 o.extFlag = tapscriptSighashExtFlag 426 o.tapLeafHash = tapLeafHash 427 o.keyVersion = 0 428 o.codeSepPos = codeSepPos 429 } 430 } 431 432 // isValidTaprootSigHash returns true if the passed sighash is a valid taproot 433 // sighash. 434 func isValidTaprootSigHash(hashType SigHashType) bool { 435 switch hashType { 436 case SigHashDefault, SigHashAll, SigHashNone, SigHashSingle: 437 fallthrough 438 case 0x81, 0x82, 0x83: 439 return true 440 441 default: 442 return false 443 } 444 } 445 446 // calcTaprootSignatureHashRaw computes the sighash as specified in BIP 143. 447 // If an invalid sighash type is passed in, an error is returned. 448 func calcTaprootSignatureHashRaw(sigHashes *TxSigHashes, hType SigHashType, 449 tx *wire.MsgTx, idx int, 450 prevOutFetcher PrevOutputFetcher, 451 sigHashOpts ...TaprootSigHashOption) ([]byte, error) { 452 453 opts := defaultTaprootSighashOptions() 454 for _, sigHashOpt := range sigHashOpts { 455 sigHashOpt(opts) 456 } 457 458 // If a valid sighash type isn't passed in, then we'll exit early. 459 if !isValidTaprootSigHash(hType) { 460 // TODO(roasbeef): use actual errr here 461 return nil, fmt.Errorf("invalid taproot sighash type: %v", hType) 462 } 463 464 // As a sanity check, ensure the passed input index for the transaction 465 // is valid. 466 if idx > len(tx.TxIn)-1 { 467 return nil, fmt.Errorf("idx %d but %d txins", idx, len(tx.TxIn)) 468 } 469 470 // We'll utilize this buffer throughout to incrementally calculate 471 // the signature hash for this transaction. 472 var sigMsg bytes.Buffer 473 474 // The final sighash always has a value of 0x00 prepended to it, which 475 // is called the sighash epoch. 476 sigMsg.WriteByte(0x00) 477 478 // First, we write the hash type encoded as a single byte. 479 if err := sigMsg.WriteByte(byte(hType)); err != nil { 480 return nil, err 481 } 482 483 // Next we'll write out the transaction specific data which binds the 484 // outer context of the sighash. 485 err := binary.Write(&sigMsg, binary.LittleEndian, tx.Version) 486 if err != nil { 487 return nil, err 488 } 489 err = binary.Write(&sigMsg, binary.LittleEndian, tx.LockTime) 490 if err != nil { 491 return nil, err 492 } 493 494 // If sighash isn't anyone can pay, then we'll include all the 495 // pre-computed midstate digests in the sighash. 496 if hType&SigHashAnyOneCanPay != SigHashAnyOneCanPay { 497 sigMsg.Write(sigHashes.HashPrevOutsV1[:]) 498 sigMsg.Write(sigHashes.HashInputAmountsV1[:]) 499 sigMsg.Write(sigHashes.HashInputScriptsV1[:]) 500 sigMsg.Write(sigHashes.HashSequenceV1[:]) 501 } 502 503 // If this is sighash all, or its taproot alias (sighash default), 504 // then we'll also include the pre-computed digest of all the outputs 505 // of the transaction. 506 if hType&SigHashSingle != SigHashSingle && 507 hType&SigHashSingle != SigHashNone { 508 509 sigMsg.Write(sigHashes.HashOutputsV1[:]) 510 } 511 512 // Next, we'll write out the relevant information for this specific 513 // input. 514 // 515 // The spend type is computed as the (ext_flag*2) + annex_present. We 516 // use this to bind the extension flag (that BIP 342 uses), as well as 517 // the annex if its present. 518 input := tx.TxIn[idx] 519 witnessHasAnnex := opts.annexHash != nil 520 spendType := byte(opts.extFlag) * 2 521 if witnessHasAnnex { 522 spendType += 1 523 } 524 525 if err := sigMsg.WriteByte(spendType); err != nil { 526 return nil, err 527 } 528 529 // If anyone can pay is active, then we'll write out just the specific 530 // information about this input, given we skipped writing all the 531 // information of all the inputs above. 532 if hType&SigHashAnyOneCanPay == SigHashAnyOneCanPay { 533 // We'll start out with writing this input specific information by 534 // first writing the entire previous output. 535 err = wire.WriteOutPoint(&sigMsg, 0, 0, &input.PreviousOutPoint) 536 if err != nil { 537 return nil, err 538 } 539 540 // Next, we'll write out the previous output (amt+script) being 541 // spent itself. 542 prevOut := prevOutFetcher.FetchPrevOutput(input.PreviousOutPoint) 543 if err := wire.WriteTxOut(&sigMsg, 0, 0, prevOut); err != nil { 544 return nil, err 545 } 546 547 // Finally, we'll write out the input sequence itself. 548 err = binary.Write(&sigMsg, binary.LittleEndian, input.Sequence) 549 if err != nil { 550 return nil, err 551 } 552 } else { 553 err := binary.Write(&sigMsg, binary.LittleEndian, uint32(idx)) 554 if err != nil { 555 return nil, err 556 } 557 } 558 559 // Now that we have the input specific information written, we'll 560 // include the anex, if we have it. 561 if witnessHasAnnex { 562 sigMsg.Write(opts.annexHash) 563 } 564 565 // Finally, if this is sighash single, then we'll write out the 566 // information for this given output. 567 if hType&sigHashMask == SigHashSingle { 568 // If this output doesn't exist, then we'll return with an error 569 // here as this is an invalid sighash type for this input. 570 if idx >= len(tx.TxOut) { 571 // TODO(roasbeef): real error here 572 return nil, fmt.Errorf("invalid sighash type for input") 573 } 574 575 // Now that we know this is a valid sighash input combination, 576 // we'll write out the information specific to this input. 577 // We'll write the wire serialization of the output and compute 578 // the sha256 in a single step. 579 shaWriter := sha256.New() 580 txOut := tx.TxOut[idx] 581 if err := wire.WriteTxOut(shaWriter, 0, 0, txOut); err != nil { 582 return nil, err 583 } 584 585 // With the digest obtained, we'll write this out into our 586 // signature message. 587 if _, err := sigMsg.Write(shaWriter.Sum(nil)); err != nil { 588 return nil, err 589 } 590 } 591 592 // Now that we've written out all the base information, we'll write any 593 // message extensions (if they exist). 594 if err := opts.writeDigestExtensions(&sigMsg); err != nil { 595 return nil, err 596 } 597 598 // The final sighash is computed as: hash_TagSigHash(0x00 || sigMsg). 599 // We wrote the 0x00 above so we don't need to append here and incur 600 // extra allocations. 601 sigHash := chainhash.TaggedHash(chainhash.TagTapSighash, sigMsg.Bytes()) 602 return sigHash[:], nil 603 } 604 605 // CalcTaprootSignatureHash computes the sighash digest of a transaction's 606 // taproot-spending input using the new sighash digest algorithm described in 607 // BIP 341. As the new digest algorithms may require the digest to commit to the 608 // entire prev output, a PrevOutputFetcher argument is required to obtain the 609 // needed information. The TxSigHashes pre-computed sighash midstate MUST be 610 // specified. 611 func CalcTaprootSignatureHash(sigHashes *TxSigHashes, hType SigHashType, 612 tx *wire.MsgTx, idx int, 613 prevOutFetcher PrevOutputFetcher) ([]byte, error) { 614 615 return calcTaprootSignatureHashRaw( 616 sigHashes, hType, tx, idx, prevOutFetcher, 617 ) 618 } 619 620 // CalcTaprootSignatureHash is similar to CalcTaprootSignatureHash but for 621 // _tapscript_ spends instead. A proper TapLeaf instance (the script leaf being 622 // signed) must be passed in. The functional options can be used to specify an 623 // annex if the signature was bound to that context. 624 // 625 // NOTE: This function is able to compute the sighash of scripts that contain a 626 // code separator if the caller passes in an instance of 627 // WithBaseTapscriptVersion with the valid position. 628 func CalcTapscriptSignaturehash(sigHashes *TxSigHashes, hType SigHashType, 629 tx *wire.MsgTx, idx int, prevOutFetcher PrevOutputFetcher, 630 tapLeaf TapLeaf, 631 sigHashOpts ...TaprootSigHashOption) ([]byte, error) { 632 633 tapLeafHash := tapLeaf.TapHash() 634 635 var opts []TaprootSigHashOption 636 opts = append( 637 opts, WithBaseTapscriptVersion(blankCodeSepValue, tapLeafHash[:]), 638 ) 639 opts = append(opts, sigHashOpts...) 640 641 return calcTaprootSignatureHashRaw( 642 sigHashes, hType, tx, idx, prevOutFetcher, opts..., 643 ) 644 }