Crypto Currency Project
Crypto Currency Project
Project
Sarang Chaudhari Venkata Koppula Anuj Rai Daman Deep Singh
Harish Yadav
October 26, 2021
Notations
For any natural number n, [n] denotes the set {1, 2, . . . , n}.
Important:
• Deadline: 06 November, 11:59pm
• Maximum score: 120
1 Introduction
In this document, we present our cryptocurrency called DSCoin. Recall, in Lab Module 5, you built a
blockchain. Here, we will extend those ideas to have a (nearly complete) cryptocurrency. First, we introduce
some basic rules/conventions/terminology:
1 For ease of debugging, this will be a small number for our project. Real world blockchains have > 1000 transactions per
block.
2 Strictly speaking, this will not be a linked list; we will discuss this later.
1
Figure 1: The blockchain is an authenticated list of transaction blocks. Each transaction block consists of
transactions (together with additional attributes). Each transaction contains the coin-id, the source of the
transaction (that is, the buyer), the destination (the seller) and coin-source (that is, the previous transaction
block where the source received this coin).
red-flag: what if a malicious party is a miner, and adds invalid blocks to the blockchain? We will address this in Section 2.2.
2
transaction is included in the latest transaction block. If so, the buyer sends a proof of payment to the seller,
and the seller can check this proof. To summarize, here are the steps involved in a transaction from a buyer
to a seller:
maintain the smallest six-digit number that is not used yet (stored as an attribute of the blockchain), and use that as the
coin-id. The miner will also increment this attribute of the blockchain after mining the block.
3
1. adds the transactions to the transaction array trarray.
2. computes Merkle tree on the transaction array. Every node in the Merkle tree has a string attribute
called val. For a leaf node corresponding to transaction, the val is simply CRF applied on a concate-
nation of the coin-id, source id, destination id and trsummary of the coinsrc block corresponding to
this transaction (separated by #).6 For any intermediate node, it is computed by applying the CRF
on the concatenation of left child’s val and right child’s val (separated by #).
3. finds a 10-digit string nonce such that CRF applied on the previous block’s digest,7 the Merkle tree’s
root’s val (i.e., also the current block’s trsummary) and nonce (separated by #) outputs a string with
first four characters being 0. This output is the new block’s digest. Such a nonce can be found by
sequentially searching over the space of all 10-digit strings.
At this point, the miner has computed all the attributes for the new transaction block. The miner simply
adds this transaction block to the blockchain.
• first checks that he/she is indeed the destination for the transaction t.
• next checks the sibling-coupled-path-to-root, and checks that the final value in the sibling-coupled-
path-to-root is equal to trsummary0 .
• checks that each of the dgsti strings are valid (for i ∈ [0, k]) – the seller checks that the first four
characters of dgsti are 0, and that dgsti is correctly computed using dgsti−1 , noncei and trsummaryi .8
• finally checks that dgstk matches the dgst of the last block in the blockchain.
4
transaction. Or maybe the malicious buyer has a miner friend who includes the invalid transaction in the
transaction block.
Interestingly, malicious miners are handled using a clever mix of incentive-engineering and data structures
(and no additional cryptography involved here). First, the blockchain is generalized – instead of having a
linked list, we have a tree-like structure, where we store all leaf blocks of the tree, and for each block, we
have a pointer to the previous block as before. For instance, in Figure 2, we have three leaf blocks – blocks
numbered 9, 11, 12. Note that anyone can identify these maliciously mined blocks – one only needs to check
the validity of each transaction in the block, check if the Merkle tree is computed correctly and finally check
that the digest is computed correctly. We define a transaction block to be valid if the dgst is correct, all
transactions in the block are valid and the Merkle tree is computed properly. You can assume that the first
few blocks (created by the moderator) are valid blocks. The longest valid chain is defined to be the longest
sequence of blocks, starting with the first block, consisting of only valid blocks. If a honest miner is mining a
new block, then the miner finds the longest valid chain, and attaches the new transaction to this valid chain.
For instance, in Figure 2, the longest valid chain is the sequence (1, 2, 3, 4, 6), and therefore, the new block
should have 6 as its previous block. If 6 was also an invalid block, then the longest valid chain terminates
at 4. Finally, if 5 was a valid block, then the longest valid chain would be terminating at 12. 10
Figure 2: The malicious blockchain has a tree-like structure. Each block has a pointer to the previous block,
and we store all leaf-blocks. In this figure, there are three leaf blocks, and four invalid blocks (shown in red).
5
also ensure that the transactions in the transaction block are valid (otherwise, if the miner’s block is invalid,
then all the computing effort goes waste).
2.3 Conclusion
The cryptocurrency described above is close to real-world cryptocurrencies (such as Bitcoin). Here are some
differences:
• Here, we assumed every person has a UID (the kerberosID). In Bitcoin, every person chooses a sign-
ing/verification key, and the verification key is the person’s UID. Whenever someone mines a block,
he/she also computes a signature on the block. 12
• Here, we assumed that every transaction consists of exactly one coin spending, and every miner receives
one coin as reward. In real life, a transaction allows person A to send any number of coins to person
B. Moreover, person A can also include a ’reward’ for the miner. This incentivises the miner to include
person A’s transaction in the transaction block. In this scenario, how should you implement the
pending transactions queue? And how would you modify the mining procedure?
• Bitcoin uses a cool stack-based scripting language. Every transaction includes a small program in this
programming language. You can read more about it here.
Finally, if you are interested in learning more about cryptocurrencies, check out this excellent book.
12 Earlier, we intended to include this in the project, and hence discussed signatures in LM1. However, given that the project
6
3 Assignment Questions
You are given the following classes. For each class, you must implement the missing methods. You are
allowed to add additional attributes if needed.
3.1 Transaction
public class Transaction: This class has the following attributes:
• public String coinID: a 6-digit long string to uniquely identify a cryptocoin. You can assume this
string consists of only digits, and these digits form a number ≥ 100000
• public Members Source: the source member of the transaction (i.e. the buyer)
• public Members Destination: the destination member of the transaction (i.e. the seller)
• public TransactionBlock coinsrc block: the TransactionBlock where the buyer received the coin
in this transaction
7
3.3 Merkle Tree and Related Classes
public class Pair<A,B> : Objects of this class would be used to store each element in the sequence
Sibling-Coupled Path to Root. The attributes of the class are:
• public A First: the first element stored in the object.
• public B Second: the second element stored in the object.
public class TreeNode: This class has the following attributes:
• public TreeNode parent: pointer to the parent node
• public TreeNode left: pointer to the left child node
• public TreeNode right: pointer to the right child node
• public String val: the value contained in this node
public class MerkleTree: This class has the following attributes:
• public TreeNode rootnode: pointer to the root node of the Merkle Tree
This class has the following methods (already implemented):
• public String Build (Transaction[] trarray) : Accepts an array of transactions and builds a Merkle
Tree using it. It returns the rootnode value.
For this class, you’re free to add required attributes and methods from previous modules.
8
– sets the elements of trarray using the input array t.
– sets previous to be null.
– computes the MerkleTree Tree
– sets trsummary to be the string stored at root of Tree.
– sets dgst= null
Note: The previous and dgst attributes are to be carefully set during insertion of the block in the
block chain.
• public boolean checkTransaction (Transaction t ): Checks whether the given transaction is valid
by testing for double spending by traversing the block chain. The method takes as input a transaction
t and does the following:
– checks that the coinsrc block of t contains the transaction t0 such that t0 .coinID = t.coinID
and t0 .Destination = t.Source
– checks that t.coinID has not been spent in any of the transaction blocks between t.coinsrc block
and the current transaction block.
Basically, the idea is to start with the current transaction block, traverse all the way back to the
coinsrc block using the previous pointer until you reach t.coinsrc block, and check that none of
these intermediate blocks are an instance of double spending. 13
3.5 Blockchain
3.5.1 Blockchain Honest
public class BlockChain Honest: This class has the following attributes:
13 Ideally, if you traverse the block chain and do not find t.coinsrc block, then you should throw an exception. Here, for the
sake of simplicity, you can assume that coinsrc block block will be present in all the test cases.
9
• public int tr-count: the number of transactions in each TransactionBlock of the blockchain
• public static final String start string: a string representing the starting dgst for all BlockChain
objects. This string should be equal to “DSCoin”.
• public TransactionBlock lastBlock: represents the last block in the blockchain.
• public void InsertBlock Honest (TransactionBlock newBlock): This method will be used to insert
newBlock to the end of the blockchain. The method does the following:
– sets newBlock.dgst= CRF.Fn(lastBlock.dgst+ “#” + newBlock.trsummary+ “#”+ newBlock.nonce).
– the nonce computation is to be done on-the-go while computing the newBlock.dgst following the
constraints for dgst of a block.
– sets the previous node of newBlock, and lastBlock of the blockchain appropriately.
– the dgst of tB begins with “0000”, and is equal to CRF.Fn(tB.previous.dgst+ “#” + tB.trsummary+
“#” + tB.nonce), 14
– tB.trsummary is correctly computed using tB.trarray
– every transaction in tB.trarray is valid.
10
• public TransactionBlock FindLongestValidChain(): Returns the last transaction block of the
longest chain (in blockchain) in which all the transaction blocks are valid. For this, you have to
consider all the chains with their respective last blocks in the list lastBlocksList. Traverse each
chain up to a valid block, say tb, before which all the blocks are valid in that chain. This chain up to
tb is a valid chain Lastly, return the last block of the longest valid chain. For better understanding,
you may refer to the Figure 2.
• public void InsertBlock Malicious (TransactionBlock newBlock): This method will be used by
to insert newBlock to the end of the longest valid chain in the blockchain. The method does the
following:
– finds the last block of the longest valid chain in the block chain (using FindLongestValidChain
method). Let lastBlock be this block.
– computes the first 10-digit lexicographic string s such that CRF.Fn(lastBlock.dgst+ “#” +
newBlock.trsummary+ “#”+ s) begins with “0000”, and sets newBlock.nonce= s.
– sets newBlock.dgst= CRF.Fn(lastBlock.dgst+ “#” + newBlock.trsummary+ “#”+newBlock.nonce).
– sets the previous node of newBlock, and lastBlock of the blockchain appropriately.
3.6 DSCoin
3.6.1 DSCoin Honest
public class DSCoin Honest: This class has the following attributes:
11
• public BlockChain Honest bChain: the blockchain where all transactions of DSCoin are stored
• public Members[] memberlist: list of all members in the DSCoin system.
• public String latestCoinID
3.7 Members
public class Members: This class has the following attributes:
• public String UID: a unique string representing the member
• public List<Pair<String,TransactionBlock>> mycoins: a list of all coins id of the member along
with the TransactionBlock from where the member received the coin. This list must be arranged in
increasing order of coin-id.
• public Transaction[] in process trans: a list of all transactions (sending coins) that have been
initiated but not finalized yet.
This class has the following methods to be implemented:
• public void initiateCoinsend (String destUID, DSCoin Honest DSobj): Picks the first (coinID,
coinsrc block) tuple from the mycoins list (that is, the pair with the smallest coinID), and removes
it. Next, it creates a Transaction object tobj, adds it to its own in process trans list. Finally, it
adds the transaction to the pendingTransactions list of DSobj.
• public Pair<List<Pair<String,String>>,List<Pair<String,String>>> finalizeCoinsend(Transaction
tobj, DSCoin Honest DSobj) throws MissingTransactionException: This method takes as input a
transaction tobj, and an object DSobj of the DSCoin Honest class. The method first finds the transac-
tion block in the blockchain containing this transaction. Starting with the last block in the blockchain,
check if the transaction is present in the block (this can be done by performing a sequential search in
the trarray of this block). If transaction is not found in the last block, proceed to the previous block,
and repeat. Let tB denote the transaction block containing the transaction tobj.
First, compute the sibling-coupled-path-to-root for proving the membership of transaction tobj in the
Merkle tree of transaction block tB. Recall, the sibling-coupled-path-to-root is a list of pairs of strings,
where each pair stores a node’s value and its sibling node’s value.
Next, the method outputs another list of pairs of strings. Suppose there are k transaction blocks after
tB. The method returns a list having k + 2 pairs. The first pair is (tB.previous.dgst, null). The next
k + 1 pairs are pairs of the form (ti .dgst, ti .previous.dgst + “#00 + ti .trsummary + “#00 + ti .nonce),
where t0 is the transaction block tB, and ti is the ith transaction block after tB.
The method finally deletes this transaction from list in process trans returns these two lists of pairs.
See example in supporting documents.
The method throws an exception “MissingTransactionException” if the concerned transaction not
found in the blockchain.
12
• public void MineCoin (DSCoin Honest DSobj): This method removes the first (DSobj.bChain.tr-count
- 1) number of valid transactions from pendingTransactions. The miner also ensures that there are
no two transactions with the same coin-id among these valid transactions (if there are two or more
transactions with the same coin-id, then the miner keeps only the first one, and dequeues additional
transactions from TransactionQueue so that there are tr-count1 number of valid transactions in the
trarray).
Next, it adds an extra transaction ‘minerRewardTransaction’ at the end for the miner. To create this
extra transaction, the method uses the latestCoinID attribute in DSCoin Honest class. Specifics of
the ‘minerRewardTransaction’ are:
– coinID: latestCoinID
– Source: null
– Destination: miner’s UID
– coinsrc block: null
Using these tr-count number of transactions, the method first creates a block tB, and then inserts it at
the end of the blockchain.
Finally, the method adds (latestCoinID, tB) to the miner’s mycoins.
• public void MineCoin (DSCoin Malicious DSobj): The malicious MineCoin method is similar to the
honest one, except that the block needs to be inserted at the appropriate position (after computing
FindLongestValidChain).
13
3.8 Moderator
public class Moderator: This class has the following methods to be implemented:
• public void initializeDSCoin (DSCoin Honest DSobj, int coinCount): Given an object of class
DSCoin Honest this method allots a total of coinCount coins to all members of DSobj in a round-
robin fashion sequentially starting with the coinID “100000”, adds the newly allotted coins to the
mycoins list of all members and sets the latestCoinID attribute of DSobj as the last allotted coin.
(Please refer to the supporting files to understand the way coins are distributed to the members).
The moderator creates a total of coinCount transactions for distributing each such coin, creates a
total of coinCount / tr-count number of transaction blocks with each having tr-count number of trans-
actions, and inserts them in the block chain. The source of each transaction must be “Moderator”,
the destination of each transaction must be appropriately set, and the coinsrc block must be null.
Finally, some attributes of DSobj and members[i] need to be updated by the Moderator.
Note: The coinIDs, thus, should go like: “100000”, “100001”, “100002”... so on.
• public void initializeDSCoin (DSCoin Malicious DSobj, int coinCount): same as the DSCoin Honest
case. Note that the moderator is assumed to be honest, and therefore the lastBlocksList consists of
only one block at the end of this initialization.
• -3 if each member doesn’t get coinCount coins in round robin fashion. If there are k Mem-
bers, then each member receives coinCount/k number of coins. The coin numbers start with
”100000”, and all these coins must be present in the transaction blocks.
• -3 if the transaction blocks have incorrect attributes (that is, if the value/digest of any block is
incorrect, or if the previous pointer is incorrect).
• -4 if the attributes of DSobj and members array are not appropriately updated. (For each i,
some attributes of members[i] need to be updated by the Moderator. Similarly, the moderator
must update some attributes of DSobj.)
4 Instructions
• Submission instructions for project: You must create a directory whose name is your kerberos
id, followed by “Project” (for example, if your entry number is “xyz120100”, then the folder name
should be “xyz120100Project”). The directory must contain all the files included in supporting code.
Finally, compress this directory, and upload it on Moodle. The file name should be kerberosidProject.zip
(that is, xyz120100Project.zip in the above example).
14
Acknowledgements
This is version 2 of the document. Many thanks to the following students for identifying errors in the
previous version(s) of supporting code/pdf : Chirag, Prateek Mishra, Aditya Agrawal, Aniruddha Deb, Adit
Malhotra, Sachit Sachdeva, Chinmay Mittal, Shamoon Rashid, Vaibhav Saha, Ekansh Singh, Tushar Sethi,
Tanish Gupta, Divyanshu Agarwal, Yash Pravin, Arin Kedia, Aryan Dua, Yeruva Hitesh Reddy, Nikhil
Agarwal, Manthan Dalmia, Divyansh Mittal, Vansh Kachhwal.
If you find any other mistakes, please send an email to [email protected], [email protected]
and [email protected]. Thanks!
15