how to hash block header in c++ I want to hash a block header in C++ but dont know how.
Im just using a test block at the moment, so that I know what the expected outcome is. https://www.blockchain.com/btc/block/669892
I have a function which formats the block header into the hex string of 0000ff3fd90c0dfca35c8738aa92e1c5bdf706ba14eaafbb379206000000000000000000ad66d8cda0330c3af011ba6b7bc705789767c55a72a818685b3e06a0b8b9a2b054e82260b9210d17099976a6
Now, im struggling to properly hash this to the expected 000000000000000000064ec839564cc03166184f0a404d82cad9c655f714d886
static void calcHash(std::string hash){
    CryptoPP::SHA256 hash;
    std::string digest;
    CryptoPP::StringSource(data, true, 
        new CryptoPP::HashFilter(hash, new 
            CryptoPP::HexEncoder(new CryptoPP::StringSink(digest)
    )));
    std::cout &lt;&lt; &quot;digest: &quot; &lt;&lt; digest &lt;&lt; std::endl;

    CryptoPP::SHA256 hash2;
    std::string digest2;
    CryptoPP::StringSource(digest, true, 
        new CryptoPP::HashFilter(hash2, new 
            CryptoPP::HexEncoder(new CryptoPP::StringSink(digest2)
    )));
    std::cout &lt;&lt; &quot;digest2: &quot; &lt;&lt; digest2 &lt;&lt; std::endl;

   return digest2;
}

When I pass that header through this function, i do not get the expected.
How do I get the expected hash from my formatted header using c++?
Firstly, you have a name conflict; hash is both the std::string argument passed to calcHash(), and also the name of your CryptoPP::SHA256 object. This code won't even compile, so are you sure this is the code you're using?
The code itself is somewhat difficult to read, too, because you pass around anonymous objects to nested constructors in an attempt to be concise, but this just makes things needlessly confusing to the reader. Perhaps you have copy-pasted one-liners from other places?
Anyway, here's the approach you should take:

Use HexDecoder (not HexEncoder) to convert your input string (let's call it headerString) to a byte array of the data represented by that hexadecimal string (call the result headerData).

Hash headerData using SHA-256 twice using the CalculateDigest() method of a CryptoPP::SHA256 object, storing the result in a byte array (call it hash2, because we call the first hash hash1).

Use HexEncoder to convert hash2 into a string which is a hexadecimal representation of the hash (call it hashString).


Here's that in code:
#include &lt;iostream&gt;

using namespace std;
using namespace CryptoPP;

static void printHash(std::string headerString) {
    // Convert hex string to byte array
    string headerData;
    HexDecoder decoder = new HexDecoder(new StringSink(headerData));
    decoder.Put((byte*)headerString.data(), headerString.size());
    decoder.MessageEnd();

    // Hash the byte array twice
    SHA256 hasher;

    byte hash1[SHA256::DIGESTSIZE];
    hasher.calculateDigest(hash1, (byte*)headerData.data(), headerData.size());
    
    byte hash2[SHA256::DIGESTSIZE];
    hasher.calculateDigest(hash2, hash1, hash1.length);

    // Convert result to hex string
    string hashString;
    HexEncoder encoder = new HexEncoder(new StringSink(hashString));
    encoder.Put(hash2, sizeof(hash2));
    encoder.MessageEnd();

    // Print the hash
    cout &lt;&lt; asLowerCase(hashString) &lt;&lt; endl;
}