<s> """<STR_LIT>""" <EOL> import logging <EOL> from ... import ecdsa <EOL> from ... encoding import sec_to_public_pair <EOL> from . import der <EOL> from . import opcodes <EOL> from . import ScriptError <EOL> from . microcode import MICROCODE_LOOKUP , VCH_TRUE , make_bool <EOL> from . tools import get_opcode <EOL> VERIFY_OPS = frozenset ( ( opcodes . OPCODE_TO_INT [ s ] for s in "<STR_LIT>" . split ( ) ) ) <EOL> INVALID_OPCODE_VALUES = frozenset ( ( opcodes . OPCODE_TO_INT [ s ] for s in "<STR_LIT>" . split ( ) ) ) <EOL> def check_signature ( script , signature_hash , public_key_blob , sig_blob , hash_type ) : <EOL> """<STR_LIT>""" <EOL> signature_type = ord ( sig_blob [ - <NUM_LIT:1> : ] ) <EOL> if signature_type != <NUM_LIT:1> : <EOL> raise ScriptError ( "<STR_LIT>" % signature_type ) <EOL> sig_pair = der . sigdecode_der ( sig_blob [ : - <NUM_LIT:1> ] ) <EOL> if hash_type == <NUM_LIT:0> : <EOL> hash_type = signature_type <EOL> elif hash_type != signature_type : <EOL> raise ScriptError ( "<STR_LIT>" ) <EOL> public_pair = sec_to_public_pair ( public_key_blob ) <EOL> v = ecdsa . verify ( ecdsa . generator_secp256k1 , public_pair , signature_hash , sig_pair ) <EOL> return make_bool ( v ) <EOL> def eval_script ( script , signature_hash , hash_type , stack = [ ] ) : <EOL> altstack = [ ] <EOL> if len ( script ) > <NUM_LIT> : <EOL> return False <EOL> pc = <NUM_LIT:0> <EOL> begin_code_hash = pc <EOL> if_condition = None <EOL> try : <EOL> while pc < len ( script ) : <EOL> opcode , data , pc = get_opcode ( script , pc ) <EOL> if len ( data ) > <NUM_LIT:0> : <EOL> stack . append ( data ) <EOL> continue <EOL> if if_condition is not None : <EOL> if opcode == opcodes . OP_ELSE : <EOL> if_condition = not if_condition <EOL> continue <EOL> if opcode == opcodes . OP_ENDIF : <EOL> if_condition = None <EOL> continue <EOL> if not if_condition : <EOL> continue <EOL> if opcode in ( opcodes . OP_IF , opcodes . OP_NOTIF ) : <EOL> if_condition = ( stack . pop ( ) == VCH_TRUE ) <EOL> continue <EOL> if opcode == opcodes . OP_CODESEPARATOR : <EOL> begin_code_hash = pc - <NUM_LIT:1> <EOL> continue <EOL> if opcode in INVALID_OPCODE_VALUES : <EOL> raise ScriptError ( "<STR_LIT>" % ( opcodes . INT_TO_OPCODE [ opcode ] , pc - <NUM_LIT:1> ) ) <EOL> if opcode in MICROCODE_LOOKUP : <EOL> MICROCODE_LOOKUP [ opcode ] ( stack ) <EOL> if opcode in VERIFY_OPS : <EOL> v = stack . pop ( ) <EOL> if v != VCH_TRUE : <EOL> raise ScriptError ( "<STR_LIT>" % ( pc - <NUM_LIT:1> ) ) <EOL> continue <EOL> if opcode == opcodes . OP_TOALTSTACK : <EOL> altstack . append ( stack . pop ( ) ) <EOL> continue <EOL> if opcode == opcodes . OP_FROMALTSTACK : <EOL> stack . append ( altstack . pop ( ) ) <EOL> continue <EOL> if opcode >= opcodes . OP_1NEGATE and opcode <= opcodes . OP_16 : <EOL> stack . append ( opcode + <NUM_LIT:1> - opcodes . OP_1 ) <EOL> continue <EOL> if opcode in ( opcodes . OP_ELSE , opcodes . OP_ENDIF ) : <EOL> raise ScriptError ( "<STR_LIT>" % opcodes . INT_TO_OPCODE [ opcode ] ) <EOL> if opcode in ( opcodes . OP_CHECKSIG , opcodes . OP_CHECKSIGVERIFY ) : <EOL> public_key_blob = stack . pop ( ) <EOL> sig_blob = stack . pop ( ) <EOL> v = check_signature ( script , signature_hash , public_key_blob , sig_blob , hash_type ) <EOL> stack . append ( v ) <EOL> if opcode == opcodes . OP_CHECKSIGVERIFY : <EOL> if stack . pop ( ) != VCH_TRUE : <EOL> raise ScriptError ( "<STR_LIT>" % pc - <NUM_LIT:1> ) <EOL> continue <EOL> if opcode in VERIFY_OPS : <EOL> v = stack . pop ( ) <EOL> if v != VCH_TRUE : <EOL> raise ScriptError ( "<STR_LIT>" % pc - <NUM_LIT:1> ) <EOL> logging . error ( "<STR_LIT>" , opcode ) <EOL> except Exception : <EOL> logging . exception ( "<STR_LIT>" ) <EOL> return len ( stack ) != <NUM_LIT:0> <EOL> def verify_script ( script_signature , script_public_key , signature_hash , hash_type = <NUM_LIT:0> ) : <EOL> stack = [ ] <EOL> if not eval_script ( script_signature , signature_hash , hash_type , stack ) : <EOL> logging . debug ( "<STR_LIT>" ) <EOL> return False <EOL> if not eval_script ( script_public_key , signature_hash , hash_type , stack ) : <EOL> logging . debug ( "<STR_LIT>" ) <EOL> return False <EOL> return stack [ - <NUM_LIT:1> ] == VCH_TRUE </s>
