¿Cómo se convierten los bytes de la versión bip32 a base58?

Convertir los bytes de la versión BIP32 - x04\x88\xad\xe4- de base256 a base58 y base58Check devuelve 7irrXy 1kz713TZjju, respectivamente.

Pensé que los bytes de la versión representaban xprv. ¿Qué me estoy perdiendo?

Estoy usando pybitcointools , si eso marca la diferencia.

¿Por qué desde base256? 0x04 0x88 0xAD 0xE4 debe ir directamente a base58 IMO.
@JonasSchnelli solo porque la biblioteca pybitcointools lo define de esa manera. No hace ninguna diferencia si está codificado como hexadecimal

Respuestas (2)

Al igual que en las direcciones de bitcoin normales (o cualquier cosa codificada en base 58), los bytes de la versión no se codifican solos. Como se describe en la sección Formato de serialización , hay una carga útil de 78 bytes que se versiona y verifica antes de codificarse en base 58:

  • 4 bytes: bytes de versión (mainnet: 0x0488B21E público, 0x0488ADE4 privado; testnet: 0x043587CF público, 0x04358394 privado)
  • 1 byte: profundidad: 0x00 para nodos maestros, 0x01 para claves derivadas de nivel 1, ....
  • 4 bytes: la huella digital de la clave principal (0x00000000 si es clave maestra)
  • 4 bytes: número de niño. Esto es ser32(i) para i en xi = xpar/i, siendo xi la clave > - serializada. (0x00000000 si es clave maestra)
  • 32 bytes: el código de cadena
  • 33 bytes: la clave pública o los datos de la clave privada (serP(K) para claves públicas, 0x00 || ser256(k) para claves privadas)

No hay una asignación de byte a carácter cuando realiza la serialización base58 de una estructura de varios bytes. No es que 0x04 se convierta en 'x', 0x88 se convierta en 'p', etc. Más bien, toda la estructura de 86 bytes (78 payload + 4 versión + 4 checksum) se codifica en algo que comienza con 'xpriv' cuando los 4 bytes más significativos de la estructura de 86 bytes son [0x04, 0x88, 0xad, 0xe4].

Entonces, ¿solo funciona para estructuras de 78 bytes? si es asi entiendo
@WizardOfOzzie es probable que una secuencia diferente de 4 bytes pueda obtener una estructura de 50 bytes para comenzar con xpriv, por ejemplo, pero sí, esos bytes exactos se eligieron para una estructura de 78 bytes.
Lo intenté y lo volví a intentar y no funcionaba. Luego me di cuenta de que no son 78, en realidad son 82 bytes cuando incluyes la suma de verificación de 4 bytes. En pybitcointools; changebase(TESTNET_PRIVATE + bytes(bytearray(78)), 256, 58) >>> 'tprv8ZgxMBicQKsPcsbCVeqqF1KVdH7gwDJbxbzpCxDUsoXHdb6SnTPYxdwSAKDC6KKJzv7khnNWRAJQsRA8BBQyiSfYnRt6zuu4vZQGKhCz4Jb. :)
@WizardOfOzzie, ¡buen punto! He actualizado mi respuesta.
Para referencia futura: todos los bytes de la versión de clave extendida de bitcoin se pueden encontrar en electrum.readthedocs.io/en/latest/xpub_version_bytes.html

Para complementar la respuesta anterior, el archivo Bitcoin chainparams.cpp contiene la siguiente información para ayudar a lograr el cumplimiento de BIP 32:

red principal:

base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();

Red de prueba:

base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();

El comando bitcoin-explorer (bx) se usa a continuación, con la tercera peor semilla de billetera cerebral posible en el mundo. Además, bx se compiló para usar testnet, no mainnet. Por lo tanto, concéntrese en donde 04358394 para tprv y 043587cf para tpub que aparecen en los ejemplos a continuación.

% eco '0' | bx base16-encode | bx sha512 | bx hd-nuevotprv8ZgxMBicQKsPdcvudXaExR6Wdz5VgdjGeZHsw5bjnypoxrCxnYsyVq2v9cPTzDsnyLAL1v4Z2tM3Rp2AA6vv9WDbNBtui5QEZTWYucefZox

% eco '0' | bx base16-encode | bx sha512 | bx hd-nuevo | bx base58verificar-decodificar

wrapper
{
    checksum 3287061687
    payload 3583940000000000000000004b0dc73821a026c0c71d07a7655968352b52d7e5896dd3907df121f914f9743900a6b53d2f0e384dc6ced2caeb36f0c9cc6f3ab0677f73c31aca87b62bbcc9fe78
    version 4
}

% eco '0' | bx base16-encode | bx sha512 | bx hd-nuevo | bx base58-decodificar 043583940000000000000000004b0dc73821a026c0c71d07a7655968352b52d7e5896dd3907df121f914f9743900a6b53d2f0e384dc6ced2caeb36f0c9bbcc6acaf83ab6371b794ecc3

% eco '0' | bx base16-encode | bx sha512 | bx hd-nuevo | bx hd-públicotpubD9nYDjxx7QwpsEhUiS7MDJ68p25nu9yxEt1AofKmEjmL3kozwA3z8G4Cm556YCYYJwfnix2GLVTtCHZq79R8UsRZBJVRPtD9HKNQBzDZVo4

% eco '0' | bx base16-encode | bx sha512 | bx hd-nuevo | bx hd-público | BX BASE58- 043587cfDecode 01CF633B1C00000000C023D310564EAD16B50E678B2FF20E2D0A0F210FCF9C603EBD16F17D055010663802605D719A28B2707DC9D7A2B804AT