Capítulo 05 de 10 · 11 min de lectura

Bloques y cadena

Un bloque es una página del libro de cuentas. Lo que lo hace especial son 32 bytes de su cabecera: el hash de la página anterior. Por culpa de ellos, tocar una coma del pasado obliga a rehacer todo lo que vino después.

De pagos sueltos a páginas

Tenemos transacciones válidas y firmadas recorriendo la red. Lo que falta es lo que pedía el capítulo 1: un orden único que todos acepten. Ordenar los pagos uno a uno sería inmanejable: miles de nodos poniéndose de acuerdo miles de veces por segundo. Así que se agrupan en lotes, los bloques, y la red solo tiene que ponerse de acuerdo en una cosa cada cierto tiempo: cuál es el siguiente bloque.

Un bloque tiene dos partes:

  • una lista de transacciones, en un orden concreto;
  • una cabecera de exactamente 80 bytes, que es su ficha de identidad.

Los 80 bytes que importan

La cabecera tiene seis campos, los mismos en xavicoin que en Bitcoin, byte a byte:

Campo Tamaño Qué es
Versión 4 bytes Qué reglas sigue el bloque
Hash del bloque anterior 32 bytes El eslabón: a qué bloque sigue este
Raíz de Merkle 32 bytes Un hash que resume todas las transacciones del bloque
Hora 4 bytes Cuándo se minó, en segundos
Bits 4 bytes La dificultad exigida, en formato compacto
Nonce 4 bytes El número que el minero va cambiando

Dos ideas sostienen todo lo demás:

El hash de un bloque es el hash de su cabecera, nada más. Ochenta bytes, da igual que el bloque lleve una transacción o cuatro mil. Por eso minar cuesta lo mismo con bloques llenos que vacíos.

Y aun así ese hash compromete todas las transacciones, gracias a la raíz de Merkle: un hash calculado a partir de los de todas las transacciones (el capítulo 10 explica cómo). Si cambia un solo byte de un solo pago, cambia la raíz; si cambia la raíz, cambia la cabecera; y si cambia la cabecera, cambia el hash del bloque.

La cadena

Ahora viene el truco. Cada cabecera contiene el hash del bloque anterior. El bloque 3 apunta al 2, el 2 al 1 y el 1 al génesis. Eso es toda la “cadena”: no hay punteros, ni números de página, ni base de datos. Solo hashes dentro de hashes.

Esta es una cadena de cuatro bloques con cabeceras de verdad. Todos cumplen su prueba de trabajo (su hash empieza por 0000) y cada uno apunta al anterior. Eres un atacante: quieres que el pago de Ana a Luis del bloque 1 sea de 1,5 en vez de 12,5.

