MCPcopy Index your code
hub / github.com/jimmysong/programmingbitcoin / evaluate

Method evaluate

code-ch13/script.py:156–244  ·  view source on GitHub ↗
(self, z, witness)

Source from the content-addressed store, hash-verified

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)

Callers 1

verify_inputMethod · 0.45

Calls 8

encode_varintFunction · 0.90
op_hash160Function · 0.90
op_equalFunction · 0.90
op_verifyFunction · 0.90
sha256Function · 0.90
p2pkh_scriptFunction · 0.70
parseMethod · 0.45
hexMethod · 0.45

Tested by

no test coverage detected