예제 #1
0
 def evaluate(self, z):
     # create a copy as we may need to add to this list if we have a
     # RedeemScript
     commands = self.commands[:]
     stack = []
     altstack = []
     while len(commands) > 0:
         command = commands.pop(0)
         if type(command) == int:
             # do what the op code says
             operation = op_function(command)
             if command in (99, 100):
                 # op_if/op_notif require the commands array
                 if not operation(stack, commands):
                     print(f'bad op: {op_name(command)}')
                     return False
             elif command in (107, 108):
                 # op_toaltstack/op_fromaltstack require the altstack
                 if not operation(stack, altstack):
                     print(f'bad op: {op_name(command)}')
                     return False
             elif command in (172, 173, 174, 175):
                 # these are signing operations, they need a sig_hash
                 # to check against
                 if not operation(stack, z):
                     print(f'bad op: {op_name(command)}')
                     return False
             else:
                 if not operation(stack):
                     print(f'bad op: {op_name(command)}')
                     return False
         else:
             # add the command to the stack
             stack.append(command)
     if len(stack) == 0:
         return False
     if stack.pop() == b'':
         return False
     return True
예제 #2
0
 def evaluate(self, z):
     # create a copy as we may need to add to this list if we have a
     # RedeemScript
     commands = self.commands[:]
     stack = []
     altstack = []
     while len(commands) > 0:
         command = commands.pop(0)
         if type(command) == int:
             # do what the op code says
             operation = op_function(command)
             if command in (99, 100):
                 # op_if/op_notif require the commands array
                 if not operation(stack, commands):
                     print(f'bad op: {op_name(command)}')
                     return False
             elif command in (107, 108):
                 # op_toaltstack/op_fromaltstack require the altstack
                 if not operation(stack, altstack):
                     print(f'bad op: {op_name(command)}')
                     return False
             elif command in (172, 173, 174, 175):
                 # these are signing operations, they need a sig_hash
                 # to check against
                 if not operation(stack, z):
                     print(f'bad op: {op_name(command)}')
                     return False
             else:
                 if not operation(stack):
                     print(f'bad op: {op_name(command)}')
                     return False
         else:
             # add the command to the stack
             stack.append(command)
             # p2sh rule. if the next three commands are:
             # OP_HASH160 <20 byte hash> OP_EQUAL this is the RedeemScript
             # OP_HASH160 == 0xa9 and OP_EQUAL == 0x87
             if len(commands) == 3 and commands[0] == 0xa9 \
                 and type(commands[1]) == bytes and len(commands[1]) == 20 \
                 and commands[2] == 0x87:
                 redeem_script = encode_varint(len(command)) + command
                 # we execute the next three op codes
                 commands.pop()
                 h160 = commands.pop()
                 commands.pop()
                 if not op_hash160(stack):
                     return False
                 stack.append(h160)
                 if not op_equal(stack):
                     return False
                 # final result should be a 1
                 if not op_verify(stack):
                     print('bad p2sh h160')
                     return False
                 # hashes match! now add the RedeemScript
                 stream = BytesIO(redeem_script)
                 commands.extend(Script.parse(stream).commands)
     if len(stack) == 0:
         return False
     if stack.pop() == b'':
         return False
     return True