【问题标题】:Bit Coin Hashing Algorithm比特币哈希算法
【发布时间】:2018-04-12 03:00:06
【问题描述】:

我和网络世界中许多绝望的浪漫主义者一样,相信我可以成功地挖到比特币。问题是,我无法获得正确的基本算法来从前一个矿块获取数据并为下一个矿块创建哈希。我从几篇文章中了解到,我们从区块的当前哈希开始,反向并附加默克尔根,添加随机数,然后获取该字符串的 SHA256 哈希。

     static void Main(string[] args)
    {

        //get the hash of the current block
        string currentHash = 
        @"000000000000000000c5c04011f9a3fb5f46064fed7e06dcdae69024ed6484c1";

        //get the merkel root
        string merkel = 
        @"f73a382814c51cbc5a59ab9817ac54c63decb7b3dac5b049df5213c029162bdf";

        //reverese the merkel root
        char[] c = merkel.ToCharArray();
        Array.Reverse(c);
        merkel = new string(c);

        //get a hash object that returns SHA256
        Hash hash = new Hash();

        //get the nonce that mined the block
        uint nonce = 3546041956;

        //string together current hash, merkel root and the hex of the nonce
        string stringTotal = currentHash + merkel + nonce.ToString("x2");

        //calculate the SHA256 hash of the 
        string nextHash = hash.GetHash(stringTotal);

        Console.WriteLine(nextHash);

        Console.ReadKey();
    }

有人知道正确的算法吗?我使用这个块https://blockchain.info/block-height/477065 并尝试计算下一个块的哈希。

【问题讨论】:

  • 散列只在一堆字节上完成。在谈论散列时您会看到的任何字符串都只是字节的表示。
  • Hash 对象接收字符串,转换为字节,应用 SHA256 算法,然后将 byte[] 中的每个字节附加到带有 ("x2") 的 StringBuilder 对象。
  • public string GetHash(string input) { string hash = ""; byte[] b = Encoding.UTF8.GetBytes(input); HashAlgorithm ha = new SHA256CryptoServiceProvider();字节[] b2 = ha.ComputeHash(b); StringBuilder builder = new StringBuilder(); foreach(b2 中的字节 i) { builder.Append(i.ToString("x2")); } 哈希 = builder.ToString();返回哈希; }
  • 反转默克尔根 - 我不敢相信你必须反转字节表示的字符(2个字符代表1个字节)
  • 将十六进制字符串表示解码为字节数组,然后反转该字节数组。散列时远离字符串,只使用流或字节数组。

标签: c# sha256


【解决方案1】:

所以我对同样的事情很好奇。这就是我想出的。这显然不是生产质量,但它传达了这个想法并且似乎有效。

如果没有反向和交换逻辑,我正在寻找的所有内容实际上都没有记录,这可能会容易得多。

无论如何,希望这会有所帮助。如果您有兴趣,我在这里找到了很多帮助:http://trogers.net/2018/01/29/how-to-validate-a-bitcoin-blocks-proof-of-work-c/

class Program
{
    static void Main(string[] args)
    {
        // https://blockchain.info/block-height/286819
        int version = 2;
        string previousBlock = "000000000000000117c80378b8da0e33559b5997f2ad55e2f7d18ec1975b9717";
        string merkelRoot = "871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a";
        uint nonce = 856192328;
        long timestamp = new DateTimeOffset(DateTime.SpecifyKind(DateTime.Parse("2014-02-20 04:57:25"), DateTimeKind.Utc)).ToUnixTimeSeconds();
        uint bits = 419520339;

        var header = new StringBuilder()
            .Append(ReverseAndSwap(version.ToString("D8")))
            .Append(ReverseAndSwap(previousBlock))
            .Append(ReverseAndSwap(merkelRoot))
            .Append(ReverseAndSwap(timestamp.ToString("x2")))
            .Append(ReverseAndSwap(bits.ToString("x2")))
            .Append(ReverseAndSwap(nonce.ToString("x2")))
            .ToString();

        Debug.Assert(string.CompareOrdinal(header, "0200000017975b97c18ed1f7e255adf297599b55330edab87803c81701000000000000008a97295a2747b4f1a0b3948df3990344c0e19fa6b2b92b3a19c8e6badc141787358b0553535f011948750833") == 0);

        var bytes = HexToBytes(header);

        SHA256 sha = new SHA256Managed();

        bytes = sha.ComputeHash(sha.ComputeHash(bytes)).Reverse().ToArray();

        var hash = BytesToHex(bytes);

        Debug.Assert(string.CompareOrdinal(hash, "0000000000000000e067a478024addfecdc93628978aa52d91fabd4292982a50") == 0);
    }

    private static string ReverseAndSwap(string input)
    {
        StringBuilder sb = new StringBuilder();

        for (var i = input.Length - 1; i >= 0; i--)
        {
            sb.Append(input[i - (i % 2 == 0 ? -1 : 1)]);
        }

        return sb.ToString();
    }

    public static byte[] HexToBytes(string hex)
    {
        byte[] hexAsBytes = new byte[hex.Length / 2];

        for (int index = 0; index < hexAsBytes.Length; index++)
        {
            string byteValue = hex.Substring(index * 2, 2);
            hexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
        }

        return hexAsBytes;
    }

    public static string BytesToHex(byte[] bytes)
    {
        var output = new StringBuilder(bytes.Length * 2);

        for (int i = 0; i < bytes.Length; ++i)
        {
            output.AppendFormat("{0:x2}", bytes[i]);
        }

        return output.ToString();
    }
}

【讨论】:

    猜你喜欢
    • 2011-09-10
    • 2016-06-23
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 2012-06-03
    • 2021-05-03
    • 2013-09-19
    相关资源
    最近更新 更多