120 lines
3.7 KiB
C#
120 lines
3.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
|
|
namespace TestConsole
|
|
{
|
|
class Block
|
|
{
|
|
public int Index { get; set; }
|
|
public string PreviousHash { get; set; }
|
|
public string Hash { get; set; }
|
|
public string Data { get; set; }
|
|
public long Timestamp { get; set; }
|
|
public int Nonce { get; set; }
|
|
|
|
public Block(int index, string previousHash, string data)
|
|
{
|
|
Index = index;
|
|
PreviousHash = previousHash;
|
|
Data = data;
|
|
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
|
Nonce = 0;
|
|
Hash = CalculateHash();
|
|
}
|
|
|
|
public string CalculateHash()
|
|
{
|
|
using (SHA256 sha256 = SHA256.Create())
|
|
{
|
|
string hash = "";
|
|
byte[] inputBytes = Encoding.UTF8.GetBytes($"{Index}{PreviousHash}{Timestamp}{Data}{Nonce}");
|
|
byte[] outputBytes = sha256.ComputeHash(inputBytes);
|
|
hash = Convert.ToBase64String(outputBytes);
|
|
|
|
while (hash.Substring(0,3) != "000")
|
|
{
|
|
Nonce++;
|
|
inputBytes = Encoding.UTF8.GetBytes($"{Index}{PreviousHash}{Timestamp}{Data}{Nonce}");
|
|
outputBytes = sha256.ComputeHash(inputBytes);
|
|
hash = Convert.ToBase64String(outputBytes);
|
|
}
|
|
return hash;
|
|
}
|
|
}
|
|
}
|
|
|
|
class Blockchain
|
|
{
|
|
public List<Block> Chain { get; set; }
|
|
|
|
public Blockchain()
|
|
{
|
|
Chain = new List<Block>();
|
|
Chain.Add(new Block(0, "", ""));
|
|
}
|
|
|
|
public Block GetLatestBlock()
|
|
{
|
|
return Chain[Chain.Count - 1];
|
|
}
|
|
|
|
public void AddBlock(string data)
|
|
{
|
|
Block latestBlock = GetLatestBlock();
|
|
int index = latestBlock.Index + 1;
|
|
string previousHash = latestBlock.Hash;
|
|
Chain.Add(new Block(index, previousHash, data));
|
|
}
|
|
|
|
public bool IsValid()
|
|
{
|
|
|
|
for (int i = 1; i < Chain.Count; i++)
|
|
{
|
|
Block currentBlock = Chain[i];
|
|
Block previusBlock = Chain[i - 1];
|
|
|
|
if (currentBlock.PreviousHash != previusBlock.Hash) return false;
|
|
if (currentBlock.Hash != currentBlock.CalculateHash()) return false;
|
|
if (currentBlock.Index != previusBlock.Index + 1) return false;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
class Program
|
|
{
|
|
static void Main(string[] args)
|
|
{
|
|
Blockchain blockchain = new Blockchain();
|
|
|
|
blockchain.AddBlock("This is block 1");
|
|
blockchain.AddBlock("This is block 2");
|
|
blockchain.AddBlock("This is block 3");
|
|
|
|
var options = new JsonSerializerOptions { WriteIndented = true };
|
|
string blockString = JsonSerializer.Serialize(blockchain.Chain, options);
|
|
|
|
Console.WriteLine(blockString);
|
|
/*
|
|
foreach (Block block in blockchain.Chain)
|
|
{
|
|
Console.WriteLine($"Index: {block.Index}");
|
|
Console.WriteLine($"Previous Hash: {block.PreviousHash}");
|
|
Console.WriteLine($"Hash: {block.Hash}");
|
|
Console.WriteLine($"Data: {block.Data}");
|
|
Console.WriteLine($"Timestamp: {block.Timestamp}");
|
|
Console.WriteLine();
|
|
}
|
|
|
|
Console.WriteLine(blockchain.IsValid() ? "Block Chen is valid" : "BlockChain is invalid");
|
|
*/
|
|
}
|
|
}
|
|
} |