<p>Firstly, you have a name conflict; <code>hash</code> is both the <code>std::string</code> argument passed to <code>calcHash()</code>, and also the name of your <code>CryptoPP::SHA256</code> object. This code won't even compile, so are you sure this is the code you're using?</p>
<p>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?</p>
<p>Anyway, here's the approach you should take:</p>
<ol>
<li><p>Use <code>HexDecoder</code> (not <code>HexEncoder</code>) to convert your input string (let's call it <code>headerString</code>) to a byte array of the data represented by that hexadecimal string (call the result <code>headerData</code>).</p>
</li>
<li><p>Hash <code>headerData</code> using SHA-256 twice using the <code>CalculateDigest()</code> method of a <code>CryptoPP::SHA256</code> object, storing the result in a byte array (call it <code>hash2</code>, because we call the first hash <code>hash1</code>).</p>
</li>
<li><p>Use <code>HexEncoder</code> to convert <code>hash2</code> into a string which is a hexadecimal representation of the hash (call it <code>hashString</code>).</p>
</li>
</ol>
<p>Here's that in code:</p>
<pre><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;
}
</code></pre>

CC BY-SA 4.0
2021-02-11T21:53:30.427Z
Thank you very much Jivan!! As a C++ newby, this has put to rest my couple days of trial and error! I have tried this, edited to fit, and it works as expected!!
Martin Bradley
CC BY-SA 4.0
2021-02-11T21:38:20.803Z
2021-02-12T13:26:32.370Z
2021-02-12T13:26:32.370Z
Jivan Pal
<p>I want to hash a block header in C++ but dont know how.</p>
<p>Im just using a test block at the moment, so that I know what the expected outcome is. <a href="https://www.blockchain.com/btc/block/669892" rel="nofollow noreferrer">https://www.blockchain.com/btc/block/669892</a></p>
<p>I have a function which formats the block header into the hex string of <code>0000ff3fd90c0dfca35c8738aa92e1c5bdf706ba14eaafbb379206000000000000000000ad66d8cda0330c3af011ba6b7bc705789767c55a72a818685b3e06a0b8b9a2b054e82260b9210d17099976a6</code></p>
<p>Now, im struggling to properly hash this to the expected <code>000000000000000000064ec839564cc03166184f0a404d82cad9c655f714d886</code></p>
<pre class="lang-cpp prettyprint-override"><code>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;
}
</code></pre>
<p>When I pass that header through this function, i do not get the expected.</p>
<p>How do I get the expected hash from my formatted header using c++?</p>

CC BY-SA 4.0
2021-02-11T17:52:22.130Z
The hash ending `d886` isn't the hash of the header, it's the hash of the whole block.
Jivan Pal
CC BY-SA 4.0
2021-02-11T18:12:37.187Z
Then I must be at a misunderstanding, I thought you calculate the header hash to compare with the target. Am I wrong?
Martin Bradley
CC BY-SA 4.0
2021-02-11T18:15:50.427Z
Apologies, yes, it is just the hash of the header, but historically it was the hash of the whole block. Nowadays, the header is tied to the transaction set via its Merkle root.
Jivan Pal
CC BY-SA 4.0
2021-02-11T18:25:09.910Z
To clarify, you are trying to compute the hash of the header of BTC block 669892, and you have computed that the binary/hex representation of that header is `0000ff3fd...`?
Jivan Pal
CC BY-SA 4.0
2021-02-11T20:57:31.000Z
Is the result you're getting? `86d814f755c6d9ca824d400a4f186631c04c5639c84e06000000000000000000`
Jivan Pal
CC BY-SA 4.0
2021-02-11T21:18:55.400Z
Yes, I am trying to has the header of the block which I have computed as `0000ff3fd...`. If I use this website https://anyhash.com/sha256, and enable 'hex', I can get the hash you mentioned after doing it twice, but I cant seem to replicate that in C++.
Martin Bradley
<hash><block-header><c++>
how to hash block header in c++
Martin Bradley
# how to hash block header in c++

(Asked by: username_0 on 2021-02-11)

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 << "digest: " << digest << 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 << "digest2: " << digest2 << 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++?

**Tags:** hash, block-header, c++

> **Comments:**
> **username_1**: The hash ending `d886` isn't the hash of the header, it's the hash of the whole block.  
> **username_0**: Then I must be at a misunderstanding, I thought you calculate the header hash to compare with the target. Am I wrong?  
> **username_1**: Apologies, yes, it is just the hash of the header, but historically it was the hash of the whole block. Nowadays, the header is tied to the transaction set via its Merkle root.  
> **username_1**: To clarify, you are trying to compute the hash of the header of BTC block 669892, and you have computed that the binary/hex representation of that header is `0000ff3fd...`?  
> **username_1**: Is the result you're getting? `86d814f755c6d9ca824d400a4f186631c04c5639c84e06000000000000000000`  
> **username_0**: Yes, I am trying to has the header of the block which I have computed as `0000ff3fd...`. If I use this website https://anyhash.com/sha256, and enable 'hex', I can get the hash you mentioned after doing it twice, but I cant seem to replicate that in C++.  

---

## 1 answers

### Answer by username_1 on 2021-02-11. Score: 1 | Accepted answer

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 

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 << asLowerCase(hashString) << endl;
}

> **Comments:**
> **username_0**: Thank you very much Jivan!! As a C++ newby, this has put to rest my couple days of trial and error! I have tried this, edited to fit, and it works as expected!!  

---

