Web3钱包的助记词作用与底层实现机制

  • Dapplink
  • 发布于 2025-04-11 14:30
  • 阅读 11

Web3钱包的助记词作用与底层实现机制

一.助记词介绍

助记词(Mnemonic Phrase)在加密货币领域,尤其是在钱包管理和私钥生成中发挥着重要作用。助记词的生成遵循广泛使用的 BIP-39 标准,通过一系列人类易于记忆和书写的英文单词,提供了更加安全且方便的私钥管理方式。

具体而言,助记词的作用包括:

  • 备份区块链钱包:用户可通过记录助记词轻松备份钱包,不再需要记忆或存储冗长复杂的私钥。
  • 恢复钱包或私钥:如果钱包丢失或设备损坏,通过助记词即可快速恢复资产。
  • 派生钱包私钥和地址:钱包根据助记词生成的种子(Seed)可派生出多个钱包地址和对应的私钥,适用于多币种或多账户场景。

根据 BIP-39 标准,助记词的单词数量可以为 12 个、15 个、18 个、21 个或 24 个,其中最常见的是使用 12 个或 24 个单词。

实际使用中,大多数钱包应用推荐用户使用12或24个单词作为助记词,以提供足够高的安全性,同时兼顾了用户记忆和存储的便捷性。用户在备份助记词时,建议使用离线方式记录,例如纸质存储或硬件钱包,避免助记词被恶意软件或黑客窃取。

需要特别注意的是,助记词的单词顺序至关重要,不同的顺序会生成完全不同的钱包地址和私钥。因此,用户在记录和恢复钱包时,一定要严格按照原始顺序进行,以确保资产安全。

二.助记词生成机制

  • 随机熵生成: 首先生成一段随机熵(Entropy)。熵的长度可以是 128 到 256 位,并且是 32 的倍数。常见的熵长度有 128 位(12 个助记词)和 256 位(24 个助记词)。
  • 计算校验和:对熵进行 SHA-256 哈希计算,并取哈希值的前几位作为校验和。校验和的长度取决于熵的长度。例如,128 位熵需要 4 位校验和(因为 128 / 32 = 4),256 位熵需要 8 位校验和。
  • 组合熵和校验和:将校验和附加到熵的末尾,形成一个新的二进制序列。这个序列的总长度为 (熵的长度 + 校验和的长度)。
  • 分割为助记词索引:将组合后的二进制序列分割成每组 11 位的片段,每个片段转换为一个数字,这个数字作为助记词列表中的索引。
  • 映射为助记词: 使用这些索引从预定义的 2048 个助记词列表(BIP-39 词库)中提取相应的助记词。这些助记词就是最终的助记词短语。

1.代码实战

1.1.NodeJs 代码

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
const bip39 = require('bip39');
const crypto_ts = require('crypto');

// 1. 生成 128 位随机熵
const entropy = crypto_ts.randomBytes(16); // 128 位是 16 字节

// 2. 计算校验和 (SHA-256)
const hash = crypto_ts.createHash('sha256').update(entropy).digest();
const checksum = hash[0] >> 4; // 取前 4 位

// 3. 组合熵和校验和
let bits = '';
for (let i = 0; i < entropy.length; i++) {   
    bits += entropy[i].toString(2).padStart(8, '0');
}
bits += checksum.toString(2).padStart(4, '0');

// 4. 分割为助记词索引
const indices = [];
for (let i = 0; i < bits.length; i += 11) {  
    const index = parseInt(bits.slice(i, i + 11), 2);   
    indices.push(index);
}

// 5. 映射为助记词
const wordlist = bip39.wordlists.english;
const mnemonic = indices.map(index => wordlist[index]).join(' ');

1.2.Python 实现

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
def generate_mnemonic(): 
    # 1. 生成 128 位随机熵 (16 字节) 
    entropy = os.urandom(16)

    # 2. 计算校验和 (SHA-256)  
    hash_bytes = hashlib.sha256(entropy).digest()  
    checksum_bits = bin(hash_bytes[0])[2:].zfill(8)[:4]  # 取前 4 位

    # 3. 组合熵和校验和  
    entropy_bits = ''.join([bin(byte)[2:].zfill(8) for byte in entropy]) 
    combined_bits = entropy_bits + checksum_bits

    # 4. 分割为助记词索引   
    indices = [int(combined_bits[i:i + 11], 2) for i in range(0, len(combined_bits), 11)]

    # 5. 映射为助记词 
    wordlist = bip39.INDEX_TO_WORD_TABLE 
    mnemonic = ' '.join([wordlist[index] for index in indices])

    return mnemonic

