1# Copyright (C) 2012-2017 The python-bitcoinlib developers
2#
3# This file is part of python-bitcoinlib.
4#
5# It is subject to the license terms in the LICENSE file found in the top-level
6# directory of this distribution.
7#
8# No part of python-bitcoinlib, including this file, may be copied, modified,
9# propagated, or distributed except according to the terms contained in the
10# LICENSE file.
11
12"""Script evaluation
13
14Be warned that there are highly likely to be consensus bugs in this code; it is
15unlikely to match Satoshi Bitcoin exactly. Think carefully before using this
16module.
17"""
18
19from __future__ import absolute_import, division, print_function, unicode_literals
20
21import sys
22_bord = ord
23if sys.version > '3':
24    long = int
25    _bord = lambda x: x
26
27import hashlib
28
29import bitcoin.core
30import bitcoin.core._bignum
31import bitcoin.core.key
32import bitcoin.core.serialize
33
34# Importing everything for simplicity; note that we use __all__ at the end so
35# we're not exporting the whole contents of the script module.
36from bitcoin.core.script import *
37
38MAX_NUM_SIZE = 4
39MAX_STACK_ITEMS = 1000
40
41SCRIPT_VERIFY_P2SH = object()
42SCRIPT_VERIFY_STRICTENC = object()
43SCRIPT_VERIFY_DERSIG = object()
44SCRIPT_VERIFY_LOW_S = object()
45SCRIPT_VERIFY_NULLDUMMY = object()
46SCRIPT_VERIFY_SIGPUSHONLY = object()
47SCRIPT_VERIFY_MINIMALDATA = object()
48SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = object()
49SCRIPT_VERIFY_CLEANSTACK = object()
50SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = object()
51
52SCRIPT_VERIFY_FLAGS_BY_NAME = {
53    'P2SH': SCRIPT_VERIFY_P2SH,
54    'STRICTENC': SCRIPT_VERIFY_STRICTENC,
55    'DERSIG': SCRIPT_VERIFY_DERSIG,
56    'LOW_S': SCRIPT_VERIFY_LOW_S,
57    'NULLDUMMY': SCRIPT_VERIFY_NULLDUMMY,
58    'SIGPUSHONLY': SCRIPT_VERIFY_SIGPUSHONLY,
59    'MINIMALDATA': SCRIPT_VERIFY_MINIMALDATA,
60    'DISCOURAGE_UPGRADABLE_NOPS': SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS,
61    'CLEANSTACK': SCRIPT_VERIFY_CLEANSTACK,
62    'CHECKLOCKTIMEVERIFY': SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY,
63}
64
65class EvalScriptError(bitcoin.core.ValidationError):
66    """Base class for exceptions raised when a script fails during EvalScript()
67
68    The execution state just prior the opcode raising the is saved. (if
69    available)
70    """
71    def __init__(self,
72                 msg,
73                 sop=None, sop_data=None, sop_pc=None,
74                 stack=None, scriptIn=None, txTo=None, inIdx=None, flags=None,
75                 altstack=None, vfExec=None, pbegincodehash=None, nOpCount=None):
76        super(EvalScriptError, self).__init__('EvalScript: %s' % msg)
77
78        self.sop = sop
79        self.sop_data = sop_data
80        self.sop_pc = sop_pc
81        self.stack = stack
82        self.scriptIn = scriptIn
83        self.txTo = txTo
84        self.inIdx = inIdx
85        self.flags = flags
86        self.altstack = altstack
87        self.vfExec = vfExec
88        self.pbegincodehash = pbegincodehash
89        self.nOpCount = nOpCount
90
91class MaxOpCountError(EvalScriptError):
92    def __init__(self, **kwargs):
93        super(MaxOpCountError, self).__init__('max opcode count exceeded',**kwargs)
94
95class MissingOpArgumentsError(EvalScriptError):
96    """Missing arguments"""
97    def __init__(self, opcode, s, n, **kwargs):
98        super(MissingOpArgumentsError, self).__init__(
99                'missing arguments for %s; need %d items, but only %d on stack' %
100                                   (OPCODE_NAMES[opcode], n, len(s)),
101                **kwargs)
102
103class ArgumentsInvalidError(EvalScriptError):
104    """Arguments are invalid"""
105    def __init__(self, opcode, msg, **kwargs):
106        super(ArgumentsInvalidError, self).__init__(
107                '%s args invalid: %s' % (OPCODE_NAMES[opcode], msg),
108                **kwargs)
109
110
111class VerifyOpFailedError(EvalScriptError):
112    """A VERIFY opcode failed"""
113    def __init__(self, opcode, **kwargs):
114        super(VerifyOpFailedError, self).__init__('%s failed' % OPCODE_NAMES[opcode],
115                                                  **kwargs)
116
117def _CastToBigNum(s, err_raiser):
118    v = bitcoin.core._bignum.vch2bn(s)
119    if len(s) > MAX_NUM_SIZE:
120        raise err_raiser(EvalScriptError, 'CastToBigNum() : overflow')
121    return v
122
123def _CastToBool(s):
124    for i in range(len(s)):
125        sv = _bord(s[i])
126        if sv != 0:
127            if (i == (len(s) - 1)) and (sv == 0x80):
128                return False
129            return True
130
131    return False
132
133
134def _CheckSig(sig, pubkey, script, txTo, inIdx, err_raiser):
135    key = bitcoin.core.key.CECKey()
136    key.set_pubkey(pubkey)
137
138    if len(sig) == 0:
139        return False
140    hashtype = _bord(sig[-1])
141    sig = sig[:-1]
142
143    # Raw signature hash due to the SIGHASH_SINGLE bug
144    #
145    # Note that we never raise an exception if RawSignatureHash() returns an
146    # error code. However the first error code case, where inIdx >=
147    # len(txTo.vin), shouldn't ever happen during EvalScript() as that would
148    # imply the scriptSig being checked doesn't correspond to a valid txout -
149    # that should cause other validation machinery to fail long before we ever
150    # got here.
151    (h, err) = RawSignatureHash(script, txTo, inIdx, hashtype)
152    return key.verify(h, sig)
153
154
155def _CheckMultiSig(opcode, script, stack, txTo, inIdx, flags, err_raiser, nOpCount):
156    i = 1
157    if len(stack) < i:
158        err_raiser(MissingOpArgumentsError, opcode, stack, i)
159
160    keys_count = _CastToBigNum(stack[-i], err_raiser)
161    if keys_count < 0 or keys_count > 20:
162        err_raiser(ArgumentsInvalidError, opcode, "keys count invalid")
163    i += 1
164    ikey = i
165    i += keys_count
166    nOpCount[0] += keys_count
167    if nOpCount[0] > MAX_SCRIPT_OPCODES:
168        err_raiser(MaxOpCountError)
169    if len(stack) < i:
170        err_raiser(ArgumentsInvalidError, opcode, "not enough keys on stack")
171
172    sigs_count = _CastToBigNum(stack[-i], err_raiser)
173    if sigs_count < 0 or sigs_count > keys_count:
174        err_raiser(ArgumentsInvalidError, opcode, "sigs count invalid")
175
176    i += 1
177    isig = i
178    i += sigs_count
179    if len(stack) < i-1:
180        raise err_raiser(ArgumentsInvalidError, opcode, "not enough sigs on stack")
181    elif len(stack) < i:
182        raise err_raiser(ArgumentsInvalidError, opcode, "missing dummy value")
183
184    # Drop the signature, since there's no way for a signature to sign itself
185    #
186    # Of course, this can only come up in very contrived cases now that
187    # scriptSig and scriptPubKey are processed separately.
188    for k in range(sigs_count):
189        sig = stack[-isig - k]
190        script = FindAndDelete(script, CScript([sig]))
191
192    success = True
193
194    while success and sigs_count > 0:
195        sig = stack[-isig]
196        pubkey = stack[-ikey]
197
198        if _CheckSig(sig, pubkey, script, txTo, inIdx, err_raiser):
199            isig += 1
200            sigs_count -= 1
201
202        ikey += 1
203        keys_count -= 1
204
205        if sigs_count > keys_count:
206            success = False
207
208            # with VERIFY bail now before we modify the stack
209            if opcode == OP_CHECKMULTISIGVERIFY:
210                err_raiser(VerifyOpFailedError, opcode)
211
212    while i > 1:
213        stack.pop()
214        i -= 1
215
216    # Note how Bitcoin Core duplicates the len(stack) check, rather than
217    # letting pop() handle it; maybe that's wrong?
218    if len(stack) and SCRIPT_VERIFY_NULLDUMMY in flags:
219        if stack[-1] != b'':
220            raise err_raiser(ArgumentsInvalidError, opcode, "dummy value not OP_0")
221
222    stack.pop()
223
224    if opcode == OP_CHECKMULTISIG:
225        if success:
226            stack.append(b"\x01")
227        else:
228            # FIXME: this is incorrect, but not caught by existing
229            # test cases
230            stack.append(b"\x00")
231
232
233# OP_2MUL and OP_2DIV are *not* included in this list as they are disabled
234_ISA_UNOP = {
235    OP_1ADD,
236    OP_1SUB,
237    OP_NEGATE,
238    OP_ABS,
239    OP_NOT,
240    OP_0NOTEQUAL,
241}
242
243def _UnaryOp(opcode, stack, err_raiser):
244    if len(stack) < 1:
245        err_raiser(MissingOpArgumentsError, opcode, stack, 1)
246    bn = _CastToBigNum(stack[-1], err_raiser)
247    stack.pop()
248
249    if opcode == OP_1ADD:
250        bn += 1
251
252    elif opcode == OP_1SUB:
253        bn -= 1
254
255    elif opcode == OP_NEGATE:
256        bn = -bn
257
258    elif opcode == OP_ABS:
259        if bn < 0:
260            bn = -bn
261
262    elif opcode == OP_NOT:
263        bn = long(bn == 0)
264
265    elif opcode == OP_0NOTEQUAL:
266        bn = long(bn != 0)
267
268    else:
269        raise AssertionError("Unknown unary opcode encountered; this should not happen")
270
271    stack.append(bitcoin.core._bignum.bn2vch(bn))
272
273
274# OP_LSHIFT and OP_RSHIFT are *not* included in this list as they are disabled
275_ISA_BINOP = {
276    OP_ADD,
277    OP_SUB,
278    OP_BOOLAND,
279    OP_BOOLOR,
280    OP_NUMEQUAL,
281    OP_NUMEQUALVERIFY,
282    OP_NUMNOTEQUAL,
283    OP_LESSTHAN,
284    OP_GREATERTHAN,
285    OP_LESSTHANOREQUAL,
286    OP_GREATERTHANOREQUAL,
287    OP_MIN,
288    OP_MAX,
289}
290
291def _BinOp(opcode, stack, err_raiser):
292    if len(stack) < 2:
293        err_raiser(MissingOpArgumentsError, opcode, stack, 2)
294
295    bn2 = _CastToBigNum(stack[-1], err_raiser)
296    bn1 = _CastToBigNum(stack[-2], err_raiser)
297
298    # We don't pop the stack yet so that OP_NUMEQUALVERIFY can raise
299    # VerifyOpFailedError with a correct stack.
300
301    if opcode == OP_ADD:
302        bn = bn1 + bn2
303
304    elif opcode == OP_SUB:
305        bn = bn1 - bn2
306
307    elif opcode == OP_BOOLAND:
308        bn = long(bn1 != 0 and bn2 != 0)
309
310    elif opcode == OP_BOOLOR:
311        bn = long(bn1 != 0 or bn2 != 0)
312
313    elif opcode == OP_NUMEQUAL:
314        bn = long(bn1 == bn2)
315
316    elif opcode == OP_NUMEQUALVERIFY:
317        bn = long(bn1 == bn2)
318        if not bn:
319            err_raiser(VerifyOpFailedError, opcode)
320        else:
321            # No exception, so time to pop the stack
322            stack.pop()
323            stack.pop()
324            return
325
326    elif opcode == OP_NUMNOTEQUAL:
327        bn = long(bn1 != bn2)
328
329    elif opcode == OP_LESSTHAN:
330        bn = long(bn1 < bn2)
331
332    elif opcode == OP_GREATERTHAN:
333        bn = long(bn1 > bn2)
334
335    elif opcode == OP_LESSTHANOREQUAL:
336        bn = long(bn1 <= bn2)
337
338    elif opcode == OP_GREATERTHANOREQUAL:
339        bn = long(bn1 >= bn2)
340
341    elif opcode == OP_MIN:
342        if bn1 < bn2:
343            bn = bn1
344        else:
345            bn = bn2
346
347    elif opcode == OP_MAX:
348        if bn1 > bn2:
349            bn = bn1
350        else:
351            bn = bn2
352
353    else:
354        raise AssertionError("Unknown binop opcode encountered; this should not happen")
355
356    stack.pop()
357    stack.pop()
358    stack.append(bitcoin.core._bignum.bn2vch(bn))
359
360
361def _CheckExec(vfExec):
362    for b in vfExec:
363        if not b:
364            return False
365    return True
366
367
368def _EvalScript(stack, scriptIn, txTo, inIdx, flags=()):
369    """Evaluate a script
370
371    """
372    if len(scriptIn) > MAX_SCRIPT_SIZE:
373        raise EvalScriptError('script too large; got %d bytes; maximum %d bytes' %
374                                        (len(scriptIn), MAX_SCRIPT_SIZE),
375                              stack=stack,
376                              scriptIn=scriptIn,
377                              txTo=txTo,
378                              inIdx=inIdx,
379                              flags=flags)
380
381    altstack = []
382    vfExec = []
383    pbegincodehash = 0
384    nOpCount = [0]
385    for (sop, sop_data, sop_pc) in scriptIn.raw_iter():
386        fExec = _CheckExec(vfExec)
387
388        def err_raiser(cls, *args):
389            """Helper function for raising EvalScriptError exceptions
390
391            cls   - subclass you want to raise
392
393            *args - arguments
394
395            Fills in the state of execution for you.
396            """
397            raise cls(*args,
398                    sop=sop,
399                    sop_data=sop_data,
400                    sop_pc=sop_pc,
401                    stack=stack, scriptIn=scriptIn, txTo=txTo, inIdx=inIdx, flags=flags,
402                    altstack=altstack, vfExec=vfExec, pbegincodehash=pbegincodehash, nOpCount=nOpCount[0])
403
404
405        if sop in DISABLED_OPCODES:
406            err_raiser(EvalScriptError, 'opcode %s is disabled' % OPCODE_NAMES[sop])
407
408        if sop > OP_16:
409            nOpCount[0] += 1
410            if nOpCount[0] > MAX_SCRIPT_OPCODES:
411                err_raiser(MaxOpCountError)
412
413        def check_args(n):
414            if len(stack) < n:
415                err_raiser(MissingOpArgumentsError, sop, stack, n)
416
417
418        if sop <= OP_PUSHDATA4:
419            if len(sop_data) > MAX_SCRIPT_ELEMENT_SIZE:
420                err_raiser(EvalScriptError,
421                           'PUSHDATA of length %d; maximum allowed is %d' %
422                                (len(sop_data), MAX_SCRIPT_ELEMENT_SIZE))
423
424            elif fExec:
425                stack.append(sop_data)
426                continue
427
428        elif fExec or (OP_IF <= sop <= OP_ENDIF):
429
430            if sop == OP_1NEGATE or ((sop >= OP_1) and (sop <= OP_16)):
431                v = sop - (OP_1 - 1)
432                stack.append(bitcoin.core._bignum.bn2vch(v))
433
434            elif sop in _ISA_BINOP:
435                _BinOp(sop, stack, err_raiser)
436
437            elif sop in _ISA_UNOP:
438                _UnaryOp(sop, stack, err_raiser)
439
440            elif sop == OP_2DROP:
441                check_args(2)
442                stack.pop()
443                stack.pop()
444
445            elif sop == OP_2DUP:
446                check_args(2)
447                v1 = stack[-2]
448                v2 = stack[-1]
449                stack.append(v1)
450                stack.append(v2)
451
452            elif sop == OP_2OVER:
453                check_args(4)
454                v1 = stack[-4]
455                v2 = stack[-3]
456                stack.append(v1)
457                stack.append(v2)
458
459            elif sop == OP_2ROT:
460                check_args(6)
461                v1 = stack[-6]
462                v2 = stack[-5]
463                del stack[-6]
464                del stack[-5]
465                stack.append(v1)
466                stack.append(v2)
467
468            elif sop == OP_2SWAP:
469                check_args(4)
470                tmp = stack[-4]
471                stack[-4] = stack[-2]
472                stack[-2] = tmp
473
474                tmp = stack[-3]
475                stack[-3] = stack[-1]
476                stack[-1] = tmp
477
478            elif sop == OP_3DUP:
479                check_args(3)
480                v1 = stack[-3]
481                v2 = stack[-2]
482                v3 = stack[-1]
483                stack.append(v1)
484                stack.append(v2)
485                stack.append(v3)
486
487            elif sop == OP_CHECKMULTISIG or sop == OP_CHECKMULTISIGVERIFY:
488                tmpScript = CScript(scriptIn[pbegincodehash:])
489                _CheckMultiSig(sop, tmpScript, stack, txTo, inIdx, flags, err_raiser, nOpCount)
490
491            elif sop == OP_CHECKSIG or sop == OP_CHECKSIGVERIFY:
492                check_args(2)
493                vchPubKey = stack[-1]
494                vchSig = stack[-2]
495                tmpScript = CScript(scriptIn[pbegincodehash:])
496
497                # Drop the signature, since there's no way for a signature to sign itself
498                #
499                # Of course, this can only come up in very contrived cases now that
500                # scriptSig and scriptPubKey are processed separately.
501                tmpScript = FindAndDelete(tmpScript, CScript([vchSig]))
502
503                ok = _CheckSig(vchSig, vchPubKey, tmpScript, txTo, inIdx,
504                               err_raiser)
505                if not ok and sop == OP_CHECKSIGVERIFY:
506                    err_raiser(VerifyOpFailedError, sop)
507
508                else:
509                    stack.pop()
510                    stack.pop()
511
512                    if ok:
513                        if sop != OP_CHECKSIGVERIFY:
514                            stack.append(b"\x01")
515                    else:
516                        # FIXME: this is incorrect, but not caught by existing
517                        # test cases
518                        stack.append(b"\x00")
519
520            elif sop == OP_CODESEPARATOR:
521                pbegincodehash = sop_pc
522
523            elif sop == OP_DEPTH:
524                bn = len(stack)
525                stack.append(bitcoin.core._bignum.bn2vch(bn))
526
527            elif sop == OP_DROP:
528                check_args(1)
529                stack.pop()
530
531            elif sop == OP_DUP:
532                check_args(1)
533                v = stack[-1]
534                stack.append(v)
535
536            elif sop == OP_ELSE:
537                if len(vfExec) == 0:
538                    err_raiser(EvalScriptError, 'ELSE found without prior IF')
539                vfExec[-1] = not vfExec[-1]
540
541            elif sop == OP_ENDIF:
542                if len(vfExec) == 0:
543                    err_raiser(EvalScriptError, 'ENDIF found without prior IF')
544                vfExec.pop()
545
546            elif sop == OP_EQUAL:
547                check_args(2)
548                v1 = stack.pop()
549                v2 = stack.pop()
550
551                if v1 == v2:
552                    stack.append(b"\x01")
553                else:
554                    stack.append(b"")
555
556            elif sop == OP_EQUALVERIFY:
557                check_args(2)
558                v1 = stack[-1]
559                v2 = stack[-2]
560
561                if v1 == v2:
562                    stack.pop()
563                    stack.pop()
564                else:
565                    err_raiser(VerifyOpFailedError, sop)
566
567            elif sop == OP_FROMALTSTACK:
568                if len(altstack) < 1:
569                    err_raiser(MissingOpArgumentsError, sop, altstack, 1)
570                v = altstack.pop()
571                stack.append(v)
572
573            elif sop == OP_HASH160:
574                check_args(1)
575                stack.append(bitcoin.core.serialize.Hash160(stack.pop()))
576
577            elif sop == OP_HASH256:
578                check_args(1)
579                stack.append(bitcoin.core.serialize.Hash(stack.pop()))
580
581            elif sop == OP_IF or sop == OP_NOTIF:
582                val = False
583
584                if fExec:
585                    check_args(1)
586                    vch = stack.pop()
587                    val = _CastToBool(vch)
588                    if sop == OP_NOTIF:
589                        val = not val
590
591                vfExec.append(val)
592
593
594            elif sop == OP_IFDUP:
595                check_args(1)
596                vch = stack[-1]
597                if _CastToBool(vch):
598                    stack.append(vch)
599
600            elif sop == OP_NIP:
601                check_args(2)
602                del stack[-2]
603
604            elif sop == OP_NOP:
605                pass
606
607            elif sop >= OP_NOP1 and sop <= OP_NOP10:
608                if SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS in flags:
609                    err_raiser(EvalScriptError, "%s reserved for soft-fork upgrades" % OPCODE_NAMES[sop])
610                else:
611                    pass
612
613            elif sop == OP_OVER:
614                check_args(2)
615                vch = stack[-2]
616                stack.append(vch)
617
618            elif sop == OP_PICK or sop == OP_ROLL:
619                check_args(2)
620                n = _CastToBigNum(stack.pop(), err_raiser)
621                if n < 0 or n >= len(stack):
622                    err_raiser(EvalScriptError, "Argument for %s out of bounds" % OPCODE_NAMES[sop])
623                vch = stack[-n-1]
624                if sop == OP_ROLL:
625                    del stack[-n-1]
626                stack.append(vch)
627
628            elif sop == OP_RETURN:
629                err_raiser(EvalScriptError, "OP_RETURN called")
630
631            elif sop == OP_RIPEMD160:
632                check_args(1)
633
634                h = hashlib.new('ripemd160')
635                h.update(stack.pop())
636                stack.append(h.digest())
637
638            elif sop == OP_ROT:
639                check_args(3)
640                tmp = stack[-3]
641                stack[-3] = stack[-2]
642                stack[-2] = tmp
643
644                tmp = stack[-2]
645                stack[-2] = stack[-1]
646                stack[-1] = tmp
647
648            elif sop == OP_SIZE:
649                check_args(1)
650                bn = len(stack[-1])
651                stack.append(bitcoin.core._bignum.bn2vch(bn))
652
653            elif sop == OP_SHA1:
654                check_args(1)
655                stack.append(hashlib.sha1(stack.pop()).digest())
656
657            elif sop == OP_SHA256:
658                check_args(1)
659                stack.append(hashlib.sha256(stack.pop()).digest())
660
661            elif sop == OP_SWAP:
662                check_args(2)
663                tmp = stack[-2]
664                stack[-2] = stack[-1]
665                stack[-1] = tmp
666
667            elif sop == OP_TOALTSTACK:
668                check_args(1)
669                v = stack.pop()
670                altstack.append(v)
671
672            elif sop == OP_TUCK:
673                check_args(2)
674                vch = stack[-1]
675                stack.insert(len(stack) - 2, vch)
676
677            elif sop == OP_VERIFY:
678                check_args(1)
679                v = _CastToBool(stack[-1])
680                if v:
681                    stack.pop()
682                else:
683                    raise err_raiser(VerifyOpFailedError, sop)
684
685            elif sop == OP_WITHIN:
686                check_args(3)
687                bn3 = _CastToBigNum(stack[-1], err_raiser)
688                bn2 = _CastToBigNum(stack[-2], err_raiser)
689                bn1 = _CastToBigNum(stack[-3], err_raiser)
690                stack.pop()
691                stack.pop()
692                stack.pop()
693                v = (bn2 <= bn1) and (bn1 < bn3)
694                if v:
695                    stack.append(b"\x01")
696                else:
697                    # FIXME: this is incorrect, but not caught by existing
698                    # test cases
699                    stack.append(b"\x00")
700
701            else:
702                err_raiser(EvalScriptError, 'unsupported opcode 0x%x' % sop)
703
704        # size limits
705        if len(stack) + len(altstack) > MAX_STACK_ITEMS:
706            err_raiser(EvalScriptError, 'max stack items limit reached')
707
708    # Unterminated IF/NOTIF/ELSE block
709    if len(vfExec):
710        raise EvalScriptError('Unterminated IF/ELSE block',
711                              stack=stack,
712                              scriptIn=scriptIn,
713                              txTo=txTo,
714                              inIdx=inIdx,
715                              flags=flags)
716
717
718def EvalScript(stack, scriptIn, txTo, inIdx, flags=()):
719    """Evaluate a script
720
721    stack    - Initial stack
722
723    scriptIn - Script
724
725    txTo     - Transaction the script is a part of
726
727    inIdx    - txin index of the scriptSig
728
729    flags    - SCRIPT_VERIFY_* flags to apply
730    """
731
732    try:
733        _EvalScript(stack, scriptIn, txTo, inIdx, flags=flags)
734    except CScriptInvalidError as err:
735        raise EvalScriptError(repr(err),
736                              stack=stack,
737                              scriptIn=scriptIn,
738                              txTo=txTo,
739                              inIdx=inIdx,
740                              flags=flags)
741
742class VerifyScriptError(bitcoin.core.ValidationError):
743    pass
744
745def VerifyScript(scriptSig, scriptPubKey, txTo, inIdx, flags=()):
746    """Verify a scriptSig satisfies a scriptPubKey
747
748    scriptSig    - Signature
749
750    scriptPubKey - PubKey
751
752    txTo         - Spending transaction
753
754    inIdx        - Index of the transaction input containing scriptSig
755
756    Raises a ValidationError subclass if the validation fails.
757    """
758    stack = []
759    EvalScript(stack, scriptSig, txTo, inIdx, flags=flags)
760    if SCRIPT_VERIFY_P2SH in flags:
761        stackCopy = list(stack)
762    EvalScript(stack, scriptPubKey, txTo, inIdx, flags=flags)
763    if len(stack) == 0:
764        raise VerifyScriptError("scriptPubKey left an empty stack")
765    if not _CastToBool(stack[-1]):
766        raise VerifyScriptError("scriptPubKey returned false")
767
768    # Additional validation for spend-to-script-hash transactions
769    if SCRIPT_VERIFY_P2SH in flags and scriptPubKey.is_p2sh():
770        if not scriptSig.is_push_only():
771            raise VerifyScriptError("P2SH scriptSig not is_push_only()")
772
773        # restore stack
774        stack = stackCopy
775
776        # stack cannot be empty here, because if it was the
777        # P2SH  HASH <> EQUAL  scriptPubKey would be evaluated with
778        # an empty stack and the EvalScript above would return false.
779        assert len(stack)
780
781        pubKey2 = CScript(stack.pop())
782
783        EvalScript(stack, pubKey2, txTo, inIdx, flags=flags)
784
785        if not len(stack):
786            raise VerifyScriptError("P2SH inner scriptPubKey left an empty stack")
787
788        if not _CastToBool(stack[-1]):
789            raise VerifyScriptError("P2SH inner scriptPubKey returned false")
790
791    if SCRIPT_VERIFY_CLEANSTACK in flags:
792        assert SCRIPT_VERIFY_P2SH in flags
793
794        if len(stack) != 1:
795            raise VerifyScriptError("scriptPubKey left extra items on stack")
796
797
798class VerifySignatureError(bitcoin.core.ValidationError):
799    pass
800
801def VerifySignature(txFrom, txTo, inIdx):
802    """Verify a scriptSig signature can spend a txout
803
804    Verifies that the scriptSig in txTo.vin[inIdx] is a valid scriptSig for the
805    corresponding COutPoint in transaction txFrom.
806    """
807    if inIdx < 0:
808        raise VerifySignatureError("inIdx negative")
809    if inIdx >= len(txTo.vin):
810        raise VerifySignatureError("inIdx >= len(txTo.vin)")
811    txin = txTo.vin[inIdx]
812
813    if txin.prevout.n < 0:
814        raise VerifySignatureError("txin prevout.n negative")
815    if txin.prevout.n >= len(txFrom.vout):
816        raise VerifySignatureError("txin prevout.n >= len(txFrom.vout)")
817    txout = txFrom.vout[txin.prevout.n]
818
819    if txin.prevout.hash != txFrom.GetTxid():
820        raise VerifySignatureError("prevout hash does not match txFrom")
821
822    VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, inIdx)
823
824
825__all__ = (
826        'MAX_STACK_ITEMS',
827        'SCRIPT_VERIFY_P2SH',
828        'SCRIPT_VERIFY_STRICTENC',
829        'SCRIPT_VERIFY_DERSIG',
830        'SCRIPT_VERIFY_LOW_S',
831        'SCRIPT_VERIFY_NULLDUMMY',
832        'SCRIPT_VERIFY_SIGPUSHONLY',
833        'SCRIPT_VERIFY_MINIMALDATA',
834        'SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS',
835        'SCRIPT_VERIFY_CLEANSTACK',
836        'SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY',
837        'SCRIPT_VERIFY_FLAGS_BY_NAME',
838        'EvalScriptError',
839        'MaxOpCountError',
840        'MissingOpArgumentsError',
841        'ArgumentsInvalidError',
842        'VerifyOpFailedError',
843        'EvalScript',
844        'VerifyScriptError',
845        'VerifyScript',
846        'VerifySignatureError',
847        'VerifySignature',
848)
849