<pre><code>def CalcKernelHash(stakeModifier, coinstakeTime, masternodeId):
    stakeModifier = binascii.unhexlify(stakeModifier)
    coinstakeTime = binascii.unhexlify(hex(coinstakeTime)[2:])
    collateral = binascii.unhexlify(&quot;0000000000204AA9D1010000&quot;)
    masternodeId = binascii.unhexlify(masternodeId)
    
    bin_s = stakeModifier[::-1] + coinstakeTime[::-1] + collateral[::1] + masternodeId[::-1]
    print(binascii.hexlify(bin_s))
    return rotate(hashlib.sha256(hashlib.sha256(bin_s).digest()).hexdigest())
</code></pre>

CC BY-SA 4.0
2021-06-01T08:39:53.333Z
that is the thing. How do you correctly serialise a string so that it gets to the same result has the uint256 type in c++? The debug output for stakeModifier is the ToString() version of it.
Chris
CC BY-SA 4.0
2021-06-01T08:43:47.307Z
@Chris Can you give me the full python source code for this example with imports so that I can run it? (Full = code that can run, but not the whole source code of the software. For example I need the code that runs this python code)
MCCCS
CC BY-SA 4.0
2021-06-01T08:57:00.030Z
edited above. All is needed is importing hashlib and binascii
Chris
CC BY-SA 4.0
2021-06-01T08:07:47.060Z
2021-06-01T11:28:42.783Z
2021-06-01T11:28:42.783Z
MCCCS
<p>This is not related to bitcoin but it uses most of the bitcoin codebase. I would like to translate some c++ code into python but struggle really hard to get the hashes right.</p>
<p>This is the function I try go get. Hash is doing a double sha256</p>
<pre><code>uint256 CalcKernelHash(const uint256&amp; stakeModifier, int64_t height, int64_t coinstakeTime, const uint256&amp; masternodeID, const Consensus::Params&amp; params) {
        // Calculate hash
        CDataStream ss(SER_GETHASH, 0);
        ss &lt;&lt; stakeModifier &lt;&lt; coinstakeTime &lt;&lt; GetMnCollateralAmount(int(height)) &lt;&lt; masternodeID;
        std::cout &lt;&lt; &quot;\n--------------------------------\n&quot;;
        std::cout &lt;&lt; &quot;DEBUG[&quot; &lt;&lt; coinstakeTime &lt;&lt; &quot;] collateral: &quot; &lt;&lt; GetMnCollateralAmount(int(height)) &lt;&lt; &quot;\n&quot;;
        std::cout &lt;&lt; &quot;DEBUG[&quot; &lt;&lt; coinstakeTime &lt;&lt; &quot;] ss: &quot; &lt;&lt; stakeModifier.ToString() &lt;&lt; coinstakeTime &lt;&lt; GetMnCollateralAmount(int(height)) &lt;&lt; masternodeID.ToString() &lt;&lt; &quot;\n&quot;;
        std::cout &lt;&lt; &quot;DEBUG[&quot; &lt;&lt; coinstakeTime &lt;&lt; &quot;] HASH: &quot; &lt;&lt; Hash(ss.begin(), ss.end()).ToString() &lt;&lt; &quot;\n&quot;;
        return Hash(ss.begin(), ss.end());
    }
</code></pre>
<p>And here it is called</p>
<pre><code>const auto hashProofOfStake = UintToArith256(CalcKernelHash(stakeModifier, height, coinstakeTime, masternodeID, params));
    
