Bitcoin Forum
May 01, 2024, 06:09:27 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Creación de múltiples direcciones mediande una seed  (Read 935 times)
xcbtrader (OP)
Hero Member
*****
Offline Offline

Activity: 865
Merit: 1006


View Profile
July 29, 2016, 07:11:26 AM
 #1

Buenas a todos.
Hace tiempo que tengo una duda, y por más que he buscado no encuentro la solución.

Mi duda es:

Me gustaría emular en código (python) el funcionamiento de las billeteras que utilizan una serie de palabras, para generar un seed  recuperación (tipo electrum).

Dadas 13 palabras, generar una dirección es fácil, lo que no se es como lo hacen para generar las sucesivas.

Pongo un ejemplo:

Code:
from bitcoin import *

seed = palabra1+palabra2+palabra3+ ..... palabra13
priv1 = sha256(seed)
pub1 = privtopub(priv1)
addr1 = pubtoaddr(pub1)

Hasta aquí, perfecto. Ya tenemos creada una dirección a partir de una seed de 13 palabras.
Mi duda, surge ahora... como genero las siguientes direcciones a partir del seed original??

Una solución que se me ocurre es:

Code:
priv2 = sha256(seed + '2')
priv3 = sha256(seed + '3')
.....
.....
privN = sha256(seed + 'N')

otra forma sería coger siempre la privada anterior como referencia.
Por ejemplo:

Code:
priv2 = sha256(seed + str(priv1))
priv3 = sha256(seed + str(priv2))
.......
.......
privN = sha256(seed + str(privN-1))

¿Alguien sabe cúal es la forma como lo calcula, por poner un ejemplo, electrum?

Un saludo

Activity + Trust + Earned Merit == The Most Recognized Users on Bitcointalk
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714543767
Hero Member
*
Offline Offline

Posts: 1714543767

View Profile Personal Message (Offline)

Ignore
1714543767
Reply with quote  #2

1714543767
Report to moderator
Shawshank
Legendary
*
Offline Offline

Activity: 1623
Merit: 1608



View Profile
July 29, 2016, 02:35:28 PM
Last edit: August 01, 2016, 07:51:45 PM by Shawshank
 #2

No sé si te va a ayudar algo lo que te comento. Me salgo un poco por la tangente...

No he trabajado con wallets HD en Python, pero supongo que habría que llamar a las funciones de BIP32Node.
https://github.com/richardkiss/pycoin/blob/master/pycoin/key/BIP32Node.py

Sí he trabajado con wallets HD en Copay y Colu, que utilizan Node.js.

Por ejemplo, en Copay obtienes el wallet HD a partir de una semilla de palabras según se especifica en BIP39.
Code:
var Mnemonic = require('bitcore-mnemonic');
var code = new Mnemonic('cheese upset pudding inmate flavor crush hard same element index laugh supreme');

var xpriv = code.toHDPrivateKey();
var privKey=xpriv.toJSON()['privateKey'];

Y en Colu, directamente de la documentación:
Code:
var Colu = require('colu')

var settings = {
    network: 'mainnet',
    privateSeed: null
}

var colu = new Colu(settings)
colu.on('connect', function () {
  var address = colu.hdwallet.getAddress()

    console.log("address: ", address)
})

colu.init()

Si quieres las siguientes direcciones, vuelves a llamar a colu.hdwallet.getAddress() tantas veces como sea necesario.

Estas dos webs me sirvieron para hacerme mejor a la idea de los wallets HD:
https://coinb.in/
http://bip32.org/

Y al mismo tiempo me sirvió para darme cuenta de que queda bastante por desarrollar. Por ejemplo, coinb.in aún no permite pasar tus propios xprv y xpub, y en bip32.org aún no está disponible el "derivation path" m/44'/0'/0' (BIP44) que se está empezando a utilizar bastante, por ejemplo, en Copay.

Mycelium Gear tiene una implementación en Ruby.

Siento no poder ser de más ayuda  Sad

EDIT: En Electrum parece que no utilizan pycoin: https://github.com/spesmilo/electrum/blob/master/lib/wallet.py  . Conviertes el mnemónico a semilla en mnemonic_to_seed, y a partir de ahí obtienes el xpub y xprv con las funciones add_xpub_from_seed y add_xprv_from_seed respectivamente.

Lightning Address: shawshank@getalby.com
xcbtrader (OP)
Hero Member
*****
Offline Offline

Activity: 865
Merit: 1006


View Profile
July 29, 2016, 05:42:07 PM
 #3

No sé si te va a ayudar algo lo que te comento. Me salgo un poco por la tangente...

No he trabajado con wallets HD en Python, pero supongo que habría que llamar a las funciones de BIP32Node.
https://github.com/richardkiss/pycoin/blob/master/pycoin/key/BIP32Node.py

