Showing Posts From
BIP39
BIP39 助记词生成原理与 Python 实现
BIP39 定义了一套将随机数编码为可记忆单词的标准,大多数钱包(MetaMask、Phantom、imToken)都支持。 BIP39 原理生成 128/160/192/224/256 位随机熵 取熵的 SHA-256 哈希前 len/32 位作为校验位,拼接到熵末尾 每 11 位映射一个 BIP39 词表单词(共 2048 个词) 最终得到 12/15/18/21/24 个单词熵长度 校验位 总位数 单词数128 bit 4 bit 132 bit 12256 bit 8 bit 264 bit 24Python 实现(bip-utils) pip install bip-utils从助记词派生以太坊私钥和地址 from bip_utils import ( Bip39SeedGenerator, Bip39MnemonicValidator, Bip44, Bip44Coins, Bip44Changes, )mnemonic = "word1 word2 word3 word4 word5 word6 word7 word8 word9 word10 word11 word12"# 可选:验证助记词是否合法 if not Bip39MnemonicValidator().IsValid(mnemonic): raise ValueError("助记词无效")# 助记词 → 种子(可选 passphrase) seed = Bip39SeedGenerator(mnemonic).Generate(passphrase="")# 种子 → BIP44 派生路径 m/44'/60'/0'/0/0 ctx = Bip44.FromSeed(seed, Bip44Coins.ETHEREUM) addr_ctx = ( ctx.Purpose() .Coin() .Account(0) .Change(Bip44Changes.CHAIN_EXT) .AddressIndex(0) )private_key_hex = addr_ctx.PrivateKey().Raw().ToHex() address = addr_ctx.PublicKey().ToAddress()print(f"私钥: {private_key_hex}") print(f"地址: {address}")派生多个地址 for i in range(5): addr_ctx = ( ctx.Purpose() .Coin() .Account(0) .Change(Bip44Changes.CHAIN_EXT) .AddressIndex(i) ) print(f"[{i}] {addr_ctx.PublicKey().ToAddress()}")Solana(BIP44 Coin 501) from bip_utils import Bip44Coinsctx = Bip44.FromSeed(seed, Bip44Coins.SOLANA) sol_ctx = ctx.Purpose().Coin().Account(0).Change(Bip44Changes.CHAIN_EXT).AddressIndex(0) print(f"Solana 地址: {sol_ctx.PublicKey().ToAddress()}")手动验证 BIP39 校验和(纯 Python) import hashlibdef validate_bip39(mnemonic: str, wordlist_path: str) -> bool: with open(wordlist_path) as f: words = f.read().splitlines() word_index = {w: i for i, w in enumerate(words)} mnemonic_words = mnemonic.strip().split() bits = "" for word in mnemonic_words: if word not in word_index: return False bits += format(word_index[word], "011b") # 最后 len/33 位是校验位 cs_len = len(bits) // 33 entropy_bits = bits[:-cs_len] checksum_bits = bits[-cs_len:] # 还原熵字节 entropy = int(entropy_bits, 2).to_bytes(len(entropy_bits) // 8, "big") # SHA256 前 cs_len 位 h = hashlib.sha256(entropy).digest() expected_cs = format(h[0], "08b")[:cs_len] return checksum_bits == expected_cs注意事项助记词等同于钱包全部资产的控制权,不能在任何联网代码中明文存储 生产环境派生私钥只能在离线机器或 HSM 上操作 仅用于工具开发/验证时,建议使用测试网地址,不要导入真实资产
