def create_test_channels(feerate=6000, local=None, remote=None): funding_txid = binascii.hexlify(b"\x01"*32).decode("ascii") funding_index = 0 funding_sat = ((local + remote) // 1000) if local is not None and remote is not None else (bitcoin.COIN * 10) local_amount = local if local is not None else (funding_sat * 1000 // 2) remote_amount = remote if remote is not None else (funding_sat * 1000 // 2) alice_raw = [ bip32("m/" + str(i)) for i in range(5) ] bob_raw = [ bip32("m/" + str(i)) for i in range(5,11) ] alice_privkeys = [lnutil.Keypair(lnutil.privkey_to_pubkey(x), x) for x in alice_raw] bob_privkeys = [lnutil.Keypair(lnutil.privkey_to_pubkey(x), x) for x in bob_raw] alice_pubkeys = [lnutil.OnlyPubkeyKeypair(x.pubkey) for x in alice_privkeys] bob_pubkeys = [lnutil.OnlyPubkeyKeypair(x.pubkey) for x in bob_privkeys] alice_seed = b"\x01" * 32 bob_seed = b"\x02" * 32 alice_first = lnutil.secret_to_pubkey(int.from_bytes(lnutil.get_per_commitment_secret_from_seed(alice_seed, lnutil.RevocationStore.START_INDEX), "big")) bob_first = lnutil.secret_to_pubkey(int.from_bytes(lnutil.get_per_commitment_secret_from_seed(bob_seed, lnutil.RevocationStore.START_INDEX), "big")) alice, bob = ( lnchannel.Channel( create_channel_state(funding_txid, funding_index, funding_sat, True, local_amount, remote_amount, alice_privkeys, bob_pubkeys, alice_seed, None, bob_first, b"\x02"*33, l_dust=200, r_dust=1300, l_csv=5, r_csv=4), name="alice", initial_feerate=feerate), lnchannel.Channel( create_channel_state(funding_txid, funding_index, funding_sat, False, remote_amount, local_amount, bob_privkeys, alice_pubkeys, bob_seed, None, alice_first, b"\x01"*33, l_dust=1300, r_dust=200, l_csv=4, r_csv=5), name="bob", initial_feerate=feerate) ) alice.hm.log[LOCAL]['ctn'] = 0 bob.hm.log[LOCAL]['ctn'] = 0 alice._state = channel_states.OPEN bob._state = channel_states.OPEN a_out = alice.get_latest_commitment(LOCAL).outputs() b_out = bob.get_next_commitment(REMOTE).outputs() assert a_out == b_out, "\n" + pformat((a_out, b_out)) sig_from_bob, a_htlc_sigs = bob.sign_next_commitment() sig_from_alice, b_htlc_sigs = alice.sign_next_commitment() assert len(a_htlc_sigs) == 0 assert len(b_htlc_sigs) == 0 alice.open_with_first_pcp(bob_first, sig_from_bob) bob.open_with_first_pcp(alice_first, sig_from_alice) alice_second = lnutil.secret_to_pubkey(int.from_bytes(lnutil.get_per_commitment_secret_from_seed(alice_seed, lnutil.RevocationStore.START_INDEX - 1), "big")) bob_second = lnutil.secret_to_pubkey(int.from_bytes(lnutil.get_per_commitment_secret_from_seed(bob_seed, lnutil.RevocationStore.START_INDEX - 1), "big")) # from funding_locked: alice.config[REMOTE].next_per_commitment_point = bob_second bob.config[REMOTE].next_per_commitment_point = alice_second # TODO: sweep_address in lnchannel.py should use static_remotekey alice.sweep_address = bitcoin.pubkey_to_address('p2wpkh', alice.config[LOCAL].payment_basepoint.pubkey.hex()) bob.sweep_address = bitcoin.pubkey_to_address('p2wpkh', bob.config[LOCAL].payment_basepoint.pubkey.hex()) return alice, bob
async def seed(ctx): """Add 50 receiving addresses to the database. RUN ONCE""" await Message.delete(ctx.message) if ctx.message.author is ctx.message.guild.owner: c.execute('''SELECT address FROM Addresses WHERE serverid=?''', (ctx.message.guild.id, )) already_ran = c.fetchone() if already_ran is None: server = ctx.message.guild server_id = server.id k = keystore.from_seed( ctx.message.content[len(command_prefix) + 5:], '', False) for x in range(0, 49): addr = bitcoin.pubkey_to_address('p2pkh', k.derive_pubkey(False, x)) addr_balance = get_balance(addr) c.execute( '''INSERT INTO Addresses (serverid, address, balance) VALUES(?,?,?)''', ( server_id, addr, addr_balance, )) conn.commit() await ctx.message.author.send( "50 btc addresses have been generated and stored.") else: await ctx.send("Addresses already generated.")
def build_contact_tx_list(address: str) -> list: parent = gui.ElectrumGui.gui ret = list() if address and parent and parent.sigHistory: alltxs = parent.sigHistory.get(None) seen = set() # 'seen' set.. guard against the same address appearing in both inputs and outputs for hentry in alltxs: if hentry.tx: ins = hentry.tx.inputs() for x in ins: xa = x['address'] if xa: # TODO xa = pubkey_to_address("p2pkh", xa) if xa == address and hentry.tx_hash not in seen: ret.append(hentry) seen.add(hentry.tx_hash) break #outs = hentry.tx.get_outputs() # for x in outs: # xa, dummy = x # if xa == address and hentry.tx_hash not in seen: # ret.append(hentry) # seen.add(hentry.tx_hash) # break # print("build_contact_tx_list: address", address.to_ui_string(), "found", len(ret),"associated txs") return ret
def to_btc(self, type: str) -> str: if isinstance(self.key, (Secp256k1Priv, Secp256k1Pub)): if self.version == Version.PRIVATE: return bitcoin.serialize_privkey(self.key.get_private_bytes(), True, type) else: return bitcoin.pubkey_to_address(type, self.key.get_public_bytes().hex()) else: raise ValueError("Can only derive BTC from Secp256k1")
def is_valid(self): mb = BitcoinMessage(self.message) sig = base64.b64decode(self.sig) message_hash = mb.GetHash() #print("hash: %s" % message_hash.hex()) pubkey = CPubKey.recover_compact(message_hash, sig) if not pubkey: return False #print("pubkey: %s" % pubkey.hex()) if pubkey.hex() == self.address: return True for txin_type in ['p2pkh', 'p2wpkh', 'p2wpkh-p2sh']: addr = pubkey_to_address(txin_type, pubkey.hex()) if addr == str(self.address): return True return False
def verify_mapping_sig(self): nsig = len(self.amap["sigs"]) if nsig < self.amap["n"]: return False jsonstring = json.dumps(self.amap["assets"],sort_keys=True) jsonstring += str(self.amap["n"]) + str(self.amap["m"]) + str(self.amap["time"]) + str(self.amap["height"]) message = jsonstring.encode('utf-8') nvalid = 0 for key in self.controller_pubkeys: for i,j in self.amap["sigs"].items(): txin_type = 'p2pkh' address = bitcoin.pubkey_to_address(txin_type, key) sig = base64.b64decode(j) verified = ecc.verify_message_with_address(address, sig, message) if verified: nvalid += 1 if nvalid >= self.amap["n"]: return True else: return False
def test_close_upfront_shutdown_script(self): alice_channel, bob_channel = create_test_channels() # create upfront shutdown script for bob, alice doesn't use upfront # shutdown script bob_uss_pub = lnutil.privkey_to_pubkey(os.urandom(32)) bob_uss_addr = bitcoin.pubkey_to_address('p2wpkh', bh2u(bob_uss_pub)) bob_uss = bfh(bitcoin.address_to_script(bob_uss_addr)) # bob commits to close to bob_uss alice_channel.config[HTLCOwner.REMOTE].upfront_shutdown_script = bob_uss # but bob closes to some receiving address, which we achieve by not # setting the upfront shutdown script in the channel config bob_channel.config[HTLCOwner.LOCAL].upfront_shutdown_script = b'' p1, p2, w1, w2, q1, q2 = self.prepare_peers(alice_channel, bob_channel) w1.network.config.set_key('dynamic_fees', False) w2.network.config.set_key('dynamic_fees', False) w1.network.config.set_key('fee_per_kb', 5000) w2.network.config.set_key('fee_per_kb', 1000) async def test(): async def close(): await asyncio.wait_for(p1.initialized, 1) await asyncio.wait_for(p2.initialized, 1) # bob closes channel with different shutdown script await p1.close_channel(alice_channel.channel_id) gath.cancel() async def main_loop(peer): async with peer.taskgroup as group: await group.spawn(peer._message_loop()) await group.spawn(peer.htlc_switch()) coros = [close(), main_loop(p1), main_loop(p2)] gath = asyncio.gather(*coros) await gath with self.assertRaises(UpfrontShutdownScriptViolation): run(test()) # bob sends the same upfront_shutdown_script has he announced alice_channel.config[HTLCOwner.REMOTE].upfront_shutdown_script = bob_uss bob_channel.config[HTLCOwner.LOCAL].upfront_shutdown_script = bob_uss p1, p2, w1, w2, q1, q2 = self.prepare_peers(alice_channel, bob_channel) w1.network.config.set_key('dynamic_fees', False) w2.network.config.set_key('dynamic_fees', False) w1.network.config.set_key('fee_per_kb', 5000) w2.network.config.set_key('fee_per_kb', 1000) async def test(): async def close(): await asyncio.wait_for(p1.initialized, 1) await asyncio.wait_for(p2.initialized, 1) await p1.close_channel(alice_channel.channel_id) gath.cancel() async def main_loop(peer): async with peer.taskgroup as group: await group.spawn(peer._message_loop()) await group.spawn(peer.htlc_switch()) coros = [close(), main_loop(p1), main_loop(p2)] gath = asyncio.gather(*coros) await gath with self.assertRaises(concurrent.futures.CancelledError): run(test())
def create_test_channels(*, feerate=6000, local_msat=None, remote_msat=None, alice_name="alice", bob_name="bob", alice_pubkey=b"\x01" * 33, bob_pubkey=b"\x02" * 33, random_seed=None): if random_seed is None: # needed for deterministic randomness random_seed = os.urandom(32) random_gen = PRNG(random_seed) funding_txid = binascii.hexlify(random_gen.get_bytes(32)).decode("ascii") funding_index = 0 funding_sat = ( (local_msat + remote_msat) // 1000) if local_msat is not None and remote_msat is not None else ( bitcoin.COIN * 10) local_amount = local_msat if local_msat is not None else (funding_sat * 1000 // 2) remote_amount = remote_msat if remote_msat is not None else (funding_sat * 1000 // 2) alice_raw = [bip32("m/" + str(i)) for i in range(5)] bob_raw = [bip32("m/" + str(i)) for i in range(5, 11)] alice_privkeys = [ lnutil.Keypair(lnutil.privkey_to_pubkey(x), x) for x in alice_raw ] bob_privkeys = [ lnutil.Keypair(lnutil.privkey_to_pubkey(x), x) for x in bob_raw ] alice_pubkeys = [ lnutil.OnlyPubkeyKeypair(x.pubkey) for x in alice_privkeys ] bob_pubkeys = [lnutil.OnlyPubkeyKeypair(x.pubkey) for x in bob_privkeys] alice_seed = random_gen.get_bytes(32) bob_seed = random_gen.get_bytes(32) alice_first = lnutil.secret_to_pubkey( int.from_bytes( lnutil.get_per_commitment_secret_from_seed( alice_seed, lnutil.RevocationStore.START_INDEX), "big")) bob_first = lnutil.secret_to_pubkey( int.from_bytes( lnutil.get_per_commitment_secret_from_seed( bob_seed, lnutil.RevocationStore.START_INDEX), "big")) alice, bob = (lnchannel.Channel(create_channel_state( funding_txid, funding_index, funding_sat, True, local_amount, remote_amount, alice_privkeys, bob_pubkeys, alice_seed, None, bob_first, other_node_id=bob_pubkey, l_dust=200, r_dust=1300, l_csv=5, r_csv=4), name=bob_name, initial_feerate=feerate), lnchannel.Channel(create_channel_state( funding_txid, funding_index, funding_sat, False, remote_amount, local_amount, bob_privkeys, alice_pubkeys, bob_seed, None, alice_first, other_node_id=alice_pubkey, l_dust=1300, r_dust=200, l_csv=4, r_csv=5), name=alice_name, initial_feerate=feerate)) alice.hm.log[LOCAL]['ctn'] = 0 bob.hm.log[LOCAL]['ctn'] = 0 alice._state = ChannelState.OPEN bob._state = ChannelState.OPEN a_out = alice.get_latest_commitment(LOCAL).outputs() b_out = bob.get_next_commitment(REMOTE).outputs() assert a_out == b_out, "\n" + pformat((a_out, b_out)) sig_from_bob, a_htlc_sigs = bob.sign_next_commitment() sig_from_alice, b_htlc_sigs = alice.sign_next_commitment() assert len(a_htlc_sigs) == 0 assert len(b_htlc_sigs) == 0 alice.open_with_first_pcp(bob_first, sig_from_bob) bob.open_with_first_pcp(alice_first, sig_from_alice) alice_second = lnutil.secret_to_pubkey( int.from_bytes( lnutil.get_per_commitment_secret_from_seed( alice_seed, lnutil.RevocationStore.START_INDEX - 1), "big")) bob_second = lnutil.secret_to_pubkey( int.from_bytes( lnutil.get_per_commitment_secret_from_seed( bob_seed, lnutil.RevocationStore.START_INDEX - 1), "big")) # from funding_locked: alice.config[REMOTE].next_per_commitment_point = bob_second bob.config[REMOTE].next_per_commitment_point = alice_second alice._fallback_sweep_address = bitcoin.pubkey_to_address( 'p2wpkh', alice.config[LOCAL].payment_basepoint.pubkey.hex()) bob._fallback_sweep_address = bitcoin.pubkey_to_address( 'p2wpkh', bob.config[LOCAL].payment_basepoint.pubkey.hex()) alice._ignore_max_htlc_value = True bob._ignore_max_htlc_value = True return alice, bob
#!/usr/bin/env python3 # [rights] Copyright 2020 brianddk at github https://github.com/brianddk # [license] Apache 2.0 License https://www.apache.org/licenses/LICENSE-2.0 # [repo] github.com/brianddk/reddit/blob/master/python/elec-get-addr.py # [btc] BTC-b32: bc1qwc2203uym96u0nmq04pcgqfs9ldqz9l3mz8fpj # [tipjar] github.com/brianddk/reddit/blob/master/tipjar/tipjar.txt # [ref] reddit.com/r/Electrum/comments/jn2m0q/-/gaz1dbm/ # [req] python -m pip install electrum # [note] with open(r"..\reddit\python\script.py", 'r') as s: exec(s.read()) from electrum.constants import set_testnet from electrum.bip32 import BIP32Node from electrum.bitcoin import pubkey_to_address # Set testnet set_testnet() # You get this from Wallet info dialog xpub = 'vpub5SLqN2bLY4WeYkHyoQNaC4JuFVxDVWtx7YUjuxRwWTkLocCBy3ejp3X3Uxmefk1ae4ZCpTVYkJPUG2pAgv8K9mdxfgcGDwWRzq7YTWCCmAq' path = 'm/0/0' xpub = BIP32Node.from_xkey(xpub) for i in range(0, 20): path = f"{path[:3]}/{i}" node = xpub.subkey_at_public_derivation(path) pubk = node.eckey.get_public_key_bytes() addr = pubkey_to_address('p2wpkh', pubk.hex()) print(f"Address at path [{path}]: {addr}")
def xpub2btc(xpub): _xtype, _depth, _fp, _cn, _c, K = bitcoin.deserialize_xpub(xpub) return bitcoin.pubkey_to_address("p2wpkh-p2sh", util.bh2u(K))
def to_btc(self, type: str) -> str: if self.version == Version.PRIVATE: return bitcoin.serialize_privkey(self.key.get_private_bytes(), True, type) else: return bitcoin.pubkey_to_address(type, self.key.get_public_bytes().hex())
def _get_key_address(self): root_xpub = self.wallet.keystore.xpub xpub = bip32_public_derivation(root_xpub, 'm/', 'm/0/0') pubk = bh2u(point_to_ser(ser_to_point(bfh(self._xpub_to_gpg_pub(xpub))), compressed=True)) addr = pubkey_to_address('p2pkh', pubk) return addr
#!./venv/bin/python from electrum import bitcoin, util import sys lines = [x.strip() for x in sys.stdin.readlines()] if len(lines) != 1: print("wrong input") sys.exit(1) _xtype, _depth, _fp, _cn, _c, K = bitcoin.deserialize_xpub(lines[0]) type = "p2pkh" if len(sys.argv) == 2: type = sys.argv[1] pubkey = bitcoin.pubkey_to_address(type, util.bh2u(K)) print(pubkey)