Una transacción byte a byte
Desglose completo del hex de una transacción RingCT: cada campo, cada función, con datos reales y aleatorios
Una transacción de Monero son tres bloques de bytes consecutivos: el prefijo (entradas, salidas, extra), la base RingCT (comisión, importes cifrados, compromisos) y la parte podable (Bulletproofs+, CLSAG, pseudo-salidas). Abajo hay una herramienta que analiza byte a byte cualquier transacción v2, calcula el txid, comprueba el balance y, si le das una clave de visualización, encuentra «tus» salidas y descifra sus importes. Con una transacción aleatoria muestra todos los secretos, para que veas cómo se aplica cada función a números concretos.
Cómo leer los bytes
La serialización de Monero es sencilla: sin cabeceras ni nombres de campo, solo valores uno detrás de otro. Hay dos tipos de piezas:
- varint: un entero de longitud variable: 7 bits por byte, y el bit más alto significa «sigue otro byte».
0x02= 2,0x80 0x01= 128,0x80 0xb5 0x18= 400000. - clave / punto / escalar: exactamente 32 bytes, sin longitud. Las listas de puntos cuya longitud se conoce por el contexto (por ejemplo, los
sde CLSAG, por el tamaño del anillo) tampoco llevan longitud.
Así que el analizador tiene que conocer el formato de antemano: el tipo RingCT, que se lee a mitad de camino, decide cómo leer todo lo que viene después.
Qué funciones se aplican y dónde
| Campo | Lo calcula | Fórmula | Más |
|---|---|---|---|
| extra: R | el remitente | R = r·G | stealth addresses |
| salida: P | el remitente | P = Hs(8·r·A ‖ i)·G + B | stealth addresses |
| view tag | el remitente | Keccak("view_tag" ‖ 8rA ‖ i)[0] | view tags |
| ecdhInfo | el remitente | v ⊕ Keccak("amount" ‖ Hs(8rA ‖ i))[0..8] | Pedersen |
| outPk | el remitente | C = y·G + v·H, y = Hs("commitment_mask" ‖ Hs(8rA ‖ i)) | Pedersen |
| anillo | el monedero del remitente | 16 índices globales, distribución gamma sobre la antigüedad | señuelos |
| key image | el dueño de la entrada | I = x·Hp(P) | key image |
| pseudoOuts | el remitente | C̃ = y'·G + v·H, máscaras elegidas para que Σ C̃ = Σ C + fee·H | RingCT |
| CLSAG | el dueño de la entrada | un anillo de desafíos sobre P_i y C_i − C̃ | firmas de anillo |
| Bulletproofs+ | el remitente | prueba de que 0 ≤ v < 2⁶⁴ para todas las salidas | pruebas de rango |
Qué hace un nodo con estos bytes
- Los analiza; cualquier byte de más o de menos supone el rechazo.
- Comprueba que las key images son nuevas y están en el subgrupo correcto.
- Reconstruye los 16 índices globales a partir de los offsets y carga de su base de datos las claves y los compromisos de esas salidas.
- Comprueba el balance
Σ C̃ = Σ outPk + fee·H; la herramienta de abajo también lo hace. - Verifica Bulletproofs+ y la CLSAG de cada entrada.
Qué hace el monedero del destinatario
- Toma
Rde extra y calcula el secreto compartido8·a·R(una operación por transacción). - Para cada salida: un hash → compara el view tag; si no coincide, se para.
- Si coincide, compara
Hs(8aR ‖ i)·G + Bcon la clave de la salida. - Si la salida es nuestra, descifra el importe, reconstruye la máscara y comprueba
y·G + v·Hfrente aoutPk.
La herramienta muestra todos estos pasos con números concretos.
El analizador se ha comprobado contra la decodificación JSON de monerod de transacciones reales de tipo 5 y tipo 6 y de una transacción coinbase: todos los campos y el txid coinciden. El botón «tx real de mainnet» carga una de ellas; compara el txid con cualquier explorador de bloques.
¿Cómo será una transacción FCMP++?
El formato de las transacciones FCMP++ aún puede cambiar antes del hard fork, así que aquí no hay un analizador de bytes para él. Pero a partir de la implementación actual la estructura general está clara, y se parece sorprendentemente a la de hoy:
| En RingCT | En FCMP++ | Funciones |
|---|---|---|
| 16 offsets por entrada | una referencia al bloque con cuyo árbol se construye la prueba | raíz del Curve Tree sobre todas las salidas |
key image I = x·Hp(P) | la misma L = x·Hp(O) | los dobles gastos se detectan igual que antes |
pseudo-salida C̃ | C̃ = C + r_c·G, parte de la tupla rerandomizada | rerandomización |
| CLSAG por entrada | SA+L por entrada (unos pocos puntos y escalares) | Schnorr generalizado |
| — | una prueba de pertenencia para toda la transacción | Generalized Bulletproofs + divisores |
| view tag de 1 byte, ECDH sobre Ed25519 | view tag de 3 bytes, X25519, ancla Janus | Carrot |
Mira la rerandomización con números concretos en la herramienta. Cuando el formato sea definitivo, aquí se añadirá también un desglose byte a byte de las transacciones FCMP++.