Skip to content

Commit

Permalink
Initial upload
Browse files Browse the repository at this point in the history
  • Loading branch information
bjoerntx committed Aug 2, 2019
1 parent 65db868 commit 88ab47c
Show file tree
Hide file tree
Showing 126 changed files with 90,977 additions and 0 deletions.
25 changes: 25 additions & 0 deletions tx_blockchain.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28729.10
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tx_blockchain", "tx_blockchain\tx_blockchain.csproj", "{6AACD7A7-B242-4B60-8687-A3AE6F09596F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6AACD7A7-B242-4B60-8687-A3AE6F09596F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6AACD7A7-B242-4B60-8687-A3AE6F09596F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6AACD7A7-B242-4B60-8687-A3AE6F09596F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6AACD7A7-B242-4B60-8687-A3AE6F09596F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EA8AC697-9C2A-4A34-AE6D-3407B0364D85}
EndGlobalSection
EndGlobal
Binary file added tx_blockchain/App_Data/nda.tx
Binary file not shown.
Binary file added tx_blockchain/App_Data/test.pdf
Binary file not shown.
23 changes: 23 additions & 0 deletions tx_blockchain/App_Start/RouteConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace tx_blockchain
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
24 changes: 24 additions & 0 deletions tx_blockchain/App_Start/WebApiConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace tx_blockchain
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services

// Web API routes
config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
50 changes: 50 additions & 0 deletions tx_blockchain/Blockchain/Block.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Security.Cryptography;
using System.Text;

// this class contains the structure of a single block in the
// blockchain and stores the document MD5 hash in the data property.
public class Block
{
public int Index { get; set; }
public DateTime TimeStamp { get; set; }
public string PreviousBlockHash { get; set; }
public string BlockHash { get; set; }
public string Data { get; set; }
public int Nonce { get; set; } = 0;

// constructor
public Block (DateTime timeStamp, string previousBlockHash, string data)
{
Index = 0;
TimeStamp = timeStamp;
PreviousBlockHash = previousBlockHash;
Data = data;
BlockHash = GenerateBlockHash();
}

// generates a new hash for the block including the time stamp,
// the previous block has, the data and the nonce.
internal string GenerateBlockHash()
{
SHA256 sha256 = SHA256.Create();

byte[] bInput = Encoding.ASCII.GetBytes($"{TimeStamp}-{PreviousBlockHash ?? ""}-{Data}-{Nonce}");
byte[] bOutput = sha256.ComputeHash(bInput);

return Convert.ToBase64String(bOutput);
}

// this method is generating hashes until a new hash with a specific
// number of leading zeros is created
public void Mine(int difficulty)
{
string sLeadingZeros = new string('0', difficulty);

while (this.BlockHash == null || this.BlockHash.Substring(0, difficulty) != sLeadingZeros)
{
this.Nonce++;
this.BlockHash = this.GenerateBlockHash();
}
}
}
84 changes: 84 additions & 0 deletions tx_blockchain/Blockchain/Blockchain.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

// this class implements the actual linked list
public class Blockchain
{
public IList<Block> Chain { set; get; }
public int Difficulty { set; get; } = 2;

public Blockchain()
{
InitializeChain();
}

public Blockchain(bool newBlockChain)
{
InitializeChain();
AddGenesisBlock(); // add the first block
}

public void InitializeChain()
{
Chain = new List<Block>();
}

public Block CreateGenesisBlock()
{
return new Block(DateTime.Now, null, "{}");
}

public void AddGenesisBlock()
{
Chain.Add(CreateGenesisBlock());
}

// return the last block in the list
public Block GetCurrentBlock()
{
return Chain[Chain.Count - 1];
}

// adds a new block to the chain
public void AddBlock(Block block)
{
// check blockchain consistency first
if (this.IsValid() == true)
{
Block latestBlock = GetCurrentBlock();
block.Index = latestBlock.Index + 1;
block.PreviousBlockHash = latestBlock.BlockHash;

// mine for a valid hash
block.Mine(this.Difficulty);

// add the block to the chain
Chain.Add(block);
}
}

// checks, if the blockchain is consistent by
// re-generating and comparing the hashes in each block
public bool IsValid()
{
for (int i = 1; i < Chain.Count; i++)
{
Block currentBlock = Chain[i];
Block previousBlock = Chain[i - 1];

if (currentBlock.BlockHash != currentBlock.GenerateBlockHash())
{
return false;
}

if (currentBlock.PreviousBlockHash != previousBlock.BlockHash)
{
return false;
}
}

return true;
}
}
42 changes: 42 additions & 0 deletions tx_blockchain/CSS/site.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.viewer {
height: calc(100vh - 56px);
}

