Hace poco me bloquearon el acceso a mi Ledger NanoS cuando olvidé el código PIN. Al intentar restablecer mi frase de recuperación, me di cuenta de que solo tengo 23 de las 24 palabras requeridas (desafortunadamente, no estoy seguro de cómo sucedió). No estoy seguro de en qué posición está la palabra, pero estoy seguro de que el orden de las otras 23 palabras es correcto. Dicho esto, tengo que probar todas las posibilidades en cualquier otra posición.
Encontré esta publicación que me da una lista de palabras para completar la palabra que falta: Perdí mi billetera de Bitcoin y solo tengo 11 de las 12 palabras de frases iniciales mnemotécnicas. ¿Cómo puedo obtener mis Bitcoins?
Estoy buscando un fragmento de código que me permita batir las soluciones sin probar manualmente las billeteras 1 por 1.
¿Conoces una de las direcciones del llavero? Ledger usa la derivación BIP44 para que pueda escribir un ciclo para verificar diferentes frases iniciales y verificar las direcciones resultantes con una dirección que sabe que debería estar en el llavero. De esta manera, puede escribir sus palabras de recuperación sin tener que estar en línea.
Por ejemplo, si fuera yo, probablemente escribiría algo usando bitcoinjs-lib . Aquí hay un comienzo escrito con bitcoinjs (NOTA, estoy usando la versión 3.3.2). Esto tomará una semilla de recuperación y una dirección y buscará en el llavero y le dirá si la dirección existe o no dentro de él.
//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
Desde aquí, puede dar un paso más y convertir la words
variable en una matriz con todos sus diferentes combos y luego repetirlos.
Ampliando esta respuesta (usando python) de la pregunta relacionada a la que se vinculó, podemos comenzar a reducir la lista de posibilidades.
Comience con su lista ordenada de palabras conocidas:
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',
]
Primero, genera un patrón de frase para cada posición posible de la palabra que falta:
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 <= 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
Esta lista de listas arrojará algo como lo siguiente:
{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}
Ahora, ingrese esto en el código de esta respuesta en la pregunta relacionada que vinculó para generar una lista de todas las frases posibles:
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
En este punto tenemos 180 frases mnemotécnicas válidas de 24 palabras, una de las cuales contiene su moneda.
Si bien podría verificar manualmente todos estos, sería una tarea tediosa. Como se discutió en la respuesta de m1xolyd1an , si conoce una de las direcciones utilizadas anteriormente, podemos usar cada una de estas frases mnemotécnicas para generar las primeras 5 o más direcciones deterministas producidas por cada frase y realizar una comparación para verificar si hay una coincidencia de dirección.
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))
Si se encuentran coincidencias de direcciones, se imprimirán como pares de valores clave:
{
"<address>": "<mnemonic phrase>"
}
Aquí hay dos scripts de python que incorporan la lógica anterior de diferentes maneras:
1 - Me temo que no puede encontrar/buscar una dirección de bitcoin con 23 de 24 palabras de frase semilla mnemotécnicas.
2 - Otro desastre es no saber el orden de las palabras.
En el futuro... Mi sugerencia será que genere y guarde un valor entropy
similar hex
al de esta muestra . Para que pueda recuperar fácilmente cualquier dirección en casos como este.
vincenzopalazzo
Nate gris