std::cout &lt;&lt; &quot;DEBUG[&quot; &lt;&lt; coinstakeTime &lt;&lt; &quot;] coinstakeTime: &quot; &lt;&lt; coinstakeTime &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;DEBUG[&quot; &lt;&lt; coinstakeTime &lt;&lt; &quot;] nbits: &quot; &lt;&lt; nBits &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;DEBUG[&quot; &lt;&lt; coinstakeTime &lt;&lt; &quot;] hashProofOfStake: &quot; &lt;&lt; hashProofOfStake.ToString() &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;DEBUG[&quot; &lt;&lt; coinstakeTime &lt;&lt; &quot;] stakeModifier: &quot; &lt;&lt; stakeModifier.ToString() &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;DEBUG[&quot; &lt;&lt; coinstakeTime &lt;&lt; &quot;] masternodeId: &quot; &lt;&lt; masternodeID.ToString() &lt;&lt; &quot;\n&quot;;
</code></pre>
<p>I have added some debug statement to check the output and have a reference</p>
<pre><code>--------------------------------
DEBUG[1622528110] collateral: 2000000000000
DEBUG[1622528110] ss: f541f372005beeb8952f964ea638527341c3b3a6eebb0c0309e4f092bd6c1b0e16225281102000000000000e2cfe3f576da4999ea2268224f34efdd3b0d567841d561b41b3ab67976c977d1
DEBUG[1622528110] HASH: e4b0d1b01a99d00e44d41eeb37c81d19940bf71270994fff53ea5caa1c79f663
DEBUG[1622528110] coinstakeTime: 1622528110
DEBUG[1622528110] nbits: 419654358
DEBUG[1622528110] hashProofOfStake: e4b0d1b01a99d00e44d41eeb37c81d19940bf71270994fff53ea5caa1c79f663
DEBUG[1622528110] stakeModifier: f541f372005beeb8952f964ea638527341c3b3a6eebb0c0309e4f092bd6c1b0e
DEBUG[1622528110] masternodeId: e2cfe3f576da4999ea2268224f34efdd3b0d567841d561b41b3ab67976c977d1
</code></pre>
<p>This is my trial in python</p>
<pre><code>import binascii
import hashlib

def rotate(x):
    s2 = bytearray.fromhex(x)
    s2.reverse()
    return binascii.hexlify(s2).decode()

def padhexa(s):
    return s[2:].zfill(16)

def CalcKernelHash(stakeModifier, coinstakeTime, masternodeId):
    stakeModifier = binascii.unhexlify(stakeModifier)
    coinstakeTime = binascii.unhexlify(&quot;%x&quot; % coinstakeTime)
    collateral = binascii.unhexlify(&quot;0%x&quot; % 2000000000000)
    masternodeId = binascii.unhexlify(masternodeId)
    
    bin_s = stakeModifier[::-1] + coinstakeTime[::-1] + collateral[::-1] + masternodeId[::1]
    print(bin_s)
    return rotate(hashlib.sha256(hashlib.sha256(bin_s).digest()).hexdigest())



CalcKernelHash('f541f372005beeb8952f964ea638527341c3b3a6eebb0c0309e4f092bd6c1b0e', 1622528110, 'e2cfe3f576da4999ea2268224f34efdd3b0d567841d561b41b3ab67976c977d1')
</code></pre>
<p>When I execute with the parameter from the debug output I get</p>
<pre><code>CalcKernelHash('f541f372005beeb8952f964ea638527341c3b3a6eebb0c0309e4f092bd6c1b0e', 1622528110, 'e2cfe3f576da4999ea2268224f34efdd3b0d567841d561b41b3ab67976c977d1')

'f01ba34ac7a897a1e37d61bac3a8ea6f0126c2ae883a2d75dab1f407d40aad0b'
</code></pre>
<p>Where I should get <code>hashProofOfStake e4b0d1b01a99d00e44d41eeb37c81d19940bf71270994fff53ea5caa1c79f663</code></p>
<p>EDIT:</p>
<p>bin_s returns <code>b'\x0e\x1bl\xbd\x92\xf0\xe4\t\x03\x0c\xbb\xee\xa6\xb3\xc3AsR8\xa6N\x96/\x95\xb8\xee[\x00r\xf3A\xf5n\xd0\xb5`\x00 J\xa9\xd1\x01\xe2\xcf\xe3\xf5v\xdaI\x99\xea&quot;h&quot;O4\xef\xdd;\rVxA\xd5a\xb4\x1b:\xb6yv\xc9w\xd1'</code></p>
<p>EDIT2:</p>
<p>Hash definition</p>
<pre><code>/** Compute the 256-bit hash of an object. */
template&lt;typename T1&gt;
inline uint256 Hash(const T1 pbegin, const T1 pend)
{
    static const unsigned char pblank[1] = {};
    uint256 result;
    CHash256().Write(pbegin == pend ? pblank : (const unsigned char*)&amp;pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
              .Finalize((unsigned char*)&amp;result);
    return result;
}
</code></pre>

CC BY-SA 4.0
2021-06-01T07:29:33.633Z
Can you print `bin_s` in python? The best way to debug hash mismatches is to print full data-to-be-hashes (called preimage)
MCCCS
CC BY-SA 4.0
2021-06-01T07:31:03.383Z
modified the answer
Chris
CC BY-SA 4.0
2021-06-01T09:54:49.100Z
Hello I almost solved this but one problem: `2000000000000` the collateral value, presumable a byte array in hex, is of odd length????
MCCCS
CC BY-SA 4.0
2021-06-01T10:01:54.217Z
I think it is the case that the preimage is not printed properly. Can you add `for (auto i: ss) std::cout << std::hex << i;` as a one-line debugging statement before hash calculation, and add its output here?
MCCCS
CC BY-SA 4.0
2021-06-01T10:09:22.607Z
It only outputs garbage ```%�!�c#b"~�|~�tW``` added also the Hash definition
Chris
CC BY-SA 4.0
2021-06-01T10:15:49.327Z
Ok, can you try printing `ss.str()`?
MCCCS
CC BY-SA 4.0
2021-06-01T10:19:32.040Z
similar garbage output.
Chris
CC BY-SA 4.0
2021-06-01T10:23:39.287Z
Can you post GetMnCollateralAmount?
MCCCS
CC BY-SA 4.0
2021-06-01T10:31:34.277Z
Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/124940/discussion-between-chris-and-mcccs).
Chris
<python><sha256><c++>
Translate c++ function into python: sha256 hash mismatch
Chris
# Translate c++ function into python: sha256 hash mismatch

