1. SUMMARY This project will involve the creation of a Blockchain miner that doe
ID: 3752267 • Letter: 1
Question
1. SUMMARY
This project will involve the creation of a Blockchain miner that does all the following:
Receives transactions from user or remote node.
Sends transactions to a remote node.
Manages incoming remote node messages using a Queue.
Generates a Merkle Tree and an eventual Merkle Root as part of Transaction processing.
Creates Blockchain Blocks using Proof of Work algorithm.
For this project, you will create the main functionality inside of an existing code base called
BlockchainBasics
. The
BlockchainBasics code that you will begin with is provided along with this document.
BlockchainBasics, once completed, will allow you to run two instances of this app on two different ports that pass
transactions to each other and mine blocks.
This app doesn’t save the blocks into a blockchain, but the central functionality you code into this app will be able
to be plugged in directly into a larger Blockchain application (the code for this will be provided in the coming
weeks) that fully manages a Blockchain, connects to multiple networked nodes, and allows you to trade items on
the network.
However, you will only be turning in the BlockchainBasics code as specified at the end of this doc.
This project will involve the following:
- Socket programming
- Queue
- Multithreading
- Hashing: SHA-256
- Merkle Trees
- Blockchain Proof of Work
2. DETAILS
a. Download BlockchainBasics.zip
i. This includes the following classes:
1. BlockchainBasics.java
2. Miner.java
3. Block.java
4. MerkleNode.java
5. BlockchainUtil.java
6. P2PServer.java
7. P2PMessageQueue.java
8. P2PMessage.java
9. P2PUtil.java
b. You only add code where you see this:
####################
### ADD CODE HERE ###
####################
c.
CLASSES where you add code:
d. Miner
i. doProofOfWork method: The logic behind this will be reviewed in class.
1. This method should first create a string that has as many zeros in it as oBlock.getDifficulty()
equals.
a.
Hint: use a while loop here that keeps looping while the length of this string you’re creating is
less than the target difficulty length.
2. Then, this method should keep looping until a valid nonce is found.
a.
The nonce starts at 0 and increments each loop.
b. A valid nonce, after it’s added to the block’s properties and the block is hashed, should result
in a hash that has as many leading zeros as the string you created above (use String’s
startsWith method for this check).
e. Block
i. computeMerkleRoot:
1. Choose which approach you want to take:
a.
The
90% approach
is much easier and is based on what we’ve done in class but your max
score for the project can only reach 90%.
b. The
100% approach
is much trickier, and you must figure out on your own.
2.
90% Project Score Logic
: This logic needs to account for possibly
2 or 4 items
in lstItems that are
passed in.
a.
This means your code should have
2 or 4 Merkle Tree leaves
depending on how many items
are passed in.
3.
100% Project Score Logic
: You can only get 90% on this project if everything else is done
perfectly. To get 100%, you must make this method flexible to accept any multiple of 2 items. So
lstItems could be 2,4,8,16,32, etc. and your code would be able to compute the Merkle Root.
a.
IMPORTANT
: If you choose this route, you’ll have to show me your logic in class
one week
before
the project is due
.
4.
NOTE
: There is a main method at the bottom of this class that you can use to test 2 and 4 items
simply by right clicking on the tab for this class and selecting “Run Block.main()”
ii. populateMerkleNode:
1. This method will work just as we did in class... set the left and right nodes and then call
generateHash in the BlockchainUtil class and set the node’s hash.
f.
BlockchainUtil
i. generateHash:
1. This method generates a SHA-256 hash of the string passed in.
2. Code for this was reviewed in class and doesn’t need to be changed.
g.
P2PMessageQueue
i. enqueue:
1. This adds a node to the queue.
2. Code will be reviewed in class.
ii. dequeue:
1. This removes and returns a node from the queue.
2. Code will be reviewed in class.
iii. hasNodes:
1. This returns true or false depending on if any nodes exist in queue.
2. Code will be reviewed in class.
h. P2PUtil
i. connectForOneMessage:
1. This method will connect to a given server via Socket for a one-time sending of a message to that
server and it will return the reply from the server and disconnect.
2. Code for the Socket communication will be reviewed in class.
3. Testing Your Code
a.
You need to run two instances of this app so that they can communicate with each other.
i. One app can be run from your IDE like you normally do.
ii. The other app must be ran from a PowerShell window or other command line tool as explained below.
b.
Running a separate instance of your app:
i.
Jar file generation
1. You first need to build your code into a JAR file.
2. Instructions are included with the project online and will be reviewed in class.
ii. Running your JAR file
1. Navigate to your JAR file in file explorer.
a.
Shortcut if using IntelliJ:
i. Find it in your left side file explorer in your IntelliJ IDE:
1. ...out > artifacts > BlockchainBasics_jar > BlockchainBasics.jar
ii. Right click on it and pic “Show in Explorer.”
2. Make sure that no file is highlighted by LEFT clicking in right space.
3. SHIFT + RIGHT click in white space as shown in class to get extra menu item of “Open PowerShell
Window here”
4. In PowerShell or other command line tool, type the following to run:
java -jar BlockchainBasics.jar
Use IntelliJ Please and please mark when you make new Java class. Thank you
Explanation / Answer
...
public class Block<T extends Tx> {
public long timeStamp;
private int index;
private List<T> transactions = new ArrayList<T>();
private String hash;
private String previousHash;
private String merkleRoot;
private String nonce = "0000";
// caches Transaction SHA256 hashes
public Map<String,T> map = new HashMap<String,T>();
...
Block.java class
...
public void computeHash() {
Gson parser = new Gson(); // probably should cache this instance
String serializedData = parser.toJson(transactions);
setHash(SHA256.generateHash(timeStamp + index + merkleRoot + serializedData + nonce + previousHash));
}
...
SimpleBlockChain.java
...
...
public class SimpleBlockchain<T extends Tx> {
public static final int BLOCK_SIZE = 10;
public List<Block<T>> chain = new ArrayList<Block<T>>();
public SimpleBlockchain() {
// create genesis block
chain.add(newBlock());
}
...
Here's the method in the Block.java class that creates a Merkle Tree out of the transaction list.
...
public List<String> merkleTree() {
ArrayList<String> tree = new ArrayList<>();
// Start by adding all the hashes of the transactions as leaves of the
// tree.
for (T t : transactions) {
tree.add(t.hash());
}
int levelOffset = 0; // Offset in the list where the currently processed
// level starts.
// Step through each level, stopping when we reach the root (levelSize
// == 1).
for (int levelSize = transactions.size(); levelSize > 1; levelSize = (levelSize + 1) / 2) {
// For each pair of nodes on that level:
for (int left = 0; left < levelSize; left += 2) {
// The right hand node can be the same as the left hand, in the
// case where we don't have enough
// transactions.
int right = Math.min(left + 1, levelSize - 1);
String tleft = tree.get(levelOffset + left);
String tright = tree.get(levelOffset + right);
tree.add(SHA256.generateHash(tleft + tright));
}
// Move to the next level.
levelOffset += levelSize;
}
return tree;
}
...
Miner.java
private String proofOfWork(Block block) {
String nonceKey = block.getNonce();
long nonce = 0;
boolean nonceFound = false;
String nonceHash = "";
Gson parser = new Gson();
String serializedData = parser.toJson(transactionPool);
String message = block.getTimeStamp() + block.getIndex() + block.getMerkleRoot() + serializedData
+ block.getPreviousHash();
while (!nonceFound) {
nonceHash = SHA256.generateHash(message + nonce);
nonceFound = nonceHash.substring(0, nonceKey.length()).equals(nonceKey);
nonce++;
}
return nonceHash;
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.