Cada 2016 bloques uno necesita calcular el valor de nuevos bits . ¿Cuál es la fórmula para calcularlo?
bits
representa el campo?En primer lugar, debemos entender qué significa el campo 'bits'.
Bits está en formato 'compacto'. Es como un formato de punto flotante, pero representa números enteros grandes en lugar de números reales arbitrarios. El primer byte indica el número de bytes que ocupa el número representado, y los siguientes uno a tres bytes dan los dígitos más significativos del número. Si el segundo byte tiene un valor superior a 127, el número se interpreta como negativo.
Para convertir un entero positivo a formato 'compacto', hacemos lo siguiente:
Por ejemplo, para representar 1000 en formato 'compacto', convertimos a base 256:
1000 = (0x03)*256 + (0xe8)*1
Entonces tenemos un número de base 256 de 2 dígitos:
03 e8
El primer dígito no es mayor que 0x7f, por lo que no anteponemos un dígito cero:
03 e8
Entonces la representación compacta se convierte en:
02 03 e8 00
La dificultad mínima tiene un objetivo de 2^(256-32)-1. Representemos eso en formato 'compacto'. Primero lo convertimos a base 256:
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Eso es 28 dígitos 0xff. El primer dígito es mayor que 0x7f, por lo que anteponemos un dígito cero:
00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Ahora tiene 29 dígitos. hexadecimal(29) = 0x1d. Así que la representación 'compacta' de esto es:
1d 00 ff ff
Observe que hemos perdido muchos dígitos 'ff' allí. Solo hemos mantenido 2 bytes de precisión, con el byte de tamaño y el byte cero antepuesto usando dos de los cuatro bytes disponibles. Si tuviéramos que volver a convertir desde el formato 'compacto' para ver qué número hemos almacenado realmente, obtendríamos:
ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
que es, de hecho, el objetivo máximo utilizado por Bitcoin. Esto es lo que una dificultad de 1 establece como objetivo de hash de bloque.
bits
¿Cómo se calcula el valor del campo?Ahora que sabemos lo que bits
significa el campo, podemos ver cómo se decide su valor. En el cliente oficial, el bits
valor se calcula mediante la función GetNextWorkRequired()
en src/main.cpp
, que hace lo siguiente:
bits
conversión actual de la representación 'compacta' al objetivo que representa)2^(256-32)-1
), configúrelo en el objetivo máximobits
valorbits
en su valor más alto posible 0x1d00ffff
, lo que representa una dificultad de 1; esta es la ' special-min-difficulty
regla'bits
en el mismo que en el último special-min-difficulty
bloque no reglabits
en el mismo que en el último bloqueAquí está el código relevante de main.cpp:
static const int64 nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
static const int64 nTargetSpacing = 10 * 60;
static const int64 nInterval = nTargetTimespan / nTargetSpacing;
...
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
for (int i = 0; pindexFirst && i < nInterval-1; i++)
pindexFirst = pindexFirst->pprev;
assert(pindexFirst);
// Limit adjustment step
int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
printf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan);
if (nActualTimespan < nTargetTimespan/4)
nActualTimespan = nTargetTimespan/4;
if (nActualTimespan > nTargetTimespan*4)
nActualTimespan = nTargetTimespan*4;
// Retarget
CBigNum bnNew;
bnNew.SetCompact(pindexLast->nBits);
bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;
if (bnNew > bnProofOfWorkLimit)
bnNew = bnProofOfWorkLimit;
...
return bnNew.GetCompact();
Así que los pasos importantes son:
El código de la clase CBigNum está en bignum.h.
utilizo el siguiente código de python para convertir de ida y vuelta entre "objetivo" y "bits":
import binascii
def target_int2bits(target):
# comprehensive explanation here: bitcoin.stackexchange.com/a/2926/2116
# get in base 256 as a hex string
target_hex = int2hex(target)
bits = "00" if (hex2int(target_hex[: 2]) > 127) else ""
bits += target_hex # append
bits = hex2bin(bits)
length = int2bin(len(bits), 1)
# the bits value could be zero (0x00) so make sure it is at least 3 bytes
bits += hex2bin("0000")
# the bits value could be bigger than 3 bytes, so cut it down to size
bits = bits[: 3]
return length + bits
def bits2target_int(bits_bytes):
exp = bin2int(bits_bytes[: 1]) # exponent is the first byte
mult = bin2int(bits_bytes[1:]) # multiplier is all but the first byte
return mult * (2 ** (8 * (exp - 3)))
def int2hex(intval):
hex_str = hex(intval)[2:]
if hex_str[-1] == "L":
hex_str = hex_str[: -1]
if len(hex_str) % 2:
hex_str = "0" + hex_str
return hex_str
def hex2int(hex_str):
return int(hex_str, 16)
def hex2bin(hex_str):
return binascii.a2b_hex(hex_str)
def int2bin(val, pad_length = False):
hexval = int2hex(val)
if pad_length: # specified in bytes
hexval = hexval.zfill(2 * pad_length)
return hex2bin(hexval)
def bin2hex(binary):
# convert raw binary data to a hex string. also accepts ascii chars (0 - 255)
return binascii.b2a_hex(binary)
def bin2int(binary):
return hex2int(bin2hex(binary))
chris moore
elpiachu
chris moore
chris moore