(Asked by: username_0 on 2021-06-01)

This is not related to bitcoin but it uses most of the bitcoin codebase. I would like to translate some c++ code into python but struggle really hard to get the hashes right.

This is the function I try go get. Hash is doing a double sha256

```
uint256 CalcKernelHash(const uint256& stakeModifier, int64_t height, int64_t coinstakeTime, const uint256& masternodeID, const Consensus::Params& params) {
        // Calculate hash
        CDataStream ss(SER_GETHASH, 0);
        ss << stakeModifier << coinstakeTime << GetMnCollateralAmount(int(height)) << masternodeID;
        std::cout << "\n--------------------------------\n";
        std::cout << "DEBUG[" << coinstakeTime << "] collateral: " << GetMnCollateralAmount(int(height)) << "\n";
        std::cout << "DEBUG[" << coinstakeTime << "] ss: " << stakeModifier.ToString() << coinstakeTime << GetMnCollateralAmount(int(height)) << masternodeID.ToString() << "\n";
        std::cout << "DEBUG[" << coinstakeTime << "] HASH: " << Hash(ss.begin(), ss.end()).ToString() << "\n";
        return Hash(ss.begin(), ss.end());
    }

```

And here it is called

```
const auto hashProofOfStake = UintToArith256(CalcKernelHash(stakeModifier, height, coinstakeTime, masternodeID, params));
    
std::cout << "DEBUG[" << coinstakeTime << "] coinstakeTime: " << coinstakeTime << "\n";
std::cout << "DEBUG[" << coinstakeTime << "] nbits: " << nBits << "\n";
std::cout << "DEBUG[" << coinstakeTime << "] hashProofOfStake: " << hashProofOfStake.ToString() << "\n";
std::cout << "DEBUG[" << coinstakeTime << "] stakeModifier: " << stakeModifier.ToString() << "\n";
std::cout << "DEBUG[" << coinstakeTime << "] masternodeId: " << masternodeID.ToString() << "\n";

```

I have added some debug statement to check the output and have a reference

```
--------------------------------
DEBUG[1622528110] collateral: 2000000000000
DEBUG[1622528110] ss: f541f372005beeb8952f964ea638527341c3b3a6eebb0c0309e4f092bd6c1b0e16225281102000000000000e2cfe3f576da4999ea2268224f34efdd3b0d567841d561b41b3ab67976c977d1
DEBUG[1622528110] HASH: e4b0d1b01a99d00e44d41eeb37c81d19940bf71270994fff53ea5caa1c79f663
DEBUG[1622528110] coinstakeTime: 1622528110
DEBUG[1622528110] nbits: 419654358
DEBUG[1622528110] hashProofOfStake: e4b0d1b01a99d00e44d41eeb37c81d19940bf71270994fff53ea5caa1c79f663
DEBUG[1622528110] stakeModifier: f541f372005beeb8952f964ea638527341c3b3a6eebb0c0309e4f092bd6c1b0e
DEBUG[1622528110] masternodeId: e2cfe3f576da4999ea2268224f34efdd3b0d567841d561b41b3ab67976c977d1

```

This is my trial in python

