def test_initial_key(self): RECEIVING_ADDRESSES = [ "1LDkC1H438qSnJLHCYkQ3WTZQkSEwoYGHc", "12mENAcc8ZhZbR6hv7LGm3jV7PwbYeF8Xk", "1A3NpABFd6YHvwr1ti1r8brU3BzQuV2Nr4", "1Gn6nWAoZrpmtV9zuNbyivWvRBpcygWaQX", "1M5i5P3DhtDbnvSTfmnUbcrTVgF8GDWQW9", ] CHANGE_ADDRESSES = [ "1iiAbyBTh1J69UzD1JcrfW8JSVJ9ve9gT", "146wnqmsQNYCZ6AXRCqLkzZyGM1ZU6nr3F", "1Mwexajvia3s8AcaGUkyEg9ZZJPJeTbKTZ", ] wallet = ElectrumWallet(initial_key="00000000000000000000000000000001") for idx, address in enumerate(RECEIVING_ADDRESSES): subkey = wallet.subkey("%s/0" % idx) calculated_address = subkey.address() self.assertEqual(address, calculated_address) wif = subkey.wif() key = Key.from_text(wif) self.assertEqual(key.address(use_uncompressed=True), address) for idx, address in enumerate(CHANGE_ADDRESSES): subkey = wallet.subkey("%s/1" % idx) calculated_address = subkey.address() self.assertEqual(address, calculated_address) wif = subkey.wif() key = Key.from_text(wif) self.assertEqual(key.address(use_uncompressed=True), address)
def _build_signature(key, certreqinfo, network): secret_exponent = encoding.to_long(256, encoding.byte_to_int, key[0][1].asOctets())[0] coin = Key(secret_exponent=secret_exponent, netcode=network) print "building signature for %s address: %s" % (network, coin.address()) pubkeybitstring = (key[0].getComponentByPosition(2), key[0].getComponentByPosition(3)) certreqinfoder = encoder.encode(certreqinfo) hashvalue = SHA256.new(certreqinfoder) dgst = hashvalue.digest() dgstaslong = encoding.to_long(256, encoding.byte_to_int, dgst)[0] order2 = pycoin.ecdsa.generator_secp256k1.order() ## random sign generator = pycoin.ecdsa.generator_secp256k1 rawsig2 = randomsign(generator, secret_exponent, dgstaslong) ## deterministic sign ##rawsig2 = pycoin.ecdsa.sign(pycoin.ecdsa.generator_secp256k1, secret_exponent, dgstaslong) r2, s2 = rawsig2 print "signature: r: %x s: %x" % (r2, s2) if not pycoin.ecdsa.verify(generator, coin.public_pair(), dgstaslong, rawsig2): raise SignatureVerifyException("Generated signature r: %x s: %x does not verify against public key %s" % (r2, s2, public_pair)) signature = ECDSASigValue() signature.setComponentByName('r', r2) signature.setComponentByName('s', s2) dersig = encoder.encode(signature) signaturevalue = "'{0}'H".format(binascii.hexlify(dersig)) bitstring = univ.BitString( value=signaturevalue ) return rfc2314.Signature( bitstring )
def vanitygen(s): s = '1' + s.lower() l = len(s) while True: r = int.from_bytes(os.urandom(32), 'big') k = Key(secret_exponent=r) if k.address()[:l] == s: print('Address:', k.address()) print('WIF:'. k.wif())
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_repr(self): key = Key(secret_exponent=273, netcode='XTN') address = key.address() pub_k = Key.from_text(address) self.assertEqual(repr(pub_k), '<mhDVBkZBWLtJkpbszdjZRkH1o5RZxMwxca>') wif = key.wif() priv_k = Key.from_text(wif) self.assertEqual(repr(priv_k), 'private_for <0264e1b1969f9102977691a40431b0b672055dcf31163897d996434420e6c95dc9>')
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_repr(self): from pycoin.key import Key netcode = 'XTN' key = Key(secret_exponent=273, netcode=netcode) wallet = BIP32Node.from_master_secret(bytes(key.wif().encode('ascii')), netcode) address = wallet.address() pub_k = wallet.from_text(address) self.assertEqual(repr(pub_k), '<myb5gZNXePNf2E2ksrjnHRFCwyuvt7oEay>') wif = wallet.wif() priv_k = wallet.from_text(wif) self.assertEqual(repr(priv_k), 'private_for <03ad094b1dc9fdce5d3648ca359b4e210a89d049532fdd39d9ccdd8ca393ac82f4>')
def test_solve_pay_to_address(self): for se in range(1, 10): 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) hl = build_hash160_lookup([se]) sv = 100 solution = 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 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 solution = st.solve(hash160_lookup=hl, sign_value=sv, signature_type=SIGHASH_ALL) sc = st.script() st = script_obj_from_script(sc) self.assertEqual(st.address(), addr)
def test_segwit_create_tx(self): from pycoin.tx.tx_utils import create_tx, sign_tx from pycoin.tx.Spendable import Spendable from pycoin.tx.pay_to.ScriptPayToAddress import ScriptPayToAddress from pycoin.tx.pay_to.ScriptPayToAddressWit import ScriptPayToAddressWit from pycoin.tx.pay_to.ScriptPayToScriptWit import ScriptPayToScriptWit from pycoin.ui import address_for_pay_to_script_wit, script_obj_from_address key1 = Key(1) coin_value = 5000000 script = ScriptPayToAddressWit(b'\0', key1.hash160()).script() tx_hash = b'\ee' * 32 tx_out_index = 0 spendable = Spendable(coin_value, script, tx_hash, tx_out_index) key2 = Key(2) tx = create_tx([spendable], [(key2.address(), coin_value)]) self.check_unsigned(tx) sign_tx(tx, [key1.wif()]) self.check_signed(tx) self.assertEqual(len(tx.txs_in[0].witness), 2) s1 = ScriptPayToAddress(key1.hash160()).script() address = address_for_pay_to_script_wit(s1) spendable.script = script_obj_from_address(address).script() tx = create_tx([spendable], [(key2.address(), coin_value)]) self.check_unsigned(tx) sign_tx(tx, [key1.wif()], p2sh_lookup=build_p2sh_lookup([s1])) self.check_signed(tx)
def handle(self, *args, **options): rpc = AuthServiceProxy('http://' + settings.BITCOIN_RPC_USERNAME + ':' + settings.BITCOIN_RPC_PASSWORD + '@' + settings.BITCOIN_RPC_IP + ':' + str(settings.BITCOIN_RPC_PORT)) private_keys_imported = False for address in Address.objects.all(): address_found = True try: rpc.dumpprivkey(address.address) except JSONRPCException as e: if e.code == -4: # Address is not found print 'Address ' + address.address + ' was not found. Importing it...' # Do some key magic new_address_full_path = address.wallet.path + [address.subpath_number] new_address_full_path_str = '/'.join([str(i) for i in new_address_full_path]) key = Key.from_text(settings.MASTERWALLET_BIP32_KEY) subkey = key.subkeys(new_address_full_path_str).next() # Check address and form the private key btc_address = subkey.address(use_uncompressed=False) assert btc_address == address.address btc_private_key = subkey.wif(use_uncompressed=False) # Do the importing rpc.importprivkey(btc_private_key, '', False) private_keys_imported = True if private_keys_imported: print 'Note! Private keys were added, but they were not scanned! Please restart bitcoin with -rescan option!'
def getOrCreateAddress(self, subpath_number): try: return Address.objects.get(wallet=self, subpath_number=subpath_number) except Address.DoesNotExist: pass new_address_full_path = self.path + [subpath_number] new_address_full_path_str = '/'.join([str(i) for i in new_address_full_path]) # Create raw bitcoin address and key key = Key.from_text(settings.MASTERWALLET_BIP32_KEY) subkey = key.subkeys(new_address_full_path_str).next() btc_address = subkey.address(use_uncompressed=False) btc_private_key = subkey.wif(use_uncompressed=False) # Make sure private key is stored to the database of bitcoind rpc = AuthServiceProxy('http://' + settings.BITCOIN_RPC_USERNAME + ':' + settings.BITCOIN_RPC_PASSWORD + '@' + settings.BITCOIN_RPC_IP + ':' + str(settings.BITCOIN_RPC_PORT)) try: rpc.importprivkey(btc_private_key, '', False) except: raise Exception('Unable to store Bitcoin address to Bitcoin node!') # Create new Address and return it new_address = Address(wallet=self, subpath_number=subpath_number, address=btc_address) new_address.save() return new_address
def __init__(self, mainnet, dashrpc): self.dashrpc = dashrpc self.mainnet = mainnet self._init_state_dir(os.path.join(DASHVEND_DIR, 'state')) self.key = Key.from_text( mainnet and BIP32_MAINNET_SEED or BIP32_TESTNET_SEED) self._init_next_address()
def test_1(self): wallet = ElectrumWallet(initial_key="00000000000000000000000000000001") for idx, address in enumerate(RECEIVING_ADDRESSES): subkey = wallet.subkey("%s/0" % idx) calculated_address = subkey.address() self.assertEqual(address, calculated_address) wif = subkey.wif() key = Key.from_text(wif) self.assertEqual(key.address(use_uncompressed=True), address) for idx, address in enumerate(CHANGE_ADDRESSES): subkey = wallet.subkey("%s/1" % idx) calculated_address = subkey.address() self.assertEqual(address, calculated_address) wif = subkey.wif() key = Key.from_text(wif) self.assertEqual(key.address(use_uncompressed=True), address)
def test_master_public_and_private(self): # these addresses were generated by hand using electrum with a master public key # corresponding to secret exponent 1 RECEIVING_ADDRESSES = [ "1AYPdHLna6bKFUbeXoAEVbaXUxifUwCMay", "13UeuWJba5epizAKyfCfiFKY5Kbxfdxe7B", "19f6KJUTL5AGBRvLBGiL6Zpcx53QA7zaKT", "1Cm33VuSkoUETwx5nsF1wgmGqYwJZxpZdY", "14Z6ErkETixQMUeivsYbrdoUFns2J1iSct", ] CHANGE_ADDRESSES = [ "1JVYsmjrqSy1BKvo1gYpNjX7AYea74nQYe", "1Cc7itfQaDqZK3vHYphFsySujQjBNba8mw", "15wrXvrAnyv3usGeQRohnnZ8tz9XAekbag", "1MnWCEjE5YiZpZrkP8HcXEeDqwg43RxLwu", "1Fgyp3PUx9AAg8yJe1zGXHP5dVC6i1tXbs", "12XTLd4u9jeqw4egLAUhoKLxHARCdKWkty", ] k = Key(secret_exponent=1) master_public_key = k.sec(use_uncompressed=True)[1:] wallet = ElectrumWallet(master_public_key=master_public_key) for idx, address in enumerate(RECEIVING_ADDRESSES): subkey = wallet.subkey("%s/0" % idx) calculated_address = subkey.address() self.assertEqual(address, calculated_address) for idx, address in enumerate(CHANGE_ADDRESSES): subkey = wallet.subkey("%s/1" % idx) calculated_address = subkey.address() self.assertEqual(address, calculated_address) wallet = ElectrumWallet(master_private_key=1) for idx, address in enumerate(RECEIVING_ADDRESSES): subkey = wallet.subkey("%s/0" % idx) calculated_address = subkey.address() self.assertEqual(address, calculated_address) wif = subkey.wif() key = Key.from_text(wif) self.assertEqual(key.address(use_uncompressed=True), address) for idx, address in enumerate(CHANGE_ADDRESSES): subkey = wallet.subkey("%s/1" % idx) calculated_address = subkey.address() self.assertEqual(address, calculated_address) wif = subkey.wif() key = Key.from_text(wif) self.assertEqual(key.address(use_uncompressed=True), address)
def _gen (self): logger.debug ('Generating entropy for new wallet...') # Generate entropy entropy = bytearray() try: entropy.extend(open("/dev/random", "rb").read(64)) except Exception: print("warning: can't use /dev/random as entropy source") entropy = bytes(entropy) if len(entropy) < 64: raise OSError("can't find sources of entropy") secret_exponent = int(binascii.hexlify (entropy)[0:32], 16) wif = secret_exponent_to_wif(secret_exponent, compressed=True, wif_prefix=wif_prefix_for_netcode (self.chain)) key = Key (secret_exponent=secret_exponent, netcode=self.chain) return (str (key.address ()), str (key.wif ()))
def test_is_wif_valid(self): WIFS = ["KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn", "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf", "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74NMTptX4", "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAvUcVfH"] for wif in WIFS: self.assertEqual(is_wif_valid(wif), "BTC") a = wif[:-1] + chr(ord(wif[-1])+1) self.assertEqual(is_wif_valid(a), None) for netcode in NETWORK_NAMES: for se in range(1, 10): key = Key(secret_exponent=se, netcode=netcode) for tv in [True, False]: wif = key.wif(use_uncompressed=tv) self.assertEqual(is_wif_valid(wif, allowable_netcodes=[netcode]), netcode) a = wif[:-1] + chr(ord(wif[-1])+1) self.assertEqual(is_wif_valid(a, allowable_netcodes=[netcode]), None)
def test_sign_verify(self): private_key = Key(secret_exponent=1) h = b"\x00" * 32 sig = private_key.sign(h) self.assertTrue(private_key.verify(h, sig)) public_key = private_key.public_copy() self.assertTrue(public_key.verify(h, sig)) h160_key = Key(hash160=private_key.hash160()) self.assertTrue(h160_key.verify(h, sig))
def mk_notif_tx(my_pcode_node, payee_pcode_node, wallet_nodes, change_nodes, fee): amount = Decimal('0.00000600') payee_notif_node = payee_pcode_node.subkey_for_path("0/0") txio_tuple = create_tx_io(amount, payee_notif_node.address(), wallet_nodes, change_nodes, fee) first_exp = Key.from_text(txio_tuple[3][0]).secret_exponent() my_masked_pcode = node_to_masked_pcode(my_pcode_node, payee_notif_node, first_exp) op_return_script = pay_to.ScriptNulldata(my_masked_pcode) op_return_txout = TxOut(0, op_return_script.script()) txio_tuple[1].append(op_return_txout) return create_signed_tx(txio_tuple)
def masked_pcode_to_pcode(masked_pcode, first_pubkey, notif_node): first_pp = Key.from_sec(first_pubkey, netcode=NETCODE).public_pair() secret, sha_secret = secret_masks(first_pp, notif_node.secret_exponent()) masked_sec = masked_pcode[2:35] my_sign = my_sec[0] masked_xval = my_sec[1:] masked_cc = masked_pcode[36:68] unmasked_xval = xor_bytes(masked_xval, secret) unmasked_cc = xor_bytes(masked_cc, sha_secret) return pcode_nosuffix(my_sign, unmasked_xval, unmasked_cc)
def key_found(arg, payables, key_iters): try: key = Key.from_text(arg) # TODO: check network if key.wif() is None: payables.append((key.address(), 0)) return True key_iters.append(iter([key.wif()])) return True except Exception: pass return False
def parse_prefixes(item, PREFIX_TRANSFORMS): for k, f in PREFIX_TRANSFORMS: if item.startswith(k): try: return f(item[len(k):]) except Exception: pass try: return Key.from_text(item) except encoding.EncodingError: pass return None
def test_sign_bitcoind_partially_signed_2_of_2(self): # Finish signing a 2 of 2 transaction, that already has one signature signed by bitcoind # This tx can be found on testnet3 blockchain, txid: 9618820d7037d2f32db798c92665231cd4599326f5bd99cb59d0b723be2a13a2 raw_script = "522103e33b41f5ed67a77d4c4c54b3e946bd30d15b8f66e42cb29fde059c16885116552102b92cb20a9fb1eb9656a74eeb7387636cf64cdf502ff50511830328c1b479986452ae" p2sh_lookup = build_p2sh_lookup([h2b(raw_script)]) partially_signed_raw_tx = "010000000196238f11a5fd3ceef4efd5a186a7e6b9217d900418e72aca917cd6a6e634e74100000000910047304402201b41b471d9dd93cf97eed7cfc39a5767a546f6bfbf3e0c91ff9ad23ab9770f1f02205ce565666271d055be1f25a7e52e34cbf659f6c70770ff59bd783a6fcd1be3dd0147522103e33b41f5ed67a77d4c4c54b3e946bd30d15b8f66e42cb29fde059c16885116552102b92cb20a9fb1eb9656a74eeb7387636cf64cdf502ff50511830328c1b479986452aeffffffff01a0bb0d00000000001976a9143b3beefd6f7802fa8706983a76a51467bfa36f8b88ac00000000" tx = Tx.from_hex(partially_signed_raw_tx) tx_out = TxOut(1000000, h2b("a914a10dfa21ee8c33b028b92562f6fe04e60563d3c087")) tx.set_unspents([tx_out]) key = Key.from_text("cThRBRu2jAeshWL3sH3qbqdq9f4jDiDbd1SVz4qjTZD2xL1pdbsx") hash160_lookup = build_hash160_lookup([key.secret_exponent()]) self.assertEqual(tx.bad_signature_count(), 1) tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup) self.assertEqual(tx.bad_signature_count(), 0) self.assertEqual(tx.id(), "9618820d7037d2f32db798c92665231cd4599326f5bd99cb59d0b723be2a13a2")
def generate(context, request, api_version, xpub=None, start=0, count=1): if not xpub: raise MyBitsException('Parameter `xpub` missing') start = int(start) count = int(count) if not 0 < count <= 20: raise MyBitsException('Parameter `count` must be between 1 and 20') try: mpk = Key.from_text(xpub) except EncodingError: raise MyBitsException('Invalid `xpub`') return [str(key.address()) for key in mpk.subkeys("0/{}-{}".format(start, start+count))]
def test_sign_pay_to_script_multisig(self): M, N = 3, 3 keys = [Key(secret_exponent=i) for i in range(1, N + 2)] tx_in = TxIn.coinbase_tx_in(script=b'') underlying_script = ScriptMultisig( m=M, sec_keys=[key.sec() for key in keys[:N]]).script() address = address_for_pay_to_script(underlying_script) self.assertEqual(address, "39qEwuwyb2cAX38MFtrNzvq3KV9hSNov3q") script = standard_tx_out_script(address) tx_out = TxOut(1000000, script) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [address]) hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[:N]) p2sh_lookup = build_p2sh_lookup([underlying_script]) tx2.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup) self.assertEqual(tx2.bad_signature_count(), 0)
def test_against_myself(): """ Test code that verifies against ourselves only. Useful but not so great. """ from pycoin.key import Key, msg_signing from pycoin.encoding import bitcoin_address_to_hash160_sec_with_prefix from pycoin.encoding import wif_to_tuple_of_secret_exponent_compressed from pycoin.key.msg_signing import parse_signed_message for wif, right_addr in [ ('L4gXBvYrXHo59HLeyem94D9yLpRkURCHmCwQtPuWW9m6o1X8p8sp', '1LsPb3D1o1Z7CzEt1kv5QVxErfqzXxaZXv'), ('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss', '1HZwkjkeaoZfTSaJxDw6aKkxp45agDiEzN'), ]: se, comp = wif_to_tuple_of_secret_exponent_compressed(wif) k = Key(secret_exponent=se, is_compressed=comp) assert k.address() == right_addr #print("\nAddr %s compressed=%s" % (right_addr, comp)) vk = Key(public_pair=k.public_pair(), is_compressed=comp) assert vk.address() == right_addr h160, pubpre = bitcoin_address_to_hash160_sec_with_prefix(right_addr) vk2 = Key(hash160=h160) assert vk2.address() == right_addr for i in range(1, 30, 10): msg = 'test message %s' % ('A'*i) sig = msg_signing.sign_message(k, msg, verbose=1) #print(sig) assert right_addr in sig # check parsing works m,a,s = parse_signed_message(sig) assert m == msg, m assert a == right_addr, a sig2 = msg_signing.sign_message(k, msg, verbose=0) assert sig2 in sig, (sig, sig2) assert s == sig2, s ok = msg_signing.verify_message(k, sig2, msg) #print("verifies: %s" % ("Ok" if ok else "WRONG")) assert ok
def get_unused_address(social_id, deriv): ''' Need to be careful about when to move up the latest_derivation listing. Figure only incrementing the database entry when blockchain activity is found is the least likely to create large gaps of empty addresses in someone's BTC Wallet. ''' serverList = read_server_list() randomServer = grab_random_server(serverList) randomAddress = randomServer['serverAddress'] randomPort = randomServer['serverPort'] pp = pprint.PrettyPrinter(indent=2) userdata = User.query.filter_by(social_id=social_id).first() # Pull BTC Address from given user data key = Key.from_text(userdata.xpub).subkey(0). \ subkey(deriv) address = key.address(use_uncompressed=False) # Check for existing payment request, delete if older than 5m. payment_request = PayReq.query.filter_by(addr=address).first() if payment_request: req_timestamp = payment_request.timestamp now_timestamp = datetime.utcnow() delta_timestamp = now_timestamp - req_timestamp if delta_timestamp > timedelta(seconds=60 * 5): db.session.delete(payment_request) db.session.commit() payment_request = None if not check_address_history(address, randomAddress, randomPort): if not payment_request: return address else: print("Address has payment request...") print("Address Derivation: ", deriv) return get_unused_address(social_id, deriv + 1) else: print("Address has blockchain history, searching new address...") print("Address Derivation: ", userdata.latest_derivation) userdata.latest_derivation = userdata.latest_derivation + 1 db.session.commit() return get_unused_address(social_id, deriv + 1)
def test_key_limits(self): nc = 'BTC' cc = b'000102030405060708090a0b0c0d0e0f' order = generator_secp256k1.order() for k in -1, 0, order, order + 1: self.assertRaises(InvalidSecretExponentError, Key, secret_exponent=k) self.assertRaises(InvalidSecretExponentError, BIP32Node, nc, cc, secret_exponent=k) for i in range(1, 512): Key(secret_exponent=i) BIP32Node(nc, cc, secret_exponent=i)
def test_repr(self): key = Key(secret_exponent=273, netcode='XTN') address = key.address() pub_k = Key.from_text(address) self.assertEqual(repr(pub_k), '<mhDVBkZBWLtJkpbszdjZRkH1o5RZxMwxca>') wif = key.wif() priv_k = Key.from_text(wif) self.assertEqual( repr(priv_k), 'private_for <0264e1b1969f9102977691a40431b0b672055dcf31163897d996434420e6c95dc9>' )
def do_test(exp_hex, wif, c_wif, public_pair_sec, c_public_pair_sec, address_b58, c_address_b58): secret_exponent = int(exp_hex, 16) sec = h2b(public_pair_sec) c_sec = h2b(c_public_pair_sec) keys_wif = [ Key(secret_exponent=secret_exponent), Key.from_text(wif), Key.from_text(c_wif), ] key_sec = Key.from_sec(sec) key_sec_c = Key.from_sec(c_sec) keys_sec = [key_sec, key_sec_c] for key in keys_wif: self.assertEqual(key.secret_exponent(), secret_exponent) self.assertEqual(key.public_copy().secret_exponent(), None) repr(key) if key._prefer_uncompressed: self.assertEqual(key.wif(), wif) else: self.assertEqual(key.wif(), c_wif) self.assertEqual(key.wif(use_uncompressed=True), wif) self.assertEqual(key.wif(use_uncompressed=False), c_wif) for key in keys_wif + keys_sec: if key._prefer_uncompressed: self.assertEqual(key.sec(), sec) else: self.assertEqual(key.sec(), c_sec) self.assertEqual(key.sec(use_uncompressed=True), sec) self.assertEqual(key.sec(use_uncompressed=False), c_sec) if key._prefer_uncompressed: self.assertEqual(key.address(), address_b58) else: self.assertEqual(key.address(), c_address_b58) self.assertEqual(key.address(use_uncompressed=False), c_address_b58) self.assertEqual(key.address(use_uncompressed=True), address_b58) key_pub = Key.from_text(address_b58, is_compressed=False) key_pub_c = Key.from_text(c_address_b58, is_compressed=True) self.assertEqual(key_pub.address(), address_b58) self.assertEqual(key_pub.address(use_uncompressed=True), address_b58) self.assertEqual(key_pub.address(use_uncompressed=False), None) self.assertEqual(key_pub_c.address(), c_address_b58) self.assertEqual(key_pub_c.address(use_uncompressed=True), None) self.assertEqual(key_pub_c.address(use_uncompressed=False), c_address_b58)
def multisig_M_of_N(self, M, N, unsigned_id, signed_id): keys = [Key(secret_exponent=i) for i in range(1, N + 2)] tx_in = TxIn.coinbase_tx_in(script=b'') script = ScriptMultisig(m=M, sec_keys=[key.sec() for key in keys[:N]]).script() tx_out = TxOut(1000000, script) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()]) self.assertEqual(tx2.id(), unsigned_id) self.assertEqual(tx2.bad_signature_count(), 1) hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys) tx2.sign(hash160_lookup=hash160_lookup) self.assertEqual(tx2.id(), signed_id) self.assertEqual(tx2.bad_signature_count(), 0) self.assertEqual( sorted(who_signed.who_signed_tx(tx2, 0)), sorted(((key.address(), SIGHASH_ALL) for key in keys[:M])))
def test_sign_bitcoind_partially_signed_2_of_2(self): # Finish signing a 2 of 2 transaction, that already has one signature signed by bitcoind # This tx can be found on testnet3 blockchain, txid: 9618820d7037d2f32db798c92665231cd4599326f5bd99cb59d0b723be2a13a2 raw_script = "522103e33b41f5ed67a77d4c4c54b3e946bd30d15b8f66e42cb29fde059c16885116552102b92cb20a9fb1eb9656a74eeb7387636cf64cdf502ff50511830328c1b479986452ae" p2sh_lookup = build_p2sh_lookup([h2b(raw_script)]) partially_signed_raw_tx = "010000000196238f11a5fd3ceef4efd5a186a7e6b9217d900418e72aca917cd6a6e634e74100000000910047304402201b41b471d9dd93cf97eed7cfc39a5767a546f6bfbf3e0c91ff9ad23ab9770f1f02205ce565666271d055be1f25a7e52e34cbf659f6c70770ff59bd783a6fcd1be3dd0147522103e33b41f5ed67a77d4c4c54b3e946bd30d15b8f66e42cb29fde059c16885116552102b92cb20a9fb1eb9656a74eeb7387636cf64cdf502ff50511830328c1b479986452aeffffffff01a0bb0d00000000001976a9143b3beefd6f7802fa8706983a76a51467bfa36f8b88ac00000000" tx = Tx.from_hex(partially_signed_raw_tx) tx_out = TxOut(1000000, h2b("a914a10dfa21ee8c33b028b92562f6fe04e60563d3c087")) tx.set_unspents([tx_out]) key = Key.from_text( "cThRBRu2jAeshWL3sH3qbqdq9f4jDiDbd1SVz4qjTZD2xL1pdbsx") hash160_lookup = build_hash160_lookup([key.secret_exponent()]) self.assertEqual(tx.bad_signature_count(), 1) tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup) self.assertEqual(tx.bad_signature_count(), 0) self.assertEqual( tx.id(), "9618820d7037d2f32db798c92665231cd4599326f5bd99cb59d0b723be2a13a2")
def sign_vote(votestr, mnprivkey): privatekey = utils.wifToPrivateKey(mnprivkey) signingkey = Bip62SigningKey.from_string(privatekey.decode('hex'), curve=ecdsa.SECP256k1) public_key = signingkey.get_verifying_key() key = Key.from_text(mnprivkey) address = key.address(use_uncompressed=True) msghash = utils.double_sha256(utils.msg_magic(votestr)) signature = signingkey.sign_digest_deterministic( msghash, hashfunc=hashlib.sha256, sigencode=ecdsa.util.sigencode_string) assert public_key.verify_digest(signature, msghash, sigdecode=ecdsa.util.sigdecode_string) for i in range(4): sig = base64.b64encode(chr(27 + i) + signature) if verify_dash_signature(generator_secp256k1, address, msghash, sig): return sig
def test_multisig_one_at_a_time(self): M = 3 N = 3 keys = [Key(secret_exponent=i) for i in range(1, N+2)] tx_in = TxIn.coinbase_tx_in(script=b'') script = ScriptMultisig(m=M, sec_keys=[key.sec() for key in keys[:N]]).script() tx_out = TxOut(1000000, script) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()]) ids = ["403e5bfc59e097bb197bf77a692d158dd3a4f7affb4a1fa41072dafe7bec7058", "5931d9995e83721243dca24772d7012afcd4378996a8b953c458175f15a544db", "9bb4421088190bbbb5b42a9eaa9baed7ec7574a407c25f71992ba56ca43d9c44", "03a1dc2a63f93a5cf5a7cb668658eb3fc2eda88c06dc287b85ba3e6aff751771"] for i in range(1, N+1): self.assertEqual(tx2.bad_signature_count(), 1) self.assertEqual(tx2.id(), ids[i-1]) hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[i-1:i]) tx2.sign(hash160_lookup=hash160_lookup) self.assertEqual(tx2.id(), ids[i]) self.assertEqual(tx2.bad_signature_count(), 0)
def parse_key(item, PREFIX_TRANSFORMS, network): key = parse_prefixes(item, PREFIX_TRANSFORMS) if key: return key if HASH160_RE.match(item): return Key(hash160=h2b(item), netcode=network) secret_exponent = parse_as_secret_exponent(item) if secret_exponent: return Key(secret_exponent=secret_exponent, netcode=network) if SEC_RE.match(item): return Key.from_sec(h2b(item)) public_pair = parse_as_public_pair(item) if public_pair: return Key(public_pair=public_pair, netcode=network) return None
def handle(self, *args, **options): rpc = AuthServiceProxy('http://' + settings.BITCOIN_RPC_USERNAME + ':' + settings.BITCOIN_RPC_PASSWORD + '@' + settings.BITCOIN_RPC_IP + ':' + str(settings.BITCOIN_RPC_PORT)) private_keys_imported = False for address in Address.objects.all(): address_found = True try: rpc.dumpprivkey(address.address) except JSONRPCException as e: if e.code == -4: # Address is not found print 'Address ' + address.address + ' was not found. Importing it...' # Do some key magic new_address_full_path = address.wallet.path + [ address.subpath_number ] new_address_full_path_str = '/'.join( [str(i) for i in new_address_full_path]) key = Key.from_text(settings.MASTERWALLET_BIP32_KEY) subkey = key.subkeys(new_address_full_path_str).next() # Check address and form the private key btc_address = subkey.address(use_uncompressed=False) assert btc_address == address.address btc_private_key = subkey.wif(use_uncompressed=False) # Do the importing rpc.importprivkey(btc_private_key, '', False) private_keys_imported = True if private_keys_imported: print 'Note! Private keys were added, but they were not scanned! Please restart bitcoin with -rescan option!'
def answer(private_key, expected_address): private_key_digits = [] for d in private_key: private_key_digits.append(BASE58_LOOKUP[d]) #print(private_key) #print(private_key_digits) prefix = private_key_digits[0] suffix = private_key_digits[1:] test_suffix = tuple(suffix) if not private_key_suffix_is_valid(test_suffix): test_suffix = find_winner(tuple(suffix)) print('WINNER!') private_key = b2a_base58(suffix_to_bytes(test_suffix)) print(private_key) return Key.from_text(private_key).address()
def test_pay_to_script_file(self): the_dir = self.set_cache_dir() p2sh_file = tempfile.NamedTemporaryFile() p2sh_file.write( "52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982102c60" "47f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee52102f9308a019258" "c31049344f85f89d5229b531c845836f99b08601f113bce036f953ae\n". encode("utf8")) p2sh_file.write( "53210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982102c60" "47f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee52102f9308a019258" "c31049344f85f89d5229b531c845836f99b08601f113bce036f953ae\n". encode("utf8")) p2sh_file.flush() tx_source_hex = ( "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0" "0ffffffff0200f902950000000017a91415fc0754e73eb85d1cbce08786fadb7320ecb8dc8700f90295" "0000000017a914594f349df0bac3084ffea8a477bba5f03dcd45078700000000") self.launch_tool("tx -C %s" % tx_source_hex) tx_to_sign = ( "01000000020a316ea8980ef9ba02f4e6637c88229bf059f39b06238d48d06a8e" "f672aea2bb0000000000ffffffff0a316ea8980ef9ba02f4e6637c88229bf059" "f39b06238d48d06a8ef672aea2bb0100000000ffffffff01f0ca052a01000000" "1976a914751e76e8199196d454941c45d1b3a323f1433bd688ac0000000000f9" "02950000000017a91415fc0754e73eb85d1cbce08786fadb7320ecb8dc8700f9" "02950000000017a914594f349df0bac3084ffea8a477bba5f03dcd450787") wifs = ' '.join(Key(_).wif() for _ in (1, 2, 3)) signed = tempfile.mktemp(suffix=".hex") self.launch_tool( "tx -a -P %s --db %s %s %s -o %s" % (p2sh_file.name, tx_source_hex, tx_to_sign, wifs, signed), env=dict(PYCOIN_CACHE_DIR=the_dir)) tx = Tx.from_hex(open(signed).read()) self.assertEqual( tx.id(), "9d991ddccf77e33cb4584e4fc061a36da0da43589232b2e78a1aa0748ac3254b")
def main(): parser = argparse.ArgumentParser( description="Manipulate bitcoin (or alt coin) transactions.", epilog=EPILOG) parser.add_argument('-t', "--transaction-version", type=int, help='Transaction version, either 1 (default) or 3 (not yet supported).') parser.add_argument('-l', "--lock-time", type=parse_locktime, help='Lock time; either a block' 'index, or a date/time (example: "2014-01-01T15:00:00"') parser.add_argument('-n', "--network", default="BTC", help='Define network code (M=Bitcoin mainnet, T=Bitcoin testnet).') parser.add_argument('-a', "--augment", action='store_true', help='augment tx by adding any missing spendable metadata by fetching' ' inputs from cache and/or web services') parser.add_argument("-i", "--fetch-spendables", metavar="address", action="append", help='Add all unspent spendables for the given bitcoin address. This information' ' is fetched from web services.') parser.add_argument('-f', "--private-key-file", metavar="path-to-private-keys", action="append", help='file containing WIF or BIP0032 private keys. If file name ends with .gpg, ' '"gpg -d" will be invoked automatically. File is read one line at a time, and if ' 'the file contains only one WIF per line, it will also be scanned for a bitcoin ' 'address, and any addresses found will be assumed to be public keys for the given' ' private key.', type=argparse.FileType('r')) parser.add_argument('-g', "--gpg-argument", help='argument to pass to gpg (besides -d).', default='') parser.add_argument("--remove-tx-in", metavar="tx_in_index_to_delete", action="append", type=int, help='remove a tx_in') parser.add_argument("--remove-tx-out", metavar="tx_out_index_to_delete", action="append", type=int, help='remove a tx_out') parser.add_argument('-F', "--fee", help='fee, in satoshis, to pay on transaction, or ' '"standard" to auto-calculate. This is only useful if the "split pool" ' 'is used; otherwise, the fee is automatically set to the unclaimed funds.', default="standard", metavar="transaction-fee", type=parse_fee) parser.add_argument('-C', "--cache", help='force the resultant transaction into the transaction cache.' ' Mostly for testing.', action='store_true'), parser.add_argument('-u', "--show-unspents", action='store_true', help='show TxOut items for this transaction in Spendable form.') parser.add_argument('-b', "--bitcoind-url", help='URL to bitcoind instance to validate against (http://user:pass@host:port).') parser.add_argument('-o', "--output-file", metavar="path-to-output-file", type=argparse.FileType('wb'), help='file to write transaction to. This supresses most other output.') parser.add_argument("argument", nargs="+", help='generic argument: can be a hex transaction id ' '(exactly 64 characters) to be fetched from cache or a web service;' ' a transaction as a hex string; a path name to a transaction to be loaded;' ' a spendable 4-tuple of the form tx_id/tx_out_idx/script_hex/satoshi_count ' 'to be added to TxIn list; an address/satoshi_count to be added to the TxOut ' 'list; an address to be added to the TxOut list and placed in the "split' ' pool".') args = parser.parse_args() # defaults txs = [] spendables = [] payables = [] key_iters = [] TX_ID_RE = re.compile(r"^[0-9a-fA-F]{64}$") # there are a few warnings we might optionally print out, but only if # they are relevant. We don't want to print them out multiple times, so we # collect them here and print them at the end if they ever kick in. warning_tx_cache = None warning_get_tx = None warning_spendables = None if args.private_key_file: wif_re = re.compile(r"[1-9a-km-zA-LMNP-Z]{51,111}") # address_re = re.compile(r"[1-9a-kmnp-zA-KMNP-Z]{27-31}") for f in args.private_key_file: if f.name.endswith(".gpg"): gpg_args = ["gpg", "-d"] if args.gpg_argument: gpg_args.extend(args.gpg_argument.split()) gpg_args.append(f.name) popen = subprocess.Popen(gpg_args, stdout=subprocess.PIPE) f = popen.stdout for line in f.readlines(): # decode if isinstance(line, bytes): line = line.decode("utf8") # look for WIFs possible_keys = wif_re.findall(line) def make_key(x): try: return Key.from_text(x) except Exception: return None keys = [make_key(x) for x in possible_keys] for key in keys: if key: key_iters.append((k.wif() for k in key.subkeys(""))) # if len(keys) == 1 and key.hierarchical_wallet() is None: # # we have exactly 1 WIF. Let's look for an address # potential_addresses = address_re.findall(line) # we create the tx_db lazily tx_db = None for arg in args.argument: # hex transaction id if TX_ID_RE.match(arg): if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_get_tx = message_about_get_tx_env() tx_db = get_tx_db() tx = tx_db.get(h2b_rev(arg)) if not tx: for m in [warning_tx_cache, warning_get_tx, warning_spendables]: if m: print("warning: %s" % m, file=sys.stderr) parser.error("can't find Tx with id %s" % arg) txs.append(tx) continue # hex transaction data try: tx = Tx.tx_from_hex(arg) txs.append(tx) continue except Exception: pass try: key = Key.from_text(arg) # TODO: check network if key.wif() is None: payables.append((key.address(), 0)) continue # TODO: support paths to subkeys key_iters.append((k.wif() for k in key.subkeys(""))) continue except Exception: pass if os.path.exists(arg): try: with open(arg, "rb") as f: if f.name.endswith("hex"): f = io.BytesIO(codecs.getreader("hex_codec")(f).read()) tx = Tx.parse(f) txs.append(tx) try: tx.parse_unspents(f) except Exception as ex: pass continue except Exception: pass parts = arg.split("/") if len(parts) == 4: # spendable try: spendables.append(Spendable.from_text(arg)) continue except Exception: pass # TODO: fix allowable_prefixes allowable_prefixes = b'\0' if len(parts) == 2 and encoding.is_valid_bitcoin_address( parts[0], allowable_prefixes=allowable_prefixes): try: payables.append(parts) continue except ValueError: pass parser.error("can't parse %s" % arg) if args.fetch_spendables: warning_spendables = message_about_spendables_for_address_env() for address in args.fetch_spendables: spendables.extend(spendables_for_address(address)) for tx in txs: if tx.missing_unspents() and args.augment: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_get_tx = message_about_get_tx_env() tx_db = get_tx_db() tx.unspents_from_db(tx_db, ignore_missing=True) txs_in = [] txs_out = [] unspents = [] # we use a clever trick here to keep each tx_in corresponding with its tx_out for tx in txs: smaller = min(len(tx.txs_in), len(tx.txs_out)) txs_in.extend(tx.txs_in[:smaller]) txs_out.extend(tx.txs_out[:smaller]) unspents.extend(tx.unspents[:smaller]) for tx in txs: smaller = min(len(tx.txs_in), len(tx.txs_out)) txs_in.extend(tx.txs_in[smaller:]) txs_out.extend(tx.txs_out[smaller:]) unspents.extend(tx.unspents[smaller:]) for spendable in spendables: txs_in.append(spendable.tx_in()) unspents.append(spendable) for address, coin_value in payables: script = standard_tx_out_script(address) txs_out.append(TxOut(coin_value, script)) lock_time = args.lock_time version = args.transaction_version # if no lock_time is explicitly set, inherit from the first tx or use default if lock_time is None: if txs: lock_time = txs[0].lock_time else: lock_time = DEFAULT_LOCK_TIME # if no version is explicitly set, inherit from the first tx or use default if version is None: if txs: version = txs[0].version else: version = DEFAULT_VERSION if args.remove_tx_in: s = set(args.remove_tx_in) txs_in = [tx_in for idx, tx_in in enumerate(txs_in) if idx not in s] if args.remove_tx_out: s = set(args.remove_tx_out) txs_out = [tx_out for idx, tx_out in enumerate(txs_out) if idx not in s] tx = Tx(txs_in=txs_in, txs_out=txs_out, lock_time=lock_time, version=version, unspents=unspents) fee = args.fee try: distribute_from_split_pool(tx, fee) except ValueError as ex: print("warning: %s" % ex.args[0], file=sys.stderr) unsigned_before = tx.bad_signature_count() if unsigned_before > 0 and key_iters: def wif_iter(iters): while len(iters) > 0: for idx, iter in enumerate(iters): try: wif = next(iter) yield wif except StopIteration: iters = iters[:idx] + iters[idx+1:] break print("signing...", file=sys.stderr) sign_tx(tx, wif_iter(key_iters)) unsigned_after = tx.bad_signature_count() if unsigned_after > 0 and key_iters: print("warning: %d TxIn items still unsigned" % unsigned_after, file=sys.stderr) if len(tx.txs_in) == 0: print("warning: transaction has no inputs", file=sys.stderr) if len(tx.txs_out) == 0: print("warning: transaction has no outputs", file=sys.stderr) include_unspents = (unsigned_after > 0) tx_as_hex = tx.as_hex(include_unspents=include_unspents) if args.output_file: f = args.output_file if f.name.endswith(".hex"): f.write(tx_as_hex.encode("utf8")) else: tx.stream(f) if include_unspents: tx.stream_unspents(f) f.close() elif args.show_unspents: for spendable in tx.tx_outs_as_spendable(): print(spendable.as_text()) else: if not tx.missing_unspents(): check_fees(tx) dump_tx(tx, args.network) if include_unspents: print("including unspents in hex dump since transaction not fully signed") print(tx_as_hex) if args.cache: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_get_tx = message_about_get_tx_env() tx_db = get_tx_db() tx_db.put(tx) if args.bitcoind_url: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_get_tx = message_about_get_tx_env() tx_db = get_tx_db() validate_bitcoind(tx, tx_db, args.bitcoind_url) if tx.missing_unspents(): print("\n** can't validate transaction as source transactions missing", file=sys.stderr) else: try: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_get_tx = message_about_get_tx_env() tx_db = get_tx_db() tx.validate_unspents(tx_db) print('all incoming transaction values validated') except BadSpendableError as ex: print("\n**** ERROR: FEES INCORRECTLY STATED: %s" % ex.args[0], file=sys.stderr) except Exception as ex: print("\n*** can't validate source transactions as untampered: %s" % ex.args[0], file=sys.stderr) # print warnings for m in [warning_tx_cache, warning_get_tx, warning_spendables]: if m: print("warning: %s" % m, file=sys.stderr)
def parse_context(args, parser): # defaults txs = [] spendables = [] payables = [] key_iters = [] TX_ID_RE = re.compile(r"^[0-9a-fA-F]{64}$") # there are a few warnings we might optionally print out, but only if # they are relevant. We don't want to print them out multiple times, so we # collect them here and print them at the end if they ever kick in. warning_tx_cache = None warning_tx_for_tx_hash = None warning_spendables = None if args.private_key_file: wif_re = re.compile(r"[1-9a-km-zA-LMNP-Z]{51,111}") # address_re = re.compile(r"[1-9a-kmnp-zA-KMNP-Z]{27-31}") for f in args.private_key_file: if f.name.endswith(".gpg"): gpg_args = ["gpg", "-d"] if args.gpg_argument: gpg_args.extend(args.gpg_argument.split()) gpg_args.append(f.name) popen = subprocess.Popen(gpg_args, stdout=subprocess.PIPE) f = popen.stdout for line in f.readlines(): # decode if isinstance(line, bytes): line = line.decode("utf8") # look for WIFs possible_keys = wif_re.findall(line) def make_key(x): try: return Key.from_text(x) except Exception: return None keys = [make_key(x) for x in possible_keys] for key in keys: if key: key_iters.append((k.wif() for k in key.subkeys(""))) # if len(keys) == 1 and key.hierarchical_wallet() is None: # # we have exactly 1 WIF. Let's look for an address # potential_addresses = address_re.findall(line) # update p2sh_lookup p2sh_lookup = {} if args.pay_to_script: for p2s in args.pay_to_script: try: script = h2b(p2s) p2sh_lookup[hash160(script)] = script except Exception: print("warning: error parsing pay-to-script value %s" % p2s) if args.pay_to_script_file: hex_re = re.compile(r"[0-9a-fA-F]+") for f in args.pay_to_script_file: count = 0 for l in f: try: m = hex_re.search(l) if m: p2s = m.group(0) script = h2b(p2s) p2sh_lookup[hash160(script)] = script count += 1 except Exception: print("warning: error parsing pay-to-script file %s" % f.name) if count == 0: print("warning: no scripts found in %s" % f.name) # we create the tx_db lazily tx_db = None for arg in args.argument: # hex transaction id if TX_ID_RE.match(arg): if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env( args.network) tx_db = get_tx_db(args.network) tx = tx_db.get(h2b_rev(arg)) if not tx: for m in [ warning_tx_cache, warning_tx_for_tx_hash, warning_spendables ]: if m: print("warning: %s" % m, file=sys.stderr) parser.error("can't find Tx with id %s" % arg) txs.append(tx) continue # hex transaction data try: tx = Tx.from_hex(arg) txs.append(tx) continue except Exception: pass is_valid = is_address_valid(arg, allowable_netcodes=[args.network]) if is_valid: payables.append((arg, 0)) continue try: key = Key.from_text(arg) # TODO: check network if key.wif() is None: payables.append((key.address(), 0)) continue # TODO: support paths to subkeys key_iters.append((k.wif() for k in key.subkeys(""))) continue except Exception: pass if os.path.exists(arg): try: with open(arg, "rb") as f: if f.name.endswith("hex"): f = io.BytesIO(codecs.getreader("hex_codec")(f).read()) tx = Tx.parse(f) txs.append(tx) try: tx.parse_unspents(f) except Exception as ex: pass continue except Exception: pass parts = arg.split("/") if len(parts) == 4: # spendable try: spendables.append(Spendable.from_text(arg)) continue except Exception: pass if len(parts) == 2 and is_address_valid( parts[0], allowable_netcodes=[args.network]): try: payables.append(parts) continue except ValueError: pass parser.error("can't parse %s" % arg) if args.fetch_spendables: warning_spendables = message_about_spendables_for_address_env( args.network) for address in args.fetch_spendables: spendables.extend(spendables_for_address(address)) for tx in txs: if tx.missing_unspents() and args.augment: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env( args.network) tx_db = get_tx_db(args.network) tx.unspents_from_db(tx_db, ignore_missing=True) return (txs, spendables, payables, key_iters, p2sh_lookup, tx_db, warning_tx_cache, warning_tx_for_tx_hash, warning_spendables)
def verify(content, signature, pub_key): key = Key.from_sec(a2b_hex(pub_key)) return key.verify(double_hash256(content), a2b_hex(signature))
if should_be != SECRET_EXPONENT: print( "\nFAILED: You probably didn't record exactly the bytes written to this drive." ) raise SystemExit print("STEP1: Secret exponent is hash of things we expected (good).") # Optional: verify the secret exponent is the basis of the private key try: import pycoin from pycoin.key import Key except: print( "\nNeed pycoin installed for complete check: pip install 'pycoin>=0.76'\n" ) raise SystemExit # pull out secret key from provided secret key k = Key.from_text(PRIVKEY) expect = pycoin.encoding.to_bytes_32(k.secret_exponent()) if expect == should_be and k.address() == ADDRESS: print("\nSUCCESS: Private key uses secret exponent we expected. Perfect.") else: print( "\nFAILED: Something went wrong along the way. Is this the right private key?" ) # EOF
def _test_sighash_single(self, netcode): k0 = Key(secret_exponent=PRIV_KEYS[0], is_compressed=True, netcode=netcode) k1 = Key(secret_exponent=PRIV_KEYS[1], is_compressed=True, netcode=netcode) k2 = Key(secret_exponent=PRIV_KEYS[2], is_compressed=True, netcode=netcode) k3 = Key(secret_exponent=PRIV_KEYS[3], is_compressed=True, netcode=netcode) k4 = Key(secret_exponent=PRIV_KEYS[4], is_compressed=True, netcode=netcode) k5 = Key(secret_exponent=PRIV_KEYS[5], is_compressed=True, netcode=netcode) # Fake a coinbase transaction coinbase_tx = Tx.coinbase_tx(k0.sec(), 500000000) coinbase_tx.txs_out.append( TxOut(1000000000, pycoin_compile('%s OP_CHECKSIG' % b2h(k1.sec())))) coinbase_tx.txs_out.append( TxOut(1000000000, pycoin_compile('%s OP_CHECKSIG' % b2h(k2.sec())))) self.assertEqual( '2acbe1006f7168bad538b477f7844e53de3a31ffddfcfc4c6625276dd714155a', b2h_rev(coinbase_tx.hash())) # Make the test transaction txs_in = [ TxIn(coinbase_tx.hash(), 0), TxIn(coinbase_tx.hash(), 1), TxIn(coinbase_tx.hash(), 2), ] txs_out = [ TxOut(900000000, standard_tx_out_script(k3.address())), TxOut(800000000, standard_tx_out_script(k4.address())), TxOut(800000000, standard_tx_out_script(k5.address())), ] tx = Tx(1, txs_in, txs_out) tx.set_unspents(coinbase_tx.txs_out) self.assertEqual( '791b98ef0a3ac87584fe273bc65abd89821569fd7c83538ac0625a8ca85ba587', b2h_rev(tx.hash())) sig_type = SIGHASH_SINGLE sig_hash = tx.signature_hash(coinbase_tx.txs_out[0].script, 0, sig_type) self.assertEqual( 'cc52d785a3b4133504d1af9e60cd71ca422609cb41df3a08bbb466b2a98a885e', b2h(to_bytes_32(sig_hash))) sig = sigmake(k0, sig_hash, sig_type) self.assertTrue(sigcheck(k0, sig_hash, sig[:-1])) tx.txs_in[0].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(0)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[1].script, 1, sig_type) self.assertEqual( '93bb883d70fccfba9b8aa2028567aca8357937c65af7f6f5ccc6993fd7735fb7', b2h(to_bytes_32(sig_hash))) sig = sigmake(k1, sig_hash, sig_type) self.assertTrue(sigcheck(k1, sig_hash, sig[:-1])) tx.txs_in[1].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(1)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[2].script, 2, sig_type) self.assertEqual( '53ef7f67c3541bffcf4e0d06c003c6014e2aa1fb38ff33240b3e1c1f3f8e2a35', b2h(to_bytes_32(sig_hash))) sig = sigmake(k2, sig_hash, sig_type) self.assertTrue(sigcheck(k2, sig_hash, sig[:-1])) tx.txs_in[2].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(2)) sig_type = SIGHASH_SINGLE | SIGHASH_ANYONECANPAY sig_hash = tx.signature_hash(coinbase_tx.txs_out[0].script, 0, sig_type) self.assertEqual( '2003393d246a7f136692ce7ab819c6eadc54ffea38eb4377ac75d7d461144e75', b2h(to_bytes_32(sig_hash))) sig = sigmake(k0, sig_hash, sig_type) self.assertTrue(sigcheck(k0, sig_hash, sig[:-1])) tx.txs_in[0].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(0)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[1].script, 1, sig_type) self.assertEqual( 'e3f469ac88e9f35e8eff0bd8ad4ad3bf899c80eb7645947d60860de4a08a35df', b2h(to_bytes_32(sig_hash))) sig = sigmake(k1, sig_hash, sig_type) self.assertTrue(sigcheck(k1, sig_hash, sig[:-1])) tx.txs_in[1].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(1)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[2].script, 2, sig_type) self.assertEqual( 'bacd7c3ab79cad71807312677c1788ad9565bf3c00ab9a153d206494fb8b7e6a', b2h(to_bytes_32(sig_hash))) sig = sigmake(k2, sig_hash, sig_type) self.assertTrue(sigcheck(k2, sig_hash, sig[:-1])) tx.txs_in[2].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(2))
def generate_new_key(): secret = secrets.randbits(256) secret_hex = b2a_hex(to_bytes_32(secret)).decode() key = Key(secret_exponent=secret) sec = public_pair_to_sec(key.public_pair()) return b2a_hex(sec).decode(), secret_hex
while 1: print("enter the %s => " % which, end='') netcode = input() if netcode: print(netcode) return netcode print("invalid netcode, please try again") src_address = get_address("source") netcode = get_net_code("netcode") spendables = spendables_for_address(src_address, netcode) print(spendables) while 1: print("enter the WIF for %s=> " % src_address, end='') wif = input() is_valid = is_wif_valid(wif) if is_valid: break print("invalid wif, please try again") key = Key.from_text(wif) if src_address not in (key.address(use_uncompressed=False), key.address(use_uncompressed=True)): print("** WIF doesn't correspond to %s" % src_address) print("The secret exponent is %d" % key.secret_exponent()) dst_address = get_address("destination") tx = create_signed_tx(spendables, payables=[dst_address], wifs=[wif]) print("here is the signed output transaction") print(tx.as_hex())
def key(testnet, wif): wif = unicode_str(wif) netcode = 'XTN' if testnet else 'BTC' if not validate.is_wif_valid(wif, allowable_netcodes=[netcode]): raise exceptions.InvalidWif(wif) return Key.from_text(wif)
def make_key(x): try: return Key.from_text(x) except Exception: return None
def _make_lookups(wif, script_hex): script_bin = h2b(script_hex) key = Key.from_text(wif) hash160_lookup = build_hash160_lookup([key.secret_exponent()]) p2sh_lookup = build_p2sh_lookup([script_bin]) return hash160_lookup, p2sh_lookup
def wif2address(wif): private_key = Key.from_text(wif); return str(private_key.address())
from pycoin.services.blockchain_info import send_tx parser = argparse.ArgumentParser() parser.add_argument('--privkey-bytes', help='provide hexlified raw privkey bytes', default='', type=str) parser.add_argument('--send-all-to', help='where to send all the money at this address', default='1MaxKayeQg4YhFkzFz4x6NDeeNv1bwKKVA', type=str) args = parser.parse_args() key_bytes = unhexlify(args.privkey_bytes.encode() ) if args.privkey_bytes != '' else os.urandom(32) private_key = Key(secret_exponent=int.from_bytes(key_bytes, 'big')) address = private_key.address() print('Your Bitcoin address is...', address) print('Your --privkey-bytes', hexlify(key_bytes).decode()) try: spendables = spendables_for_address(address, None) print('Spending', spendables) except HTTPError as e: print( 'Blockchain throws a 500 error if there are no spendables. Try sending some coins to', address, 'and try again. Remeber to copy privkey-bytes.') sys.exit() tx = create_tx(spendables, [args.send_all_to])
def register_page(request, refererUUID): getBtcPrice() price = sysvar.objects.get(pk=1) btcPrice = price.btcPrice counter = price.counter email_taken = False username_taken = False if request.user.is_authenticated(): return render(request, 'home.html') registration_form = RegistrationForm() if request.method == 'POST': form = RegistrationForm(request.POST) if form.is_valid(): datas = {} if User.objects.filter( username=form.cleaned_data['username']).exists(): username_taken = True return render( request, 'register_page.html', { 'form': registration_form, 'username_taken': username_taken, 'btcPrice': btcPrice }) elif User.objects.filter( email=form.cleaned_data['email']).exists(): email_taken = True return render( request, 'register_page.html', { 'form': registration_form, 'email_taken': email_taken, 'btcPrice': btcPrice }) datas['username'] = form.cleaned_data['username'] datas['email'] = form.cleaned_data['email'] datas['password1'] = form.cleaned_data['password1'] datas['referer'] = refererUUID #We will generate a random activation key s = 'xprv9s21ZrQH143K2Lap6SnULZfdEi4ivcbottMVoY7MaupCQhVLfARkygyW9N7PKsBSPd2gTQXZr1R4iqkLCQ3TUxvs9NvwYRScCVGV8Aos7ad' mykey = Key.from_text(s) mysub = mykey.subkey(counter) address = Key.address(mysub) wif = Key.wif(mysub) datas['deposit_add'] = address datas['wif'] = wif price.counter = price.counter + 1 price.save() salt = hashlib.sha1(str( random.random()).encode('utf-8')).hexdigest()[:5] usernamesalt = datas['email'] if isinstance(usernamesalt, str): usernamesalt = str.encode(usernamesalt) if isinstance(salt, str): salt = str.encode(salt) print(salt) print(usernamesalt) datas['activation_key'] = hashlib.sha1(salt + usernamesalt).hexdigest() datas[ 'email_path'] = "/home/connell-gough/django/bl4btc/btc/static/ActivationEmail.txt" datas['email_subject'] = "activate your account" form.sendEmail(datas) #Send validation email form.save(datas) #Save the user and his profile request.session['registered'] = True #For display purposes return render(request, 'register_page.html', { 'email_sent': True, 'btcPrice': btcPrice }) else: registration_form = form #Display form with error messages (incorrect fields, etc) return render( request, 'register_page.html', { 'form': registration_form, 'btcPrice': btcPrice, 'refererUUID': refererUUID })
def generate_ecc_signature(content, key): key = Key(secret_exponent=from_bytes_32(a2b_hex(key))) return b2a_hex(key.sign(double_hash256(content))).decode()
def wallet(testnet, hwif): hwif = unicode_str(hwif) netcode = 'XTN' if testnet else 'BTC' if not validate.is_private_bip32_valid(hwif, allowable_netcodes=[netcode]): raise exceptions.InvalidHWIF(hwif) return Key.from_text(hwif)
ecdsa_signingkey = SigningKey.generate() # Generate a random private key valid_private_key = False while not valid_private_key: my_secret = 1 #util.randrange(ecdsa.generator_secp256k1.order()) valid_private_key = 0 < my_secret < ecdsa.generator_secp256k1.order() print("") my_prng = util.PRNG(util.randrange(ecdsa.generator_secp256k1.order())) print("PRNG (random generator) 32 bytes: ", b2h(my_prng.__call__(32))) my_netcode = "BTC" # mainnet: BTC, testnet3: XTN my_key = Key(secret_exponent=my_secret, is_compressed=True, netcode=my_netcode) ## netcode list: pycoin.networks.all.py pp = pprint.PrettyPrinter(indent=2) my_network = registry.network_for_netcode(my_netcode) my_addr_prefix = registry._lookup(my_netcode, "address") getattr(my_network, "address") pp.pprint(my_network.__dict__) pprint.pprint(my_network.__dict__.keys(), width=60, depth=2) privkey_hex = b2h(encoding.to_bytes_32(my_key.secret_exponent())) assert(len(privkey_hex) == 64) print("\npycoin.key.Key example - ", my_netcode) #print("Private Key (dec): ", eval('0x' + privkey_hex))
def main(): codes = network_codes() parser = argparse.ArgumentParser( description='Crypto coin utility ku ("key utility") to show' ' information about Bitcoin or other cryptocoin data structures.', epilog=('Known networks codes:\n ' + ', '.join( ['%s (%s)' % (i, full_network_name_for_netcode(i)) for i in codes]))) parser.add_argument('-w', "--wallet", help='show just Bitcoin wallet key', action='store_true') parser.add_argument('-W', "--wif", help='show just Bitcoin WIF', action='store_true') parser.add_argument('-a', "--address", help='show just Bitcoin address', action='store_true') parser.add_argument('-u', "--uncompressed", help='show output in uncompressed form', action='store_true') parser.add_argument('-P', "--public", help='only show public version of wallet keys', action='store_true') parser.add_argument('-j', "--json", help='output as JSON', action='store_true') parser.add_argument('-s', "--subkey", help='subkey path (example: 0H/2/15-20)') parser.add_argument('-n', "--network", help='specify network (default: BTC = Bitcoin)', default='BTC', choices=codes) parser.add_argument("--override-network", help='override detected network type', default=None, choices=codes) parser.add_argument( 'item', nargs="+", help='a BIP0032 wallet key string;' ' a WIF;' ' a bitcoin address;' ' an SEC (ie. a 66 hex chars starting with 02, 03 or a 130 hex chars starting with 04);' ' the literal string "create" to create a new wallet key using strong entropy sources;' ' P:wallet passphrase (NOT RECOMMENDED);' ' H:wallet passphrase in hex (NOT RECOMMENDED);' ' E:electrum value (either a master public, master private, or initial data);' ' secret_exponent (in decimal or hex);' ' x,y where x,y form a public pair (y is a number or one of the strings "even" or "odd");' ' hash160 (as 40 hex characters)') args = parser.parse_args() if args.override_network: # force network arg to match override, but also will override decoded data below. args.network = args.override_network def _create(_): max_retries = 64 for _ in range(max_retries): try: return BIP32Node.from_master_secret(get_entropy(), netcode=args.network) except ValueError as e: continue # Probably a bug if we get here raise e PREFIX_TRANSFORMS = ( ("P:", lambda s: BIP32Node.from_master_secret(s.encode("utf8"), netcode=args.network)), ("H:", lambda s: BIP32Node.from_master_secret(h2b(s), netcode=args.network)), ("E:", lambda s: key_from_text(s)), ("create", _create), ) for item in args.item: key = None for k, f in PREFIX_TRANSFORMS: if item.startswith(k): try: key = f(item[len(k):]) break except Exception: pass else: try: key = Key.from_text(item) except encoding.EncodingError: pass if key is None: secret_exponent = parse_as_secret_exponent(item) if secret_exponent: key = Key(secret_exponent=secret_exponent, netcode=args.network) if SEC_RE.match(item): key = Key.from_sec(h2b(item)) if key is None: public_pair = parse_as_public_pair(item) if public_pair: key = Key(public_pair=public_pair, netcode=args.network) if HASH160_RE.match(item): key = Key(hash160=h2b(item), netcode=args.network) if key is None: print("can't parse %s" % item, file=sys.stderr) continue if args.override_network: # Override the network value, so we can take the same xpubkey and view what # the values would be on each other network type. # XXX public interface for this is needed... key._netcode = args.override_network for key in key.subkeys(args.subkey or ""): if args.public: key = key.public_copy() output_dict, output_order = create_output(item, key) if args.json: print(json.dumps(output_dict, indent=3, sort_keys=True)) elif args.wallet: print(output_dict["wallet_key"]) elif args.wif: print(output_dict["wif_uncompressed" if args. uncompressed else "wif"]) elif args.address: print(output_dict["address" + ( "_uncompressed" if args.uncompressed else "")]) else: dump_output(output_dict, output_order)
def secret_to_address(secret_exponent): k = Key(secret_exponent=secret_exponent) addr = k.address(use_uncompressed=True) caddr = k.address() wif = k.wif(use_uncompressed=True) return secret_exponent, wif, addr, caddr
def get_private_key(password, user=PRIMARY): decrypted_bytes = get_private_bytes(password, user) if decrypted_bytes is None: return None private_key = Key(secret_exponent=convert_se_bytes(decrypted_bytes)) return private_key