使用BIP39中定义的标准化过程,钱包自动生成助记词。钱包从一个熵源开始,添加一个校验和,然后将熵映射到一个单词列表,具体步骤如下:
下表描述了初始熵长度(ENT),校验和长度(CS)和单词中生成的助记词(MS)的长度之间的关系。
熵(bits)Checksum(bits)熵+Checksum(bits)助记词长度(words)128413212160516515192619818224723121256826424
助记词代表长度为128到256位的熵。然后使用熵通过使用密钥扩展函数PBKDF2来导出更长(512位)的种子。然后,所产生的种子用于构建确定性钱包并获得其密钥。
密钥扩展功能有两个参数:助记词和盐(salt)。密钥扩展功能中的盐的目的是使得难以构建能够进行暴力攻击的查找表。在BIP-39标准中,salt具有另一个目的 - 它允许引入密码短语作为保护种子的额外安全因子。
12个长度的助记词,无密码生成种子
给定父扩展私钥和索引i,可以计算相应的子扩展私钥。
函数CKDpriv((kpar,cpar),i)→(ki,ci)
如果i ≥ 2^31(硬化的子密钥):让I= HMAC-SHA512(Key = cpar,Data = 0x00 || ser256(kpar)|| ser32(i))。 (注意:0x00将私钥补齐到33字节长。)
如果i<2^31(普通的子密钥):让I= HMAC-SHA512(Key = cpar,Data = serP(point(kpar))|| ser32(i))。
给定父扩展公钥和索引i,可以计算相应的子扩展公钥。它只针对未硬化的子密钥定义。
如果i ≥ 2^31(硬化子密钥):返回失败
如果i<2^31(普通子密钥):让I= HMAC-SHA512(Key = cpar, Data = serP(Kpar) || ser32(i)).
扩展私钥的前缀是xprv,如:
tprv8iGPAfgu51nkCZZtua8jFgzVoCQLqHZrLCQonxTo7qdtzutL8ZFZt1yAtpcUF8sHdNyiVhece3SSRsBvtUCKpGkRvxXgV2TMdcDbKQzstta
扩展公钥的前缀是tpub,如:
tpubDExRK5j9DPUR62bgoDoKf6ecNDvGzckkuW1b5UW6Y7SHqQ96kx5A4Wb34w6bkHUStdq5w7ZHPQHkipwRdSQMbGnqTAQj1sEBaJmL9wXvBSu
每个扩展密钥有 2^31 个普通子密钥,2^31个硬化子密钥。这些子密钥都有一个索引,普通子密钥使用索引0到2^31-1,硬化的子密钥使用索引 2^31 到 2^32-1,为了简化硬化密钥索引的符号,数字iH表示i + 2^31。以上过程再结合BIP43,BIP44,HD钱包就实现了多币种、多账户、多用途等功能。
var bitcoin = require('bitcoinjs-lib');
var bip39 = require("bip39")
var bip32 = require("bip32")const myNetwork = bitcoin.networks.testnet
const mnemonic = 'eternal list thank chaos trick paper sniff ridge make govern invest abandon'
// const mnemonic = bip39.generateMnemonic()
const seed = bip39.mnemonicToSeed(mnemonic, "lixu1234qwer")
const root = bip32.fromSeed(seed, myNetwork)
for(var i = 0; i < 3; i++) {
const path = "m/44'/1'/0'/0/"+i
console.log("路径:", path)
const keyPair = root.derivePath(path)
const privateKey = keyPair.toWIF()
console.log("私钥", privateKey)
const publicKey = keyPair.publicKey.toString("hex")
console.log("公钥:", publicKey)
let address = getAddress(keyPair, myNetwork)
console.log("地址:", address, "\n")
}
function getAddress(keyPair, network) {
const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey , network:network})
return address
}
版权声明:博客中的文章版权归博主所有,未经授权禁止转载,转载请联系作者取得同意并注明出处。
未经授权禁止转载、改编,转载请注明出处。