def test_script_type_pay_to_public_pair(self): for se in range(1, 100): key = Key(secret_exponent=se) for b in [True, False]: st = ScriptPayToPublicKey.from_key(key, use_uncompressed=b) addr = key.address(use_uncompressed=b) self.assertEqual(st.address(), addr) sc = st.script() st = script_obj_from_script(sc) self.assertEqual(st.address(), addr)
def test_script_type_pay_to_address(self): for se in range(1, 100): key = Key(secret_exponent=se) for b in [True, False]: addr = key.address(use_uncompressed=b) st = script_obj_from_address(addr) self.assertEqual(st.address(), addr) sc = st.script() st = script_obj_from_script(sc) self.assertEqual(st.address(), addr)
def test_sign(self): sv = 33143560198659167577410026742586567991638126035902913554051654024377193788946 tx_out_script = b'v\xa9\x14\x91\xb2K\xf9\xf5(\x852\x96\n\xc6\x87\xab\xb05\x12{\x1d(\xa5\x88\xac' st = script_obj_from_script(tx_out_script) hl = build_hash160_lookup([1]) solution = st.solve(hash160_lookup=hl, signature_for_hash_type_f=const_f(sv), signature_type=SIGHASH_ALL) self.assertEqual( solution, h2b("47304402205e3df5b55be62140042c220b1fdf105cc85113af562a215c1fc5b5c522d1" "b3d3022038c9594b156faed7f37c30077affbf6acf42bf17b1e639a1fcc6c51a67aba2" "1601410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817" "98483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" ))
def test_solve_pay_to_public_pair(self): for se in range(1, 10): key = Key(secret_exponent=se) for b in [True, False]: addr = key.address(use_uncompressed=b) st = ScriptPayToPublicKey.from_key(key, use_uncompressed=b) self.assertEqual(st.address(), addr) hl = build_hash160_lookup([se]) sv = 100 st.solve(hash160_lookup=hl, signature_for_hash_type_f=const_f(sv), signature_type=SIGHASH_ALL) sc = st.script() st = script_obj_from_script(sc) self.assertEqual(st.address(), addr)
def who_signed_tx(tx, tx_in_idx, netcode='BTC'): """ Given a transaction (tx) an input index (tx_in_idx), attempt to figure out which addresses where used in signing (so far). This method depends on tx.unspents being properly configured. This should work on partially-signed MULTISIG transactions (it will return as many addresses as there are good signatures). Returns a list of ( address, sig_type ) pairs. Raises NoAddressesForScriptTypeError if addresses cannot be determined for the input's script. TODO: This does not yet support P2SH. """ tx_in = tx.txs_in[tx_in_idx] parent_tx_out_idx = tx_in.previous_index parent_tx_out_script = tx.unspents[tx_in_idx].script script_obj = script_obj_from_script(parent_tx_out_script) signed_by = [] if type(script_obj) not in (ScriptPayToAddress, ScriptPayToPublicKey, ScriptMultisig): raise NoAddressesForScriptTypeError( 'unable to determine signing addresses for script type of parent tx {}[{}]' .format(b2h_rev(tx_in.previous_hash), parent_tx_out_idx)) script = tx_in.script pc = 0 while pc < len(script): opcode, data, pc = get_opcode(script, pc) if data is None: continue try: sig_pair, sig_type = parse_signature_blob(data) except (ValueError, TypeError, binascii.Error, UnexpectedDER): continue sig_hash = tx.signature_hash(parent_tx_out_script, parent_tx_out_idx, sig_type) for sec_key in script_obj.sec_keys: public_pair = sec_to_public_pair(sec_key) if secp256k1_generator.verify(public_pair, sig_hash, sig_pair): addr_pfx = address_prefix_for_netcode(netcode) addr = public_pair_to_bitcoin_address(public_pair, address_prefix=addr_pfx) signed_by.append((addr, sig_type)) return signed_by
def test_recognize_multisig(self): h = ( "010000000139c92b102879eb95f14e7344e4dd7d481e1238b1bfb1fa0f735068d2927b" "231400000000910047304402208fc06d216ebb4b6a3a3e0f906e1512c372fa8a9c2a92" "505d04e9b451ea7acd0c0220764303bb7e514ddd77855949d941c934e9cbda8e3c3827" "bfdb5777477e73885b014730440220569ec6d2e81625dd18c73920e0079cdb4c1d67d3" "d7616759eb0c18cf566b3d3402201c60318f0a62e3ba85ca0f158d4dfe63c0779269eb" "6765b6fc939fc51e7a8ea901ffffffff0140787d01000000001976a914641ad5051edd" "97029a003fe9efb29359fcee409d88ac0000000040787d0100000000c952410496ec45" "f878b62c46c4be8e336dff7cc58df9b502178cc240eb3d31b1266f69f5767071aa3e01" "7d1b82a0bb28dab5e27d4d8e9725b3e68ed5f8a2d45c730621e34104cc71eb30d653c0" "c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b8" "7bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4410461cbdcc5409fb4b4d42b51" "d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8" "a540911abe3e7854a26f39f58b25c15342af53ae") f = io.BytesIO(h2b(h)) tx = Tx.parse(f) tx.parse_unspents(f) self.assertEqual( tx.id(), "10c61e258e0a2b19b245a96a2d0a1538fe81cd4ecd547e0a3df7ed6fd3761ada") the_script = tx.unspents[0].script s = script_obj_from_script(tx.unspents[0].script) self.assertEqual(s.script(), the_script)
def test_weird_tx(self): # this is from tx 12a8d1d62d12307eac6e62f2f14d7e826604e53c320a154593845aa7c8e59fbf st = script_obj_from_script(b'Q') self.assertNotEqual(st, None)