# 生成并打印助记词mnemonic_phrase = generate_mnemonic()
print(f"Generated mnemonic phrase: {mnemonic_phrase}")

三.助记词验证过程

1.助记词验证原理

  • 检查单词数量:助记词的单词数量通常为 12、15、18、21 或 24 个单词。如果给定的助记词的单词数量不在这些范围内,则助记词无效。
  • 检查单词是否在词汇表中:每个助记词单词必须存在于 BIP-39 标准的 2048 个单词的词汇表中。如果有任何一个单词不在词汇表中,则助记词无效。
  • 将助记词转化成位串:将每个助记词单词转换为它在词汇表中的索引。每个索引表示一个 11 位的二进制数。将所有的二进制数连接起来形成一个位串。
  • 提取种子和校验和:位串的长度应该是助记词单词数乘以 11。例如,12 个单词的助记词对应的位串长度为 132 位。位串的前 128 位是种子,后 4 位是校验和。
  • 计算校验和:将种子通过 SHA-256 哈希函数计算出一个哈希值,然后取哈希值的前 4 位作为计算得到的校验和。
  • 验证校验和:比较提取的校验和和计算得到的校验和。如果两者匹配,则助记词有效,否则无效。

2.验证过程代码实现

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
def validate_mnemonic(mnemonic, wordlist):  
    words = mnemonic.split()    

    # 检查单词数量   
    if len(words) not in [12, 15, 18, 21, 24]:    
        return False    

    # 检查单词是否在词汇表中  
    for word in words:     
        if word not in wordlist:      
            return False    

    # 将助记词转化成位串  
    binary_string = ''  
    for word in words:  
        index = wordlist.index(word)      
        binary_string += format(index, '011b')     

    # 提取种子和校验和   
    seed_bits_length = (len(words) * 11) - (len(words) // 3)  
    seed_bits = binary_string[:seed_bits_length]  
    checksum_bits = binary_string[seed_bits_length:]     

    # 计算校验和   
    import hashlib   
    seed_bytes = int(seed_bits, 2).to_bytes(len(seed_bits) // 8, byteorder='big')   
    hash_value = hashlib.sha256(seed_bytes).hexdigest() 
    hash_bits = bin(int(hash_value, 16))[2:].zfill(256)   
    calculated_checksum = hash_bits[:len(words) // 3]     

    # 验证校验和  
    return checksum_bits == calculated_checksum

# Example usage:
mnemonic = "legal winner thank year wave sausage worth useful legal winner thank yellow"
wordlist = [...]  # BIP-39 wordlist
is_valid = validate_mnemonic(mnemonic, wordlist)
print("Is valid mnemonic:", is_valid)

四.助记词编解码过程

  • 助记词词库准备(Wordlist)
    • BIP-39 标准定义了一个包含 2048个单词 的固定英文单词表,每个单词对应一个索引值(从0到2047)
    • 也有中文等其他语言版本的单词表,都是2048个词,索引也是0到2047
  • 确定单词索引值:每个助记词对应单词表中的一个索引数字
  • 索引值转为二进制(Binary)每个索引范围为0~2047,正好11个二进制位(因为 2 ^ 11 = 2048)
  • 合并二进制,分离熵(Entropy)和校验位(Checksum)
  • 将熵从二进制转为16进制, 取前128位熵,转成16进制

编码流程如下,解码是下面的逆过程

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
助记词(Mnemonic words)    
    ↓ (单词表查询索引)
单词索引(Index)  
    ↓ (索引转11位二进制)
二进制(Binary string)
    ↓ (截取熵Entropy)
二进制熵(Binary Entropy)
    ↓ (转16进制)
熵(Entropy, Hexadecimal)

五.The Web3 社区基于 BIP-39 封装代码实战

1.nodejs 代码封装

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
const bip39  = require('bip39');
const bip32  = require('bip32');

export function createHelpWord(number: number, language: string) {   
    switch (language) {     
        case 'chinese_simplified':       
            if(number === 12) {          
                return bip39.generateMnemonic(128, null, bip39.wordlists.chinese_simplified);    
            } else if(number === 15) {       
                return bip39.generateMnemonic(160, null, bip39.wordlists.chinese_simplified);    
            } else if(number === 18) {     
                return bip39.generateMnemonic(192, null, bip39.wordlists.chinese_simplified);    
            } else if(number === 21) {    
                return bip39.generateMnemonic(224, null, bip39.wordlists.chinese_simplified); 
            } else if(number === 24) {      
                return bip39.generateMnemonic(256, null, bip39.wordlists.chinese_simplified);       
            } else {       
                return "unsupported"   
            }      
        case 'chinese_traditional':   
            if(number === 12) {            
                return bip39.generateMnemonic(128, null, bip39.wordlists.chinese_traditional);     
            } else if(number === 15) {     
                return bip39.generateMnemonic(160, null, bip39.wordlists.chinese_traditional);    
            } else if(number === 18) {      
                return bip39.generateMnemonic(192, null, bip39.wordlists.chinese_traditional);     
            } else if(number === 21) {      
                return bip39.generateMnemonic(224, null, bip39.wordlists.chinese_traditional);     
            } else if(number === 24) {   
                return bip39.generateMnemonic(256, null, bip39.wordlists.chinese_traditional);      
            } else {         
                return "unsupported"          
            }       
        case 'english':    
            if(number === 12) {         
                return bip39.generateMnemonic(128, null, bip39.wordlists.english);      
            } else if(number === 15) {         
                return bip39.generateMnemonic(160, null, bip39.wordlists.english);    
            } else if(number === 18) {      
                return bip39.generateMnemonic(192, null, bip39.wordlists.english);     
            } else if(number === 21) {         
                return bip39.generateMnemonic(224, null, bip39.wordlists.english);       
            } else if(number === 24) {         
                return bip39.generateMnemonic(256, null, bip39.wordlists.english);      
            } else {              
                return "unsupported"       
            }    
        case 'french':       
            if(number === 12) {       
                return bip39.generateMnemonic(128, null, bip39.wordlists.french);         
            } else if(number === 15) {     
                return bip39.generateMnemonic(160, null, bip39.wordlists.french);      
            } else if(number === 18) {      
                return bip39.generateMnemonic(192, null, bip39.wordlists.french);       
            } else if(number === 21) {      
                return bip39.generateMnemonic(224, null, bip39.wordlists.french);      
            } else if(number === 24) {             
                return bip39.generateMnemonic(256, null, bip39.wordlists.french);    
            } else {               
                return "unsupported"       
            }     
        case 'italian':   
            if(number === 12) {     
                return bip39.generateMnemonic(128, null, bip39.wordlists.italian);      
            } else if(number === 15) {   
                return bip39.generateMnemonic(160, null, bip39.wordlists.italian);     
            } else if(number === 18) {      
                return bip39.generateMnemonic(192, null, bip39.wordlists.italian);       
            } else if(number === 21) {  
                return bip39.generateMnemonic(224, null, bip39.wordlists.italian);      
            } else if(number === 24) {           
                return bip39.generateMnemonic(256, null, bip39.wordlists.italian);   
            } else {             
                return "unsupported"         
            }    
        case 'japanese':   
            if(number === 12) {     
                return bip39.generateMnemonic(128, null, bip39.wordlists.japanese);     
            } else if(number === 15) {       
                return bip39.generateMnemonic(160, null, bip39.wordlists.japanese);      
            } else if(number === 18) {   
                return bip39.generateMnemonic(192, null, bip39.wordlists.japanese);      
            } else if(number === 21) {          
                return bip39.generateMnemonic(224, null, bip39.wordlists.japanese);   
            } else if(number === 24) {         
                return bip39.generateMnemonic(256, null, bip39.wordlists.japanese);      
            } else {         
                return "unsupported"       
            }      
        case 'korean':  
            if(number === 12) {        
                return bip39.generateMnemonic(128, null, bip39.wordlists.korean);   
            } else if(number === 15) {         
                return bip39.generateMnemonic(160, null, bip39.wordlists.korean);   
            } else if(number === 18) {         
                return bip39.generateMnemonic(192, null, bip39.wordlists.korean);  
            } else if(number === 21) {          
                return bip39.generateMnemonic(224, null, bip39.wordlists.korean);       
            } else if(number === 24) {        
                return bip39.generateMnemonic(256, null, bip39.wordlists.korean); 
            } else {             
                return "unsupported"   
            }     
        case 'spanish':    
            if(number === 12) {          
                return bip39.generateMnemonic(128, null, bip39.wordlists.spanish);        
            } else if(number === 15) {      
                return bip39.generateMnemonic(160, null, bip39.wordlists.spanish);  
            } else if(number === 18) {      
                return bip39.generateMnemonic(192, null, bip39.wordlists.spanish);          
            } else if(number === 21) {      
                return bip39.generateMnemonic(224, null, bip39.wordlists.spanish);       
            } else if(number === 24) {          
                return bip39.generateMnemonic(256, null, bip39.wordlists.spanish);      
            } else {            
                return "unsupported"        
            }    
        default:   
            return "unsupported"  
        }
    }

export function wordsToEntropy(mnemonic: string, language: string) { 
    switch (language) {   
        case 'chinese_simplified':       
            return bip39.mnemonicToEntropy(mnemonic, bip39.wordlists.chinese_simplified);   
        case 'chinese_traditional':    
            return bip39.mnemonicToEntropy(mnemonic, bip39.wordlists.chinese_traditional);   
        case 'english':      
            return bip39.mnemonicToEntropy(mnemonic, bip39.wordlists.english);      
        case 'french':          
            return bip39.mnemonicToEntropy(mnemonic, bip39.wordlists.french);   
        case 'italian':     
            return bip39.mnemonicToEntropy(mnemonic, bip39.wordlists.italian);   
        case 'japanese':         
            return bip39.mnemonicToEntropy(mnemonic, bip39.wordlists.japanese);    
        case 'korean':    
            return bip39.mnemonicToEntropy(mnemonic, bip39.wordlists.korean);    
        case 'spanish':   
            return bip39.mnemonicToEntropy(mnemonic, bip39.wordlists.spanish);     
        default:         
            return "unsupported"   
        }
    }

export function entropyToWords(encrytMnemonic:string, language:string) {  
    switch (language) {  
        case 'chinese_simplified':       
            return bip39.entropyToMnemonic(encrytMnemonic, bip39.wordlists.chinese_simplified);    
        case 'chinese_traditional':       
            return bip39.entropyToMnemonic(encrytMnemonic, bip39.wordlists.chinese_traditional);      
        case 'english':        
            return bip39.entropyToMnemonic(encrytMnemonic, bip39.wordlists.english);   
        case 'french':          
            return bip39.entropyToMnemonic(encrytMnemonic, bip39.wordlists.french);   
        case 'italian':          
            return bip39.entropyToMnemonic(encrytMnemonic, bip39.wordlists.italian);  
        case 'japanese':          
            return bip39.entropyToMnemonic(encrytMnemonic, bip39.wordlists.japanese);    
        case 'korean':       
            return bip39.entropyToMnemonic(encrytMnemonic, bip39.wordlists.korean);    
        case 'spanish':       
            return bip39.entropyToMnemonic(encrytMnemonic, bip39.wordlists.spanish);      
        default:       
            return "unsupported"  
        }
    }

export function mnemonicToSeed(mnemonic, password){  
    return bip39.mnemonicToSeed(mnemonic, password)
}

export function mnemonicToSeedHex(mnemonic, password){  
    return bip39.mnemonicToSeedHex(mnemonic, password);
}

export function validateMnemonic(mnemonic, language) {    
    switch (language) {    
        case 'chinese_simplified':      
            return bip39.validateMnemonic(mnemonic, bip39.wordlists.chinese_simplified);  
        case 'chinese_traditional':     
            return bip39.validateMnemonic(mnemonic, bip39.wordlists.chinese_traditional); 
        case 'english':         
            return bip39.validateMnemonic(mnemonic, bip39.wordlists.english);    
        case 'french':        
            return bip39.validateMnemonic(mnemonic, bip39.wordlists.french);    
        case 'italian':      
            return bip39.validateMnemonic(mnemonic, bip39.wordlists.italian);   
        case 'japanese':       
            return bip39.validateMnemonic(mnemonic, bip39.wordlists.japanese);
        case 'korean': 
            return bip39.validateMnemonic(mnemonic, bip39.wordlists.korean);     
        case 'spanish':
            return bip39.validateMnemonic(mnemonic, bip39.wordlists.spanish);     
        default:        
            return "unsupported"   
        }
    }
  • 测试使用
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
test('test create mnemonic', async () => {   
    const mnemonic_12_english = createMnemonic(12, "english")  
    const mnemonic_12_chinese = createMnemonic(12, "chinese_simplified")   
    console.log(mnemonic_12_chinese)    console.log(mnemonic_12_chinese)
    const mnemonic_to_entropy = mnemonicToEntropy(mnemonic_12_chinese, "chinese_simplified") 
    console.log(mnemonic_to_entropy)

    const entropy_to_mnemonic = entropyToMnemonic(mnemonic_to_entropy, "chinese_simplified") 
    console.log(entropy_to_mnemonic)

    const mnemonic_to_seed = mnemonicToSeed(mnemonic_to_entropy, "") 
    console.log(mnemonic_to_seed)

    const mnemonic_to_seed_sync = mnemonicToSeedSync(mnemonic_to_entropy, "") 
    console.log(mnemonic_to_seed_sync)

    const vm = validateMnemonic(mnemonic_to_entropy, "")   
    console.log(vm)});

2.Python 代码封装

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
class Bip39Mnemonic:  
    def __init__(self):       
        pass

    def createMnemonic(self, number):     
        mnemonic = bip39.get_entropy_bits(number)     
        return mnemonic

    def mnemonicToEntropy(self,  mnemonic):      
        decode_words = bip39.decode_phrase( mnemonic)   
        return decode_words   
    def entropyToMnemonic(self, entropy):       
        nemonic_entropy = bip39.encode_bytes(entropy)      
        return nemonic_entropy

    def mnemonicToSeed(self, mnemonic):   
        nemonic_to_seed = bip39.phrase_to_seed(mnemonic)       
        return nemonic_to_seed

    def validateMnemonic(self, mnemonic):      
        return bip39.check_phrase(mnemonic)

    def generateMnemonic(self):    
        # 1. 生成 128 位随机熵 (16 字节)    
        entropy = os.urandom(16)

        # 2. 计算校验和 (SHA-256)      
        hash_bytes = hashlib.sha256(entropy).digest()     
        checksum_bits = bin(hash_bytes[0])[2:].zfill(8)[:4]  # 取前 4 位

        # 3. 组合熵和校验和   
        entropy_bits = ''.join([bin(byte)[2:].zfill(8) for byte in entropy])       
        combined_bits = entropy_bits + checksum_bits

        # 4. 分割为助记词索引      
        indices = [int(combined_bits[i:i + 11], 2) for i in range(0, len(combined_bits), 11)]

        # 5. 映射为助记词   
        wordlist = bip39.INDEX_TO_WORD_TABLE       
        mnemonic = ' '.join([wordlist[index] for index in indices])

        return mnemonic
  • 测试使用
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
import bip

bip39_mnemonic = bip.Bip39Mnemonic()
mnemonic_phrase = bip39_mnemonic.generateMnemonic()
print(f"Generated mnemonic phrase: {mnemonic_phrase}")

mnemonic_12_phrase = bip39_mnemonic.createMnemonic(12)
print(f"create mnemonic phrase: {mnemonic_phrase}")

六.本节小结

助记词(Mnemonic Phrase)是一种在区块链和加密货币领域广泛使用的安全私钥管理方式,基于 BIP-39 标准。助记词使用一系列易于记忆的单词,能够有效备份和恢复钱包,并派生出多个私钥和地址,极大提升用户使用便捷性与安全性。

助记词的生成主要经历以下步骤:

  • 随机熵生成:生成128至256位随机熵。
  • 计算校验和:通过SHA-256对熵哈希并提取校验位。
  • 组合熵和校验和:形成新的二进制序列。
  • 转换为单词索引:二进制序列切割为每11位一组。
  • 映射为助记词:使用索引从标准单词列表中选取助记词。

在实际使用中,常见的是12或24个单词的助记词,推荐用户离线存储,确保安全性。验证助记词时,需要检查单词数量、词汇表有效性、以及校验位的正确性,以保证助记词的合法性。

代码实战部分,文章分别展示了Node.js和Python的助记词生成与验证代码示例,帮助开发者更好地理解并实现相关功能。此外,文章还提供了对助记词编解码过程的详细描述,强调助记词和熵之间相互转换的机制。

最后,为了简化开发,文章中封装了Node.js和Python的助记词工具函数,涵盖多语言助记词生成、助记词与熵互转、以及助记词的种子(Seed)派生和有效性验证。这种封装大幅提高了Web3开发中的安全性与开发效率。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Dapplink
Dapplink
0xBdcb...f214
首个模块化、可组合的Layer3协议。