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. In contrast to project-related and team-related work where a student may concentrate on one technology as a team member, labs are designed to give each and every student exposure to all the technologies that come into play in the course. 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 your 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 that now is not the time to
learn a new programming language along with the concepts
themselves. So use whatever
programming language you know best.
Lab 6 Due: 5:00 pm, Monday, May 13, 2019
Problem
1: Cryptocurrency and Mining:
BACKGROUND:
WHAT YOU NEED TO DO:
STEP 1:
You may have noticed that in the last lab, the blockchain
magically got created by just adding new transactions. We
are going to modify that in this lab, to make it a tad bit more
realistic.
First,
you will need to think up a name for your new cryptocurrency you
will be mining on your blockchain. You can't call it
Bitcoin or Ether or any other existent cryptocurrency.
Barring that, there are no rules. You could call it
"Barbaracoin" or "Yapstone" or "Foolsgold" or "Capnjack" or
whatever you'd like. You will create a Miner class (see
below). Your Miner will take newly-created transactions
and collect transactions into blocks. Each new block will
include a "coinbase" transaction that creates "Barbaracoins" (or
whatever). The naming of your cryptocurrency is entirely
up to you. Have fun.
Your
cryptocurrency should be denominated in fractional form (similar
to satoshis in bitcoin), and we will keep it
simple: you will need to denominate your cryptocurrency in
1/1000s (milli-coins). So, as an example, 1 "Barbarinsky"
is 10-3, or 0.001, "Barbaracoins". You get the
idea. You will use the fractional form when designating
the Value of an Output (see below).
You are
to create a new class/structure called TxnMemoryPool, which can be
of any type you wish, but a simple list of Transaction
objects/structures will do (order is unimportant), and this will
store your transactions in memory during processing. Note
you will no longer be automatically adding transactions to
blocks on creation of the transactions. Rather, you will
add them to the TxnMemoryPool on creation. This will simulate
receiving them from the network.
If you
plan to use multiple threads, you should set up a method or
function that creates a new unique transaction every 1-10
seconds (if using threads, you can make this decision as you
progress through your testing) and adds each new transaction to
the TxnMemoryPool. If you plan not to use multiple
threads, you may simply pre-create 91 new transactions and add
them to your TxnMemoryPool before beginning mining,
which may prove easier. You should modify your blockchain
code to include a new MAX_TXNS field, which is the maximum
number of transactions per block. You should set this to
10 (including the coinbase transaction). So 9 transactions
+ 1 coinbase transaction = 10 Max.
If
you're wondering what in the world will go in your inputs and
outputs, you might remember that even a SHA-256 hash of a single
character, such as 'a', will always result in a 256-bit,
32-byte hash, every time, ad infinitum. This means
that you could simply stuff a hash of the current
timestamp+some_randomly_generated_number into the inputs, and no
one will be the wiser. Again, we are not concerning
ourselves at this point with "connecting-up" the outputs to the
inputs. Now, speaking of outputs, it's time now to create
a more formal definition of an output: an Output
class/structure. Let's make our new Output look like this:
Note
that it is up to you to determine the best "decimal" format for
your particular language. That may be a Decimal object
(serialized), or an int (knowing that any Value is denominated
in 1/1000s of your currency), etc. That's your call.
So if you placed a "1500" in your Value, that would mean 1.5
"Barbaracoins" (or "CapnJacks", etc.). At this point, you
can put anything you want in the string Script. See above
conversation on inputs.
STEP
2:
You will create a new Miner class/function, that will go through
the TxnMemoryPool (which will eventually be growing at a steady
rate), and your Miner will attempt to create a block whose
Blockhash is less than the target you will set. In this
lab, our target will be calculated as:
Target = coefficient
* 2(0x8 * (exponent – 0x3))
Your Header.Bits (for all blocks) will default to 0x207fffff, which is the
difficulty bits for Regtest. This means that your coefficient
will be '0x7fffff' and your exponent will be
'0x20'. Note that this is just a starting default.
It's designed to make mining a slight challenge but
nothing you're going to spend eternity waiting on (on
average...your mileage may vary...). Feel free to adjust
your bits in order to play around with different levels of
difficulty if you get bored. In our case for this lab, you
will not need to worry about automatically adjusting the mining
difficulty. For example, for a little more challenge, you
could try the difficulty bits value used on Testnet:
0x1d00ffff. When you are done experimenting, you will want
to reset your Header.Bits to the default of 0x207fffff for final submission.
As
you build your candidate blocks, keep in mind you will need a
coinbase transaction as the first transaction in each of the
blocks. This coinbase transaction will create an amount of
your cryptocurrency that is also up to you. You could
follow the bitcoin model and start out with 50 bitcoins, or you
could be more or less generous. That's entirely up to you.
Hopefully
you adequately encapsulated the creation of the genesis block in
your blockchain.
Beyond
this, nothing much changes from Lab 5. And as usual,
unless specified, everything else is up to you.
STEP
3:
You are to write a test case (can be a simple main function or
an actual test harness from a framework) in which you run your
new Blockchain mining. You will create a new Blockchain
and by doing so you will create your genesis block. After
mining the transactions in the TxnMemoryPool, print out the
block height of the tip of the chain.
Submit all code and related files (if any) as specified below.
Finally, and importantly, you are of course free, and
encouraged, to look at the actual bitcoin source code for
mining. But remember, your submission had best not closely
resemble any of that source in such a way that it would indicate
direct copying.
You may find the following references helpful (in addition to the links from previous labs):
The
Bitcoinwiki Article
on Target
The Bitcoinwiki
on Difficulty
Bit-Ish Data Article on Building a Blockchain: Difficulty
Explained
freeCodeCamp Article
on Mining
The Bitcoinwiki
Page on Block Hashing Algorithm
The Bitcoinwiki
Page on Transactions
The Bitcoinwiki
Page on Raw Transactions
The Bitcoinwiki
Page on Blocks
Sample
program that mines
Bitcoin Developer Reference on Target
Stack Exchange conversation
on mining
Use the folder named "lab6" in your Subversion repository. See the syllabus for more info about submission using Subversion. Upload your Lab 6 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.