Showing Posts From

Solana

BIP39 助记词生成 Solana 地址:SLIP-10 + Ed25519 全流程

BIP39 助记词生成 ETH 地址靠 secp256k1 + keccak256,走 Solana 就完全换了一套——Ed25519 + SLIP-0010,最后不做 hash,直接 Base58 编码公钥。 全流程 助记词 (Mnemonic) │ PBKDF2-HMAC-SHA512 ▼ Seed (64 字节) │ SLIP-0010 (Ed25519) ▼ Master Key │ 按路径 m/44'/501'/0'/0' 派生 ▼ Ed25519 私钥 (32 字节) │ Ed25519 公钥算法 ▼ 公钥 (32 字节) │ Base58 编码 ▼ Solana 地址和 BTC/ETH 唯一相同的只有第一步"助记词转 seed",之后全变了。 第一步:助记词 → seed 标准 BIP39,PBKDF2-HMAC-SHA512: password = 助记词字符串 salt = "mnemonic" + passphrase iters = 2048 output = 64 字节Python: from mnemonic import Mnemonicmnemo = Mnemonic("english") seed = mnemo.to_seed( "abandon abandon abandon abandon abandon abandon " "abandon abandon abandon abandon abandon about", passphrase="", ) print(seed.hex())第二步:seed → Master Key(SLIP-10 Ed25519) Solana 用 SLIP-0010(Ed25519 版本),和 BIP32 的 secp256k1 分道扬镳: I = HMAC-SHA512(key="ed25519 seed", data=seed) IL = master private key (32 字节) IR = master chain code (32 字节)第三步:派生路径 Solana 默认路径: m/44'/501'/0'/0'44':BIP44 501':Solana 的 coin type 0':account 0':change每一级都是 hardened derivation(' 表示 + 2³¹)。Ed25519 只支持 hardened 派生,非 hardened 会直接报错。 第四步:公钥 & 地址 私钥经 Ed25519 算出 32 字节公钥。地址 = Base58(公钥),就这么简单:没有 SHA-256 double hash 没有 RIPEMD-160 没有 keccak 没有 checksum(Base58 本身没自带校验,也没有像 BTC 那样附 4 字节 hash)Python 一把梭 bip_utils 把上面所有细节封好了: from bip_utils import Bip39SeedGenerator, Bip44, Bip44Coinsmnemonic = ("abandon abandon abandon abandon abandon abandon " "abandon abandon abandon abandon abandon about")seed = Bip39SeedGenerator(mnemonic).Generate()bip44 = Bip44.FromSeed(seed, Bip44Coins.SOLANA) account = bip44.Purpose().Coin().Account(0).Change(Bip44Changes.CHAIN_EXT).AddressIndex(0)print("地址:", account.PublicKey().ToAddress()) print("私钥:", account.PrivateKey().Raw().ToHex())Phantom / Solflare 里的第一个账号导出出来应该跟上面一样。 常见误区 Solana 地址和 ETH 地址长得像 其实完全不同:ETH 地址:40 字符 hex + 0x 前缀,checksum 在 EIP-55 里靠大小写实现 Solana 地址:Base58 编码的 32 字节公钥,长度 32~44 字符,无固定前缀Solana 私钥文件是 64 字节而不是 32 Solana 的钱包 JSON(Phantom 导出)通常是 64 字节:前 32 是私钥 seed、后 32 是公钥。生成时: priv32 = account.PrivateKey().Raw().ToBytes() pub32 = account.PublicKey().RawUncompressed().ToBytes()[-32:] keypair_bytes = priv32 + pub32 # 64 字节导入 solana-cli 或 Phantom 时用这个格式。 Ed25519 派生路径可以省略部分层级 Phantom 早期用 m/44'/501'/0'(只三层)而非 m/44'/501'/0'/0'——同一助记词在这两种路径下算出来的地址不同。发现"钱包地址对不上"时先检查是不是路径差异,试试:m/44'/501'/0' — Phantom "legacy" m/44'/501'/0'/0' — 现在的默认一句话总结 Solana 地址生成 = BIP39 seed → SLIP-10 Ed25519 派生 → Base58(公钥)。和 EVM 完全两套加密路径,别拿 ETH 的经验类比。用 bip_utils 三行搞定,别自己实现 Ed25519。