Wie berechnet man den neuen „Bits“-Wert?

Alle 2016 Blöcke muss man einen neuen Bitwert berechnen. Wie lautet die Formel zur Berechnung?

Fragen Sie, wie die Schwierigkeit berechnet wird oder wie Bits der Schwierigkeit entsprechen? Oder beides?
Ich verstehe, wie man Bits konvertiert -> Schwierigkeit, ich frage, wie die Schwierigkeit angepasst wird. Ich vermute, angesichts des Zeitstempels von Block n und n + 2015 gibt es eine Formel dafür, die auch eine bestimmte Rundung berücksichtigt, um das Bitfeld in einem Block n + 2016 zu feuern.
OK. Ich hoffe, meine Antwort sagt Ihnen, was Sie wissen wollten. Es ist ziemlich lang, aber ich wollte das Format sowie die Details erklären, wie „Bits“ berechnet werden.
Es ist interessant, dass Sie danach fragen, gerade als sich die Regeln ändern werden. Nach dem 15. Februar 2012 wird Testnet nach 20 Minuten erfolgloser Blocksuche einfach.

Antworten (3)

Was stellt das bitsFeld dar?

Zunächst müssen wir verstehen, was das Feld „Bits“ bedeutet.

Bits ist im „kompakten“ Format. Dies ist eine Art Fließkommaformat, aber es repräsentiert große ganze Zahlen und keine willkürlichen reellen Zahlen. Das erste Byte gibt die Anzahl der Bytes an, die die dargestellte Zahl einnimmt, und die nächsten ein bis drei Bytes geben die höchstwertigen Stellen der Zahl an. Wenn das 2. Byte einen Wert größer als 127 hat, wird die Zahl als negativ interpretiert.

Um eine positive Ganzzahl in das 'kompakte' Format zu konvertieren, gehen wir wie folgt vor:

  • Wandle die ganze Zahl in die Basis 256 um.
  • Wenn die erste (höchstwertige) Ziffer größer als 127 (0x7f) ist, stellen Sie eine Nullziffer voran
  • Das erste Byte des „kompakten“ Formats ist die Anzahl der Ziffern in der obigen Basis-256-Darstellung, einschließlich der vorangestellten Null, falls vorhanden
  • die folgenden drei Bytes sind die ersten drei Ziffern der obigen Darstellung. Wenn weniger als drei Ziffern vorhanden sind, sind eines oder mehrere der letzten Bytes der kompakten Darstellung Null.

Beispiel 1 - Konvertieren Sie 1000 in das 'kompakte' Format

Um beispielsweise 1000 im „kompakten“ Format darzustellen, konvertieren wir in die Basis 256:

1000 = (0x03)*256 + (0xe8)*1

Wir haben also eine 2-stellige Basis-256-Nummer:

03 e8

Die erste Ziffer ist nicht größer als 0x7f, also stellen wir keine Nullziffer voran:

03 e8

Dann wird die kompakte Darstellung zu:

02 03 e8 00

Beispiel 2 - Konvertieren Sie das maximale Ziel in das 'kompakte' Format

Die Mindestschwierigkeit hat ein Ziel von 2^(256-32)-1. Lassen Sie uns das im 'kompakten' Format darstellen. Zuerst konvertieren wir es zur Basis 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

Das sind 28 0xff-Ziffern. Die erste Ziffer ist größer als 0x7f, also stellen wir eine Nullziffer voran:

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

Jetzt ist es 29 Ziffern lang. hex(29) = 0x1d. Die "kompakte" Darstellung davon lautet also:

1d 00 ff ff

Beachten Sie, dass wir dort viele 'ff'-Ziffern verloren haben. Wir haben nur 2 Bytes Genauigkeit beibehalten, was mit dem Größenbyte und dem vorangestellten Nullbyte zwei der vier verfügbaren Bytes belegt. Wenn wir vom „kompakten“ Format zurückkonvertieren, um zu sehen, welche Nummer wir tatsächlich gespeichert haben, erhalten wir:

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

Dies ist in der Tat das maximale Ziel, das von Bitcoin verwendet wird. So legt eine Schwierigkeit von 1 das Block-Hash-Ziel fest.

Wie wird der Wert des bitsFeldes berechnet?

Da wir nun wissen, was das bitsFeld bedeutet, können wir uns ansehen, wie sein Wert bestimmt wird. Im offiziellen Client wird der bitsWert durch die Funktion GetNextWorkRequired()in berechnet src/main.cpp, die Folgendes bewirkt:

  • wenn wir an einem Block arbeiten, der ein Vielfaches von 2016 ist (alle 2 Wochen)
    • Sehen Sie sich die Zeitstempel auf dem letzten Block und den Block 2015-Blöcken davor an
    • Berechnen Sie die Differenz dieser beiden Zeitstempel
    • wenn der Unterschied größer als 8 Wochen ist, setzen Sie ihn auf 8 Wochen; dies verhindert, dass die Schwierigkeit um mehr als den Faktor 4 sinkt
    • wenn der Unterschied weniger als eine halbe Woche beträgt, stellen Sie ihn auf eine halbe Woche ein; dies verhindert, dass die Schwierigkeit um mehr als den Faktor 4 ansteigt
    • Multiplizieren Sie die Differenz mit dem aktuellen Ziel (d. h. dem Strom bits, der von der „kompakten“ Darstellung in das Ziel umgewandelt wird, das er darstellt)
    • Teilen Sie das Ergebnis durch 2 Wochen
    • Wenn das Ergebnis größer als das maximale Ziel ( 2^(256-32)-1) ist, setzen Sie es auf das maximale Ziel
    • Konvertieren Sie das Ergebnis in eine 'kompakte' Form und verwenden Sie diese als neuen bitsWert
  • andernfalls (wir arbeiten an einem Block, der KEIN Vielfaches von 2016 ist
    • wenn wir im Testnet sind und es nach dem 15. Februar 2012 ist
      • wenn mehr als 20 Minuten vergangen sind, seit der letzte Block gefunden wurde
        • auf bitsden höchstmöglichen Wert eingestellt, 0x1d00ffff, was eine Schwierigkeit von 1 darstellt; das ist die ' special-min-difficultyregel'
      • Andernfalls
        • auf bitsden gleichen Wert wie im letzten Nichtregelblock special-min-difficultygesetzt
    • andernfalls (wir sind nicht im Testnet oder vor dem 15. Februar 2012)
      • bitswie im letzten Block eingestellt
2^224 ist nicht das, was Sie dargestellt haben, meinten Sie 2^224-1? wolframalpha.com/input/?i=2%5E224+in+hex
Ja, habe ich. Vielen Dank! Ich habe meine Antwort entsprechend korrigiert.
Eine Sache, die hinzugefügt werden muss, ist, dass sich das Ziel nie ändert +- ein Faktor von 4 pro Änderung
@makerofthings7, das von "Wenn der Unterschied größer als 8 Wochen ist, setze ihn auf 8 Wochen" und der folgenden Zeile abgedeckt wird. Ich habe diese Zeilen erweitert, um deutlich zu machen, wofür sie sind.
Vielen Dank und ich sehe jetzt, ich arbeite immer noch an meinen Übersetzungsfähigkeiten von C++ ins Englische ;)

Hier ist der relevante Code aus 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();

Die wichtigen Schritte sind also:

  1. Übersetze die Bits von Block n+2015 in ein BigNum-Ziel.
  2. Berechnen Sie die Zeitspanne zwischen den Blöcken n und n+2015 (als ganzzahlige Anzahl von Sekunden).
  3. Multiplizieren Sie das alte Ziel mit der Zeitspanne.
  4. Teilen Sie das Ergebnis durch die gewünschte Zeitspanne 2 Wochen = 1209600 Sekunden. Dies ist eine ganzzahlige Arithmetik, also wird abgerundet. Das Ergebnis ist das neue Ziel.
  5. Konvertieren Sie das Ziel in Bits.

Der Code für die Klasse CBigNum befindet sich unter bignum.h.

Ich verwende den folgenden Python-Code, um zwischen "Ziel" und "Bits" hin und her zu konvertieren:

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))
Wo ist der Block def bin2int() in Ihrem Code?
@JamesBond Ich habe es gerade hinzugefügt