예제 #1
0
 public static BlockHash Hash(byte[] bytes) =>
 BlockHash.FromHashDigest(HashDigest <SHA256> .DeriveFrom(bytes));
예제 #2
0
 /// <summary>
 /// Converts a given hexadecimal representation of a digest into
 /// a <see cref="HashDigest{T}"/> object.
 /// <para>This is a shortcut of
 /// <see cref="HashDigest{T}.FromString(string)"/> method.</para>
 /// <para>This is an inverse function of
 /// <see cref="HashDigest{T}.ToString()"/> method.</para>
 /// </summary>
 /// <param name="hexDigest">A hexadecimal representation of
 /// a <see cref="HashDigest{T}"/>.</param>
 /// <typeparam name="T">A <see cref="HashAlgorithm"/> which corresponds
 /// to a digest.</typeparam>
 /// <returns>A corresponding <see cref="HashDigest{T}"/> value.
 /// </returns>
 /// <exception cref="ArgumentNullException">Thrown when the given
 /// <paramref name="hexDigest"/> is <c>null</c>.</exception>
 /// <exception cref="ArgumentOutOfRangeException">Thrown when the given
 /// <paramref name="hexDigest"/>'s length is not the double of
 /// the <see cref="HashDigest{T}.Size"/>, the hash algorithm
 /// (i.e., <typeparamref name="T"/> requires.</exception>
 /// <seealso cref="HashDigest{T}.FromString(string)"/>
 /// <seealso cref="HashDigest{T}.ToString()"/>
 public static HashDigest <T> ToHashDigest <T>(this string hexDigest)
     where T : HashAlgorithm
 {
     return(HashDigest <T> .FromString(hexDigest));
 }
예제 #3
0
        public static void Validate(IEnumerable <Block <T> > blocks)
        {
            HashDigest <SHA256>?prevHash      = null;
            DateTime?           prevTimestamp = null;
            DateTime            now           = DateTime.UtcNow;
            IEnumerable <(ulong i, DifficultyExpectation)> indexedDifficulties =
                ExpectDifficulties(blocks)
                .Select((exp, i) => { return((ulong)i, exp); });

            foreach (var(i, exp) in indexedDifficulties)
            {
                Trace.Assert(exp.Block != null);
                Block <T> block = exp.Block;

                if (i != block.Index)
                {
                    throw new InvalidBlockIndexException(
                              $"the expected block index is {i}, but its index is" +
                              $" {block.Index}'"
                              );
                }

                if (block.Difficulty < exp.Difficulty)
                {
                    throw new InvalidBlockDifficultyException(
                              $"the expected difficulty of the block #{i} " +
                              $"is {exp.Difficulty}, but its difficulty is " +
                              $"{block.Difficulty}'"
                              );
                }

                if (block.PreviousHash != prevHash)
                {
                    if (prevHash == null)
                    {
                        throw new InvalidBlockPreviousHashException(
                                  "the genesis block must have not previous block"
                                  );
                    }

                    throw new InvalidBlockPreviousHashException(
                              $"the block #{i} is not continuous from the block #{i - 1};" +
                              $"while previous block's hash is {prevHash}, " +
                              $"the block #{i}'s pointer to the previous hash refers to " +
                              $"{block.PreviousHash?.ToString() ?? "nothing"}"
                              );
                }

                if (now < block.Timestamp)
                {
                    throw new InvalidBlockTimestampException(
                              $"the block #{i}'s timestamp ({block.Timestamp}) is " +
                              $"later than now ({now})"
                              );
                }

                if (block.Timestamp <= prevTimestamp)
                {
                    throw new InvalidBlockTimestampException(
                              $"the block #{i}'s timestamp ({block.Timestamp}) is earlier than " +
                              $"the block #{i - 1}'s ({prevTimestamp})"
                              );
                }

                block.Validate();
                prevHash      = block.Hash;
                prevTimestamp = block.Timestamp;
            }
        }