def main(): # generate 16 bytes of entropy and # convert to a mnemonic phrase (12 words) entropy = bytes([random.getrandbits(8) for i in range(16)]) mnemonic = bip39.mnemonic_from_bytes(entropy) # or just define hardcoded: mnemonic = "alien visual jealous source coral memory embark certain radar capable clip edit" print(mnemonic) # convert to seed, empty password seed = bip39.mnemonic_to_seed(mnemonic) # convert to the root key # you can define the version - x/y/zprv for desired network root = bip32.HDKey.from_seed(seed, version=NETWORKS["test"]["xprv"]) print(root.to_base58()) print("\nBIP-44 - legacy") # derive account according to bip44 bip44_xprv = root.derive("m/44h/1h/0h") print(bip44_xprv.to_base58()) # corresponding master public key: bip44_xpub = bip44_xprv.to_public() print(bip44_xpub.to_base58()) # first 5 receiving addresses for i in range(5): # .key member is a public key for HD public keys # and a private key for HD private keys pub = bip44_xpub.derive("m/0/%d" % i).key sc = script.p2pkh(pub) print(sc.address(NETWORKS["test"])) print("\nBIP-84 - native segwit") # derive account according to bip84 bip84_xprv = root.derive("m/84h/1h/0h") # you can also change version of the key to get zpub (vpub on testnet) bip84_xprv.version = NETWORKS["test"]["zprv"] print(bip84_xprv.to_base58()) # corresponding master public key: bip84_xpub = bip84_xprv.to_public() print(bip84_xpub.to_base58()) # first 5 receiving addresses for i in range(5): pub = bip84_xpub.derive("m/0/%d" % i).key sc = script.p2wpkh(pub) print(sc.address(NETWORKS["test"])) print("\nBIP-49 - nested segwit") # derive account according to bip49 bip49_xprv = root.derive("m/49h/1h/0h") # you can also change version of the key to get ypub (upub on testnet) bip49_xprv.version = NETWORKS["test"]["yprv"] print(bip49_xprv.to_base58()) # corresponding master public key: bip49_xpub = bip49_xprv.to_public() print(bip49_xpub.to_base58()) # first 5 receiving addresses for i in range(5): pub = bip49_xpub.derive("m/0/%d" % i).key # use p2sh(p2wpkh(pubkey)) to get nested segwit scriptpubkey sc = script.p2sh(script.p2wpkh(pub)) print(sc.address(NETWORKS["test"]))
def main(): # all from the same private key prv = ec.PrivateKey.from_wif( "L2e5y14ZD3U1J7Yr62t331RtYe2hRW2TBBP8qNQHB8nSPBNgt6dM") pub = prv.get_public_key() print("Public key:") print(hexlify(pub.serialize())) # we will generate regtest addresses network = NETWORKS["regtest"] print("Legacy (pay to pubkey hash):") sc = script.p2pkh(pub) # default network is main print(sc.address(network)) print("Segwit (pay to witness pubkey hash):") sc = script.p2wpkh(pub) print(sc.address(network)) print("Nested segwit (p2sh-p2wpkh):") sc = script.p2sh(script.p2wpkh(pub)) print(sc.address(network)) print("\nMultisig address (2 of 3):") # unsorted pubs = [ ec.PublicKey.parse( unhexlify( "02edd7a58d2ff1e483d35f92a32e53607423f936b29bf95613cab24b0b7f92e0f1" )), ec.PublicKey.parse( unhexlify( "03a4a6d360acc45cb281e0022b03218fad6ee93881643488ae39d22b854d9fa261" )), ec.PublicKey.parse( unhexlify( "02e1fdc3b011effbba4b0771eb0f7193dee24cfe101ab7e8b64516d83f7116a615" )), ] # 2 of 3 multisig script sc = script.multisig(2, pubs) print("Legacy, unsorted (p2sh):") redeem_sc = script.p2sh(sc) print(redeem_sc.address(network)) print("Native segwit, sorted (p2wsh):") sc = script.multisig(2, sorted(pubs)) witness_sc = script.p2wsh(sc) print(witness_sc.address(network)) print("Nested segwit, sorted (p2sh-p2wsh):") sc = script.multisig(2, sorted(pubs)) witness_sc = script.p2wsh(sc) redeem_sc = script.p2sh(witness_sc) print(redeem_sc.address(network))
def scriptpubkey(self, idx=None): if idx is None and "*" in self.serialize(): raise RuntimeError("Index is required") if self.is_multisig: keys = [] for i, key in enumerate(self.base_key): keys.append(derive_pubkey(key, self.path_suffix[i], idx)) if self.sort_keys: keys = sorted(keys) sc = script.multisig(int(self.multisig_M), keys) if self.sh: return script.p2sh(sc) elif self.sh_wsh: return script.p2sh(script.p2wsh(sc)) elif self.wsh: return script.p2wsh(sc) else: key = derive_pubkey(self.base_key, self.path_suffix, idx) if self.wpkh: return script.p2wpkh(key) elif self.sh_wpkh: return script.p2sh(script.p2wpkh(key)) else: return script.p2pkh(key)
def main(): #Extended public key string to an address, tested against https://iancoleman.io/bip39/ #Mnemonic used: february deposit cram leopard ripple turtle impulse history accident noodle love crazy limit pond tourist #bip44, first address "124d7o3DmtXqvn1dJLxj9TQYA7v9Cmcyes" key = "xpub6D2VGgnY7WJ8H3SKBPhqbarfA6uZbcUSLnuwgzE5qvmXyq23yNg42GKJgDXMJ27Q3NBeFjQDyz8Za27sYUfmWs7PNow8i3FUNwHufbyyWQK" #bip49, first address "3CntmFG5nBG9sCCr2b6MWhTAk9RLEicERn" #key = "ypub6YFkZihjEjQdftpu4NwwNobdTB7eRHQjcTjyDj4hhANcj3KqXVTQuEuz1rL49NtzFLCxvnSAd4gnCG1yfWdDv1evXSrMKZfCcYQ3yR6eyP2" #bip84, first address "bc1qv5rgjspu3kljw8kczdvyl4x0gkk09jp7ddmrp8" #key = "zpub6riY8dgyiTYHfTE3xqKscWYjZrKtwWwtc4LBfvnkqPHH9gUAC4HJrydyphFihghnGnEw5cyDDgq5iZULuheBJqJW825Cv5LCgUh7VJTTLhw" k = bip32.HDKey.from_base58(key) child = k.derive([0, 0]) if key[0:4] == "xpub": address = script.p2pkh(child).address() elif key[0:4] == "zpub": address = script.p2wpkh(child).address() elif key[0:4] == "ypub": address = script.p2sh(script.p2wpkh(child)).address() print(address)
def main(): # all from the same private key prv = ec.PrivateKey.from_wif( "L2e5y14ZD3U1J7Yr62t331RtYe2hRW2TBBP8qNQHB8nSPBNgt6dM") pub = prv.get_public_key() inputs = [ # legacy { "txid": unhexlify( "7f0c7538e898bbe5531fa47d4057b52c914ec45e20ae1a5572ea1005a8ba50f8" ), "vout": 0, "value": int(1e8), "script": script.p2pkh(pub), }, # native segwit { "txid": unhexlify( "f51e6fc2392558a70ae970e93538f368828ad2800a7370f372a652de463429fc" ), "vout": 0, "value": int(2e8), "script": script.p2wpkh(pub), }, # nested segwit { "txid": unhexlify( "2e4cb680ed008b6e529c4c83f00d55326a2e68b48ddf11267e3f5323006966a6" ), "vout": 1, "value": int(3e8), "script": script.p2sh(script.p2wpkh(pub)), "redeem": script.p2wpkh(pub), }, ] # sending back almost the same amount vin = [TransactionInput(inp["txid"], inp["vout"]) for inp in inputs] vout = [ TransactionOutput(inp["value"] - 1500, inp["script"]) for inp in inputs ] tx = Transaction(vin=vin, vout=vout) print("Unsigned transaction:") print(hexlify(tx.serialize()).decode("utf-8")) for i in range(len(inputs)): inp = inputs[i] script_type = inp["script"].script_type() # legacy input if script_type == "p2pkh": h = tx.sighash_legacy(i, inp["script"]) sig = prv.sign(h) tx.vin[i].script_sig = script.script_sig_p2pkh(sig, pub) # native segwit elif script_type == "p2wpkh": sc = script.p2pkh_from_p2wpkh(inp["script"]) h = tx.sighash_segwit(i, sc, inp["value"]) sig = prv.sign(h) tx.vin[i].witness = script.witness_p2wpkh(sig, pub) # nested segwit elif script_type == "p2sh": if "redeem" in inp and inp["redeem"].script_type() == "p2wpkh": sc = script.p2pkh_from_p2wpkh(inp["redeem"]) h = tx.sighash_segwit(i, sc, inp["value"]) sig = prv.sign(h) tx.vin[i].script_sig = script.script_sig_p2sh(inp["redeem"]) tx.vin[i].witness = script.witness_p2wpkh(sig, pub) else: raise NotImplementedError("Script type is not supported") else: raise NotImplementedError("Script type is not supported") print("Signed transaction:") print(hexlify(tx.serialize()).decode("utf-8"))