def test_build_spends(self): # first, here is the tx database TX_DB = {} # create a coinbase Tx where we know the public & private key exponent = wif_to_secret_exponent("5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y") compressed = False public_key_sec = public_pair_to_sec( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent), compressed=compressed ) the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8), COINBASE_BYTES_FROM_80971) TX_DB[the_coinbase_tx.hash()] = the_coinbase_tx # now create a Tx that spends the coinbase compressed = False exponent_2 = int("137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1", 16) bitcoin_address_2 = public_pair_to_bitcoin_address( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_2), compressed=compressed ) self.assertEqual("12WivmEn8AUth6x6U8HuJuXHaJzDw3gHNZ", bitcoin_address_2) coins_from = [(the_coinbase_tx.hash(), 0, the_coinbase_tx.txs_out[0])] coins_to = [(int(50 * 1e8), bitcoin_address_2)] unsigned_coinbase_spend_tx = standard_tx(coins_from, coins_to) solver = build_hash160_lookup([exponent]) coinbase_spend_tx = unsigned_coinbase_spend_tx.sign(solver) # now check that it validates self.assertEqual(coinbase_spend_tx.bad_signature_count(), 0) TX_DB[coinbase_spend_tx.hash()] = coinbase_spend_tx ## now try to respend from priv_key_2 to priv_key_3 compressed = True exponent_3 = int("f8d39b8ecd0e1b6fee5a340519f239097569d7a403a50bb14fb2f04eff8db0ff", 16) bitcoin_address_3 = public_pair_to_bitcoin_address( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_3), compressed=compressed ) self.assertEqual("13zzEHPCH2WUZJzANymow3ZrxcZ8iFBrY5", bitcoin_address_3) coins_from = [(coinbase_spend_tx.hash(), 0, coinbase_spend_tx.txs_out[0])] unsigned_spend_tx = standard_tx(coins_from, [(int(50 * 1e8), bitcoin_address_3)]) solver.update(build_hash160_lookup([exponent_2])) spend_tx = unsigned_spend_tx.sign(solver) # now check that it validates self.assertEqual(spend_tx.bad_signature_count(), 0)
def test_build_spends(self): # create a coinbase Tx where we know the public & private key exponent = wif_to_secret_exponent( "5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y") compressed = False public_key_sec = public_pair_to_sec( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent), compressed=compressed) the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8), COINBASE_BYTES_FROM_80971) # now create a Tx that spends the coinbase compressed = False exponent_2 = int( "137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1", 16) bitcoin_address_2 = public_pair_to_bitcoin_address( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_2), compressed=compressed) self.assertEqual("12WivmEn8AUth6x6U8HuJuXHaJzDw3gHNZ", bitcoin_address_2) TX_DB = dict((tx.hash(), tx) for tx in [the_coinbase_tx]) coins_from = [(the_coinbase_tx.hash(), 0)] coins_to = [(int(50 * 1e8), bitcoin_address_2)] coinbase_spend_tx = Tx.standard_tx(coins_from, coins_to, TX_DB, [exponent]) coinbase_spend_tx.validate(TX_DB) ## now try to respend from priv_key_2 to priv_key_3 compressed = True exponent_3 = int( "f8d39b8ecd0e1b6fee5a340519f239097569d7a403a50bb14fb2f04eff8db0ff", 16) bitcoin_address_3 = public_pair_to_bitcoin_address( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_3), compressed=compressed) self.assertEqual("13zzEHPCH2WUZJzANymow3ZrxcZ8iFBrY5", bitcoin_address_3) TX_DB = dict((tx.hash(), tx) for tx in [coinbase_spend_tx]) spend_tx = Tx.standard_tx([(coinbase_spend_tx.hash(), 0)], [(int(50 * 1e8), bitcoin_address_3)], TX_DB, [exponent_2]) spend_tx.validate(TX_DB)
def test_signature_hash(self): compressed = False exponent_2 = int( "137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1", 16) bitcoin_address_2 = public_pair_to_bitcoin_address( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_2), compressed=compressed) exponent = wif_to_secret_exponent( "5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y") public_key_sec = public_pair_to_sec( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent), compressed=compressed) the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8), COINBASE_BYTES_FROM_80971) coins_from = [(the_coinbase_tx.hash(), 0, the_coinbase_tx.txs_out[0])] coins_to = [(int(50 * 1e8), bitcoin_address_2)] unsigned_coinbase_spend_tx = standard_tx(coins_from, coins_to) tx_out_script_to_check = the_coinbase_tx.txs_out[0].script idx = 0 actual_hash = unsigned_coinbase_spend_tx.signature_hash( tx_out_script_to_check, idx, hash_type=SIGHASH_ALL) self.assertEqual( actual_hash, 29819170155392455064899446505816569230970401928540834591675173488544269166940 )
def test_build_spends(self): # first, here is the tx database TX_DB = {} def tx_out_for_hash_index_f(tx_hash, tx_out_idx): tx = TX_DB.get(tx_hash) return tx.txs_out[tx_out_idx] # create a coinbase Tx where we know the public & private key exponent = wif_to_secret_exponent("5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y") compressed = False public_key_sec = public_pair_to_sec(ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent), compressed=compressed) the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8), COINBASE_BYTES_FROM_80971) TX_DB[the_coinbase_tx.hash()] = the_coinbase_tx # now create a Tx that spends the coinbase compressed = False exponent_2 = int("137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1", 16) bitcoin_address_2 = public_pair_to_bitcoin_address( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_2), compressed=compressed) self.assertEqual("12WivmEn8AUth6x6U8HuJuXHaJzDw3gHNZ", bitcoin_address_2) coins_from = [(the_coinbase_tx.hash(), 0, the_coinbase_tx.txs_out[0])] coins_to = [(int(50 * 1e8), bitcoin_address_2)] unsigned_coinbase_spend_tx = UnsignedTx.standard_tx(coins_from, coins_to) solver = SecretExponentSolver([exponent]) coinbase_spend_tx = unsigned_coinbase_spend_tx.sign(solver) # now check that it validates coinbase_spend_tx.validate(tx_out_for_hash_index_f) TX_DB[coinbase_spend_tx.hash()] = coinbase_spend_tx ## now try to respend from priv_key_2 to priv_key_3 compressed = True exponent_3 = int("f8d39b8ecd0e1b6fee5a340519f239097569d7a403a50bb14fb2f04eff8db0ff", 16) bitcoin_address_3 = public_pair_to_bitcoin_address( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_3), compressed=compressed) self.assertEqual("13zzEHPCH2WUZJzANymow3ZrxcZ8iFBrY5", bitcoin_address_3) unsigned_spend_tx = UnsignedTx.standard_tx([(coinbase_spend_tx.hash(), 0, coinbase_spend_tx.txs_out[0])], [(int(50 * 1e8), bitcoin_address_3)]) solver.add_secret_exponents([exponent_2]) spend_tx = unsigned_spend_tx.sign(solver) # now check that it validates spend_tx.validate(tx_out_for_hash_index_f)
def master_public_key(self): if self._master_public_key is None: self._public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.generator_secp256k1, self.master_private_key()) self._master_public_key = to_bytes_32( self._public_pair[0]) + to_bytes_32(self._public_pair[1]) return self._master_public_key
def generate_redeem_link(email): #Generate (Public, Private) key pair rand = os.urandom(32).encode('hex') secret_exponent = int("0x" + rand, 0) private_key = encoding.secret_exponent_to_wif(secret_exponent, compressed=True) public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.secp256k1.generator_secp256k1, secret_exponent) public_key1 = "04" + format(public_pair[0], 'x') + format( public_pair[1], 'x') #Only submit public_key/email to server post_request_data = {"public_key1": public_key1, "email": email} response = requests.post(SPLIT_KEY_API, data=post_request_data) result = response.json() btc_address = result.get("bitcoin_address") if btc_address: email_redeem_code(btc_address) redeem_url = "{}?key1={}&bitcoin_address={}".format( REDEEM_ENDPOINT, private_key, btc_address) return [email, btc_address, redeem_url] else: raise RuntimeError(result['message'])
def importprivkey(self, wif): secret_exponent = wif_to_secret_exponent(wif) public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, secret_exponent) address = public_pair_to_bitcoin_address(public_pair) secret_exponent = hex(secret_exponent)[2:].encode('utf8') self.insertaddress(address, secret_exponent) return address
def create_addr(): priv = codecs.encode(os.urandom(32), 'hex').decode() secret_exponent= int('0x'+rand, 0) public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.secp256k1.generator_secp256k1, secret_exponent) hash160 = encoding.public_pair_to_hash160_sec(public_pair, compressed=True) addr = encoding.hash160_sec_to_bitcoin_address(hash160) return addr, priv
def generate_redeem_link(email): #Generate (Public, Private) key pair rand = os.urandom(32).encode('hex') secret_exponent= int("0x"+rand, 0) % ecdsa.secp256k1._r private_key = encoding.secret_exponent_to_wif(secret_exponent, compressed=True) public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.secp256k1.generator_secp256k1,secret_exponent) public_key1 = "04" + format(public_pair[0], '064x') + format(public_pair[1], '064x') #Only submit public_key/email to server post_request_data = { "public_key1" : public_key1, "email" : email, "refund_time": REFUND_TIME} headers={'Authorization': 'Bearer {}'.format(API_KEY)} response = requests.post(SPLIT_KEY_API, data=post_request_data, headers=headers) result = response.json() btc_address = result.get("bitcoin_address") if btc_address: email_redeem_code(btc_address) redeem_url="{}?key1={}&bitcoin_address={}".format(REDEEM_ENDPOINT, private_key, btc_address) return dict(redeem_url = redeem_url, bitcoin_address = btc_address) else: raise RuntimeError(result['message'])
def importprivkey(self, wif): secret_exponent = wif_to_secret_exponent(wif) public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.generator_secp256k1, secret_exponent) address = public_pair_to_bitcoin_address(public_pair) secret_exponent = hex(secret_exponent)[2:].encode('utf8') self.insertaddress(address, secret_exponent) return address
def private_key_to_public_key(private_key_wif): secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif, is_test=config.TESTNET) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) public_key = public_pair_to_sec(public_pair, compressed=compressed) public_key_hex = binascii.hexlify(public_key).decode('utf-8') return public_key_hex
def private_key_to_public_key (private_key_wif): try: secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(private_key_wif, [wif_prefix(is_test=config.TESTNET)]) except EncodingError: raise exceptions.AltcoinSupportError('pycoin: unsupported WIF prefix') public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) public_key = public_pair_to_sec(public_pair, compressed=compressed) public_key_hex = binascii.hexlify(public_key).decode('utf-8') return public_key_hex
def do_test(secret_exponent, val_list): public_point = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) for v in val_list: signature = sign(generator_secp256k1, secret_exponent, v) r = verify(generator_secp256k1, public_point, v, signature) assert r == True signature = signature[0],signature[1]+1 r = verify(generator_secp256k1, public_point, v, signature) assert r == False
def gen_address(private_key, compressed=True): # private_key = codecs.encode(os.urandom(32), 'hex').decode() secret_exponent = int('0x' + private_key, 0) print('WIF: ' + encoding.secret_exponent_to_wif(secret_exponent, compressed=compressed)) public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.secp256k1.generator_secp256k1, secret_exponent) print('public pair:', public_pair) hash160 = encoding.public_pair_to_hash160_sec(public_pair, compressed=compressed) print("hash160: {}".format(hash160.hex())) return encoding.hash160_sec_to_bitcoin_address(hash160, address_prefix=b'\0')
def test_build_spends(self): # create a coinbase Tx where we know the public & private key exponent = wif_to_secret_exponent("5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y") compressed = False public_key_sec = public_pair_to_sec(ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent), compressed=compressed) the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8), COINBASE_BYTES_FROM_80971) # now create a Tx that spends the coinbase compressed = False exponent_2 = int("137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1", 16) bitcoin_address_2 = public_pair_to_bitcoin_address( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_2), compressed=compressed) self.assertEqual("12WivmEn8AUth6x6U8HuJuXHaJzDw3gHNZ", bitcoin_address_2) TX_DB = dict((tx.hash(), tx) for tx in [the_coinbase_tx]) coins_from = [(the_coinbase_tx.hash(), 0)] coins_to = [(int(50 * 1e8), bitcoin_address_2)] coinbase_spend_tx = Tx.standard_tx(coins_from, coins_to, TX_DB, [exponent]) coinbase_spend_tx.validate(TX_DB) ## now try to respend from priv_key_2 to priv_key_3 compressed = True exponent_3 = int("f8d39b8ecd0e1b6fee5a340519f239097569d7a403a50bb14fb2f04eff8db0ff", 16) bitcoin_address_3 = public_pair_to_bitcoin_address( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_3), compressed=compressed) self.assertEqual("13zzEHPCH2WUZJzANymow3ZrxcZ8iFBrY5", bitcoin_address_3) TX_DB = dict((tx.hash(), tx) for tx in [coinbase_spend_tx]) spend_tx = Tx.standard_tx([(coinbase_spend_tx.hash(), 0)], [(int(50 * 1e8), bitcoin_address_3)], TX_DB, [exponent_2]) spend_tx.validate(TX_DB)
def main(): parser = argparse.ArgumentParser(description="Bitcoin utilities. WARNING: obsolete. Use ku instead.") parser.add_argument('-a', "--address", help='show as Bitcoin address', action='store_true') parser.add_argument('-1', "--hash160", help='show as hash 160', action='store_true') parser.add_argument('-v', "--verbose", help='dump all information available', action='store_true') parser.add_argument('-w', "--wif", help='show as Bitcoin WIF', action='store_true') parser.add_argument('-n', "--uncompressed", help='show in uncompressed form', action='store_true') parser.add_argument('item', help='a WIF, secret exponent, X/Y public pair, SEC (as hex), hash160 (as hex), Bitcoin address', nargs="+") args = parser.parse_args() for c in args.item: # figure out what it is: # - secret exponent # - WIF # - X/Y public key (base 10 or hex) # - sec # - hash160 # - Bitcoin address secret_exponent = parse_as_private_key(c) if secret_exponent: public_pair = ecdsa.public_pair_for_secret_exponent(secp256k1.generator_secp256k1, secret_exponent) print("secret exponent: %d" % secret_exponent) print(" hex: %x" % secret_exponent) print("WIF: %s" % encoding.secret_exponent_to_wif(secret_exponent, compressed=True)) print(" uncompressed: %s" % encoding.secret_exponent_to_wif(secret_exponent, compressed=False)) else: public_pair = parse_as_public_pair(c) if public_pair: bitcoin_address_uncompressed = encoding.public_pair_to_bitcoin_address(public_pair, compressed=False) bitcoin_address_compressed = encoding.public_pair_to_bitcoin_address(public_pair, compressed=True) print("public pair x: %d" % public_pair[0]) print("public pair y: %d" % public_pair[1]) print(" x as hex: %x" % public_pair[0]) print(" y as hex: %x" % public_pair[1]) print("y parity: %s" % "odd" if (public_pair[1] & 1) else "even") print("key pair as sec: %s" % b2h(encoding.public_pair_to_sec(public_pair, compressed=True))) s = b2h(encoding.public_pair_to_sec(public_pair, compressed=False)) print(" uncompressed: %s\\\n %s" % (s[:66], s[66:])) hash160 = encoding.public_pair_to_hash160_sec(public_pair, compressed=True) hash160_unc = encoding.public_pair_to_hash160_sec(public_pair, compressed=False) myeccpoint = encoding.public_pair_to_sec(public_pair, compressed=True) myhash = encoding.ripemd160( myeccpoint ).digest( ) print("BTSX PubKey: %s" % BTS_ADDRESS_PREFIX + encoding.b2a_base58(myeccpoint + myhash[ :4 ])) else: hash160 = parse_as_address(c) hash160_unc = None if not hash160: sys.stderr.write("can't decode input %s\n" % c) sys.exit(1) print("hash160: %s" % b2h(hash160)) if hash160_unc: print(" uncompressed: %s" % b2h(hash160_unc)) print("Bitcoin address: %s" % encoding.hash160_sec_to_bitcoin_address(hash160)) if hash160_unc: print(" uncompressed: %s" % encoding.hash160_sec_to_bitcoin_address(hash160_unc))
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 = binascii.unhexlify(public_pair_sec) c_sec = binascii.unhexlify(c_public_pair_sec) self.assertEqual( secret_exponent_to_wif(secret_exponent, compressed=False), wif) self.assertEqual( secret_exponent_to_wif(secret_exponent, compressed=True), c_wif) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( wif) self.assertEqual(exponent, secret_exponent) self.assertFalse(compressed) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( c_wif) self.assertEqual(exponent, secret_exponent) self.assertTrue(compressed) public_pair = public_pair_for_secret_exponent( generator_secp256k1, secret_exponent) pk_public_pair = public_pair_from_sec(sec) compressed = is_sec_compressed(sec) self.assertEqual(pk_public_pair, public_pair) self.assertFalse(is_sec_compressed(sec)) self.assertEqual( public_pair_to_sec(pk_public_pair, compressed=False), sec) pk_public_pair = public_pair_from_sec(c_sec) compressed = is_sec_compressed(c_sec) self.assertEqual(pk_public_pair, public_pair) self.assertTrue(compressed) self.assertEqual( public_pair_to_sec(pk_public_pair, compressed=True), c_sec) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=True) self.assertEqual(bca, c_address_b58) self.assertEqual( bitcoin_address_to_ripemd160_sha_sec(c_address_b58), public_pair_to_ripemd160_sha_sec(pk_public_pair, compressed=True)) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=False) self.assertEqual(bca, address_b58) self.assertEqual( bitcoin_address_to_ripemd160_sha_sec(address_b58), public_pair_to_ripemd160_sha_sec(pk_public_pair, compressed=False))
def test_signature_hash(self): compressed = False exponent_2 = int("137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1", 16) bitcoin_address_2 = public_pair_to_bitcoin_address( ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent_2), compressed=compressed) exponent = wif_to_secret_exponent("5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y") public_key_sec = public_pair_to_sec(ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent), compressed=compressed) the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8), COINBASE_BYTES_FROM_80971) coins_from = [(the_coinbase_tx.hash(), 0, the_coinbase_tx.txs_out[0])] coins_to = [(int(50 * 1e8), bitcoin_address_2)] unsigned_coinbase_spend_tx = standard_tx(coins_from, coins_to) tx_out_script_to_check = the_coinbase_tx.txs_out[0].script idx = 0 actual_hash = unsigned_coinbase_spend_tx.signature_hash(tx_out_script_to_check, idx, hash_type=SIGHASH_ALL) self.assertEqual(actual_hash, 29819170155392455064899446505816569230970401928540834591675173488544269166940)
def __init__(self, secret_exponents): super(OfflineAwareSolver, self).__init__(secret_exponents) STANDARD_SCRIPT_OUT = "OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG" self.script_hash160 = [] for se in secret_exponents: pp = public_pair_for_secret_exponent(generator_secp256k1, se) h160sec = public_pair_to_hash160_sec(pp, False) script_text = STANDARD_SCRIPT_OUT % b2h(h160sec) print script_text self.script_hash160.append(compile(script_text))
def __init__(self, secret_exponent=None, public_pair=None, hash160=None, prefer_uncompressed=None, is_compressed=True, is_pay_to_script=False, netcode=None): """ secret_exponent: a long representing the secret exponent public_pair: a tuple of long integers on the ecdsa curve hash160: a hash160 value corresponding to a bitcoin address Include at most one of secret_exponent, public_pair or hash160. prefer_uncompressed: whether or not to produce text outputs as compressed or uncompressed. is_pay_to_script: whether or not this key is for a pay-to-script style transaction netcode: the code for the network (as defined in pycoin.networks) Include at most one of secret_exponent, public_pair or hash160. prefer_uncompressed, is_compressed (booleans) are optional. """ if netcode is None: netcode = get_current_netcode() if [secret_exponent, public_pair, hash160].count(None) != 2: raise ValueError("exactly one of secret_exponent, public_pair, hash160 must be passed.") if prefer_uncompressed is None: prefer_uncompressed = not is_compressed self._prefer_uncompressed = prefer_uncompressed self._secret_exponent = secret_exponent self._public_pair = public_pair self._hash160_uncompressed = None self._hash160_compressed = None if hash160: if is_compressed: self._hash160_compressed = hash160 else: self._hash160_uncompressed = hash160 self._netcode = netcode if self._public_pair is None and self._secret_exponent is not None: if self._secret_exponent < 1 \ or self._secret_exponent >= ecdsa.generator_secp256k1.order(): raise InvalidSecretExponentError() public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.generator_secp256k1, self._secret_exponent) self._public_pair = public_pair if self._public_pair is not None \ and (None in self._public_pair or not ecdsa.is_public_pair_valid(ecdsa.generator_secp256k1, self._public_pair)): raise InvalidPublicPairError()
def dumppubkey(self, address): if is_valid_bitcoin_address(address)==False: return Exception("Invalid address %s" % address) try: secret_exponent = self.getsecretexponent(address) public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, secret_exponent) pubkey = public_pair_to_sec(public_pair, compressed=True) pubkey = b2h(pubkey) except: raise Exception("Unknown address: %s" % address) return pubkey
def do_test(secret_exponent, val_list): public_point = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) for v in val_list: signature = sign(generator_secp256k1, secret_exponent, v) r = verify(generator_secp256k1, public_point, v, signature) # Check that the 's' value is 'low', to prevent possible transaction malleability as per # https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#low-s-values-in-signatures assert signature[1] <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 assert r == True signature = signature[0],signature[1]+1 r = verify(generator_secp256k1, public_point, v, signature) assert r == False
def main(): parser = argparse.ArgumentParser(description="Bitcoin utilities.") parser.add_argument('-a', "--address", help='show as Bitcoin address', action='store_true') parser.add_argument('-1', "--hash160", help='show as hash 160', action='store_true') parser.add_argument('-v', "--verbose", help='dump all information available', action='store_true') parser.add_argument('-w', "--wif", help='show as Bitcoin WIF', action='store_true') parser.add_argument('-n', "--uncompressed", help='show in uncompressed form', action='store_true') parser.add_argument('item', help='a WIF, secret exponent, X/Y public pair, SEC (as hex), hash160 (as hex), Bitcoin address', nargs="+") args = parser.parse_args() for c in args.item: # figure out what it is: # - secret exponent # - WIF # - X/Y public key (base 10 or hex) # - sec # - hash160 # - Bitcoin address secret_exponent = parse_as_private_key(c) if secret_exponent: public_pair = ecdsa.public_pair_for_secret_exponent(secp256k1.generator_secp256k1, secret_exponent) print("secret exponent: %d" % secret_exponent) print(" hex: %x" % secret_exponent) print("WIF: %s" % encoding.secret_exponent_to_wif(secret_exponent, compressed=True)) print(" uncompressed: %s" % encoding.secret_exponent_to_wif(secret_exponent, compressed=False)) else: public_pair = parse_as_public_pair(c) if public_pair: bitcoin_address_uncompressed = encoding.public_pair_to_bitcoin_address(public_pair, compressed=False) bitcoin_address_compressed = encoding.public_pair_to_bitcoin_address(public_pair, compressed=True) print("public pair x: %d" % public_pair[0]) print("public pair y: %d" % public_pair[1]) print(" x as hex: %x" % public_pair[0]) print(" y as hex: %x" % public_pair[1]) print("y parity: %s" % "odd" if (public_pair[1] & 1) else "even") print("key pair as sec: %s" % b2h(encoding.public_pair_to_sec(public_pair, compressed=True))) s = b2h(encoding.public_pair_to_sec(public_pair, compressed=False)) print(" uncompressed: %s\\\n %s" % (s[:66], s[66:])) hash160 = encoding.public_pair_to_hash160_sec(public_pair, compressed=True) hash160_unc = encoding.public_pair_to_hash160_sec(public_pair, compressed=False) else: hash160 = parse_as_address(c) hash160_unc = None if not hash160: sys.stderr.write("can't decode input %s\n" % c) sys.exit(1) print("hash160: %s" % b2h(hash160)) if hash160_unc: print(" uncompressed: %s" % b2h(hash160_unc)) print("Bitcoin address: %s" % encoding.hash160_sec_to_bitcoin_address(hash160)) if hash160_unc: print(" uncompressed: %s" % encoding.hash160_sec_to_bitcoin_address(hash160_unc))
def dumppubkey(self, address): if is_valid_bitcoin_address(address) == False: return Exception("Invalid address %s" % address) try: secret_exponent = self.getsecretexponent(address) public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.generator_secp256k1, secret_exponent) pubkey = public_pair_to_sec(public_pair, compressed=True) pubkey = b2h(pubkey) except: raise Exception("Unknown address: %s" % address) return pubkey
def gen_address(private_key, compressed=True): # private_key = codecs.encode(os.urandom(32), 'hex').decode() secret_exponent = int('0x' + private_key, 0) print('WIF: ' + encoding.secret_exponent_to_wif(secret_exponent, compressed=compressed)) public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.secp256k1.generator_secp256k1, secret_exponent) print('public pair:', public_pair) hash160 = encoding.public_pair_to_hash160_sec(public_pair, compressed=compressed) print("hash160: {}".format(hash160.hex())) return encoding.hash160_sec_to_bitcoin_address(hash160, address_prefix=b'\0')
def public_pair(self): """ Return a pair of integers representing the public key (or None). """ if self._public_pair is None and self.secret_exponent(): public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.generator_secp256k1, self._secret_exponent) if not ecdsa.is_public_pair_valid(ecdsa.generator_secp256k1, public_pair): raise InvalidKeyGeneratedError( "this key would produce an invalid public pair; please skip it") self._public_pair = public_pair return self._public_pair
def create_coinbase_tx(parser): args = parser.parse_args() try: if len(args.txinfo) != 1: parser.error("coinbase transactions need exactly one output parameter (wif/BTC count)") wif, btc_amount = args.txinfo[0].split("/") satoshi_amount = btc_to_satoshi(btc_amount) secret_exponent, compressed = encoding.wif_to_tuple_of_secret_exponent_compressed(wif) public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.secp256k1.generator_secp256k1, secret_exponent) public_key_sec = encoding.public_pair_to_sec(public_pair, compressed=compressed) coinbase_tx = Tx.coinbase_tx(public_key_sec, satoshi_amount) return coinbase_tx except Exception: parser.error("coinbase transactions need exactly one output parameter (wif/BTC count)")
def private_key_to_public_key (private_key_wif): if config.TESTNET: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_TESTNET] else: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_MAINNET] try: secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif, allowable_wif_prefixes=allowable_wif_prefixes) except EncodingError: raise AltcoinSupportError('pycoin: unsupported WIF prefix') public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) public_key = public_pair_to_sec(public_pair, compressed=compressed) public_key_hex = binascii.hexlify(public_key).decode('utf-8') return public_key_hex
def private_key_to_public_key(private_key_wif): if config.TESTNET: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_TESTNET] else: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_MAINNET] try: secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif, allowable_wif_prefixes=allowable_wif_prefixes) except EncodingError: raise AltcoinSupportError('pycoin: unsupported WIF prefix') public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) public_key = public_pair_to_sec(public_pair, compressed=compressed) public_key_hex = binascii.hexlify(public_key).decode('utf-8') return public_key_hex
def public_pair(self): """ Return a pair of integers representing the public key (or None). """ if self._public_pair is None and self.secret_exponent(): public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.generator_secp256k1, self._secret_exponent) if not ecdsa.is_public_pair_valid(ecdsa.generator_secp256k1, public_pair): raise InvalidKeyGeneratedError( "this key would produce an invalid public pair; please skip it" ) self._public_pair = public_pair return self._public_pair
def search(target_xfp): k = BIP32Node.from_hwif( "tprv8ZgxMBicQKsPeXJHL3vPPgTAEqQ5P2FD9qDeCQT4Cp1EMY5QkwMPWFxHdxHrxZhhcVRJ2m7BNWTz9Xre68y7mX5vCdMJ5qXMUfnrZ2si2X4" ) pid = os.getpid() target_xfp = h2b_rev(target_xfp) # test by going -33 here. #sec_exp = k._secret_exponent - 33 sec_exp = k._secret_exponent + (pid * int(1e40)) i = 0 last_xfp = None while 1: i += 1 sec_exp += 1 public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.generator_secp256k1, sec_exp) xfp = public_pair_to_hash160_sec(public_pair, compressed=True)[:4] if i <= 5: # checking code (slow) b = BIP32Node(netcode='BTC', chain_code=bytes(32), secret_exponent=sec_exp) chk = b.fingerprint() assert b._secret_exponent == sec_exp assert xfp == chk, (xfp, chk) assert xfp != last_xfp, 'repeat xfp!' last_xfp = xfp if xfp == target_xfp: print(f"\n\nFOUND: sec_exp = {sec_exp}\n") b = BIP32Node(netcode='BTC', chain_code=bytes(32), secret_exponent=sec_exp) chk = b.fingerprint() assert b._secret_exponent == sec_exp assert xfp == chk, (xfp, chk) print(b.hwif(), end='\n\n') return if not (i % 27): print(' %6d %9d' % (pid, i), end='\r')
def test_sign(self): for se in ["47f7616ea6f9b923076625b4488115de1ef1187f760e65f89eb6f4f7ff04b012"] + [x * 64 for x in "123456789abcde"]: secret_exponent = int(se, 16) val = 28832970699858290 #int.from_bytes(b"foo bar", byteorder="big") sig = sign(generator_secp256k1, secret_exponent, val) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) v = verify(generator_secp256k1, public_pair, val, sig) self.assertTrue(v) sig1 = (sig[0] + 1, sig[1]) v = verify(generator_secp256k1, public_pair, val, sig1) self.assertFalse(v) public_pairs = possible_public_pairs_for_signature(generator_secp256k1, val, sig) self.assertIn(public_pair, public_pairs) print(se)
def test_sign(self): for se in ["47f7616ea6f9b923076625b4488115de1ef1187f760e65f89eb6f4f7ff04b012"] + [x * 64 for x in "123456789abcde"]: secret_exponent = int(se, 16) val = int.from_bytes(b"foo bar", byteorder="big") sig = sign(generator_secp256k1, secret_exponent, val) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) v = verify(generator_secp256k1, public_pair, val, sig) self.assertTrue(v) sig1 = (sig[0] + 1, sig[1]) v = verify(generator_secp256k1, public_pair, val, sig1) self.assertFalse(v) public_pairs = possible_public_pairs_for_signature(generator_secp256k1, val, sig) self.assertIn(public_pair, public_pairs) print(se)
def __call__(self, tx_out_script, signature_hash, signature_type): """Figure out how to create a signature for the incoming transaction, and sign it. tx_out_script: the tx_out script that needs to be "solved" signature_hash: the bignum hash value of the new transaction reassigning the coins signature_type: always SIGHASH_ALL (1) """ if signature_hash == 0: raise SolvingError("signature_hash can't be 0") tx_script = TxScript(tx_out_script) opcode_value_list = tx_script.match_script_to_templates() ba = bytearray() compressed = True for opcode, v in opcode_value_list: if opcode == opcodes.OP_PUBKEY: public_pair = sec_to_public_pair(v) bitcoin_address = public_pair_to_bitcoin_address( public_pair, compressed=compressed) elif opcode == opcodes.OP_PUBKEYHASH: bitcoin_address = hash160_sec_to_bitcoin_address(v) else: raise SolvingError("can't determine how to sign this script") secret_exponent = self.wallet.getsecretexponent(bitcoin_address) r, s = ecdsa.sign(ecdsa.generator_secp256k1, secret_exponent, signature_hash) sig = der.sigencode_der(r, s) + bytes_from_int(signature_type) ba += tools.compile(binascii.hexlify(sig).decode("utf8")) if opcode == opcodes.OP_PUBKEYHASH: public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.generator_secp256k1, secret_exponent) ba += tools.compile( binascii.hexlify( public_pair_to_sec( public_pair, compressed=compressed)).decode("utf8")) return bytes(ba)
def warp(self, passphrase, salt=""): """ Return dictionary of WarpWallet public and private keys corresponding to the given passphrase and salt. """ s1 = binascii.hexlify(self._scrypt(passphrase, salt)) out = self._pbkdf2(passphrase, salt) s2 = binascii.hexlify(out) base = binascii.unhexlify(s1) s3 = binascii.hexlify(self._sxor(base,out)) secret_exponent = int(s3, 16) public_pair = ecdsa.public_pair_for_secret_exponent(secp256k1.generator_secp256k1, secret_exponent) private_key = encoding.secret_exponent_to_wif(secret_exponent, compressed=False) public_key = encoding.public_pair_to_bitcoin_address(public_pair, compressed=False) out = { "keys" : { "private_key" : private_key, "public_key" : public_key }, "seeds" : [s1, s2, s3], "passphrase" : passphrase, "salt" : salt } return out
def pycoin_sign_raw_transaction(tx_hex, private_key_wif): for char in private_key_wif: if char not in script.b58_digits: raise exceptions.TransactionError('invalid private key') if config.TESTNET: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_TESTNET] else: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_MAINNET] secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif, allowable_wif_prefixes=allowable_wif_prefixes) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) hash160 = public_pair_to_hash160_sec(public_pair, compressed) hash160_lookup = {hash160: (secret_exponent, public_pair, compressed)} tx = Tx.tx_from_hex(tx_hex) for idx, tx_in in enumerate(tx.txs_in): tx.sign_tx_in(hash160_lookup, idx, tx_in.script, hash_type=SIGHASH_ALL) return tx.as_hex()
def _calculate_all(self): for attr in "_secret_exponent _public_pair _wif_uncompressed _wif_compressed _sec_compressed" \ " _sec_uncompressed _hash160_compressed _hash160_uncompressed _address_compressed" \ " _address_uncompressed _netcode".split(): setattr(self, attr, getattr(self, attr, None)) if self._hierarchical_wallet: if self._hierarchical_wallet.is_private: self._secret_exponent = self._hierarchical_wallet.secret_exponent else: self._public_pair = self._hierarchical_wallet.public_pair self._netcode = self._hierarchical_wallet.netcode wif_prefix = wif_prefix_for_netcode(self._netcode) if self._secret_exponent: self._wif_uncompressed = secret_exponent_to_wif( self._secret_exponent, compressed=False, wif_prefix=wif_prefix) self._wif_compressed = secret_exponent_to_wif( self._secret_exponent, compressed=True, wif_prefix=wif_prefix) self._public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.generator_secp256k1, self._secret_exponent) if self._public_pair: self._sec_compressed = public_pair_to_sec(self._public_pair, compressed=True) self._sec_uncompressed = public_pair_to_sec(self._public_pair, compressed=False) self._hash160_compressed = hash160(self._sec_compressed) self._hash160_uncompressed = hash160(self._sec_uncompressed) address_prefix = address_prefix_for_netcode(self._netcode) if self._hash160_compressed: self._address_compressed = hash160_sec_to_bitcoin_address( self._hash160_compressed, address_prefix=address_prefix) if self._hash160_uncompressed: self._address_uncompressed = hash160_sec_to_bitcoin_address( self._hash160_uncompressed, address_prefix=address_prefix)
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 = binascii.unhexlify(public_pair_sec) c_sec = binascii.unhexlify(c_public_pair_sec) self.assertEqual(secret_exponent_to_wif(secret_exponent, compressed=False), wif) self.assertEqual(secret_exponent_to_wif(secret_exponent, compressed=True), c_wif) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(wif) self.assertEqual(exponent, secret_exponent) self.assertFalse(compressed) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(c_wif) self.assertEqual(exponent, secret_exponent) self.assertTrue(compressed) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) pk_public_pair = public_pair_from_sec(sec) compressed = is_sec_compressed(sec) self.assertEqual(pk_public_pair, public_pair) self.assertFalse(is_sec_compressed(sec)) self.assertEqual(public_pair_to_sec(pk_public_pair, compressed=False), sec) pk_public_pair = public_pair_from_sec(c_sec) compressed = is_sec_compressed(c_sec) self.assertEqual(pk_public_pair, public_pair) self.assertTrue(compressed) self.assertEqual(public_pair_to_sec(pk_public_pair, compressed=True), c_sec) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=True) self.assertEqual(bca, c_address_b58) self.assertEqual(bitcoin_address_to_ripemd160_sha_sec(c_address_b58), public_pair_to_ripemd160_sha_sec(pk_public_pair, compressed=True)) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=False) self.assertEqual(bca, address_b58) self.assertEqual(bitcoin_address_to_ripemd160_sha_sec(address_b58), public_pair_to_ripemd160_sha_sec(pk_public_pair, compressed=False))
def __call__(self, tx_out_script, signature_hash, signature_type): """Figure out how to create a signature for the incoming transaction, and sign it. tx_out_script: the tx_out script that needs to be "solved" signature_hash: the bignum hash value of the new transaction reassigning the coins signature_type: always SIGHASH_ALL (1) """ if signature_hash == 0: raise SolvingError("signature_hash can't be 0") tx_script = TxScript(tx_out_script) opcode_value_list = tx_script.match_script_to_templates() ba = bytearray() compressed = True for opcode, v in opcode_value_list: if opcode == opcodes.OP_PUBKEY: public_pair = sec_to_public_pair(v) bitcoin_address = public_pair_to_bitcoin_address(public_pair, compressed=compressed) elif opcode == opcodes.OP_PUBKEYHASH: bitcoin_address = hash160_sec_to_bitcoin_address(v) else: raise SolvingError("can't determine how to sign this script") secret_exponent = self.wallet.getsecretexponent(bitcoin_address) r, s = ecdsa.sign(ecdsa.generator_secp256k1, secret_exponent, signature_hash) sig = der.sigencode_der(r, s) + bytes_from_int(signature_type) ba += tools.compile(binascii.hexlify(sig).decode("utf8")) if opcode == opcodes.OP_PUBKEYHASH: public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, secret_exponent) ba += tools.compile( binascii.hexlify(public_pair_to_sec(public_pair, compressed=compressed)).decode("utf8") ) return bytes(ba)
def from_secret_exponent_and_msg(cls, secret_exponent, msg): msg_hash = global_hash(msg) r, s = ecdsa.sign(ecdsa.generator_secp256k1, secret_exponent, msg_hash) x, y = ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, secret_exponent) return Signature(pub_x=x, pub_y=y, r=r, s=s, msg_hash=msg_hash)
import hashlib from pycoin import ecdsa, encoding import os import codecs if __name__ == '__main__': #rand = codecs.encode(os.urandom(32), 'hex').decode() #secret_exponent= int('0x'+rand, 0) secret_exponent = int(hp, 16) print('WIF: ' + encoding.secret_exponent_to_wif(secret_exponent, compressed=False)) public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.secp256k1.generator_secp256k1, secret_exponent) hash160 = encoding.public_pair_to_hash160_sec(public_pair, compressed=True) codecs.encode(hash160, 'hex') print('Bitcoin address: %s' % encoding.hash160_sec_to_bitcoin_address(hash160)) with open('../../Mining/dict/UrbanDictionary.txt', 'r') as f: contents = f.readlines() fout = open('privaddr-pair.txt', 'w') i = 0 for l in contents: priv = seed2hpriv(l)
import hashlib import struct import unittest from pycoin.ecdsa import generator_secp256k1, public_pair_for_secret_exponent from pycoin.encoding import public_pair_to_bitcoin_address, secret_exponent_to_wif from pycoin.tx.exceptions import BadSpendableError from pycoin.tx.tx_utils import create_signed_tx from pycoin.tx.Spendable import Spendable from pycoin.ui import standard_tx_out_script BITCOIN_ADDRESSES = [public_pair_to_bitcoin_address( public_pair_for_secret_exponent(generator_secp256k1, i)) for i in range(1, 21)] WIFS = [secret_exponent_to_wif(i) for i in range(1, 21)] FAKE_HASHES = [hashlib.sha256(struct.pack("Q", idx)).digest() for idx in range(100)] class SpendTest(unittest.TestCase): def test_simple_spend(self): FEE = 10000 # create a fake Spendable COIN_VALUE = 100000000
:param seconds: seconds in float, int, w/e :return: none ''' for i in range(int(seconds * 10)): time.sleep(0.1) if object.is_shutdown: break # Crypto Helpers def valid_secp256k1_signature(x, y, msg, r, s): return ecdsa.verify(ecdsa.generator_secp256k1, (x, y), global_hash(msg), (r, s)) def pubkey_for_secret_exponent(exponent): return ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent) PUB_KEY_FOR_KNOWN_SE = ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, 1) PUB_KEY_X_FOR_KNOWN_SE = PUB_KEY_FOR_KNOWN_SE[0] # Network-y functions def storage_fee(block): return (len(block.to_json()) - len(str(block.state_hash))) // 32 * FEE_CONSTANT # Exceptions InvalidBlockException = BlockNotFoundException = Exception
def serialise(inputs, destination_output=None, data_output=None, change_output=None, multisig=False, source=None): s = (1).to_bytes(4, byteorder='little') # Version # Number of inputs. s += var_int(int(len(inputs))) # List of Inputs. for i in range(len(inputs)): txin = inputs[i] s += binascii.unhexlify(bytes(txin['txid'], 'utf-8'))[::-1] # TxOutHash s += txin['vout'].to_bytes(4, byteorder='little') # TxOutIndex # No signature. script = b'' s += var_int(int(len(script))) # Script length s += script # Script s += b'\xff' * 4 # Sequence # Number of outputs. n = 0 if destination_output: n += 1 if data_output: data_array, value = data_output for data_chunk in data_array: n += 1 else: data_array = [] if change_output: n += 1 s += var_int(n) # Destination output. if destination_output: address, value = destination_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script # Data output. for data_chunk in data_array: data_array, value = data_output # DUPE s += (value).to_bytes(8, byteorder='little') # Value if multisig: # Get source public key. from pycoin.ecdsa import generator_secp256k1, public_pair_for_secret_exponent from pycoin.encoding import wif_to_tuple_of_secret_exponent_compressed, public_pair_to_sec private_key_wif = rpc('dumpprivkey', [source]) secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif) public_pair = public_pair_for_secret_exponent( generator_secp256k1, secret_exponent) source_pubkey = public_pair_to_sec(public_pair, compressed=compressed) # Get data (fake) public key. pad_length = 33 - 1 - len(data_chunk) assert pad_length >= 0 data_pubkey = bytes([len(data_chunk) ]) + data_chunk + (pad_length * b'\x00') script = OP_1 # OP_1 script += op_push( len(source_pubkey)) # Push bytes of source public key script += source_pubkey # Source public key script += op_push( len(data_pubkey)) # Push bytes of data chunk (fake) public key script += data_pubkey # Data chunk (fake) public key script += OP_2 # OP_2 script += OP_CHECKMULTISIG # OP_CHECKMULTISIG else: script = OP_RETURN # OP_RETURN script += op_push(len( data_chunk)) # Push bytes of data chunk (NOTE: OP_SMALLDATA?) script += data_chunk # Data chunk s += var_int(int(len(script))) # Script length s += script # Change output. if change_output: address, value = change_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script s += (0).to_bytes(4, byteorder='little') # LockTime return s
def pubkey_for_secret_exponent(exponent): return ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, exponent)
def coinbase_tx(secret_exponent): public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.secp256k1.generator_secp256k1, secret_exponent) public_key_sec = public_pair_to_sec(public_pair) return Tx.coinbase_tx(public_key_sec, 2500000000)
def serialise (encoding, inputs, destination_outputs, data_output=None, change_output=None, source=None, pubkey=None): s = (1).to_bytes(4, byteorder='little') # Version # Number of inputs. s += var_int(int(len(inputs))) # List of Inputs. for i in range(len(inputs)): txin = inputs[i] s += binascii.unhexlify(bytes(txin['txid'], 'utf-8'))[::-1] # TxOutHash s += txin['vout'].to_bytes(4, byteorder='little') # TxOutIndex script = binascii.unhexlify(bytes(txin['scriptPubKey'], 'utf-8')) s += var_int(int(len(script))) # Script length s += script # Script s += b'\xff' * 4 # Sequence # Number of outputs. n = 0 n += len(destination_outputs) if data_output: data_array, value = data_output for data_chunk in data_array: n += 1 else: data_array = [] if change_output: n += 1 s += var_int(n) # Destination output. for address, value in destination_outputs: pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script # Data output. for data_chunk in data_array: data_array, value = data_output # DUPE s += value.to_bytes(8, byteorder='little') # Value # Get source public key (either provided as a string or derived from a private key in the wallet). if encoding in ('multisig', 'pubkeyhash'): if pubkey: pubkeypair = bitcoin_utils.parse_as_public_pair(pubkey) source_pubkey = public_pair_to_sec(pubkeypair, compressed=True) else: if config.PREFIX == config.UNITTEST_PREFIX: private_key_wif = 'cPdUqd5EbBWsjcG9xiL1hz8bEyGFiz4SW99maU9JgpL9TEcxUf3j' else: private_key_wif = rpc('dumpprivkey', [source]) if private_key_wif[0] == 'c': testnet = True else: testnet = False secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(private_key_wif, is_test=testnet) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) source_pubkey = public_pair_to_sec(public_pair, compressed=compressed) if encoding == 'multisig': # Get data (fake) public key. pad_length = 33 - 1 - len(data_chunk) assert pad_length >= 0 data_pubkey = bytes([len(data_chunk)]) + data_chunk + (pad_length * b'\x00') # Construct script. script = OP_1 # OP_1 script += op_push(len(source_pubkey)) # Push bytes of source public key script += source_pubkey # Source public key script += op_push(len(data_pubkey)) # Push bytes of data chunk (fake) public key script += data_pubkey # Data chunk (fake) public key script += OP_2 # OP_2 script += OP_CHECKMULTISIG # OP_CHECKMULTISIG elif encoding == 'opreturn': script = OP_RETURN # OP_RETURN script += op_push(len(data_chunk)) # Push bytes of data chunk (NOTE: OP_SMALLDATA?) script += data_chunk # Data chunk elif encoding == 'pubkeyhash': pad_length = 20 - 1 - len(data_chunk) assert pad_length >= 0 obj1 = ARC4.new(binascii.unhexlify(inputs[0]['txid'])) # Arbitrary, easy‐to‐find, unique key. pubkeyhash = bytes([len(data_chunk)]) + data_chunk + (pad_length * b'\x00') pubkeyhash_encrypted = obj1.encrypt(pubkeyhash) # Construct script. script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash_encrypted # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG else: raise exceptions.TransactionError('Unknown encoding‐scheme.') s += var_int(int(len(script))) # Script length s += script # Change output. if change_output: address, value = change_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script s += (0).to_bytes(4, byteorder='little') # LockTime return s
#ensure there is enough money to do it ... funding_amount = Decimal(options.funding_amount) total = funding_amount * code_count total_s = int(total * s_per_b) print "Checking that a total of %s BTC (%s satoshis) is available ..." % (total, total_s) #which means first taking the WIF, turn to secret exponent, ask for public_pair and get BTC address from public pair ... then ask blockchain service about that address. satoshis = 0 coin_sources = [] secret_exponent = None bitcoin_address_compressed = None try: secret_exponent = encoding.wif_to_secret_exponent(options.funding_source) public_pair = ecdsa.public_pair_for_secret_exponent(secp256k1.generator_secp256k1, secret_exponent) bitcoin_address_compressed = encoding.public_pair_to_bitcoin_address(public_pair, compressed=True) except: print "Hrm something went wrong in trying to figure out BTC address from WIF %s" % (options.funding_source) sys.exit() try: if not options.forced_tx_source: coin_sources = blockchain_info.coin_sources_for_address(bitcoin_address_compressed) else: #forced args should combine all the info we need to run the code below ... so, value in satoshis, script, tx_hash and tx_output_n #value is in satoshis. tx_output_n does appear to start at zero after all. #u can find a tx outputs info by putting the tx in here: https://blockchain.info/rawtx/8684f9ea9f35953d0235cd4f5c73485dcf0eeb4cada6d2f657b63bea1e425178?scripts=true #eg args below ... wanted to redo something that used output # 0 of this tx as a source: 8684f9ea9f35953d0235cd4f5c73485dcf0eeb4cada6d2f657b63bea1e425178, soooo from the https://blockchain.info/rawtx/8684f9ea9f35953d0235cd4f5c73485dcf0eeb4cada6d2f657b63bea1e425178?scripts=true link we got: #8684f9ea9f35953d0235cd4f5c73485dcf0eeb4cada6d2f657b63bea1e425178,0,500000,76a91439d61ff876886683142acf9b0235ea0bcc3ecf8788ac hash, tx_output_n, s_value, script = options.forced_tx_source.split(',')
import hashlib import struct import unittest from pycoin.ecdsa import generator_secp256k1, public_pair_for_secret_exponent from pycoin.encoding import public_pair_to_bitcoin_address, secret_exponent_to_wif from pycoin.tx.Tx import BadSpendableError from pycoin.tx.TxOut import standard_tx_out_script from pycoin.tx.tx_utils import create_signed_tx from pycoin.tx.Spendable import Spendable BITCOIN_ADDRESSES = [ public_pair_to_bitcoin_address( public_pair_for_secret_exponent(generator_secp256k1, i)) for i in range(1, 21) ] WIFS = [secret_exponent_to_wif(i) for i in range(1, 21)] FAKE_HASHES = [ hashlib.sha256(struct.pack("Q", idx)).digest() for idx in range(100) ] class SpendTest(unittest.TestCase): def test_simple_spend(self): FEE = 10000
def serialise(inputs, destination_output=None, data_output=None, change_output=None, source=None, multisig=False): s = (1).to_bytes(4, byteorder='little') # Version # Number of inputs. s += var_int(int(len(inputs))) # List of Inputs. for i in range(len(inputs)): txin = inputs[i] s += binascii.unhexlify(bytes(txin['txid'], 'utf-8'))[::-1] # TxOutHash s += txin['vout'].to_bytes(4, byteorder='little') # TxOutIndex script = str.encode(txin['scriptPubKey']) s += var_int(int(len(script))) # Script length s += script # Script s += b'\xff' * 4 # Sequence # Number of outputs. n = 0 if destination_output: n += 1 if data_output: data_array, value = data_output for data_chunk in data_array: n += 1 else: data_array = [] if change_output: n += 1 s += var_int(n) # Destination output. if destination_output: address, value = destination_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script # Data output. for data_chunk in data_array: data_array, value = data_output # DUPE s += value.to_bytes(8, byteorder='little') # Value if multisig: # Get source public key (either provided as a string or derived from a private key in the wallet). if isinstance(multisig, str): pubkeypair = bitcoin_utils.parse_as_public_pair(multisig) source_pubkey = public_pair_to_sec(pubkeypair, compressed=True) else: if config.PREFIX == config.UNITTEST_PREFIX: private_key_wif = 'cPdUqd5EbBWsjcG9xiL1hz8bEyGFiz4SW99maU9JgpL9TEcxUf3j' else: private_key_wif = rpc('dumpprivkey', [source]) if private_key_wif[0] == 'c': testnet = True else: testnet = False secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif, is_test=testnet) public_pair = public_pair_for_secret_exponent( generator_secp256k1, secret_exponent) source_pubkey = public_pair_to_sec(public_pair, compressed=compressed) # Get data (fake) public key. pad_length = 33 - 1 - len(data_chunk) assert pad_length >= 0 data_pubkey = bytes([len(data_chunk) ]) + data_chunk + (pad_length * b'\x00') script = OP_1 # OP_1 script += op_push( len(source_pubkey)) # Push bytes of source public key script += source_pubkey # Source public key script += op_push( len(data_pubkey)) # Push bytes of data chunk (fake) public key script += data_pubkey # Data chunk (fake) public key script += OP_2 # OP_2 script += OP_CHECKMULTISIG # OP_CHECKMULTISIG else: script = OP_RETURN # OP_RETURN script += op_push(len( data_chunk)) # Push bytes of data chunk (NOTE: OP_SMALLDATA?) script += data_chunk # Data chunk s += var_int(int(len(script))) # Script length s += script # Change output. if change_output: address, value = change_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script s += (0).to_bytes(4, byteorder='little') # LockTime return s
def serialise (inputs, destination_output=None, data_output=None, change_output=None, multisig=False, source=None): s = (1).to_bytes(4, byteorder='little') # Version # Number of inputs. s += var_int(int(len(inputs))) # List of Inputs. for i in range(len(inputs)): txin = inputs[i] s += binascii.unhexlify(bytes(txin['txid'], 'utf-8'))[::-1] # TxOutHash s += txin['vout'].to_bytes(4, byteorder='little') # TxOutIndex # No signature. script = b'' s += var_int(int(len(script))) # Script length s += script # Script s += b'\xff' * 4 # Sequence # Number of outputs. n = 0 if destination_output: n += 1 if data_output: data_array, value = data_output for data_chunk in data_array: n += 1 else: data_array = [] if change_output: n += 1 s += var_int(n) # Destination output. if destination_output: address, value = destination_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script # Data output. for data_chunk in data_array: data_array, value = data_output # DUPE s += (value).to_bytes(8, byteorder='little') # Value if multisig: # Get source public key. from pycoin.ecdsa import generator_secp256k1, public_pair_for_secret_exponent from pycoin.encoding import wif_to_tuple_of_secret_exponent_compressed, public_pair_to_sec private_key_wif = rpc('dumpprivkey', [source]) secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(private_key_wif) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) source_pubkey = public_pair_to_sec(public_pair, compressed=compressed) # Get data (fake) public key. pad_length = 33 - 1 - len(data_chunk) assert pad_length >= 0 data_pubkey = bytes([len(data_chunk)]) + data_chunk + (pad_length * b'\x00') script = OP_1 # OP_1 script += op_push(len(source_pubkey)) # Push bytes of source public key script += source_pubkey # Source public key script += op_push(len(data_pubkey)) # Push bytes of data chunk (fake) public key script += data_pubkey # Data chunk (fake) public key script += OP_2 # OP_2 script += OP_CHECKMULTISIG # OP_CHECKMULTISIG else: script = OP_RETURN # OP_RETURN script += op_push(len(data_chunk)) # Push bytes of data chunk (NOTE: OP_SMALLDATA?) script += data_chunk # Data chunk s += var_int(int(len(script))) # Script length s += script # Change output. if change_output: address, value = change_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script s += (0).to_bytes(4, byteorder='little') # LockTime return s
def private_key_to_public_key (private_key_wif): secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(private_key_wif, is_test=config.TESTNET) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) public_key = public_pair_to_sec(public_pair, compressed=compressed) public_key_hex = binascii.hexlify(public_key).decode('utf-8') return public_key_hex