¿Cómo se realiza la codificación de extraNonce en el bloque génesis?

Puedes ver aquí la base de monedas del bloque génesis

txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));

Desglosado en hexadecimal se ve así

Tamaño de nBits como variante

0x04

nBits mismos

0xffff001d

Mensaje de Satoshi en HEX

0x5468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73

Y entre los nBits y el mensaje de Satoshi tenemos estos tres bytes que deberían ser los extraNonce

0x010445

Que corresponden al código CBigNum(4), ya que 4 es un número entero, son 4 bytes, si esto se codificó como una variante, su valor es < 253, por lo que habría tomado solo 1 byte, pero como puede ver, hay tres bytes. Al preguntar a los desarrolladores de bitcoin en IRC, me dijeron que se debe a que la biblioteca BigNum codifica los bits de manera diferente.

Empecé a hurgar en el código fuente de Bitcoin, específicamente en el contenedor Bignum, encontré muchos constructores y operadores sobrecargados, pero finalmente no pude encontrar cómo se calculan y devuelven estos tres bytes debido a mi poca experiencia con C++.

Sin embargo, creo que es esta función

void setulong(unsigned long n)
{
    if (!BN_set_word(this, n))
        throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
}

Sin embargo, todavía no devuelve estos bytes. Entonces, mi pregunta es, ¿cómo se codifica el número entero 4 que aún debe estar 0x04en hexadecimal para que sea esta secuencia de bytes 0x010445(big-endian) para que pueda hacerlo en C?

Respuestas (1)

Parece que estás malinterpretando el código.

CBigNum es solo una clase que almacena números. CBigNum(4)simplemente almacena el número 4 y CBigNum(SHA256(block))almacenaría el hash de un bloque como un número (después de todo, SHA256 nos da números). CBigNumhace lo que dice: almacena un gran número. Como tiene una función que exporta el número como big endian, es útil aquí, y la fuente de Bitcoin a menudo la usará para concatenar números en un flujo de datos.

Echemos un vistazo rápido al script del bloque de génesis, sin mirar el código. Abra la página wiki correspondiente: Script

04FFFF001D0104455468652054696D65732030332F4A616E2F32303039204368616E63656C6C6F72206F6E206272696E6B206F66207365636F6E64206261696C6F757420666F722062616E6B73

Parte de esto se puede interpretar como:

04 -> PUSH 4  bytes (FFFF001D)
01 -> PUSH 1  byte  (04)
45 -> PUSH 69 bytes (The Times 03/Jan/2009 Chancellor on brink of second bailout for banks)
Gracias. Sin embargo, debe comprender que el código apenas está documentado en el interior. El protocolo está bien documentado en su mayoría, pero el código no tanto. Se dice que CBigNum es un contenedor para ser un contenedor C++ para BigNum y nada más. No podría haber sabido lo que hace.
Ni siquiera he mirado ese código, exactamente por esta razón. La respuesta que te di se basa únicamente en la información que encontré en la wiki.