bits
представляет поле?Прежде всего, нам нужно понять, что означает поле «биты».
Биты в «компактном» формате. Это похоже на формат с плавающей запятой, но он представляет большие целые числа, а не произвольные действительные числа. Первый байт указывает количество байтов, которое занимает представленное число, а следующие от одного до трех байтов дают старшие значащие цифры числа. Если 2-й байт имеет значение больше 127, то число интерпретируется как отрицательное.
Чтобы преобразовать положительное целое число в «компактный» формат, мы:
Например, чтобы представить 1000 в «компактном» формате, мы конвертируем в основание 256:
1000 = (0x03)*256 + (0xe8)*1
Итак, у нас есть двухзначный номер с основанием 256:
03 e8
Первая цифра не больше 0x7f, поэтому мы не добавляем нулевую цифру:
03 e8
Тогда компактное представление принимает вид:
02 03 e8 00
Минимальная сложность имеет цель 2^(256-32)-1. Представим это в «компактном» формате. Сначала мы преобразуем его в основание 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
Это 28 цифр 0xff. Первая цифра больше 0x7f, поэтому мы добавляем нулевую цифру:
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
Теперь это 29 цифр. шестнадцатеричный (29) = 0x1d. Таким образом, «компактное» представление этого:
1d 00 ff ff
Обратите внимание, что мы потеряли много цифр 'ff'. Мы сохранили только 2 байта точности, что с байтом размера и добавленным нулевым байтом, использующим два из четырех доступных байтов. Если бы нам нужно было преобразовать обратно из «компактного» формата, чтобы увидеть, какое число мы фактически сохранили, мы получим:
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
что на самом деле является максимальной целью, используемой Биткойном. Это то, что сложность 1 устанавливает цель хэша блока.
bits
рассчитывается значение поля?Теперь, когда мы знаем, что bits
означает поле, мы можем посмотреть, как определяется его значение. В официальном клиенте bits
значение вычисляется функцией GetNextWorkRequired()
в src/main.cpp
, которая делает следующее:
bits
преобразованный из «компактного» представления в цель, которую он представляет)2^(256-32)-1
), установите его на максимальное целевое значениеbits
значениеbits
максимально возможное значение 0x1d00ffff
, что соответствует сложности 1; это " special-min-difficulty
правило"bits
так же, как и в последнем special-min-difficulty
блоке без правилbits
так же, как в последнем блокеВот соответствующий код из 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();
Итак, важные шаги:
Код класса CBigNum находится в bignum.h.
я использую следующий код Python для преобразования туда и обратно между «целью» и «битами»:
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))
Крис Мур
Пиачу
Крис Мур
Крис Мур