Bytes
La unidad básica de datos en los datos brutos de Bitcoin
Esta es una guía rápida para explicar qué son los bytes y cómo se usan en Bitcoin. Te será útil si estás trabajando con transacciones y otros datos brutos de Bitcoin.
Vas a hacer algo de programación de bajo nivel al trabajar con datos de Bitcoin, así que conviene saber qué estás mirando.
Introducción
Al usar Bitcoin en el día a día, verás con frecuencia bytes brutos de datos:
- Clave Privada. Son 32 bytes de datos que representan un número muy grande.
- TXID. Son 32 bytes de datos que representan el identificador único de una transacción.
Al trabajar con Bitcoin, pronto descubres que todos los datos centrales también están hechos de bytes brutos:
- Transacción. Un montón de bytes que describen el movimiento de bitcoins de un lugar a otro.
0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000 - Bloque. Una colección de transacciones, junto con una cabecera de bloque arriba resumiendo los datos del bloque.
Bitcoin es un programa de computadora, y las computadoras leen y se comunican usando bytes. Así que, si piensas trabajar con Bitcoin a nivel técnico, es útil saber qué es un byte, cómo se muestra y qué tipos de datos puede almacenar.
Básico
Antes de llegar a los bytes, necesitamos saber qué es un "bit".
Bit
Un bit es la unidad más pequeña de datos que una computadora puede guardar. Puede ser un 1 o un 0 (es decir, un único transistor "encendido" o "apagado"):
Esos bits son los bloques de construcción para almacenar datos dentro de las computadoras.
Si te atascas programando, recuerda que al final todo es solo un montón de unos y ceros.
Byte
Un byte es simplemente un grupo de 8 bits individuales:
Un byte es una unidad conveniente de almacenamiento de datos en una computadora. Igual que a veces es más práctico medir peso en kilogramos en vez de gramos, a veces es más práctico medir datos en bytes en vez de bits.
Los bytes son, de hecho, la medida estándar para los datos, y la mayoría de los datos con los que vas a trabajar en Bitcoin se mide en bytes.
Un byte son 8 bits individuales. Así que una clave privada de 32 bytes tiene 256 bits (32 × 8 = 256).
Representando bytes
Podemos representar un byte de dos formas:
- Usando ocho dígitos binarios, uno por cada bit (por ejemplo,
0b11111111) - Usando dos dígitos hexadecimales (por ejemplo,
0xFF)
Esto funciona porque, si divides un byte en dos mitades de 4 bits, cada mitad puede manejar 16 combinaciones distintas de 1 y 0. Así que, si le das a cada mitad su propio carácter hexadecimal, puedes representar un byte usando solo dos caracteres en vez de ocho.
A esta representación más corta se le llama byte hexadecimal.
Frecuentemente mostramos bytes en formato hexadecimal para ahorrar espacio, lo cual es mucho más conveniente al representar varios bytes de datos:
Así que, la próxima vez que veas una clave privada así:
61dc9ff8b15450212970c6fa997338bb205dd48ffaca3a056b09a3b44a244d76
En realidad estás mirando 32 bytes individuales:
61 dc 9f f8 b1 54 50 21 29 70 c6 fa 99 73 38 bb 20 5d d4 8f fa ca 3a 05 6b 09 a3 b4 4a 24 4d 76
Cuando empecé a trabajar con Bitcoin, cometí el error de interpretar cosas como las claves privadas como cadenas de letras y números individuales. Pero en realidad es una secuencia de bytes, en la que cada dos caracteres son un byte.
Almacenando datos en bytes
Entonces, ¿cómo podemos almacenar cosas útiles como números, texto y otras cosas dentro de esos bytes?
Honestamente, depende solo de cómo interpretes los bits.
Un byte puede contener distintos tipos de datos según cómo lo interpretes. Por ejemplo, el byte 01100111 podría representar la letra "g" o el número 103. Todo depende del tipo de dato con el que estés trabajando.
Números
Puedes usar bytes para almacenar números enteros:
Si queremos almacenar un número en una computadora, lo almacenamos usando su representación binaria dentro de los bits de un byte. Y, si queremos almacenar números más grandes, simplemente usamos más bytes.
Ejemplos
Los números son muy comunes dentro de los datos de Bitcoin: la clave privada (número de 32 bytes), el valor de salida (8 bytes), el VOUT (4 bytes), el nonce (4 bytes), el objetivo (32 bytes), el locktime (4 bytes) y el tiempo del bloque (4 bytes, en Unix Time).
Texto
También puedes usar bytes para almacenar texto, asignando a cada carácter su propio byte.
No existe un estándar oficial para codificar texto dentro de los datos de Bitcoin, pero el mapeo de caracteres a bytes más usado es ASCII:
Como puedes ver, cada byte representa un carácter distinto. Solo necesitas la tabla ASCII a mano para ver qué byte corresponde a qué carácter.
Ejemplos
El texto no se almacena con frecuencia en los datos de Bitcoin, pero aparece en algunos lugares: OP_RETURN (datos arbitrarios en una salida), el scriptsig de la transacción coinbase (texto del minero), el tipo/"comando" en la cabecera de cada mensaje (12 bytes ASCII) y el campo User-Agent en el mensaje "version".
Configuraciones (Bit Field)
A veces puedes usar los bits dentro de bytes de datos para representar varias configuraciones de encendido/apagado.
Esto se conoce como bit field (campo de bits), y es una forma eficiente de almacenar varias configuraciones en el menor espacio posible.
Ejemplos
Los bit fields se usan en algunos lugares en Bitcoin: el campo Services en el mensaje "version" (8 bytes/64 bits que indican los servicios de un nodo), el campo version de la cabecera de bloque (4 bytes/32 bits para señalar compatibilidad con actualizaciones) y el campo sequence de una transacción (interpretado como bit field al definir el locktime relativo).
Solo bytes
A veces los bytes no necesitan representar nada en particular. Pueden ser útiles simplemente como un bloque único de datos.
Ejemplos
La salida de una función hash es solo una secuencia única de bytes, y eso las hace útiles como "huellas dactilares" de datos: el TXID (identificador único de transacción), el hash de bloque (identificador único de bloque) y el hash de clave pública. Y a veces usamos simplemente un conjunto de bytes con apariencia aleatoria, sin significado, como los magic bytes (f9beb4d9) usados como marcador entre mensajes.
Datos personalizados
Al final, puedes usar bytes para representar lo que quieras. No tienen que ser solo números y texto (aunque sean los más comunes). Todo depende de cómo elijas interpretar las combinaciones de 1 y 0 dentro de esos bytes.
Ejemplos
Estas son algunas codificaciones exclusivas de Bitcoin: Script (un byte en un scriptpubkey/scriptsig puede referirse a una operación "OP_CODE"), Compact Size y el campo bits de la cabecera de bloque (almacena el objetivo actual de forma compacta).
Trabajando con bytes
Poder trabajar con bytes brutos en Bitcoin es especialmente importante cuando se trata de red o cuando estás haciendo hash de datos.
La buena noticia es que puedes trabajar con bytes brutos en cualquier lenguaje de programación decente. Esto cambia según el lenguaje, pero normalmente implica escribir el valor de cada byte individual en algún tipo de cadena o array especial, así:
"\xF9\xBE\xB4\xD9"
{0xF9, 0xBE, 0xB4, 0xD9}
Pero este tipo de formato no es fácil de pasar, así que a menudo convertirás esos bytes en cadenas hexadecimales para fines de visualización:
"f9beb4d9"
Así es como normalmente muestro bytes en este sitio, y como normalmente verás bytes mostrados en exploradores de blockchain.
A veces también querrás obtener el valor entero que representan esos bytes:
4190024921
Así que, al trabajar con datos de Bitcoin, quieres poder convertir de un lado a otro entre bytes reales, cadenas hexadecimales e enteros en tu lenguaje de programación favorito.
# bytes <-> hexadecimal <-> entero (Ruby)
bytes = ["f9beb4d9"].pack("H*") # string hex -> bytes
hex = bytes.unpack1("H*") # bytes -> string hex => "f9beb4d9"
int = hex.to_i(16) # hex -> entero => 4190024921 Resumen
Un bit es la unidad más pequeña de datos (un 1 o 0), y un byte es un grupo de 8 bits. Los bytes son la unidad básica de los datos brutos de Bitcoin.
Normalmente mostramos bytes en formato hexadecimal (2 caracteres por byte) para ahorrar espacio. Y un byte puede almacenar distintos tipos de datos — números, texto, configuraciones, huellas digitales — dependiendo de cómo interpretes sus bits.
Cuando empiezas a trabajar con datos brutos de Bitcoin, todo es solo cuestión de saber qué representan esos bytes.