| 13 | ) |
| 14 | |
| 15 | func VerifyScript(transaction *tx.Tx, scriptSig *script.Script, scriptPubKey *script.Script, |
| 16 | nIn int, value amount.Amount, flags uint32, scriptChecker Checker) error { |
| 17 | if flags&script.ScriptEnableSigHashForkID == script.ScriptEnableSigHashForkID { |
| 18 | flags |= script.ScriptVerifyStrictEnc |
| 19 | } |
| 20 | if flags&script.ScriptVerifySigPushOnly == script.ScriptVerifySigPushOnly && !scriptSig.IsPushOnly() { |
| 21 | log.Debug("ScriptErrSigPushOnly") |
| 22 | return errcode.New(errcode.ScriptErrSigPushOnly) |
| 23 | } |
| 24 | stack := util.NewStack() |
| 25 | err := EvalScript(stack, scriptSig, transaction, nIn, value, flags, scriptChecker) |
| 26 | if err != nil { |
| 27 | return err |
| 28 | } |
| 29 | stackCopy := stack.Copy() |
| 30 | err = EvalScript(stack, scriptPubKey, transaction, nIn, value, flags, scriptChecker) |
| 31 | if err != nil { |
| 32 | return err |
| 33 | } |
| 34 | if stack.Empty() { |
| 35 | log.Debug("ScriptErrEvalFalse") |
| 36 | return errcode.New(errcode.ScriptErrEvalFalse) |
| 37 | } |
| 38 | vch := stack.Top(-1) |
| 39 | if !script.BytesToBool(vch.([]byte)) { |
| 40 | log.Debug("ScriptErrEvalFalse") |
| 41 | return errcode.New(errcode.ScriptErrEvalFalse) |
| 42 | } |
| 43 | |
| 44 | if flags&script.ScriptVerifyP2SH == script.ScriptVerifyP2SH && scriptPubKey.IsPayToScriptHash() { |
| 45 | if !scriptSig.IsPushOnly() { |
| 46 | log.Debug("ScriptErrScriptSigNotPushOnly") |
| 47 | return errcode.New(errcode.ScriptErrSigPushOnly) |
| 48 | } |
| 49 | util.Swap(stack, stackCopy) |
| 50 | topBytes := stack.Top(-1) |
| 51 | stack.Pop() |
| 52 | scriptPubKey2 := script.NewScriptRaw(topBytes.([]byte)) |
| 53 | err = EvalScript(stack, scriptPubKey2, transaction, nIn, value, flags, scriptChecker) |
| 54 | if err != nil { |
| 55 | return err |
| 56 | } |
| 57 | if stack.Empty() { |
| 58 | log.Debug("ScriptErrEvalFalse") |
| 59 | return errcode.New(errcode.ScriptErrEvalFalse) |
| 60 | } |
| 61 | vch1 := stack.Top(-1) |
| 62 | if !script.BytesToBool(vch1.([]byte)) { |
| 63 | log.Debug("ScriptErrEvalFalse") |
| 64 | return errcode.New(errcode.ScriptErrEvalFalse) |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | // The CLEANSTACK check is only performed after potential P2SH evaluation, |
| 69 | // as the non-P2SH evaluation of a P2SH script will obviously not result in |
| 70 | // a clean stack (the P2SH inputs remain). The same holds for witness |
| 71 | // evaluation. |
| 72 | if (flags & script.ScriptVerifyCleanStack) != 0 { |