Example #1
0
        public static byte[] ComputeMerkleRoot(this Block block, IHashProvider hashProvider)
        {
            if (block.Objects == null || block.Objects.Count == 0)
            {
                return(hashProvider.ComputeHashBytes(Block.NoObjects));
            }

            // https://en.bitcoin.it/wiki/Protocol_documentation#Merkle_Trees

            var p = new List <byte[]>();

            foreach (var o in block.Objects)
            {
                p.Add(hashProvider.DoubleHash(o));
            }
            if (p.Count > 1 && p.Count % 2 != 0)
            {
                p.Add(p[p.Count - 1]);
            }
            if (p.Count == 1)
            {
                return(p[0]);
            }

pass:
            {
                var n = new List <byte[]>(p.Count / 2);
                for (var i = 0; i < p.Count; i++)
                {
                    for (var j = i + 1; j < p.Count; j++)
                    {
                        var a = block.Objects[i].Hash;
                        var b = block.Objects[j].Hash;
                        var d = hashProvider.DoubleHash(a, b);
                        n.Add(d);
                        i++;
                    }
                }
                if (n.Count == 1)
                {
                    return(n[0]);
                }
                if (n.Count % 2 != 0)
                {
                    n.Add(n[n.Count - 1]);
                }

                p = n;
                goto pass;
            }
        }