def dump (self): print 'hash: %s' % (hexify (dhash (self.render())),) print 'inputs: %d' % (len(self.inputs)) for i in range (len (self.inputs)): (outpoint, index), script, sequence = self.inputs[i] redeem = pprint_script (parse_script (script)) print '%3d %s:%d %r %d' % (i, hexify(outpoint), index, redeem, sequence) print '%d outputs' % (len(self.outputs)) for i in range (len (self.outputs)): value, pk_script = self.outputs[i] pk_script = pprint_script (parse_script (pk_script)) print '%3d %s %r' % (i, bcrepr (value), pk_script) print 'lock_time:', self.lock_time
def dump_tx (self, PUSH, tx, tx_num): PUSH ( elem0 ('tr'), TD (tx_num), TD (shorten (Name (dhash (tx.raw)).hex())), elem0 ('td'), elem0 ('table'), ) for i in range (len (tx.inputs)): (outpoint, index), script, sequence = tx.inputs[i] if tx_num == 0: script = shorthex (script) else: script = describe_iscript (parse_script (script)) PUSH (trow (shorten (outpoint.hex()), index, script)) PUSH (elems1 ('table', 'td')) PUSH (elem0 ('td'), elem0 ('table')) for i in range (len (tx.outputs)): value, pk_script = tx.outputs[i] kind, addr = get_output_addr (pk_script) if kind == 'normal': kind = '' else: kind = kind + ':' k = '%s%s' % (kind, addr) PUSH (trow (i, bcrepr (value), k)) #RP ('</table></td><td>%s</td></tr>' % tx.lock_time,) PUSH (elems1 ('table', 'td', 'tr'))
def describe_iscript(p): if len(p) == 2 and p[0][0] == 0 and p[1][0] == 0: # PUSH PUSH pubkey = p[1][1] if pubkey[0] in ('\x02', '\x03', '\x04'): return key_to_address(rhash(pubkey)) else: return shorthex(pubkey) elif p[0] == (0, '', PUSH_OP) and all([x[0] == 0 for x in p[1:]]): # p2sh redeem sigs = p[1:-1] try: redeem = parse_script(p[-1][1]) probe = is_multi_tx(redeem) if probe is not None: _, val = probe else: val = repr(probe) return 'p2sh (%d sigs):%s' % (len(sigs), val) except ScriptError: return 'bad p2sh' elif len(p) == 1 and p[0][0] == 0: return 'sig' else: return repr(pprint_script(p))
def describe_iscript (p): if len(p) == 2 and p[0][0] == 0 and p[1][0] == 0: # PUSH PUSH pubkey = p[1][1] if pubkey[0] in ('\x02', '\x03', '\x04'): return key_to_address (rhash (pubkey)) else: return shorthex (pubkey) elif p[0] == (0, '', PUSH_OP) and all ([x[0] == 0 for x in p[1:]]): # p2sh redeem sigs = p[1:-1] try: redeem = parse_script (p[-1][1]) probe = is_multi_tx (redeem) if probe is not None: _, val = probe else: val = repr(probe) return 'p2sh (%d sigs):%s' % (len(sigs), val) except ScriptError: return 'bad p2sh' elif len(p) == 1 and p[0][0] == 0: return 'sig' else: return repr (pprint_script (p))
def dump_tx (self, request, tx, tx_num): RP = request.push RP ('<tr><td>%s</td><td>%s</td>\r\n' % (tx_num, shorthex (dhash (tx.raw)))) RP ('<td><table>') for i in range (len (tx.inputs)): (outpoint, index), script, sequence = tx.inputs[i] RP ('<tr><td>%3d</td><td>%s:%d</td><td>%s</td></tr>' % ( i, shorthex (outpoint), index, shorthex (script), )) RP ('</table></td><td><table>') for i in range (len (tx.outputs)): value, pk_script = tx.outputs[i] script = parse_script (pk_script) parsed = pprint_script (script) if is_normal_tx (parsed): h = script[2][1] k = key_to_address (h) elif is_pubkey_tx (parsed): pk = script[0][1] k = 'pk:' + key_to_address (rhash (pk)) elif is_p2sh_tx (parsed): h = script[1][1] k = 'p2sh:' + key_to_address (h, 5) else: k = parsed RP ('<tr><td>%s</td><td>%s</td></tr>' % (bcrepr (value), k)) # lock time seems to always be zero #RP ('</table></td><td>%s</td></tr>' % tx.lock_time,) RP ('</table></td></tr>')
def dump_tx(self, request, tx, tx_num): RP = request.push RP('<tr><td>%s</td><td>%s</td>\r\n' % (tx_num, shorthex(dhash(tx.raw)))) RP('<td><table>') for i in range(len(tx.inputs)): (outpoint, index), script, sequence = tx.inputs[i] RP('<tr><td>%3d</td><td>%s:%d</td><td>%s</td></tr>' % ( i, shorthex(outpoint), index, shorthex(script), )) RP('</table></td><td><table>') for i in range(len(tx.outputs)): value, pk_script = tx.outputs[i] script = parse_script(pk_script) parsed = pprint_script(script) if is_normal_tx(parsed): h = script[2][1] k = key_to_address(h) elif is_pubkey_tx(parsed): pk = script[0][1] k = 'pk:' + key_to_address(rhash(pk)) elif is_p2sh_tx(parsed): h = script[1][1] k = 'p2sh:' + key_to_address(h, 5) else: k = parsed RP('<tr><td>%s</td><td>%s</td></tr>' % (bcrepr(value), k)) # lock time seems to always be zero #RP ('</table></td><td>%s</td></tr>' % tx.lock_time,) RP('</table></td></tr>')
def dump(self, fout=sys.stdout): D = fout.write D('hash: %s\n' % (hexify(dhash(self.render())), )) D('inputs: %d\n' % (len(self.inputs))) for i in range(len(self.inputs)): (outpoint, index), script, sequence = self.inputs[i] try: redeem = pprint_script(parse_script(script)) except ScriptError: redeem = script.encode('hex') D('%3d %064x:%d %r %d\n' % (i, outpoint, index, redeem, sequence)) D('outputs: %d\n' % (len(self.outputs), )) for i in range(len(self.outputs)): value, pk_script = self.outputs[i] pk_script = pprint_script(parse_script(pk_script)) D('%3d %s %r\n' % (i, bcrepr(value), pk_script)) D('lock_time: %s\n' % (self.lock_time, ))
def check_sig(self, s): pub_key = self.pop() sig = self.pop() s0 = parse_script(s) s1 = remove_codeseps(s0) s2 = remove_sigs(s1, [sig]) # rare? s3 = unparse_script(s2) return self.check_one_sig(pub_key, sig, s3)
def dump (self, fout=sys.stdout): D = fout.write D ('hash: %s\n' % (hexify (dhash (self.render())),)) D ('inputs: %d\n' % (len(self.inputs))) for i in range (len (self.inputs)): (outpoint, index), script, sequence = self.inputs[i] try: redeem = pprint_script (parse_script (script)) except ScriptError: redeem = script.encode ('hex') D ('%3d %064x:%d %r %d\n' % (i, outpoint, index, redeem, sequence)) D ('outputs: %d\n' % (len(self.outputs),)) for i in range (len (self.outputs)): value, pk_script = self.outputs[i] pk_script = pprint_script (parse_script (pk_script)) D ('%3d %s %r\n' % (i, bcrepr (value), pk_script)) D ('lock_time: %s\n' % (self.lock_time,))
def check_sig (self, s): pub_key = self.pop() sig = self.pop() s0 = parse_script (s) s1 = remove_codeseps (s0) s2 = remove_sigs (s1, [sig]) # rare? s3 = unparse_script (s2) return self.check_one_sig (pub_key, sig, s3)
def verify0 (self, index, prev_outscript): outpoint, script, sequence = self.inputs[index] m = verifying_machine (prev_outscript, self, index) #print 'source script', pprint_script (parse_script (script)) eval_script (m, parse_script (script)) m.clear_alt() # should terminate with OP_CHECKSIG or its like #print 'redeem script', pprint_script (parse_script (prev_outscript)) r = eval_script (m, parse_script (prev_outscript)) if r is None: # if the script did not end in a CHECKSIG op, we need # to check the top of the stack (essentially, OP_VERIFY) m.need (1) if not m.truth(): raise VerifyError elif r == 1: pass else: # this can happen if r == 0 (verify failed) or r == -1 (openssl error) raise VerifyError
def verify0(self, index, prev_outscript): outpoint, script, sequence = self.inputs[index] m = verifying_machine(prev_outscript, self, index) #print 'source script', pprint_script (parse_script (script)) eval_script(m, parse_script(script)) m.clear_alt() # should terminate with OP_CHECKSIG or its like #print 'redeem script', pprint_script (parse_script (prev_outscript)) r = eval_script(m, parse_script(prev_outscript)) if r is None: # if the script did not end in a CHECKSIG op, we need # to check the top of the stack (essentially, OP_VERIFY) m.need(1) if not m.truth(): raise VerifyError elif r == 1: pass else: # this can happen if r == 0 (verify failed) or r == -1 (openssl error) raise VerifyError
def get_output_addr (pk_script): if len(pk_script) > 500: return 'big', '' try: script = parse_script (pk_script) probe = is_normal_tx (script) if not probe: probe = is_pubkey_tx (script) if not probe: probe = is_p2sh_tx (script) if not probe: probe = is_multi_tx (script) if probe: return probe else: return 'other', repr (pprint_script (script)) except: return 'bad', pk_script.encode ('hex')
def check_multi_sig(self, s): npub = self.pop_int() #print 'npub=', npub pubs = [self.pop() for x in range(npub)] nsig = self.pop_int() #print 'nsig=', nsig sigs = [self.pop() for x in range(nsig)] s0 = parse_script(s) s1 = remove_codeseps(s0) s2 = remove_sigs(s1, sigs) # rare? s3 = unparse_script(s2) for sig in sigs: nmatch = 0 #print 'checking sig...' for pub in pubs: if self.check_one_sig(pub, sig, s3): nmatch += 1 if nmatch == 0: #print 'sig matched no pubs' return 0 return 1
def check_multi_sig (self, s): npub = self.pop_int() #print 'npub=', npub pubs = [self.pop() for x in range (npub)] nsig = self.pop_int() #print 'nsig=', nsig sigs = [self.pop() for x in range (nsig)] s0 = parse_script (s) s1 = remove_codeseps (s0) s2 = remove_sigs (s1, sigs) # rare? s3 = unparse_script (s2) for sig in sigs: nmatch = 0 #print 'checking sig...' for pub in pubs: if self.check_one_sig (pub, sig, s3): nmatch += 1 if nmatch == 0: #print 'sig matched no pubs' return 0 return 1