I wanted to convert the following bitcoin mining python code to VB.net (2012) and I tried to convert it's functionality, but it throws some errors and I'm stuck as I even can't get the resulting value of "header" variable.

and the final hash result should be 0000000000000000e067a478024addfecdc93628978aa52d91fabd4292982a50, but I'm no where near that.

why this produces errors, converting from hex to byte is not the correct method?

in python L is used to format it to long right?, so what does the <L & <LLL in the python code do? and is this ::-1 used to prevent overflow when reading the hex string?

and, in exp = bits >> 24 what does it do, bitwise operations?

import hashlib, struct

ver = 2
prev_block = "000000000000000117c80378b8da0e33559b5997f2ad55e2f7d18ec1975b9717"
mrkl_root = "871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a"
time_ = 0x53058b35 # 2014-02-20 04:57:25
bits = 0x19015f53

# https://en.bitcoin.it/wiki/Difficulty
exp = bits >> 24
mant = bits & 0xffffff
target_hexstr = '%064x' % (mant * (1<<(8*(exp - 3))))
target_str = target_hexstr.decode('hex')

nonce = 0
while nonce < 0x100000000:
    header = ( struct.pack("<L", ver) + prev_block.decode('hex')[::-1] +
          mrkl_root.decode('hex')[::-1] + struct.pack("<LLL", time_, bits, nonce))
    hash = hashlib.sha256(hashlib.sha256(header).digest()).digest()
    print nonce, hash[::-1].encode('hex')
    if hash[::-1] < target_str:
        print 'success'
nonce += 1

The VB.NET code I've been coding up until now is,

Public Class Form1
Dim version As Long = 0
Dim time As Integer
Dim pblock As Byte
Dim mklroot As Byte
Dim header As String
Dim nonce As Integer = 856192328

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Textbox1.Text = "2"
    Textbox2.Text = "000000000000000117c80378b8da0e33559b5997f2ad55e2f7d18ec1975b9717"
    Textbox3.Text = "871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a"
    Textbox4.Text = "0x53058b35" '2014-02-20 04:57:25
    Textbox5.Text = "0x19015f53"

    Dim n As Int32 = T2.Text.Length - 1

    version = CLng(Textbox1.Text)
    'pblock = CByte(Textbox2.Text)
    pblock = Convert.ToByte(Convert.ToInt32(Textbox2.Text, 16))
    mklroot = Convert.ToByte(Convert.ToInt32(Textbox3.Text, 16))
    time = CInt(Textbox4.Text)

    header = version & pblock & mklroot & time & nonce
    Textbox6.Text = header

   End Sub
 End Class

Chech this explanation..


TL;DR version

Assuming you came accros this site bitcoin-mining-hard-way-algorithms. I'll show you in C# and you can convert to VB, using the same logic.

Here is the deal: All information in a bitcoin block is hexadecimal. So the header you are formming is compounded by:

var header = $"{ver}{prev_block}{mrkl_root}{timestamp}{bits}{nonce}";

Let's calculate each:

ver = 2

Must be converted to a 8 byte hexadecimal, but afterwards must be reversed. ( when reversing a hex string you reverse the pairs so "00-00-02" become "02-00-00";

A simple function to reverse can be as:

string reverse(string hex)
   char[] reverted = new char[hex.Length];
   for (int i = hex.Length - 1, j = 0; i > 0; i -= 2, j += 2)
       reverted[j] = hex[i - 1];
       reverted[j + 1] = hex[i];
   return new string(reverted);


var ver = 2.ToString("X8"); // Returns a hex representation: 00000002
ver = reverse(ver); //02000000


prev_block = "000000000000000117c80378b8da0e33559b5997f2ad55e2f7d18ec1975b9717"

Its the previous block hash of the chain, and must be reversed too.

var prev_block = reverse("000000000000000117c80378b8da0e33559b5997f2ad55e2f7d18ec1975b9717");

Then, the mrkl_root is calculated from 99 transaction hashes. The resulting Merkle root is (If you don't know MerkleRoot take a look in this repo: diegomary/bitcoin-merkle-root-netcore):

mrkl_root = "871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a"

And again you reverse it:

var mrkl_root = reverse("871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a")

Then the timestamp is a unixtimestamp to the date "2014-02-20 04:57:25", the timestamp value of that date is 1392872245, so you convert to hexadecimal value 53058B35, and REVERSE IT = "358b0553" (I wont put the code but you get the picture, ^^)

var timestamp= "358b0553";// # 2014-02-20 04:57:25

Then the number of bits as you can see here (https://blockchain.info/block-height/286819), is 419520339, convert to hexadecimal and you get 19015F53; And reverse it: 535f0119

var bits = "535f0119";

The nonce is a arbitrary value that you will iterate over until you get the desired final hash, in this examples was a integer value 856192328. You convert to 8 bytes hexadecimal and reverse it.

var nonce = reverse(856192328.ToString("X8"));

And that's it, if you apply the SHA256 two times over this header will give you the desired result:

var header = $"{ver}{prev_block}{mrkl_root}{timestamp}{bits}{nonce}";
byte[] a1 = Enumerable.Range(0, header.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(header.Substring(x, 2), 16))
var c = a1.ToArray();
SHA256 sha256 = SHA256.Create();
byte[] firstHash = sha256.ComputeHash(c);
byte[] hashOfHash = sha256.ComputeHash(firstHash);
Console.WriteLine(BitConverter.ToString(hashOfHash).Replace("-", "").ToLower()); //Output: 0000000000000000e067a478024addfecdc93628978aa52d91fabd4292982a50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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