.verified::before {
font-size: 100px;
font-family: "Font Awesome 5 Free";
font-weight: 900;
content: "\f058";
}

.notverified::before {
font-size: 100px;
font-family: "Font Awesome 5 Free";
font-weight: 900;
content: "\f057";
}

.result {
display: block;
}

.verified {
color: green;
}

.notverified {
color: red;
}

.result-text-notverified::before {
content: "The document could not be validated with the last block on the blockchain.";
}

.result-text-verified::before {
content: "The document has been validated with the last block on the blockchain.";
}

#tx-documentViewer {
top: 56px !important;
height: calc(100vH - 56px) !important;
}
2 changes: 2 additions & 0 deletions tx_blockchain/ClassDiagram1.cd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<ClassDiagram />
116 changes: 116 additions & 0 deletions tx_blockchain/Controllers/DocumentController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
using Newtonsoft.Json;
using System;
using System.Web.Http;
using System.Web.Mvc;
using tx_blockchain.Helpers;
using tx_blockchain.Models;

namespace tx_blockchain.Controllers
{
public class DocumentController : Controller
{
// this method stores the document hash in the blockchain
[System.Web.Http.HttpPost]
public ActionResult StoreDocument(
[FromBody] string Document,
[FromBody] string UniqueId,
[FromBody] string SignerName)
{
byte[] bPDF;

// create temporary ServerTextControl
using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl())
{
tx.Create();

// load the document
tx.Load(Convert.FromBase64String(Document),
TXTextControl.BinaryStreamType.InternalUnicodeFormat);

TXTextControl.SaveSettings saveSettings = new TXTextControl.SaveSettings()
{
CreatorApplication = "TX Text Control Sample Application",
};

// save the document as PDF
tx.Save(out bPDF, TXTextControl.BinaryStreamType.AdobePDF, saveSettings);
}

// calculate the MD5 checksum of the binary data
// and store in SignedDocument object
SignedDocument document = new SignedDocument()
{
Checksum = Checksum.CalculateMD5(bPDF)
};

// define a Blockchain object
Blockchain bcDocument;

// if the blockchain exists, load it
if (System.IO.File.Exists(
Server.MapPath("~/App_Data/Blockchains/" + UniqueId + ".bc")))
{
string bc = System.IO.File.ReadAllText(
Server.MapPath("~/App_Data/Blockchains/" + UniqueId + ".bc"));

bcDocument = JsonConvert.DeserializeObject<Blockchain>(bc);
}
else
bcDocument = new Blockchain(true); // otherwise create a new blockchain

// add a new block to the blockchain and store the SignedDocument object
bcDocument.AddBlock(new Block(DateTime.Now, null, JsonConvert.SerializeObject(document)));

// store the blockchain as a file
System.IO.File.WriteAllText(
Server.MapPath("~/App_Data/Blockchains/" + UniqueId + ".bc"),
JsonConvert.SerializeObject(bcDocument));

// create and return a view model with the PDF and the unique document ID
StoredDocument storedDocument = new StoredDocument()
{
PDF = Convert.ToBase64String(bPDF),
DocumentId = UniqueId
};

return new JsonResult() { Data = storedDocument,
JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}

// this method validates a document with the last block on the blockchain
[System.Web.Http.HttpPost]
public bool ValidateDocument([FromBody] string Document, [FromBody] string UniqueId)
{
if (Document == null || UniqueId == null)
return false;

// calculate the MD5 of the uploaded document
string sChecksum = Checksum.CalculateMD5(Convert.FromBase64String(Document));

Blockchain newDocument;

// load the associated blockchain
if (System.IO.File.Exists(
Server.MapPath("~/App_Data/Blockchains/" + UniqueId + ".bc")))
{
string bc = System.IO.File.ReadAllText(
Server.MapPath("~/App_Data/Blockchains/" + UniqueId + ".bc"));

newDocument = JsonConvert.DeserializeObject<Blockchain>(bc);

// get the SignedDocument object from the block
SignedDocument signedDocument =
JsonConvert.DeserializeObject<SignedDocument>(newDocument.GetCurrentBlock().Data);

// compare the checksum in the stored block
// with the checksum of the uploaded document
if (signedDocument.Checksum == sChecksum)
return true; // document valid
else
return false; // not valid
}
else
return false; // blockchain doesn't exist
}
}
}
Loading

0 comments on commit 88ab47c

Please sign in to comment.