Post
Topic
Board Bitcoin Technical Support
Re: [overview] Recover Bitcoin from any old storage format
by
JBRai
on 02/02/2020, 23:46:57 UTC
Hi All

in the following script where do input the private key with the missing characters? is it Bitcoin Public Key?

Using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Security.Cryptography;
using System.Text;


namespace CommonLibrary
{
    ///
    /// https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses
    ///

    public class BitcoinConversions
    {
        ///
        /// Satohi is the smallest amount of bitcoin, 10^-8
        ///

        public const decimal Satoshi = 0.00000001m;


        ///
        /// Characters used in Base58Encoding which is all chars excluding "0OIl"
        ///

        private const string Base58Chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";




        ///
        /// Converts a hex string to intiger.
        ///

        /// hex value to convert.
        ///
        //public static UInt32 HexToInt(string hex)
        //{
        //    byte[] ba = HexToByteArray(hex);
        //    if (!BitConverter.IsLittleEndian)
        //    {
        //        ba = ba.Reverse().ToArray();
        //    }
        //    // Prevent out of range exception by adding zeros.
        //    if (ba.Length < 4)
        //    {
        //        ba = ba.Concat(new byte[4 - ba.Length]).ToArray();
        //    }
        //    return BitConverter.ToUInt32(ba, 0);
        //}




        ///
        /// Converts a hex string to bye array.
        ///

        /// hex to convert.
        /// byte array of hex
        public static byte[] HexToByteArray(string hex)
        {
            int NumberChars = hex.Length;
            byte[] bytes = new byte[NumberChars / 2];
            for (int i = 0; i < NumberChars; i += 2)
                bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
            return bytes;
        }


        ///
        /// Converts a byte array to hex string.
        ///

        /// byte array to convert.
        ///
        public static string ByteArrayToHex(byte[] b)
        {
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < b.Length; i++)
            {
                result.Append(b.ToString("x2"));
            }
            return result.ToString();
        }




        ///
        /// Converts the Hash160 (RIPEMD-160) to Base58 encoded string.
        ///

        /// Hash160 string value.
        /// Base58 Encoded result.
        public static string Base58ToHash160(string data)
        {
            // Decode Base58 string to BigInteger
            BigInteger intData = 0;
            for (var i = 0; i < data.Length; i++)
            {
                intData = intData * 58 + Base58Chars.IndexOf(data);
            }


            // Encode BigInteger to byte[]
            // Leading zero bytes get encoded as leading `1` characters
            var bData = intData.ToByteArray();
            if (BitConverter.IsLittleEndian)
            {
                bData = bData.Reverse().ToArray();
            }
            bData = bData.SkipWhile(b => b == 0).ToArray();
            var hash160 = BitConverter.ToString(bData).Replace("-", "").ToLower();
            // Remove checksum (4 bytes = 8 last chars)
            return hash160.Remove(hash160.Length - Cool;
        }




        ///
        /// Computes the hash value of the specified byte array.
        ///

        /// byte array to compute hash of.
        ///
        private static byte[] DoubleShaByte(byte[] b)
        {
            using (SHA256 sha = new SHA256Managed())
            {
                byte[] hash1 = sha.ComputeHash(b);
                byte[] hash2 = sha.ComputeHash(hash1);


                return hash2;
            }
        }


        ///
        /// Returns Transaction Id for the given Raw Transaction hex.
        ///

        /// Raw Transaction hex.
        /// Transaction Id
        public static string GetTxId(string txHex)
        {
            byte[] ba = HexToByteArray(txHex);
            byte[] sha2x = DoubleShaByte(ba);


            return ByteArrayToHex(sha2x.Reverse().ToArray());
        }




        ///
        /// Converts Public Key to Hash160 (RIPEMD-160)
        /// A.K.A. payload
        ///

        /// Bitcoin Public Key
        /// hash160 (RIPEMD-160)
        public static byte[] PubKeyToHash160(string pubKey)
        {
            using (SHA256 sha = new SHA256Managed())
            {
                byte[] pubKeyBytes = HexToByteArray(pubKey);


                // 2. Perform Sha256 hashing on public key
                byte[] hash1 = sha.ComputeHash(pubKeyBytes);


                // 3. Perform RIPEMD-160 hashing on step 2
                using (RIPEMD160 r160 = new RIPEMD160Managed())
                {
                    byte[] hash2 = r160.ComputeHash(hash1);


                    return hash2;
                }
            }
        }


        ///
        /// Converts Hash160 (RIPEMD-160) to Base58 bitcoin Address.
        ///

        /// Hash160 (RIPEMD-160) bytes
        /// Base58 encoded bytes
        public static string Hash160ToBase58(byte[] hash160)
        {
            // 4. Add version byte in front of RIPEMD-160 hash (0x00 for Main Network)
            byte[] ver = { 0x00 };
            byte[] hash160Extended = ver.Concat(hash160).ToArray();


            // 5&6. Perform SHA-256 hash on the extended RIPEMD-160 result x2
            byte[] sha2x = DoubleShaByte(hash160Extended);


            // 7. The first 4 bytes are address checksum
            byte[] checkSumByte = new byte[4];
            checkSumByte[0] = sha2x[0];
            checkSumByte[1] = sha2x[1];
            checkSumByte[2] = sha2x[2];
            checkSumByte[3] = sha2x[3];


            // 8. 25-byte binary Bitcoin Address = RIPEMD-160 extended + Checksum
            byte[] hash160WithCheckSum = hash160Extended.Concat(checkSumByte).ToArray();


            return Hash160WithCheckSumToBase58(hash160WithCheckSum);
        }
        public static string Hash160ToBase58(string hash160)
        {
            byte[] hash160Bytes = HexToByteArray(hash160);
            return Hash160ToBase58(hash160Bytes);
        }


        ///
        /// Converts hash to Base58 Encoded string.
        ///

        /// 1-byte_version + hash_or_other_data + 4-byte_check_code
        /// Base58 encoded result
        public static string Hash160WithCheckSumToBase58(byte[] hash)
        {
            // Decode byte[] to BigInteger
            BigInteger intData = hash.Aggregate(0, (current, t) => current * 256 + t);


            // Encode BigInteger to Base58 string
            StringBuilder result = new StringBuilder();
            while (intData > 0)
            {
                var remainder = (int)(intData % 58);
                intData /= 58;
                result.Insert(0, Base58Chars[remainder]);
            }


            // Append '1' for each leading 0 byte
            for (var i = 0; i < hash.Length && hash == 0; i++)
            {
                result.Insert(0, '1');
            }


            return result.ToString();
        }
        public static string Hash160WithCheckSumToBase58(string hash)
        {
            byte[] hashByte = HexToByteArray(hash);
            return Hash160WithCheckSumToBase58(hashByte);
        }


        ///
        /// Converts Public Key to Base58 encoded Bitcoin Address.
        ///

        /// Bitcoin Public Key.
        /// Base58 encoded Bitcoin Address.
        public static string PubKeyToBase58(string pubKey)
        {
            byte[] hash160 = PubKeyToHash160(pubKey);


            string base58 = Hash160ToBase58(hash160);


            return base58;
        }
    }
}