From d5697d785e6558090a353a7bd4438b8592940151 Mon Sep 17 00:00:00 2001 From: Trevor D'Arcy-Evans Date: Sun, 5 Dec 2021 20:43:53 +0000 Subject: [PATCH 1/6] - added standard .NET ignore --- csharp/.gitignore | 274 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 csharp/.gitignore diff --git a/csharp/.gitignore b/csharp/.gitignore new file mode 100644 index 00000000..0c055039 --- /dev/null +++ b/csharp/.gitignore @@ -0,0 +1,274 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Mono auto generated files +mono_crash.* + +/.project + +# Coverlet code coverage output +**/coverage.json +**/coverage.opencover.xml +CodeCoverage/ + +# Sonarqube +.sonarqube From 5d626ebf852fc24e864eca3e10afdc343cf4550a Mon Sep 17 00:00:00 2001 From: Trevor D'Arcy-Evans Date: Sun, 5 Dec 2021 20:44:38 +0000 Subject: [PATCH 2/6] - updated to .NET Core 6.0 --- csharp/BlockChain.Console/App.config | 10 --- .../BlockChain.Console.csproj | 71 ++++------------ csharp/BlockChain.Console/Program.cs | 13 ++- csharp/BlockChain.Console/appsettings.json | 4 + csharp/BlockChain.sln | 41 +++------- csharp/BlockChain/BlockChain.csproj | 82 ++++--------------- csharp/BlockChain/WebServer.cs | 8 +- csharp/BlockChain/packages.config | 5 -- 8 files changed, 62 insertions(+), 172 deletions(-) delete mode 100644 csharp/BlockChain.Console/App.config create mode 100644 csharp/BlockChain.Console/appsettings.json delete mode 100644 csharp/BlockChain/packages.config diff --git a/csharp/BlockChain.Console/App.config b/csharp/BlockChain.Console/App.config deleted file mode 100644 index 089f2495..00000000 --- a/csharp/BlockChain.Console/App.config +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/csharp/BlockChain.Console/BlockChain.Console.csproj b/csharp/BlockChain.Console/BlockChain.Console.csproj index 5bc56703..5a59c04f 100644 --- a/csharp/BlockChain.Console/BlockChain.Console.csproj +++ b/csharp/BlockChain.Console/BlockChain.Console.csproj @@ -1,63 +1,28 @@ - - - + + - Debug - AnyCPU - {D0C795A0-6F20-4A8E-BE44-801678754DA4} Exe - BlockChainDemo.Console - BlockChainDemo.Console - v4.5.1 - 512 - true - SAK - SAK - SAK - SAK - + net6.0 + enable + enable - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 + + + false + - - - - - - - - - - - - + + - + + + - - {e06fc4ce-77d0-4a64-94a6-32a08920e481} - BlockChain - + + PreserveNewest + - - \ No newline at end of file + diff --git a/csharp/BlockChain.Console/Program.cs b/csharp/BlockChain.Console/Program.cs index 2573f931..7aebb95f 100644 --- a/csharp/BlockChain.Console/Program.cs +++ b/csharp/BlockChain.Console/Program.cs @@ -1,11 +1,16 @@ -namespace BlockChainDemo.Console +using Microsoft.Extensions.Configuration; + +namespace BlockChainDemo.Console { - class Program + public class Program { - static void Main(string[] args) + public static void Main(string[] args) { var chain = new BlockChain(); - var server = new WebServer(chain); + var config = new ConfigurationBuilder() + .AddJsonFile("appsettings.json") + .Build(); + var server = new WebServer(chain, config); System.Console.Read(); } } diff --git a/csharp/BlockChain.Console/appsettings.json b/csharp/BlockChain.Console/appsettings.json new file mode 100644 index 00000000..3d0d8732 --- /dev/null +++ b/csharp/BlockChain.Console/appsettings.json @@ -0,0 +1,4 @@ +{ + "host": "localhost", + "port": "5000" +} diff --git a/csharp/BlockChain.sln b/csharp/BlockChain.sln index 0175024f..47d552cf 100644 --- a/csharp/BlockChain.sln +++ b/csharp/BlockChain.sln @@ -1,43 +1,28 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27004.2008 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlockChain", "BlockChain\BlockChain.csproj", "{E06FC4CE-77D0-4A64-94A6-32A08920E481}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlockChain", "BlockChain\BlockChain.csproj", "{C420D6B3-543C-4526-BB5F-4319AB6CEE6B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlockChain.Console", "BlockChain.Console\BlockChain.Console.csproj", "{D0C795A0-6F20-4A8E-BE44-801678754DA4}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlockChain.Console", "BlockChain.Console\BlockChain.Console.csproj", "{B6202B59-6049-436D-B047-3D01D96CC470}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E06FC4CE-77D0-4A64-94A6-32A08920E481}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E06FC4CE-77D0-4A64-94A6-32A08920E481}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E06FC4CE-77D0-4A64-94A6-32A08920E481}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E06FC4CE-77D0-4A64-94A6-32A08920E481}.Release|Any CPU.Build.0 = Release|Any CPU - {D0C795A0-6F20-4A8E-BE44-801678754DA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D0C795A0-6F20-4A8E-BE44-801678754DA4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D0C795A0-6F20-4A8E-BE44-801678754DA4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D0C795A0-6F20-4A8E-BE44-801678754DA4}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {7FB3650B-CAFB-4A71-940B-0CA6F0377422} - EndGlobalSection - GlobalSection(TeamFoundationVersionControl) = preSolution - SccNumberOfProjects = 3 - SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} - SccTeamFoundationServer = https://devfire.visualstudio.com/ - SccLocalPath0 = . - SccProjectUniqueName1 = BlockChain\\BlockChain.csproj - SccProjectName1 = BlockChain - SccLocalPath1 = BlockChain - SccProjectUniqueName2 = BlockChain.Console\\BlockChain.Console.csproj - SccProjectName2 = BlockChain.Console - SccLocalPath2 = BlockChain.Console + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C420D6B3-543C-4526-BB5F-4319AB6CEE6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C420D6B3-543C-4526-BB5F-4319AB6CEE6B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C420D6B3-543C-4526-BB5F-4319AB6CEE6B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C420D6B3-543C-4526-BB5F-4319AB6CEE6B}.Release|Any CPU.Build.0 = Release|Any CPU + {B6202B59-6049-436D-B047-3D01D96CC470}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6202B59-6049-436D-B047-3D01D96CC470}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6202B59-6049-436D-B047-3D01D96CC470}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B6202B59-6049-436D-B047-3D01D96CC470}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/csharp/BlockChain/BlockChain.csproj b/csharp/BlockChain/BlockChain.csproj index 86681aca..1310d221 100644 --- a/csharp/BlockChain/BlockChain.csproj +++ b/csharp/BlockChain/BlockChain.csproj @@ -1,73 +1,19 @@ - - - + + - Debug - AnyCPU - {E06FC4CE-77D0-4A64-94A6-32A08920E481} - Library - Properties - BlockChainDemo - BlockChainDemo - v4.5.1 - 512 - SAK - SAK - SAK - SAK - + net6.0 + enable + enable - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 + + + false + - - ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - - - - - - - - - - - - ..\packages\TinyWebServer.dll.1.0.1\lib\net40\TinyWebServer.dll - - - - - - - - - - - - + + + - - - \ No newline at end of file + + diff --git a/csharp/BlockChain/WebServer.cs b/csharp/BlockChain/WebServer.cs index cd7b86b5..a4820b30 100644 --- a/csharp/BlockChain/WebServer.cs +++ b/csharp/BlockChain/WebServer.cs @@ -3,16 +3,16 @@ using System.IO; using System.Net; using System.Net.Http; +using Microsoft.Extensions.Configuration; namespace BlockChainDemo { public class WebServer { - public WebServer(BlockChain chain) + public WebServer(BlockChain chain, IConfiguration config) { - var settings = ConfigurationManager.AppSettings; - string host = settings["host"]?.Length > 1 ? settings["host"] : "localhost"; - string port = settings["port"]?.Length > 1 ? settings["port"] : "12345"; + string host = config["host"]?.Length > 1 ? config["host"] : "localhost"; + string port = config["port"]?.Length > 1 ? config["port"] : "12345"; var server = new TinyWebServer.WebServer(request => { diff --git a/csharp/BlockChain/packages.config b/csharp/BlockChain/packages.config deleted file mode 100644 index 4c8c0646..00000000 --- a/csharp/BlockChain/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file From e03d317488d49bdf7479cba68f738b25fc44a89f Mon Sep 17 00:00:00 2001 From: Trevor D'Arcy-Evans Date: Sun, 5 Dec 2021 20:54:04 +0000 Subject: [PATCH 3/6] - code cleanup --- csharp/BlockChain.Console/Properties/AssemblyInfo.cs | 1 - csharp/BlockChain/Properties/AssemblyInfo.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/csharp/BlockChain.Console/Properties/AssemblyInfo.cs b/csharp/BlockChain.Console/Properties/AssemblyInfo.cs index 2b25de21..0bb611b2 100644 --- a/csharp/BlockChain.Console/Properties/AssemblyInfo.cs +++ b/csharp/BlockChain.Console/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/csharp/BlockChain/Properties/AssemblyInfo.cs b/csharp/BlockChain/Properties/AssemblyInfo.cs index 87b9d4eb..76b787cb 100644 --- a/csharp/BlockChain/Properties/AssemblyInfo.cs +++ b/csharp/BlockChain/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following From b15a43c582e153820a007aaee6e7fe8e7e00bc3d Mon Sep 17 00:00:00 2001 From: Trevor D'Arcy-Evans Date: Sun, 5 Dec 2021 20:54:15 +0000 Subject: [PATCH 4/6] - formatting --- csharp/BlockChain.Console/Program.cs | 20 +- csharp/BlockChain/Block.cs | 24 +- csharp/BlockChain/BlockChain.cs | 368 +++++++++++++-------------- csharp/BlockChain/Node.cs | 10 +- csharp/BlockChain/Transaction.cs | 14 +- csharp/BlockChain/WebServer.cs | 112 ++++---- 6 files changed, 274 insertions(+), 274 deletions(-) diff --git a/csharp/BlockChain.Console/Program.cs b/csharp/BlockChain.Console/Program.cs index 7aebb95f..af8bb018 100644 --- a/csharp/BlockChain.Console/Program.cs +++ b/csharp/BlockChain.Console/Program.cs @@ -2,16 +2,16 @@ namespace BlockChainDemo.Console { - public class Program + public class Program + { + public static void Main(string[] args) { - public static void Main(string[] args) - { - var chain = new BlockChain(); - var config = new ConfigurationBuilder() - .AddJsonFile("appsettings.json") - .Build(); - var server = new WebServer(chain, config); - System.Console.Read(); - } + var chain = new BlockChain(); + var config = new ConfigurationBuilder() + .AddJsonFile("appsettings.json") + .Build(); + var server = new WebServer(chain, config); + System.Console.Read(); } + } } diff --git a/csharp/BlockChain/Block.cs b/csharp/BlockChain/Block.cs index 9ca9d808..7e7d60af 100644 --- a/csharp/BlockChain/Block.cs +++ b/csharp/BlockChain/Block.cs @@ -3,17 +3,17 @@ namespace BlockChainDemo { - public class Block - { - public int Index { get; set; } - public DateTime Timestamp { get; set; } - public List Transactions { get; set; } - public int Proof { get; set; } - public string PreviousHash { get; set; } + public class Block + { + public int Index { get; set; } + public DateTime Timestamp { get; set; } + public List Transactions { get; set; } + public int Proof { get; set; } + public string PreviousHash { get; set; } - public override string ToString() - { - return $"{Index} [{Timestamp.ToString("yyyy-MM-dd HH:mm:ss")}] Proof: {Proof} | PrevHash: {PreviousHash} | Trx: {Transactions.Count}"; - } + public override string ToString() + { + return $"{Index} [{Timestamp.ToString("yyyy-MM-dd HH:mm:ss")}] Proof: {Proof} | PrevHash: {PreviousHash} | Trx: {Transactions.Count}"; } -} \ No newline at end of file + } +} diff --git a/csharp/BlockChain/BlockChain.cs b/csharp/BlockChain/BlockChain.cs index 250d6f86..7fe791e2 100644 --- a/csharp/BlockChain/BlockChain.cs +++ b/csharp/BlockChain/BlockChain.cs @@ -10,217 +10,217 @@ namespace BlockChainDemo { - public class BlockChain + public class BlockChain + { + private List _currentTransactions = new List(); + private List _chain = new List(); + private List _nodes = new List(); + private Block _lastBlock => _chain.Last(); + + public string NodeId { get; private set; } + + //ctor + public BlockChain() { - private List _currentTransactions = new List(); - private List _chain = new List(); - private List _nodes = new List(); - private Block _lastBlock => _chain.Last(); + NodeId = Guid.NewGuid().ToString().Replace("-", ""); + CreateNewBlock(proof: 100, previousHash: "1"); //genesis block + } - public string NodeId { get; private set; } + //private functionality + private void RegisterNode(string address) + { + _nodes.Add(new Node { Address = new Uri(address) }); + } - //ctor - public BlockChain() - { - NodeId = Guid.NewGuid().ToString().Replace("-", ""); - CreateNewBlock(proof: 100, previousHash: "1"); //genesis block - } + private bool IsValidChain(List chain) + { + Block block = null; + Block lastBlock = chain.First(); + int currentIndex = 1; + while (currentIndex < chain.Count) + { + block = chain.ElementAt(currentIndex); + Debug.WriteLine($"{lastBlock}"); + Debug.WriteLine($"{block}"); + Debug.WriteLine("----------------------------"); + + //Check that the hash of the block is correct + if (block.PreviousHash != GetHash(lastBlock)) + return false; + + //Check that the Proof of Work is correct + if (!IsValidProof(lastBlock.Proof, block.Proof, lastBlock.PreviousHash)) + return false; + + lastBlock = block; + currentIndex++; + } + + return true; + } - //private functionality - private void RegisterNode(string address) - { - _nodes.Add(new Node { Address = new Uri(address) }); - } + private bool ResolveConflicts() + { + List newChain = null; + int maxLength = _chain.Count; - private bool IsValidChain(List chain) - { - Block block = null; - Block lastBlock = chain.First(); - int currentIndex = 1; - while (currentIndex < chain.Count) - { - block = chain.ElementAt(currentIndex); - Debug.WriteLine($"{lastBlock}"); - Debug.WriteLine($"{block}"); - Debug.WriteLine("----------------------------"); - - //Check that the hash of the block is correct - if (block.PreviousHash != GetHash(lastBlock)) - return false; - - //Check that the Proof of Work is correct - if (!IsValidProof(lastBlock.Proof, block.Proof, lastBlock.PreviousHash)) - return false; - - lastBlock = block; - currentIndex++; - } - - return true; - } + foreach (Node node in _nodes) + { + var url = new Uri(node.Address, "/chain"); + var request = (HttpWebRequest)WebRequest.Create(url); + var response = (HttpWebResponse)request.GetResponse(); - private bool ResolveConflicts() + if (response.StatusCode == HttpStatusCode.OK) { - List newChain = null; - int maxLength = _chain.Count; - - foreach (Node node in _nodes) - { - var url = new Uri(node.Address, "/chain"); - var request = (HttpWebRequest)WebRequest.Create(url); - var response = (HttpWebResponse)request.GetResponse(); - - if (response.StatusCode == HttpStatusCode.OK) - { - var model = new - { - chain = new List(), - length = 0 - }; - string json = new StreamReader(response.GetResponseStream()).ReadToEnd(); - var data = JsonConvert.DeserializeAnonymousType(json, model); - - if (data.chain.Count > _chain.Count && IsValidChain(data.chain)) - { - maxLength = data.chain.Count; - newChain = data.chain; - } - } - } - - if (newChain != null) - { - _chain = newChain; - return true; - } - - return false; + var model = new + { + chain = new List(), + length = 0 + }; + string json = new StreamReader(response.GetResponseStream()).ReadToEnd(); + var data = JsonConvert.DeserializeAnonymousType(json, model); + + if (data.chain.Count > _chain.Count && IsValidChain(data.chain)) + { + maxLength = data.chain.Count; + newChain = data.chain; + } } + } - private Block CreateNewBlock(int proof, string previousHash = null) - { - var block = new Block - { - Index = _chain.Count, - Timestamp = DateTime.UtcNow, - Transactions = _currentTransactions.ToList(), - Proof = proof, - PreviousHash = previousHash ?? GetHash(_chain.Last()) - }; - - _currentTransactions.Clear(); - _chain.Add(block); - return block; - } + if (newChain != null) + { + _chain = newChain; + return true; + } - private int CreateProofOfWork(int lastProof, string previousHash) - { - int proof = 0; - while (!IsValidProof(lastProof, proof, previousHash)) - proof++; + return false; + } - return proof; - } + private Block CreateNewBlock(int proof, string previousHash = null) + { + var block = new Block + { + Index = _chain.Count, + Timestamp = DateTime.UtcNow, + Transactions = _currentTransactions.ToList(), + Proof = proof, + PreviousHash = previousHash ?? GetHash(_chain.Last()) + }; + + _currentTransactions.Clear(); + _chain.Add(block); + return block; + } - private bool IsValidProof(int lastProof, int proof, string previousHash) - { - string guess = $"{lastProof}{proof}{previousHash}"; - string result = GetSha256(guess); - return result.StartsWith("0000"); - } + private int CreateProofOfWork(int lastProof, string previousHash) + { + int proof = 0; + while (!IsValidProof(lastProof, proof, previousHash)) + proof++; - private string GetHash(Block block) - { - string blockText = JsonConvert.SerializeObject(block); - return GetSha256(blockText); - } + return proof; + } - private string GetSha256(string data) - { - var sha256 = new SHA256Managed(); - var hashBuilder = new StringBuilder(); + private bool IsValidProof(int lastProof, int proof, string previousHash) + { + string guess = $"{lastProof}{proof}{previousHash}"; + string result = GetSha256(guess); + return result.StartsWith("0000"); + } - byte[] bytes = Encoding.Unicode.GetBytes(data); - byte[] hash = sha256.ComputeHash(bytes); + private string GetHash(Block block) + { + string blockText = JsonConvert.SerializeObject(block); + return GetSha256(blockText); + } - foreach (byte x in hash) - hashBuilder.Append($"{x:x2}"); + private string GetSha256(string data) + { + var sha256 = new SHA256Managed(); + var hashBuilder = new StringBuilder(); - return hashBuilder.ToString(); - } + byte[] bytes = Encoding.Unicode.GetBytes(data); + byte[] hash = sha256.ComputeHash(bytes); - //web server calls - internal string Mine() - { - int proof = CreateProofOfWork(_lastBlock.Proof, _lastBlock.PreviousHash); + foreach (byte x in hash) + hashBuilder.Append($"{x:x2}"); - CreateTransaction(sender: "0", recipient: NodeId, amount: 1); - Block block = CreateNewBlock(proof /*, _lastBlock.PreviousHash*/); + return hashBuilder.ToString(); + } - var response = new - { - Message = "New Block Forged", - Index = block.Index, - Transactions = block.Transactions.ToArray(), - Proof = block.Proof, - PreviousHash = block.PreviousHash - }; + //web server calls + internal string Mine() + { + int proof = CreateProofOfWork(_lastBlock.Proof, _lastBlock.PreviousHash); - return JsonConvert.SerializeObject(response); - } + CreateTransaction(sender: "0", recipient: NodeId, amount: 1); + Block block = CreateNewBlock(proof /*, _lastBlock.PreviousHash*/); - internal string GetFullChain() - { - var response = new - { - chain = _chain.ToArray(), - length = _chain.Count - }; + var response = new + { + Message = "New Block Forged", + Index = block.Index, + Transactions = block.Transactions.ToArray(), + Proof = block.Proof, + PreviousHash = block.PreviousHash + }; - return JsonConvert.SerializeObject(response); - } + return JsonConvert.SerializeObject(response); + } - internal string RegisterNodes(string[] nodes) - { - var builder = new StringBuilder(); - foreach (string node in nodes) - { - string url = $"http://{node}"; - RegisterNode(url); - builder.Append($"{url}, "); - } - - builder.Insert(0, $"{nodes.Count()} new nodes have been added: "); - string result = builder.ToString(); - return result.Substring(0, result.Length - 2); - } + internal string GetFullChain() + { + var response = new + { + chain = _chain.ToArray(), + length = _chain.Count + }; - internal string Consensus() - { - bool replaced = ResolveConflicts(); - string message = replaced ? "was replaced" : "is authoritive"; - - var response = new - { - Message = $"Our chain {message}", - Chain = _chain - }; - - return JsonConvert.SerializeObject(response); - } + return JsonConvert.SerializeObject(response); + } - internal int CreateTransaction(string sender, string recipient, int amount) - { - var transaction = new Transaction - { - Sender = sender, - Recipient = recipient, - Amount = amount - }; + internal string RegisterNodes(string[] nodes) + { + var builder = new StringBuilder(); + foreach (string node in nodes) + { + string url = $"http://{node}"; + RegisterNode(url); + builder.Append($"{url}, "); + } + + builder.Insert(0, $"{nodes.Count()} new nodes have been added: "); + string result = builder.ToString(); + return result.Substring(0, result.Length - 2); + } + + internal string Consensus() + { + bool replaced = ResolveConflicts(); + string message = replaced ? "was replaced" : "is authoritive"; - _currentTransactions.Add(transaction); + var response = new + { + Message = $"Our chain {message}", + Chain = _chain + }; - return _lastBlock != null ? _lastBlock.Index + 1 : 0; - } + return JsonConvert.SerializeObject(response); + } + + internal int CreateTransaction(string sender, string recipient, int amount) + { + var transaction = new Transaction + { + Sender = sender, + Recipient = recipient, + Amount = amount + }; + + _currentTransactions.Add(transaction); + + return _lastBlock != null ? _lastBlock.Index + 1 : 0; } + } } diff --git a/csharp/BlockChain/Node.cs b/csharp/BlockChain/Node.cs index 5ba425f9..6fe39e11 100644 --- a/csharp/BlockChain/Node.cs +++ b/csharp/BlockChain/Node.cs @@ -2,8 +2,8 @@ namespace BlockChainDemo { - public class Node - { - public Uri Address { get; set; } - } -} \ No newline at end of file + public class Node + { + public Uri Address { get; set; } + } +} diff --git a/csharp/BlockChain/Transaction.cs b/csharp/BlockChain/Transaction.cs index 1cbaeb7a..8de83ff2 100644 --- a/csharp/BlockChain/Transaction.cs +++ b/csharp/BlockChain/Transaction.cs @@ -1,9 +1,9 @@ namespace BlockChainDemo { - public class Transaction - { - public int Amount { get; set; } - public string Recipient { get; set; } - public string Sender { get; set; } - } -} \ No newline at end of file + public class Transaction + { + public int Amount { get; set; } + public string Recipient { get; set; } + public string Sender { get; set; } + } +} diff --git a/csharp/BlockChain/WebServer.cs b/csharp/BlockChain/WebServer.cs index a4820b30..fd5930d6 100644 --- a/csharp/BlockChain/WebServer.cs +++ b/csharp/BlockChain/WebServer.cs @@ -7,72 +7,72 @@ namespace BlockChainDemo { - public class WebServer + public class WebServer + { + public WebServer(BlockChain chain, IConfiguration config) { - public WebServer(BlockChain chain, IConfiguration config) - { - string host = config["host"]?.Length > 1 ? config["host"] : "localhost"; - string port = config["port"]?.Length > 1 ? config["port"] : "12345"; + string host = config["host"]?.Length > 1 ? config["host"] : "localhost"; + string port = config["port"]?.Length > 1 ? config["port"] : "12345"; - var server = new TinyWebServer.WebServer(request => - { - string path = request.Url.PathAndQuery.ToLower(); - string query = ""; - string json = ""; - if (path.Contains("?")) - { - string[] parts = path.Split('?'); - path = parts[0]; - query = parts[1]; - } + var server = new TinyWebServer.WebServer(request => + { + string path = request.Url.PathAndQuery.ToLower(); + string query = ""; + string json = ""; + if (path.Contains("?")) + { + string[] parts = path.Split('?'); + path = parts[0]; + query = parts[1]; + } - switch (path) - { - //GET: http://localhost:12345/mine - case "/mine": - return chain.Mine(); + switch (path) + { + //GET: http://localhost:12345/mine + case "/mine": + return chain.Mine(); - //POST: http://localhost:12345/transactions/new - //{ "Amount":123, "Recipient":"ebeabf5cc1d54abdbca5a8fe9493b479", "Sender":"31de2e0ef1cb4937830fcfd5d2b3b24f" } - case "/transactions/new": - if (request.HttpMethod != HttpMethod.Post.Method) - return $"{new HttpResponseMessage(HttpStatusCode.MethodNotAllowed)}"; + //POST: http://localhost:12345/transactions/new + //{ "Amount":123, "Recipient":"ebeabf5cc1d54abdbca5a8fe9493b479", "Sender":"31de2e0ef1cb4937830fcfd5d2b3b24f" } + case "/transactions/new": + if (request.HttpMethod != HttpMethod.Post.Method) + return $"{new HttpResponseMessage(HttpStatusCode.MethodNotAllowed)}"; - json = new StreamReader(request.InputStream).ReadToEnd(); - Transaction trx = JsonConvert.DeserializeObject(json); - int blockId = chain.CreateTransaction(trx.Sender, trx.Recipient, trx.Amount); - return $"Your transaction will be included in block {blockId}"; + json = new StreamReader(request.InputStream).ReadToEnd(); + Transaction trx = JsonConvert.DeserializeObject(json); + int blockId = chain.CreateTransaction(trx.Sender, trx.Recipient, trx.Amount); + return $"Your transaction will be included in block {blockId}"; - //GET: http://localhost:12345/chain - case "/chain": - return chain.GetFullChain(); + //GET: http://localhost:12345/chain + case "/chain": + return chain.GetFullChain(); - //POST: http://localhost:12345/nodes/register - //{ "Urls": ["localhost:54321", "localhost:54345", "localhost:12321"] } - case "/nodes/register": - if (request.HttpMethod != HttpMethod.Post.Method) - return $"{new HttpResponseMessage(HttpStatusCode.MethodNotAllowed)}"; + //POST: http://localhost:12345/nodes/register + //{ "Urls": ["localhost:54321", "localhost:54345", "localhost:12321"] } + case "/nodes/register": + if (request.HttpMethod != HttpMethod.Post.Method) + return $"{new HttpResponseMessage(HttpStatusCode.MethodNotAllowed)}"; - json = new StreamReader(request.InputStream).ReadToEnd(); - var urlList = new { Urls = new string[0] }; - var obj = JsonConvert.DeserializeAnonymousType(json, urlList); - return chain.RegisterNodes(obj.Urls); + json = new StreamReader(request.InputStream).ReadToEnd(); + var urlList = new { Urls = new string[0] }; + var obj = JsonConvert.DeserializeAnonymousType(json, urlList); + return chain.RegisterNodes(obj.Urls); - //GET: http://localhost:12345/nodes/resolve - case "/nodes/resolve": - return chain.Consensus(); - } + //GET: http://localhost:12345/nodes/resolve + case "/nodes/resolve": + return chain.Consensus(); + } - return ""; - }, - $"http://{host}:{port}/mine/", - $"http://{host}:{port}/transactions/new/", - $"http://{host}:{port}/chain/", - $"http://{host}:{port}/nodes/register/", - $"http://{host}:{port}/nodes/resolve/" - ); + return ""; + }, + $"http://{host}:{port}/mine/", + $"http://{host}:{port}/transactions/new/", + $"http://{host}:{port}/chain/", + $"http://{host}:{port}/nodes/register/", + $"http://{host}:{port}/nodes/resolve/" + ); - server.Run(); - } + server.Run(); } + } } From 2cc2a7524c36aa33a0f760aa6b30c7262ccb684f Mon Sep 17 00:00:00 2001 From: Trevor D'Arcy-Evans Date: Sun, 5 Dec 2021 20:56:43 +0000 Subject: [PATCH 5/6] - code cleanup --- csharp/BlockChain.Console/Program.cs | 6 +++--- csharp/BlockChain/Block.cs | 8 ++++---- csharp/BlockChain/BlockChain.cs | 22 +++++++++++----------- csharp/BlockChain/Node.cs | 6 +++--- csharp/BlockChain/WebServer.cs | 15 +++++++-------- 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/csharp/BlockChain.Console/Program.cs b/csharp/BlockChain.Console/Program.cs index af8bb018..cbc9bc3f 100644 --- a/csharp/BlockChain.Console/Program.cs +++ b/csharp/BlockChain.Console/Program.cs @@ -1,7 +1,7 @@ -using Microsoft.Extensions.Configuration; - -namespace BlockChainDemo.Console +namespace BlockChainDemo.Console { + using Microsoft.Extensions.Configuration; + public class Program { public static void Main(string[] args) diff --git a/csharp/BlockChain/Block.cs b/csharp/BlockChain/Block.cs index 7e7d60af..11fccd1e 100644 --- a/csharp/BlockChain/Block.cs +++ b/csharp/BlockChain/Block.cs @@ -1,8 +1,8 @@ -using System; -using System.Collections.Generic; - -namespace BlockChainDemo +namespace BlockChainDemo { + using System; + using System.Collections.Generic; + public class Block { public int Index { get; set; } diff --git a/csharp/BlockChain/BlockChain.cs b/csharp/BlockChain/BlockChain.cs index 7fe791e2..5657d6e7 100644 --- a/csharp/BlockChain/BlockChain.cs +++ b/csharp/BlockChain/BlockChain.cs @@ -1,15 +1,15 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net; -using System.Security.Cryptography; -using System.Text; - -namespace BlockChainDemo +namespace BlockChainDemo { + using Newtonsoft.Json; + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.IO; + using System.Linq; + using System.Net; + using System.Security.Cryptography; + using System.Text; + public class BlockChain { private List _currentTransactions = new List(); diff --git a/csharp/BlockChain/Node.cs b/csharp/BlockChain/Node.cs index 6fe39e11..35d41f89 100644 --- a/csharp/BlockChain/Node.cs +++ b/csharp/BlockChain/Node.cs @@ -1,7 +1,7 @@ -using System; - -namespace BlockChainDemo +namespace BlockChainDemo { + using System; + public class Node { public Uri Address { get; set; } diff --git a/csharp/BlockChain/WebServer.cs b/csharp/BlockChain/WebServer.cs index fd5930d6..3f3b4302 100644 --- a/csharp/BlockChain/WebServer.cs +++ b/csharp/BlockChain/WebServer.cs @@ -1,12 +1,11 @@ -using Newtonsoft.Json; -using System.Configuration; -using System.IO; -using System.Net; -using System.Net.Http; -using Microsoft.Extensions.Configuration; - -namespace BlockChainDemo +namespace BlockChainDemo { + using System.IO; + using System.Net; + using System.Net.Http; + using Microsoft.Extensions.Configuration; + using Newtonsoft.Json; + public class WebServer { public WebServer(BlockChain chain, IConfiguration config) From 03a3f731b63b364b36ed70ccc829251fa887c767 Mon Sep 17 00:00:00 2001 From: Trevor D'Arcy-Evans Date: Sun, 5 Dec 2021 21:04:38 +0000 Subject: [PATCH 6/6] - code cleanup --- csharp/BlockChain/BlockChain.cs | 42 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/csharp/BlockChain/BlockChain.cs b/csharp/BlockChain/BlockChain.cs index 5657d6e7..4502916f 100644 --- a/csharp/BlockChain/BlockChain.cs +++ b/csharp/BlockChain/BlockChain.cs @@ -34,9 +34,9 @@ private void RegisterNode(string address) private bool IsValidChain(List chain) { - Block block = null; - Block lastBlock = chain.First(); - int currentIndex = 1; + Block block; + var lastBlock = chain.First(); + var currentIndex = 1; while (currentIndex < chain.Count) { block = chain.ElementAt(currentIndex); @@ -46,11 +46,15 @@ private bool IsValidChain(List chain) //Check that the hash of the block is correct if (block.PreviousHash != GetHash(lastBlock)) + { return false; + } //Check that the Proof of Work is correct if (!IsValidProof(lastBlock.Proof, block.Proof, lastBlock.PreviousHash)) + { return false; + } lastBlock = block; currentIndex++; @@ -62,7 +66,7 @@ private bool IsValidChain(List chain) private bool ResolveConflicts() { List newChain = null; - int maxLength = _chain.Count; + var maxLength = _chain.Count; foreach (Node node in _nodes) { @@ -77,7 +81,7 @@ private bool ResolveConflicts() chain = new List(), length = 0 }; - string json = new StreamReader(response.GetResponseStream()).ReadToEnd(); + var json = new StreamReader(response.GetResponseStream()).ReadToEnd(); var data = JsonConvert.DeserializeAnonymousType(json, model); if (data.chain.Count > _chain.Count && IsValidChain(data.chain)) @@ -115,23 +119,25 @@ private Block CreateNewBlock(int proof, string previousHash = null) private int CreateProofOfWork(int lastProof, string previousHash) { - int proof = 0; + var proof = 0; while (!IsValidProof(lastProof, proof, previousHash)) + { proof++; + } return proof; } private bool IsValidProof(int lastProof, int proof, string previousHash) { - string guess = $"{lastProof}{proof}{previousHash}"; - string result = GetSha256(guess); + var guess = $"{lastProof}{proof}{previousHash}"; + var result = GetSha256(guess); return result.StartsWith("0000"); } private string GetHash(Block block) { - string blockText = JsonConvert.SerializeObject(block); + var blockText = JsonConvert.SerializeObject(block); return GetSha256(blockText); } @@ -140,11 +146,13 @@ private string GetSha256(string data) var sha256 = new SHA256Managed(); var hashBuilder = new StringBuilder(); - byte[] bytes = Encoding.Unicode.GetBytes(data); - byte[] hash = sha256.ComputeHash(bytes); + var bytes = Encoding.Unicode.GetBytes(data); + var hash = sha256.ComputeHash(bytes); foreach (byte x in hash) + { hashBuilder.Append($"{x:x2}"); + } return hashBuilder.ToString(); } @@ -152,10 +160,10 @@ private string GetSha256(string data) //web server calls internal string Mine() { - int proof = CreateProofOfWork(_lastBlock.Proof, _lastBlock.PreviousHash); + var proof = CreateProofOfWork(_lastBlock.Proof, _lastBlock.PreviousHash); CreateTransaction(sender: "0", recipient: NodeId, amount: 1); - Block block = CreateNewBlock(proof /*, _lastBlock.PreviousHash*/); + var block = CreateNewBlock(proof /*, _lastBlock.PreviousHash*/); var response = new { @@ -185,20 +193,20 @@ internal string RegisterNodes(string[] nodes) var builder = new StringBuilder(); foreach (string node in nodes) { - string url = $"http://{node}"; + var url = $"http://{node}"; RegisterNode(url); builder.Append($"{url}, "); } builder.Insert(0, $"{nodes.Count()} new nodes have been added: "); - string result = builder.ToString(); + var result = builder.ToString(); return result.Substring(0, result.Length - 2); } internal string Consensus() { - bool replaced = ResolveConflicts(); - string message = replaced ? "was replaced" : "is authoritive"; + var replaced = ResolveConflicts(); + var message = replaced ? "was replaced" : "is authoritive"; var response = new {