1

I have two values

1. h = hash of the block (32 bytes long in memory representation - not hex)
2. bits (uint32_t)

To make the calculation easier we create a function difficulty such that:

auto d = difficulty(bits)

Now what is the best way to create such a difficulty function that, I believe should, return a 256 bit value?

Then I am thinking casting both h and d values into an array of type uint64_t and compare all 4 elements from msb (bit 255) to make sure the condition holds.

Is there a better way for comparing as well?

0

2 Answers 2

2

Bitcoin Core has its own arith_uint256 class for calculations on 256-bit unsigned integers. Its code to convert "bits" (so-called compact format) to arith_uint256 can be found in arith_uint256::SetCompact in the file arith_uint256.cpp.

So you could always just use its code directly. This might be a good idea because if your version differs in any way from their behavior (e.g. rounding errors), you could disagree with Bitcoin Core on the validity of a block. If your version is in a widely-used client, this would fork the block chain.

0

I have come up with following version that seems to be working correctly for few test cases I have defined.

First we need a helper function that prints hex value given binary data:

void hexdump(unsigned char *data, int len)
{
    int c = 0;
    while (c < len)
    {
        cout << hex << std::setw(2) << std::setfill('0') << static_cast<int>(data[c++]);
    }
    printf("\n");
}

Now lets define the actual function that takes block.bits and converts it to 256 bit value in memory:

bool convert_bits(uint32_t bits, uint64_t* value, int val_len = 4)
{
    assert(val_len == 4);
    assert(value != NULL);

    if (val_len != 4 || value == NULL)
    {
        return false;
    }

    // if bits =  0x1b0404cb, hex target = 0x0404cb * 2**(8*(0x1b - 3)) 
    uint32_t x = 8 * ((bits >> 24) - 3); // number of zero bits on right
    uint64_t val = bits & 0x00FFFFFF;

    // Number of maximum bits required for val is 24.
    assert(x <= (256 - 24));
    if (x > (256 - 24))
    {
        return false;
    }   

    int startq = (3 - int(x / 64));
    int endq = (3 - int((x + 24) / 64));

    int shift = ((3 + endq) * 64 - x);
    if (startq != endq)
    {
        shift = 64 - shift;
    }

    value[startq] = htobe64(val << shift);
    value[endq] = htobe64(val >> shift);

    return true;
}

Now lets test the above function:

int main()
{
    uint64_t num[4] = { 0, 0, 0, 0 };
    if(convert_bits(0x1b0404cb, num))
    {
        hexdump((unsigned char *)num, sizeof(uint64_t) * 4);
    }
    return 0;
}

This prints: 00000000000404cb000000000000000000000000000000000000000000000000

3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.