Activa JavaScript para usar la demo.

    Los 80 bytes de la cabecera del bloque 1 · esto, y solo esto, es lo que se hashea

    • versión
    • hash del bloque anterior
    • raíz de Merkle (resumen de las transacciones)
    • hora
    • bits (dificultad)
    • nonce

    Lo que acabas de ver es el mecanismo de seguridad central de Bitcoin, así que merece la pena decirlo despacio:

    1. Al cambiar una transacción del bloque 1, cambió su raíz de Merkle, y con ella su hash. El hash nuevo ya no empieza por ceros: el bloque ha perdido su prueba de trabajo.
    2. El bloque 2 sigue apuntando al hash antiguo del bloque 1, que ya no existe. El eslabón está roto, y con él el del bloque 3.
    3. Para arreglarlo tienes que volver a minar el bloque 1. Pero su hash nuevo es distinto, así que hay que corregir el “anterior” del bloque 2… lo que cambia su hash y le hace perder su prueba de trabajo. Y así hasta el final.

    A ti te ha costado un par de segundos porque la dificultad de la demo es de juguete. En Bitcoin, cada bloque representa diez minutos de trabajo de toda la red mundial de mineros. Un pago enterrado bajo seis bloques exige rehacer una hora de ese trabajo… y durante esa hora la cadena honesta ha crecido otros seis bloques. Salvo que controles más potencia que todos los demás juntos, no la alcanzas nunca. Por eso un pago es más seguro cuantos más bloques tiene encima: cada uno es una confirmación.

    El bloque génesis

    Todos los bloques apuntan a uno anterior, así que tiene que haber uno que no apunte a ninguno: el bloque génesis. Su campo “anterior” son 32 bytes a cero, y no se descarga de ningún sitio: está escrito en el código del programa. Es el punto de partida común que todos los nodos dan por bueno sin comprobarlo contra nada.

    Esto tiene una consecuencia elegante: dos redes con génesis distintos son, automáticamente, cadenas distintas que no se pueden mezclar. El de la red de pruebas de xavicoin es este:

    {
      "hash": "0000002b9eb662948e78c5a169370d222af9a40d7b3ab25e865f1625a7e7e31a",
      "height": 0,
      "prevblock": "0000000000000000000000000000000000000000000000000000000000000000",
      "merkleroot": "ff8f8f79213e9b89b7c1e645e2b47ca1f94dcfd010cf2cab6b8d313d95910a37",
      "time": 1789862400,
      "bits": "1e00ffff",
      "nonce": 50946434,
      "size": 219
    }

    Fíjate en el nonce: hicieron falta casi 51 millones de intentos para que ese hash empezara por seis ceros. Y en su única transacción va incrustado un mensaje, xavicoin devnet 20/Sep/2026: aprender construyendo, igual que Satoshi incrustó un titular de periódico en el de Bitcoin.

    La posición de un bloque en la cadena se llama altura: el génesis es el 0, el siguiente el 1, y así. Curiosamente, la altura no está en la cabecera: se deduce contando eslabones hasta el génesis.

    Qué comprueba un nodo al recibir un bloque

    Un nodo no se fía de ningún bloque, venga de quien venga. Lo primero que hace es lo que se puede comprobar mirando solo el bloque, empezando por lo más barato. Si el hash no cumple la prueba de trabajo, ni se molesta en mirar lo demás:

    // internal/core/block.go
    func (b *Block) CheckSanity(p *Params) error {
    	if !CheckProofOfWork(b.Hash(), b.Header.Bits, p.PowLimit()) {
    		return errors.New("prueba de trabajo insuficiente")
    	}
    	if len(b.Txs) == 0 {
    		return fmt.Errorf("%w: sin transacciones", ErrMutated)
    	}
    	if root, mutated := b.ComputeMerkleRoot(); mutated || root != b.Header.MerkleRoot {
    		return fmt.Errorf("%w: raíz de Merkle incorrecta", ErrMutated)
    	}
    	if size := len(b.Serialize()); size > p.MaxBlockSize {
    		return fmt.Errorf("bloque de %d bytes, máximo %d", size, p.MaxBlockSize)
    	}
    	// … y que cada transacción esté bien formada

    La segunda comprobación importante es justo la de la demo: que la raíz de Merkle de la cabecera corresponda de verdad a las transacciones que vienen detrás. Si alguien cambia un pago y deja la cabecera intacta, se detecta aquí.

    Después vienen las reglas que dependen del bloque anterior: que ese bloque exista y sea válido, que los bits sean exactamente los que tocan, y que la hora sea razonable.

    ¿Y quién dice qué hora es?

    Nadie. No hay un reloj central, y el campo de la hora lo rellena el minero, que podría mentir. Así que las reglas son tolerantes, pero no ingenuas:

    • la hora debe ser posterior a la mediana de los 11 bloques anteriores (se usa la mediana, y no la hora del último, porque unos pocos mentirosos no pueden moverla);
    • y no puede estar demasiado en el futuro según el reloj del nodo que lo recibe (dos horas en Bitcoin; dos minutos en la red de pruebas de xavicoin).

    La hora de un bloque es, por tanto, aproximada. Basta para lo único que de verdad la necesita: medir cuánto se tarda en minar, que es el tema del próximo capítulo.

    En el código

    La cabecera es una estructura de seis campos, y su hash, una línea:

    // internal/core/block.go
    type Header struct {
    	Version    uint32      `json:"version"`
    	PrevBlock  crypto.Hash `json:"prevblock"`
    	MerkleRoot crypto.Hash `json:"merkleroot"`
    	Timestamp  uint32      `json:"time"`  // segundos Unix
    	Bits       uint32      `json:"bits"`  // target en formato compacto
    	Nonce      uint32      `json:"nonce"` // lo que varía el minero
    }
    
    // Hash es el identificador del bloque: doble SHA-256 de la cabecera.
    func (h *Header) Hash() crypto.Hash { return crypto.Hash256(h.Serialize()) }

    Como el formato es idéntico al de Bitcoin, el primer test de este paquete mete en esa estructura los datos reales del bloque génesis de Bitcoin y comprueba que sale su hash real, 000000000019d6….

    Lo que viene

    Todo este capítulo se apoya en una frase que todavía no hemos justificado: que minar un bloque cuesta mucho. ¿Cuánto es “mucho”? ¿Quién lo decide, si no manda nadie? ¿Y qué pasa cuando se apuntan mil mineros más, o se van la mitad? Toca hablar de la prueba de trabajo y de la dificultad.