Each lab will consist of a small problem and details of how to proceed. Each lab is intended to give every student hands-on experience with the core concepts and technologies covered during the course. A student may concentrate, as a team member, on one technology over another for the final project, but labs are designed to give each and every student exposure to all the technologies that come into play. You need to submit labs to the TAs for grading--see submission instructions below. Generally, unless otherwise specified, you will have one week to complete each assigned lab.
See the syllabus for information on grading. Turning in lab assignments on time is required, without exception, and all late deliveries will be penalized, regardless of cause. Submit your assignments to the subversion repository according to the directions on the syllabus page.
You
may
write these solutions in any programming language of
your choice. Our suggestion is now is not the time to
learn a new programming language along with the concepts
themselves. So our suggestion is to use whatever
programming language you know best.
Lab 3 Due: 5:00 pm, Thursday, July 12, 2018
Problem
1: Merkle Tree Algorithm laboratory:
BACKGROUND:
WHAT YOU NEED TO DO:
STEP 1:
You
are to write a program in your programming language of choice
(Java/haskell/C#/python/Go/ruby, etc.) that implements a tamper-proof
Merkle Tree. Note these instructions depend on your having successfully set up Testnet and that the blocks have all been downloaded to your Testnet environment locally. You can verify this quite easily by typing (make sure you have bitd running Testnet):
$ bitc getblock 000000000000004fbc510b95ba2366576879aad7f018b20bf8532267182cb7d1
and see that you get a dump of that block (as opposed to an error).
Visit https://live.blockcypher.com/btc-testnet/block/000000000000004fbc510b95ba2366576879aad7f018b20bf8532267182cb7d1/ and obtain the transaction ids for that particular block. There are 14 Transactions in that block, and they happen to be the same transactions we discussed in class when reviewing Merkle Trees. You can also obtain the transactions by clicking on the "</> API Call" button (see the image below) and selecting and copying the transactions (just the strings of transaction IDs in the txids[] list!) and saving them to a file.
Note you can just as easily copy the Transaction IDs from the results from the getblock call you made at the command line (above) to verify your Testnet chain data.
Once you have the transactions, code your program such that it creates a valid Merkle Tree that hashes to the Merkle Root in the above image, namely: "a259dffe797877b1542f563e8a70c127c788245f7d8a88af05fda7f0d5290fef" (note this root is also in the API Call dump that you pulled the transactions from above). Make sure you have read Chapter 9, "The Blockchain", in Antonopolous. See the example merkle.cpp source file (~mark/pub/56600/src.lecture/lecture.3/merklebuilder) for an example of the algorithm to produce the tree.
You can compile the file with the following command (you will need the libbitcoin core source installed):
g++ -o merkle merkle.cpp -std=c++11 $(pkg-config --cflags --libs libbitcoin)
Don't forget the -std=c++11. If you do want to compile this, you will likely need to compile libbitcoin from source.
At each stage of the hashing process, print out your progress, similar to this output (note this output is actual, you may use it to prove your code's solution at any tree depth).
You are free to design your program in any way you see fit as long as the functions and/or classes produce the correct Merkle Root, and the code you submit is not merkle.cpp. Note you will have to mutz with big endian/little endian transformations along the way to get to the actual Merkle Root for this block, and we discussed this in the lecture when we worked through the block.hashing.py example program. In some languages (Ruby, Python), this will essentially involve reversing the binary strings before and after hashing. See the References section below and look through the example program block.hashing.py for an example on how to do this (in python). Note that block.hashing.py relies on pybitcointools (https://github.com/vbuterin/pybitcointools)
which you will need to install if you want to actually run the python
code. For pybitcointools, you will need to revert to git revision aeb0a2bbb8bbfe421432d776c649650eaeb882a5. You can do this after downloading pybitcointools by changing into the pybitcointools subdirectory and typing:
git log | head
You should see the previous commit at aeb0a2bbb8bbfe421432d776c649650eaeb882a5. That is the one you want. Simply run:
git checkout aeb0a2bbb8bbfe421432d776c649650eaeb882a5
and build as normal.
STEP 2:
References:
You
may
find the following references helpful (in addition to the links
from previous labs):
Bitcoin.org on Merkle Trees
Another Wiki on Merkle Trees
Wikipedia Article on Merkle Trees
On Endianness:
Learn me a bitcoin discussion
Bitcoin Wiki discussion
Bitcoin Developer discussion
Github discussion
Another description
Use the folder named "lab3" in your Subversion repository. See the syllabus for more info about submission using Subversion. Upload your Lab 3 code and any supporting materials to the repo. Please include a README text file to explain what parts of the work you are submitting, where the different parts of the work are located and please provide a little info on how to compile and run your code.