diff --git a/DltNode/DltNode.Blockchain/Block.cs b/DltNode/DltNode.Blockchain/Block.cs new file mode 100644 index 0000000..3121e0c --- /dev/null +++ b/DltNode/DltNode.Blockchain/Block.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DltNode.Hash; + +namespace DltNode.Blockchain +{ + public class Block + { + public readonly Byte[] blockHash; + + public readonly Byte[] previousBlockHash; + + public readonly List transactions; + + public readonly Byte[] zero; + /// + /// + /// + /// + /// Put null in to first block constructor + public Block(List transactions, Block previousBlock) + { + zero = new byte[32]; + this.previousBlockHash = previousBlock?.blockHash ?? zero; + this.transactions = transactions; + + List hashes = new List(); + hashes.Add(previousBlockHash); + foreach(var tx in transactions) + { + + hashes.Add(tx.GetHash()); + } + blockHash = computeMerkleTreeHash(hashes); + } + public Byte[] computeMerkleTreeHash(List hashes) + { + if (hashes.Count == 1) + return hashes[0]; + else if (hashes.Count == 2) + return PureHash.computeHash(hashes[0].Concat(hashes[1]).ToArray()); + else + { + List firstPart = hashes.GetRange(0, hashes.Count / 2); + List secondPart = hashes.GetRange(hashes.Count / 2, hashes.Count - 1); + var hashOfLeft = computeMerkleTreeHash(firstPart); + var hashOfRight = computeMerkleTreeHash(secondPart); + return PureHash.computeHash(hashOfLeft.Concat(hashOfRight).ToArray()); + } + + return Array.Empty(); + } + } +} diff --git a/DltNode/DltNode.Blockchain/Blockchain.cs b/DltNode/DltNode.Blockchain/Blockchain.cs new file mode 100644 index 0000000..b785aa2 --- /dev/null +++ b/DltNode/DltNode.Blockchain/Blockchain.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DltNode.Blockchain +{ + public class Blockchain + { + public List blockchain; + + public Blockchain(Block genesisBlock) + { + blockchain = new List(); + blockchain.Add(genesisBlock); + } + public Boolean AddNewBlock(Block newBlock) + { + if (newBlock.previousBlockHash != blockchain[blockchain.Count() - 1].blockHash) + { + return false; + } + else + { + blockchain.Add(newBlock); + return true; + } + } + + public Int32 Height => blockchain.Count(); + } +} diff --git a/DltNode/DltNode.Blockchain/Class1.cs b/DltNode/DltNode.Blockchain/Class1.cs deleted file mode 100644 index 8e8bc27..0000000 --- a/DltNode/DltNode.Blockchain/Class1.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace DltNode.Blockchain -{ - public class Class1 - { - // example - } -} diff --git a/DltNode/DltNode.Blockchain/DltNode.Blockchain.csproj b/DltNode/DltNode.Blockchain/DltNode.Blockchain.csproj index cb63190..64e79be 100644 --- a/DltNode/DltNode.Blockchain/DltNode.Blockchain.csproj +++ b/DltNode/DltNode.Blockchain/DltNode.Blockchain.csproj @@ -1,7 +1,11 @@ - netcoreapp3.1 + net5.0 + + + + diff --git a/DltNode/DltNode.Blockchain/Transaction.cs b/DltNode/DltNode.Blockchain/Transaction.cs new file mode 100644 index 0000000..4785600 --- /dev/null +++ b/DltNode/DltNode.Blockchain/Transaction.cs @@ -0,0 +1,16 @@ +using System; +using DltNode.Hash; +using System.Text; +namespace DltNode.Blockchain +{ + public class Transaction + { + public readonly String info; + public Transaction(string info) + { + this.info = info; + } + + public Byte[] GetHash() => PureHash.computeHash(Encoding.UTF8.GetBytes(info)); + } +} diff --git a/DltNode/DltNode.Hash/DltNode.Hash.csproj b/DltNode/DltNode.Hash/DltNode.Hash.csproj new file mode 100644 index 0000000..d4c395e --- /dev/null +++ b/DltNode/DltNode.Hash/DltNode.Hash.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.1 + + + diff --git a/DltNode/DltNode.Hash/PureHash.cs b/DltNode/DltNode.Hash/PureHash.cs new file mode 100644 index 0000000..d680df0 --- /dev/null +++ b/DltNode/DltNode.Hash/PureHash.cs @@ -0,0 +1,20 @@ +using System; +using System.Security.Cryptography; +using System.Collections; +namespace DltNode.Hash +{ + public static class PureHash + { + + //public + public static byte[] computeHash(byte[] input) + { + var hashing = SHA256.Create(); + //input.Length + + + return hashing.ComputeHash(input); + } + + } +} diff --git a/DltNode/DltNode.Main/DltNode.Main.csproj b/DltNode/DltNode.Main/DltNode.Main.csproj index 5312c73..3281960 100644 --- a/DltNode/DltNode.Main/DltNode.Main.csproj +++ b/DltNode/DltNode.Main/DltNode.Main.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net5.0 diff --git a/DltNode/DltNode.Main/Program.cs b/DltNode/DltNode.Main/Program.cs index 968f589..09fc907 100644 --- a/DltNode/DltNode.Main/Program.cs +++ b/DltNode/DltNode.Main/Program.cs @@ -1,14 +1,34 @@ using System; - +using System.Collections.Generic; +using System.Text; +using DltNode.Blockchain; namespace DltNode.Main { class Program { static void Main(string[] args) { - Console.WriteLine("Hello World!"); - Console.WriteLine(); - Console.WriteLine(1); + Transaction tx1 = new Transaction("Product X has moved from A to B"); + Transaction tx2 = new Transaction("Product Y has moved from C to D"); + + List transactions = new List(); + transactions.Add(tx1); + transactions.Add(tx2); + + Block firstBlock = new Block(transactions, null); + Console.WriteLine(BitConverter.ToString(firstBlock.blockHash)); + Transaction tx0 = new Transaction("Product Z has moved from E to F"); + List transactions1 = new List(); + transactions1.Add(tx0); + + Block secondBlock = new Block(transactions1, firstBlock); + Console.WriteLine(BitConverter.ToString(secondBlock.previousBlockHash)); + Console.WriteLine(BitConverter.ToString(secondBlock.blockHash)); + + Blockchain.Blockchain blockchain = new Blockchain.Blockchain(firstBlock); + Console.WriteLine(blockchain.Height); + Console.WriteLine(blockchain.AddNewBlock(secondBlock)); + Console.WriteLine(blockchain.Height); } } } diff --git a/DltNode/DltNode.sln b/DltNode/DltNode.sln index 076bbac..e0bed4f 100644 --- a/DltNode/DltNode.sln +++ b/DltNode/DltNode.sln @@ -3,9 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30804.86 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DltNode.Main", "DltNode.Main\DltNode.Main.csproj", "{B8E636E8-B130-42C2-A2D9-24E95AAB97AA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DltNode.Main", "DltNode.Main\DltNode.Main.csproj", "{B8E636E8-B130-42C2-A2D9-24E95AAB97AA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DltNode.Blockchain", "DltNode.Blockchain\DltNode.Blockchain.csproj", "{15EB2A24-0420-4CB0-9D46-EE8E84534BF1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DltNode.Blockchain", "DltNode.Blockchain\DltNode.Blockchain.csproj", "{15EB2A24-0420-4CB0-9D46-EE8E84534BF1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DltNode.Hash", "DltNode.Hash\DltNode.Hash.csproj", "{5E5F9D32-2481-4688-9C9C-0F9D2BCB6C67}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -21,6 +23,10 @@ Global {15EB2A24-0420-4CB0-9D46-EE8E84534BF1}.Debug|Any CPU.Build.0 = Debug|Any CPU {15EB2A24-0420-4CB0-9D46-EE8E84534BF1}.Release|Any CPU.ActiveCfg = Release|Any CPU {15EB2A24-0420-4CB0-9D46-EE8E84534BF1}.Release|Any CPU.Build.0 = Release|Any CPU + {5E5F9D32-2481-4688-9C9C-0F9D2BCB6C67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5E5F9D32-2481-4688-9C9C-0F9D2BCB6C67}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5E5F9D32-2481-4688-9C9C-0F9D2BCB6C67}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5E5F9D32-2481-4688-9C9C-0F9D2BCB6C67}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE