MCPcopy
hub / github.com/btcsuite/btcd / verifyWitnessProgram

Method verifyWitnessProgram

txscript/engine.go:569–858  ·  view source on GitHub ↗

verifyWitnessProgram validates the stored witness program using the passed witness as input.

(witness wire.TxWitness)

Source from the content-addressed store, hash-verified

567// verifyWitnessProgram validates the stored witness program using the passed
568// witness as input.
569func (vm *Engine) verifyWitnessProgram(witness wire.TxWitness) error {
570 switch {
571
572 // We're attempting to verify a base (witness version 0) segwit output,
573 // so we'll be looking for either a p2wsh or a p2wkh spend.
574 case vm.isWitnessVersionActive(BaseSegwitWitnessVersion):
575 switch len(vm.witnessProgram) {
576 case payToWitnessPubKeyHashDataSize: // P2WKH
577 // The witness stack should consist of exactly two
578 // items: the signature, and the pubkey.
579 if len(witness) != 2 {
580 err := fmt.Sprintf("should have exactly two "+
581 "items in witness, instead have %v", len(witness))
582 return scriptError(ErrWitnessProgramMismatch, err)
583 }
584
585 // Now we'll resume execution as if it were a regular
586 // p2pkh transaction.
587 pkScript, err := payToPubKeyHashScript(vm.witnessProgram)
588 if err != nil {
589 return err
590 }
591
592 const scriptVersion = 0
593 err = checkScriptParses(vm.version, pkScript)
594 if err != nil {
595 return err
596 }
597
598 // Set the stack to the provided witness stack, then
599 // append the pkScript generated above as the next
600 // script to execute.
601 vm.scripts = append(vm.scripts, pkScript)
602 vm.SetStack(witness)
603
604 case payToWitnessScriptHashDataSize: // P2WSH
605 // Additionally, The witness stack MUST NOT be empty at
606 // this point.
607 if len(witness) == 0 {
608 return scriptError(ErrWitnessProgramEmpty, "witness "+
609 "program empty passed empty witness")
610 }
611
612 // Obtain the witness script which should be the last
613 // element in the passed stack. The size of the script
614 // MUST NOT exceed the max script size.
615 witnessScript := witness[len(witness)-1]
616 if len(witnessScript) > MaxScriptSize {
617 str := fmt.Sprintf("witnessScript size %d "+
618 "is larger than max allowed size %d",
619 len(witnessScript), MaxScriptSize)
620 return scriptError(ErrScriptTooBig, str)
621 }
622
623 // Ensure that the serialized pkScript at the end of
624 // the witness stack matches the witness program.
625 witnessHash := sha256.Sum256(witnessScript)
626 if !bytes.Equal(witnessHash[:], vm.witnessProgram) {

Callers 1

StepMethod · 0.95

Calls 15

SetStackMethod · 0.95
hasFlagMethod · 0.95
GetStackMethod · 0.95
scriptErrorFunction · 0.85
payToPubKeyHashScriptFunction · 0.85
checkScriptParsesFunction · 0.85
newTaprootExecutionCtxFunction · 0.85
isAnnexedWitnessFunction · 0.85
extractAnnexFunction · 0.85
VerifyTaprootKeySpendFunction · 0.85

Tested by

no test coverage detected