Sí he trabajado con wallets HD en Copay y Colu, que utilizan Node.js.

Por ejemplo, en Copay obtienes el wallet HD a partir de una semilla de palabras según se especifica en BIP39.
Code:
var Mnemonic = require('bitcore-mnemonic');
var code = new Mnemonic('syrup absorb parrot fold pond kit again album tide sunset spoon test');

var xpriv = code.toHDPrivateKey();
var privKey=xpriv.toJSON()['privateKey'];

Y en Colu, directamente de la documentación:
Code:
var Colu = require('colu')

var settings = {
    network: 'mainnet',
    privateSeed: null
}

var colu = new Colu(settings)
colu.on('connect', function () {
  var address = colu.hdwallet.getAddress()

    console.log("address: ", address)
})

colu.init()

Si quieres las siguientes direcciones, vuelves a llamar a colu.hdwallet.getAddress() tantas veces como sea necesario.

Estas dos webs me sirvieron para hacerme mejor a la idea de los wallets HD:
https://coinb.in/
http://bip32.org/

Y al mismo tiempo me sirvió para darme cuenta de que queda bastante por desarrollar. Por ejemplo, coinb.in aún no permite pasar tus propios xprv y xpub, y en bip32.org aún no está disponible el "derivation path" m/44'/0'/0' (BIP44) que se está empezando a utilizar bastante, por ejemplo, en Copay.

Mycelium Gear tiene una implementación en Ruby.

Siento no poder ser de más ayuda  Sad

EDIT: En Electrum parece que no utilizan pycoin: https://github.com/spesmilo/electrum/blob/master/lib/wallet.py  . Conviertes el mnemónico a semilla en mnemonic_to_seed, y a partir de ahí obtienes el xpub y xprv con las funciones add_xpub_from_seed y add_xprv_from_seed respectivamente.


Me ha servido ...
Muchas gracias.
Ahora intentando entenderlo todo.
Saludos

Shawshank
Legendary
*
Offline Offline

Activity: 1623
Merit: 1608



View Profile
August 01, 2016, 07:51:25 PM
 #4

Esta es la buena en Node.js.

Por si a alguien le sirve, aquí la derivación m/44'/0'/0' que necesitaba para un pequeño proyecto que estoy desarrollando.

Code:
var Mnemonic = require('bitcore-mnemonic');
var code = new Mnemonic('cheese upset pudding inmate flavor crush hard same element index laugh supreme');

var hdPrivateKey = code.toHDPrivateKey();
var accountKey = hdPrivateKey.derive(44, true).derive(0, true).derive(0, true);
var addr = accountKey.derive(0).derive(0).privateKey.toAddress();

console.log('addr: ', addr);

Sigue el formato m / purpose' / coin_type' / account' / change / address_index de BIP32. purpose es 44 porque sigue BIP44.

Para ir consiguiendo las siguientes direcciones, se va incrementando el segundo índice la línea:
var addr = accountKey.derive(0).derive(0).privateKey.toAddress();

Así, por ejemplo:
var addr1 = accountKey.derive(0).derive(1).privateKey.toAddress();
var addr2= accountKey.derive(0).derive(2).privateKey.toAddress();

Lightning Address: shawshank@getalby.com
xcbtrader (OP)
Hero Member
*****
Offline Offline

Activity: 865
Merit: 1006


View Profile
August 01, 2016, 09:57:21 PM
 #5

En python yo he puesto esto:

Code:
__author__ = 'xcbtrader'
# -*- coding: utf8 -*-

from bitcoin import *

print ('===================================================')
seed = random_electrum_seed()
bip32Master = bip32_master_key(seed)
print ('Master: ' + bip32Master)

print ('===================================================')
bip32Child1 = bip32_ckd(bip32Master,1)
print ('Child1: ' + bip32Child1)
priv1 = bip32_extract_key(bip32Child1)
print ('Priv1: ' + priv1)
pub1 = privtopub(priv1)
print ('Pub1: ' + pub1)
addr1 = pubtoaddr(pub1)
print ('Addr1: ' + addr1)
wif1 = encode_privkey(priv1, 'wif')
print ('Wif1: ' + wif1)

print ('===================================================')
bip32Child2 = bip32_ckd(bip32Master,2)
print ('Child2: ' + bip32Child2)
priv2 = bip32_extract_key(bip32Child2)
print ('Priv2: ' + priv2)
pub2 = privtopub(priv2)
print ('Pub2: ' + pub2)
addr2 = pubtoaddr(pub2)
print ('Addr2: ' + addr2)
wif2 = encode_privkey(priv2, 'wif')
print ('Wif2: ' + wif2)
print ('===================================================')


Saludos

Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!