```
import binascii
import hashlib

def rotate(x):
    s2 = bytearray.fromhex(x)
    s2.reverse()
    return binascii.hexlify(s2).decode()

def padhexa(s):
    return s[2:].zfill(16)

def CalcKernelHash(stakeModifier, coinstakeTime, masternodeId):
    stakeModifier = binascii.unhexlify(stakeModifier)
    coinstakeTime = binascii.unhexlify("%x" % coinstakeTime)
    collateral = binascii.unhexlify("0%x" % 2000000000000)
    masternodeId = binascii.unhexlify(masternodeId)
    
    bin_s = stakeModifier[::-1] + coinstakeTime[::-1] + collateral[::-1] + masternodeId[::1]
    print(bin_s)
    return rotate(hashlib.sha256(hashlib.sha256(bin_s).digest()).hexdigest())

CalcKernelHash('f541f372005beeb8952f964ea638527341c3b3a6eebb0c0309e4f092bd6c1b0e', 1622528110, 'e2cfe3f576da4999ea2268224f34efdd3b0d567841d561b41b3ab67976c977d1')

```

When I execute with the parameter from the debug output I get

```
CalcKernelHash('f541f372005beeb8952f964ea638527341c3b3a6eebb0c0309e4f092bd6c1b0e', 1622528110, 'e2cfe3f576da4999ea2268224f34efdd3b0d567841d561b41b3ab67976c977d1')

'f01ba34ac7a897a1e37d61bac3a8ea6f0126c2ae883a2d75dab1f407d40aad0b'

```

Where I should get `hashProofOfStake e4b0d1b01a99d00e44d41eeb37c81d19940bf71270994fff53ea5caa1c79f663`

EDIT:

bin\_s returns `b'\x0e\x1bl\xbd\x92\xf0\xe4\t\x03\x0c\xbb\xee\xa6\xb3\xc3AsR8\xa6N\x96/\x95\xb8\xee[\x00r\xf3A\xf5n\xd0\xb5`\x00 J\xa9\xd1\x01\xe2\xcf\xe3\xf5v\xdaI\x99\xea"h"O4\xef\xdd;\rVxA\xd5a\xb4\x1b:\xb6yv\xc9w\xd1'`

EDIT2:

Hash definition

```
/** Compute the 256-bit hash of an object. */
template<typename T1>
inline uint256 Hash(const T1 pbegin, const T1 pend)
{
    static const unsigned char pblank[1] = {};
    uint256 result;
    CHash256().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
              .Finalize((unsigned char*)&result);
    return result;
}

```

**Tags:** python, sha256, c++

> **Comments:**
> **username_1**: Can you print `bin_s` in python? The best way to debug hash mismatches is to print full data-to-be-hashes (called preimage)  
> **username_0**: modified the answer  
> **username_1**: Hello I almost solved this but one problem: `2000000000000` the collateral value, presumable a byte array in hex, is of odd length????  
> **username_1**: I think it is the case that the preimage is not printed properly. Can you add `for (auto i: ss) std::cout << std::hex << i;` as a one-line debugging statement before hash calculation, and add its output here?  
> **username_0**: It only outputs garbage ```%�!�c#b"~�|~�tW``` added also the Hash definition  
> **username_1**: Ok, can you try printing `ss.str()`?  
> **username_0**: similar garbage output.  
> **username_1**: Can you post GetMnCollateralAmount?  
> **username_0**: Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/124940/discussion-between-username_0-and-username_1).  

---

## 1 answers

### Answer by username_1 on 2021-06-01. Score: 1 | Accepted answer

```
def CalcKernelHash(stakeModifier, coinstakeTime, masternodeId):
    stakeModifier = binascii.unhexlify(stakeModifier)
    coinstakeTime = binascii.unhexlify(hex(coinstakeTime)[2:])
    collateral = binascii.unhexlify("0000000000204AA9D1010000")
    masternodeId = binascii.unhexlify(masternodeId)
    
    bin_s = stakeModifier[::-1] + coinstakeTime[::-1] + collateral[::1] + masternodeId[::-1]
    print(binascii.hexlify(bin_s))
    return rotate(hashlib.sha256(hashlib.sha256(bin_s).digest()).hexdigest())

```

> **Comments:**
> **username_0**: that is the thing. How do you correctly serialise a string so that it gets to the same result has the uint256 type in c++? The debug output for stakeModifier is the ToString() version of it.  
> **username_1**: @username_0 Can you give me the full python source code for this example with imports so that I can run it? (Full = code that can run, but not the whole source code of the software. For example I need the code that runs this python code)  
> **username_0**: edited above. All is needed is importing hashlib and binascii  

---

