Wallet-Recovery

自動化 Bip39 種子恢復

  • December 17, 2021

最近,當我忘記密碼時,我被鎖在我的 Ledger NanoS 之外。在嘗試從我的恢復片語中重置時,我意識到我只有 24 個必需單詞中的 23 個(不幸的是不確定它是如何發生的)。我不確定單詞在哪個位置,但我確定其他 23 個單詞的順序是正確的。話雖如此,我必須在每個其他位置嘗試所有可能性。

我發現這篇文章給了我一個單詞列表來填充缺失的單詞: 失去我的比特幣錢包並且只有 12 個助記詞助記詞中的 11 個。我怎樣才能得到我的比特幣?

我正在尋找一段程式碼,它可以讓我在不手動嘗試錢包 1 的情況下攪動解決方案。

你知道鑰匙串中的地址之一嗎?Ledger 使用 BIP44 派生,因此您可以編寫一個循環來檢查不同的種子片語,並根據您知道應該在鑰匙串中的地址檢查結果地址。這樣您就可以輸入您的恢復詞,而無需線上。

例如,如果是我,我可能會使用bitcoinjs-lib寫一些東西。這是用bitcoinjs編寫的開始(注意我使用的是 3.3.2 版本)。這將獲取一個恢復種子和一個地址,它將搜尋鑰匙串並告訴您該地址是否存在於其中。

//var words = "segment increase inch ensure corn cigar suggest fetch output proof peasant enact";
//var addr = "1c4XzQx7Uh8CnxzAN5CRrUjkbxGB1GUWp";

var searchbtn = document.getElementById("searchbtn");
searchbtn.onclick = function(){

   var words = document.getElementById("words").value;
   var addr = document.getElementById("addr").value;
   var depth = document.getElementById("depth").value;
   inkeychain(addr, words, depth);
}


function inkeychain(addr, keychain, depth){
   var isfound = false;
   for(var i=0;i<depth;i++){
       var seed = hd.bip39.mnemonicToSeed(keychain);
       var root = b.bitcoin.HDNode.fromSeedBuffer(seed)
       //const root = bitcoin.HDNode.fromSeedHex(seed.toString('hex'))
       var wallet = root.derivePath("m/44'/0'/0'/0/"+i);

       //legacy
       var address = wallet.getAddress();
       var wif = wallet.keyPair.toWIF();

       //segwit p2sh
       var pubKey = wallet.keyPair.getPublicKeyBuffer();
       var pubKeyHash = b.bitcoin.crypto.hash160(pubKey);
       var redeemScript = b.bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash);
       var redeemScriptHash = b.bitcoin.crypto.hash160(redeemScript);
       var scriptPubKey2 = b.bitcoin.script.scriptHash.output.encode(redeemScriptHash);
       var p2shsegwit = b.bitcoin.address.fromOutputScript(scriptPubKey2);

       if(address===addr){
       isfound = true;
           console.log(address, wif);
           $('#result').html('Found '+addr+' in this keychain at '+i+' position in the keychain');
           alert('Found!');
       } else if (p2shsegwit===addr){
           //check for segwit p2sh
           isfound = true; 
           console.log(p2shsegwit, wif);
           $('#result').html('Found '+addr+' in this keychain at '+i+' position in the keychain');
           alert('Found!');
       } 
   }
if(isfound===false){
   $('#result').html('No matches');
}

}

<https://bitcoinfunction.com/?id=5d9ea508d9bed>

從這裡你可以更進一步,將words變數變成一個包含所有不同組合的數組,然後將它們全部循環。

從您連結到的相關問題中擴展答案(使用 python),我們可以開始縮小可能性列表。

從已知單詞的有序列表開始:

ordered_known_words = [
   'glory',
   'twice',
   'film',
   'near',
   'senior',
   'trust',
   'thunder',
   'endorse',
   'suggest',
   'scheme',
   'habit',
   'limit',
   'slow',
   'yard',
   'clog',
   'attend',
   'axis',
   'enough',
   'only',
   'magic',
   'hair',
   'rule',
   'zone',
]

首先,為您失去的單詞的每個可能位置生成一個片語模式:

def generate_phrase_patterns(ordered_known_words, mnemonic_length=24):
   list_of_patterns = []

   for i in range(0, mnemonic_length):
       list_template = ['{x}'] * mnemonic_length
       word_position = 0

       for position, known_word in enumerate(ordered_known_words):
           if i &lt;= position:
               list_template[position + 1] = known_word
           else:
               list_template[position] = known_word
           word_position += 1

       list_of_patterns.append(', '.join(list_template))

   return list_of_patterns

這將產生一個列表列表,如下所示:

{x}, glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, {x}, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, {x}, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, {x}, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, {x}, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, {x}, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, {x}, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, {x}, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, {x}, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, {x}, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, {x}, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, {x}, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, {x}, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, {x}, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, {x}, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, {x}, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, {x}, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, {x}, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, {x}, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, {x}, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, {x}, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, {x}, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, {x}, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone, {x}

現在,將此答案輸入到您連結的相關問題的程式碼中,以生成所有可能片語的列表:

def generate_all_valid_phrases(phrase_patterns):
   from btctools.HD import check, WORDS
   total_phrases = []
   for pattern in phrase_patterns:
       for word in WORDS:
           mnemonic = pattern.format(x=word)
           if check(mnemonic):
               total_phrases.append(mnemonic)
   return total_phrases

至此,我們有 180 個有效的 24 字助記詞,其中一個包含您的硬幣。

雖然您可以手動檢查所有這些,但這將是一項乏味的任務。正如m1xolyd1an 的回答中所討論的,如果您知道以前使用的地址之一,我們可以使用這些助記片語中的每一個來生成每個片語產生的前 5 個左右確定性地址,並執行比較以檢查地址匹配。

from btctools import Xprv
import json

master_address_list = []

for phrase in total_phrases:

   m = Xprv.from_mnemonic(phrase)

   # check first few address spaces for a known match
   for i in range(0, 5):
       addr = (m/44./0./0./0/i).address('P2PKH')
       if addr == '1C26mdyEsNpe4fpkYtuHzH4Y378wez8mxP':
           master_address_list.append({addr: phrase})
       elif addr == '1BjoCJhvRCx9nVLPaKhg4qQ2YYps8mDgY4':
           master_address_list.append({addr: phrase})


print(f'Address match(s) found: ', len(master_address_list))
print(json.dumps(master_address_list, indent=4, sort_keys=True))

如果找到任何地址匹配,這會將它們列印為鍵值對:

{
   "&lt;address&gt;": "&lt;mnemonic phrase&gt;"
}

這裡有兩個 python 腳本以不同的方式結合了上述邏輯:

  • <https://github.com/d-fay/cryptotools/blob/master/solve_partial_12word_mnemonic_example.py>
  • <https://github.com/d-fay/cryptotools/blob/master/solve_partial_24word_mnemonic_example.py>

引用自:https://bitcoin.stackexchange.com/questions/90918