evaluateにより、script_sigとscript_pubkeyの検証を行いたい
Scriptの第二引数である0xac(172)はOP_CHECKSIG
from script import Script z = 0x7c076ff316692a3d7eb3c3bb0f8b1488cf72e1afcd929e29307032997a838a3d sec = bytes.fromhex('04887387e452b8eacc4acfde10d9aaf7f6d9a0f975aabb10d006e\ 4da568744d06c61de6d95231cd89026e286df3b6ae4a894a3378e393e93a0f45b666329a0ae34') sig = bytes.fromhex('3045022000eff69ef2b1bd93a66ed5219add4fb51e11a840f4048\ 76325a1e8ffe0529a2c022100c7207fee197d27c618aea621406f6bf5ef6fca38681d82b2f06fd\ dbdce6feab601') script_pubkey = Script([sec, 0xac]) script_sig = Script([sig]) combined_script = script_sig + script_pubkey print(combined_script.evaluate(z))
def evaluate(self, z): cmds = self.cmds[:] stack = [] altstack = [] while len(cmds) > 0: cmd = cmds.pop(0) if type(cmd) == int: operation = OP_CODE_FUNCTIONS[cmd] if cmd in (99, 100): if not operation(stack, cmds): LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd])) return False elif cmd in (107, 108): if not operation(stack, altstack): LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd])) return False elif cmd in (172, 173, 174, 175): if not operation(stack, z): LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd])) return False else: if not operation(stack): LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd])) return False else: stack.append(cmd) if len(stack) == 0: return False if statck.pop() == b'': return False return True
99: op_if,
100: op_notif,
op_if: If the top stack value is not False, the statements are executed. The top stack value is removed.
def op_if(stack, items): if len(stack) < 1: return False true_items = [] false_itmes = [] current_array = true_items found = False num_endifs_needed = 1 while len(items) > 0: item = items.pop(0) if item in (99, 100): num_endifs_needed += 1 current_array.append(item) elif num_endifs_needed == 1 and item == 103: current_array = false_items elif item == 104: if num_endifs_needed == 1: found = True break else: num_endifs_neede -= 1 current_array.append(item) else: current_array.append(item) if not found: return False element = stack.pop() if decode_num(element) == 0: items[:0] = false_items else: items[:0] = true_items return True
op_notif: If the top stack value is False, the statements are executed. The top stack value is removed.
def op_notif(stack, items): if len(stack) < 1: return False true_items = [] false_items = [] current_array = true_items found = False num_endifs_needed = 1 while len(items) > 0: item = items.pop(0) if item in (99, 100): num_endifs_needed += 1 current_array.append(item) elif num_endifs_needed == 1 and item == 103: current_array = false_items elif item == 104: if num_endifs_needed == 1: found = True break else: num_endifs_needed -= 1 current_array.append(item) else: current_array.append(item) if not found: return False element = stack.pop() if decode_num(element) == 0: items[:0] = true_items else: items[:0] = false_items return True
—–
107: op_toaltstack,
108: op_fromaltstack,
op_toaltstack:
def op_toaltstack(stack, altstack): if len(stack) < 1: return False altstack.append(stack.pop()) return True
op_fromaltstack
def op_fromaltstack(stack, altstack): if len(altstack) < 1: return False stack.append(alstack.pop()) return True
172: op_checksig,
173: op_checksigverify,
174: op_checkmultisig,
175: op_checkmultisigverify,
0xac(172)のOP_CHECKSIGが非常に重要