def pkh_segwit_address_from_wif(wif): """ The P2SH redeemScript is always 22 bytes. It starts with a OP_0, followed by a canonical push of the keyhash (i.e. 0x0014{20-byte keyhash}) Same as any other P2SH, the scriptPubKey is OP_HASH160 hash160(redeemScript) OP_EQUAL """ my_key = Key.from_text(wif) script = ScriptPayToAddressWit(b'\0', my_key.hash160()).script() script_hex = binascii.hexlify(script).decode() return address_for_pay_to_script(script, netcode=NET_CODE), script_hex
def genAddress(prvkey, path, netcode, is_segwit=False): master = key_from_text(prvkey) key = master.subkey_for_path(path) key._netcode = netcode if not is_segwit: # legacy address = key.address() elif is_segwit: # segwit hash160_c = key.hash160(use_uncompressed=False) script = ScriptPayToAddressWit(b'\0', hash160_c).script() address = address_for_pay_to_script(script, key._netcode) return address, key.wif()
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 create_hash160_output(key, add_output, output_dict): network_name = network_name_for_netcode(key._netcode) hash160_c = key.hash160(use_uncompressed=False) hash160_u = key.hash160(use_uncompressed=True) hash160 = hash160_c or hash160_u if hash160: add_output("hash160", b2h(hash160)) if hash160_c and hash160_u: add_output("hash160_uncompressed", b2h(hash160_u), " uncompressed") if hash160: address = key.address(use_uncompressed=hash160_c is None) add_output("address", address, "%s address" % network_name) output_dict["%s_address" % key._netcode] = address if hash160_c and hash160_u: address = key.address(use_uncompressed=True) add_output("address_uncompressed", address, "%s address uncompressed" % network_name) output_dict["%s_address_uncompressed" % key._netcode] = address # don't print segwit addresses unless we're sure we have a compressed key if hash160_c: p2aw_script = ScriptPayToAddressWit(b'\0', hash160_c) address_segwit = p2aw_script.info()["address_f"](key._netcode) if address_segwit: # this network seems to support segwit add_output("address_segwit", address_segwit, "%s segwit address" % network_name) output_dict["%s_address_segwit" % key._netcode] = address_segwit p2sh_script = p2aw_script.script() p2s_address = address_for_pay_to_script(p2aw_script.script(), key._netcode) if p2s_address: add_output("p2sh_segwit", p2s_address) p2sh_script_hex = b2h(p2sh_script) add_output("p2sh_segwit_script", p2sh_script_hex, " corresponding p2sh script")
def main(): if len(sys.argv) != 2: print("usage: %s bip32_key_file" % sys.argv[0]) sys.exit(-1) with open(sys.argv[1], "r") as f: hwif = f.readline().strip() # turn the bip32 text into a BIP32Node object BIP32_KEY = BIP32Node.from_hwif(hwif) # create three sec_keys (these are public keys, streamed using the SEC format) SEC_0 = BIP32_KEY.subkey_for_path("0/0/0").sec() SEC_1 = BIP32_KEY.subkey_for_path("0/1/0").sec() SEC_2 = BIP32_KEY.subkey_for_path("0/2/0").sec() public_key_sec_list = [SEC_0, SEC_1, SEC_2] # create the 2-of-3 multisig script # any 2 signatures can release the funds pay_to_multisig_script = ScriptMultisig(2, public_key_sec_list).script() # create a "2-of-3" multisig address_for_multisig the_address = address_for_pay_to_script(pay_to_multisig_script) print("Here is your pay 2-of-3 address: %s" % the_address) print("Here is the pay 2-of-3 script: %s" % b2h(pay_to_multisig_script)) print("The hex script should go into p2sh_lookup.hex") base_dir = os.path.dirname(sys.argv[1]) print("The three WIFs are written into %s as wif0, wif1 and wif2" % base_dir) for i in range(3): wif = BIP32_KEY.subkey_for_path("0/%d/0" % i).wif() with open(os.path.join(base_dir, "wif%d" % i), "w") as f: f.write(wif)
def main(): if len(sys.argv) != 2: print("usage: %s bip32_key_file" % sys.argv[0]) sys.exit(-1) with open(sys.argv[1], "r") as f: hwif = f.readline().strip() # turn the bip32 text into a BIP32Node object BIP32_KEY = BIP32Node.from_hwif(hwif) # create three sec_keys (these are public keys, streamed using the SEC format) SEC_0 = BIP32_KEY.subkey_for_path("0/0/0").sec() SEC_1 = BIP32_KEY.subkey_for_path("0/1/0").sec() SEC_2 = BIP32_KEY.subkey_for_path("0/2/0").sec() public_key_sec_list = [SEC_0, SEC_1, SEC_2] # create the 2-of-3 multisig script # any 2 signatures can release the funds pay_to_multisig_script = ScriptMultisig(2, public_key_sec_list).script() # create a "2-of-3" multisig address_for_multisig the_address = address_for_pay_to_script(pay_to_multisig_script) print("Here is your pay 2-of-3 address: %s" % the_address) print("Here is the pay 2-of-3 script: %s" % b2h(pay_to_multisig_script)) print("The hex script should go into p2sh_lookup.hex") base_dir = os.path.dirname(sys.argv[1]) print("The three WIFs are written into %s as wif0, wif1 and wif2" % base_dir) for i in range(3): wif = BIP32_KEY.subkey_for_path("0/%d/0" % i).wif() with open(os.path.join(base_dir, "wif%d" % i), "w") as f: f.write(wif)
def create_hash160_output(key, add_output, output_dict): network_name = network_name_for_netcode(key._netcode) hash160_c = key.hash160(use_uncompressed=False) hash160_u = key.hash160(use_uncompressed=True) hash160 = hash160_c or hash160_u if hash160: add_output("hash160", b2h(hash160)) if hash160_c and hash160_u: add_output("hash160_uncompressed", b2h(hash160_u), " uncompressed") if hash160: address = key.address(use_uncompressed=hash160_c is None) add_output("address", address, "%s address" % network_name) output_dict["%s_address" % key._netcode] = address if hash160_c and hash160_u: address = key.address(use_uncompressed=True) add_output("address_uncompressed", address, "%s address uncompressed" % network_name) output_dict["%s_address_uncompressed" % key._netcode] = address # don't print segwit addresses unless we're sure we have a compressed key if hash160_c: p2aw_script = ScriptPayToAddressWit(b'\0', hash160_c) address_segwit = p2aw_script.info()["address_f"](key._netcode) if address_segwit: # this network seems to support segwit add_output("address_segwit", address_segwit, "%s segwit address" % network_name) output_dict["%s_address_segwit" % key._netcode] = address_segwit p2sh_script = p2aw_script.script() p2s_address = address_for_pay_to_script(p2aw_script.script(), key._netcode) if p2s_address: add_output("p2sh_segwit", p2s_address) p2sh_script_hex = b2h(p2sh_script) add_output("p2sh_segwit_script", p2sh_script_hex, " corresponding p2sh script")
def script_address(script_hex, netcode="BTC"): return address_for_pay_to_script(h2b(script_hex), netcode=netcode)
def get_multisig_address(m, pub_keys): pay_to_multisig_script = ScriptMultisig(m, pub_keys).script() return address_for_pay_to_script( pay_to_multisig_script, netcode=NET_CODE), pay_to_multisig_script.hex()
def p2sh_p2wpkh_address(self) -> str: p2aw_script = self.p2wpkh_script() # type: bytes return address_for_pay_to_script(p2aw_script, netcode=self.netcode())
def get_new_address(user_wallet, is_change=False, get_all_addresses=False): # Be sure this is a valid currency supported by the exchange if user_wallet.currencycode in settings.COINS.keys(): all_addresses = [] last_active_address = 0 # Use the wallet's public_key to generate addresses. wallet_public_key = BIP32Node.from_hwif(user_wallet.public_key) # External address if not is_change: wallet_base = wallet_public_key.subkey(i=0, is_hardened=False, as_private=False) index = user_wallet.last_external_index # Change address else: wallet_base = wallet_public_key.subkey(i=1, is_hardened=False, as_private=False) index = user_wallet.last_change_index if get_all_addresses: index = 0 # If index is non-zero, then increment by one to generate a new unused # index. if index > 0: index += 1 # Look for an unused address. # @TODO: https://github.com/ .. /issues/6 search through a gap of 20 searching = True while searching: # Create addresses following BIP44 # https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki address_key = wallet_base.subkey(i=index, is_hardened=False, as_private=False) new_address = { 'index': index, 'p2pkh': address_key.bitcoin_address() } # Generate bech32 for Bitcoin and Bitcoin Testnet # @TODO get working with LTC https://github.com/richardkiss/pycoin/issues/323 if user_wallet.currencycode in ['BTC', 'XTN']: try: script = ScriptPayToAddressWit( b'\0', address_key.hash160(use_uncompressed=False)).script() new_address['p2sh_p2wpkh'] = address_for_pay_to_script( script, netcode=user_wallet.currencycode) new_address['bech32'] = address_for_pay_to_script_wit( script, netcode=user_wallet.currencycode) except Exception as e: #print(e) new_address['p2sh_p2wpkh'] = None new_address['bech32'] = None else: new_address['p2sh_p2wpkh'] = None new_address['bech32'] = None #print("coin: %s, p2pkh: %s, p2sh_p2wpkh: %s, bech32: %s" % (user_wallet.currencycode, p2pkh, p2sh_p2wpkh, bech32)) if address_is_used(new_address, user_wallet): index += 1 if get_all_addresses: all_addresses.append(new_address) else: last_active_address += 1 if get_all_addresses and last_active_address > 20: searching = False else: searching = False #print("%s address: %s" % (user_wallet.currencycode, p2pkh)) if get_all_addresses: return all_addresses, index else: return new_address, index else: return False, False