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