(self, z, witness)
| 154 | return encode_varint(total) + result |
| 155 | |
| 156 | def evaluate(self, z, witness): |
| 157 | # create a copy as we may need to add to this list if we have a |
| 158 | # RedeemScript |
| 159 | cmds = self.cmds[:] |
| 160 | stack = [] |
| 161 | altstack = [] |
| 162 | while len(cmds) > 0: |
| 163 | cmd = cmds.pop(0) |
| 164 | if type(cmd) == int: |
| 165 | # do what the opcode says |
| 166 | operation = OP_CODE_FUNCTIONS[cmd] |
| 167 | if cmd in (99, 100): |
| 168 | # op_if/op_notif require the cmds array |
| 169 | if not operation(stack, cmds): |
| 170 | LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd])) |
| 171 | return False |
| 172 | elif cmd in (107, 108): |
| 173 | # op_toaltstack/op_fromaltstack require the altstack |
| 174 | if not operation(stack, altstack): |
| 175 | LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd])) |
| 176 | return False |
| 177 | elif cmd in (172, 173, 174, 175): |
| 178 | # these are signing operations, they need a sig_hash |
| 179 | # to check against |
| 180 | if not operation(stack, z): |
| 181 | LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd])) |
| 182 | return False |
| 183 | else: |
| 184 | if not operation(stack): |
| 185 | LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd])) |
| 186 | return False |
| 187 | else: |
| 188 | # add the cmd to the stack |
| 189 | stack.append(cmd) |
| 190 | # p2sh rule. if the next three cmds are: |
| 191 | # OP_HASH160 <20 byte hash> OP_EQUAL this is the RedeemScript |
| 192 | # OP_HASH160 == 0xa9 and OP_EQUAL == 0x87 |
| 193 | if len(cmds) == 3 and cmds[0] == 0xa9 \ |
| 194 | and type(cmds[1]) == bytes and len(cmds[1]) == 20 \ |
| 195 | and cmds[2] == 0x87: |
| 196 | redeem_script = encode_varint(len(cmd)) + cmd |
| 197 | # we execute the next three opcodes |
| 198 | cmds.pop() |
| 199 | h160 = cmds.pop() |
| 200 | cmds.pop() |
| 201 | if not op_hash160(stack): |
| 202 | return False |
| 203 | stack.append(h160) |
| 204 | if not op_equal(stack): |
| 205 | return False |
| 206 | # final result should be a 1 |
| 207 | if not op_verify(stack): |
| 208 | LOGGER.info('bad p2sh h160') |
| 209 | return False |
| 210 | # hashes match! now add the RedeemScript |
| 211 | redeem_script = encode_varint(len(cmd)) + cmd |
| 212 | stream = BytesIO(redeem_script) |
| 213 | cmds.extend(Script.parse(stream).cmds) |
no test coverage detected