Author

Topic: Block hash code in c# (Read 1062 times)

hero member
Activity: 765
Merit: 503
December 09, 2014, 07:37:09 PM
#1
I just ported the code on https://en.bitcoin.it/wiki/Block_hashing_algorithm to c#.  Not sure if anyone on here can add it to the wiki, or perhaps in that new informational site that was socialzed on here.

Code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace BlockHash
{
    class Program
    {
        static void Main(string[] args)
        {
            //Block 125552
            //https://en.bitcoin.it/wiki/Block_hashing_algorithm

            Debug.Assert(BitConverter.IsLittleEndian == true);

            Byte[] version = BitConverter.GetBytes(1);
            Byte[] prevBlockHash = SwapOrder(StringToByteArray("00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81"));
            Byte[] rootHash = SwapOrder(StringToByteArray("2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3"));

           
            Byte[] time = BitConverter.GetBytes(1305998791);
            Byte[] bits = BitConverter.GetBytes(440711666);
            Byte[] nonce = BitConverter.GetBytes(2504433986);

            //Check byte lengths
            Debug.Assert(version.Length == 4);
            Debug.Assert(time.Length == 4);
            Debug.Assert(bits.Length == 4);
            Debug.Assert(nonce.Length == 4);

            Debug.Assert(prevBlockHash.Length == 32);
            Debug.Assert(rootHash.Length == 32);

            //concat it all
            Byte[] hex_header = new Byte[80];
            version.CopyTo(hex_header, 0);
            prevBlockHash.CopyTo(hex_header, 4);
            rootHash.CopyTo(hex_header, 36);
            time.CopyTo(hex_header, 68);
            bits.CopyTo(hex_header, 72);
            nonce.CopyTo(hex_header, 76);

            using (SHA256Managed SHAhash = new SHA256Managed())
            {
                Byte[] pass1 = SHAhash.ComputeHash(hex_header);
                Byte[] pass2 = SHAhash.ComputeHash(pass1);

                Byte[] final = SwapOrder(pass2);

                // Create a new Stringbuilder to collect the bytes
                // and create a string.
                StringBuilder stringBuilder = new StringBuilder();

                // Loop through each byte of the hashed data 
                // and format each one as a hexadecimal string.
                for (int ii = 0; ii < final.Length; ii++)
                {
                    stringBuilder.Append(final[ii].ToString("x2"));
                }

                // Return the hexadecimal string.
                Console.WriteLine(stringBuilder.ToString());

                //http://blockexplorer.com/block/00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d
                Debug.Assert(stringBuilder.ToString() == "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d");
            }

            Console.ReadKey();
        }

        public static byte[] StringToByteArray(string hex)
        {
            return Enumerable.Range(0, hex.Length)
                             .Where(x => x % 2 == 0)
                             .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                             .ToArray();
        }

        public static Byte[] SwapOrder(Byte[] input)
        {
            return input.Reverse().ToArray();
        }
    }
}

Block used was 125552 http://blockexplorer.com/block/00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d
Jump to: