Skip to content

MisterM13/MonadChainChat

Repository files navigation

Written with StackEdit by Matthias Müller.

Creating a Blockchain based Chat Application - Monad Chain Chat

About the Project

This Project is part of the work for the monad seminar at the University of Basel. The goal is to create a simple chat application, which works on a blockchain, written in haskell with monadic structures.

How to protect the chat data from corruption in case of an application crash?

We have two or three files:

  • the chatevent (= append only log),
  • the metadata
  • and a key file (if it is not also integrated into the metadata file).

To guarantee that no data is lost due to a crash, we make a newevent file, which contains the newly generated informations. Then the newevent and the chatevent file get read out, connected together to a headchatevent file. The headchatevent gets controlled by a special controll function, which generates, if everything was correct, a headmeta file. Then the headmeta file gets proofed. After that, the chatevent gets overwritten by headchatevent and the metadata gets overwritten by headmeta.

First tries in implementing creating & saving functions

As Haskell has a predefined appendFile function, I decided to append every new message / event Block right on the chatevent without making a special head file for this case. Within the appendEvent function, how i called the function to append a new event to the chatevent, i also call the makeMetahead function, which makes the temporary meta file (with a function extractMeta, which should extract the needed information from the chatevent and put it into the headmeta). At the end, when we finished appending messages on the chatevent, we can call the makeMeta function, which reads in the headmeta file and then the chatevent and extracts the data once again from chatevent, then it checks the two datasets with each other, to proof that the metahead file is up to date. If it proofs correct, it copies metahead.txt to meta.txt with one command (doesen't work jet, because the file is locked from the readin, i still have to find a solution for that).

Ordering the messages

As i found no good solution to get a timestamp from the system, I decided to use nummeration. To make it congruent, i still have to find a Way to resolve multiple nummerations so the order is still given over more than one log. I will maybe write the matching/joint numbers in both logs. For the write ahead log i have two ideas to keep it congruent. On one hand i could use a checksum, for all the messages that are saved at the head file. So if something's missing, the checksum doesn't mach. On the other hand i could make a lock file, which is existent during the saving process and deleted afterwards, so if the file is present and it's not during the saving function, something is corrupted. As i overthought the two methods i realised there's a much simpler way. I create a metaHead file then append the new things to the meta file. Once all is appended, the metaHead file is removed. So if something crashes, the file is still present and we know some data is maybe corrupted. Update: On my research for the Elliptic Curve implementation i found the Data.Time.Clock.POSIX module and how to use it. As using the current System time it should be much easier to use, instead of using multiple counters for every chat. So i implemented a time function, which returns the time as integer as nanoseconds since epoch, as this function was already implemented in the example code. Maybe I write also an additional function to prevent time which is older than the current log time.

Multiple chatlogs and timestamps

When I thought about having multiple chatlogs, I stumbled over several problems: First of all i need to find a method to read out all the logs, but haskel readFile doesn't work with regular expressions, so i can't just read out all the Files with:

readFile "*.txt"

The solution i thought for this problem is writing a seperate names.txt file, which includes all the chat names. Then i can read out this file and give the user the option which chat he wants to open. The second problem that comes up, is how to get a timestamp as I won't use a system time function. Hopefully the solution to this is relative nummerating: Every message has two numbers, the first is the number of the own numeration, and the second of the numeration of the other user, so we should get a relative time consistency. However i still have to plan how and which Blockevents get both time numbers and which not.

Problems with imports

At a certain point I met the problem, that I need some special modules like Data.Strings. As I saw them at hackage.haskell.org I first tried just to make import Data.Strings at my file, but the module was not known by the compiler, so I tried to install the module. I tried Cabal and Stack and both gave an error message that the file/folder is unknown. Because the Module was not within the normal Stack files, I couldn't just use stack install, so I imported the files manually by creating a directory Data and putting the File Strings.hs in it and it worked. I had also some Problems importing Crypto.ECC (used for encrypting and hashing) , but then I realized that the package was named Cryptonite-0.30 instead of Crypto.

Elliptic Curve Cryptography

For the ECC I found the Crytonite library, as already mentioned above. But the library didn't have examples and as I'm not very proficient on Elliptic Curve and reading the module descriptions, I had some hard time to find out how to use this module. Luckily I found a Youtube Video about this module (they are likely rare). There was also an other very interesting tutorial Video I can adwise, but it was only about hashing, TOTP and HMac.

Restructuring the Backgrid of the MonadChainChat

As everything got a little bit messy with that lot of files, I tried to restructure the whole architecture. Making different Folders:

Chats : is used to store the readable chat (also known as metadata)

Chatlogs : is used to store the blockchain eventlogs with cryptological verification data

Keystore : is used to store all the keys (own private and public key, and the public key of chat partners)

Import : is used to easely import the files (eventlog and key)

Export : is used to easely export the files (eventlog and key)

I also made a new concept of the makeMeta method. How it should work at the end: schematic

About

a blockchain based chat written in haskell

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published