MP2 uses Go-channels and Go-routines to simulate mining and tamper-resistant log.
Authors: Steve Huang, Asher Kang, Maria Ringes.
Clone the following git repository with git clone https://github.com/Revelation999/mp2
.
Change the current directory into the recently cloned mp2
folder. Start the Bitcoin/Blockchain protocol with go run mp2
.
A) Difficulty Level -- The program will ask the user to enter an n
value between (and including) 0 and 32 such that the difficulty level is set to 2^(256-8n). The larger the value n
, the smaller the difficulty level will be. A smaller difficulty level will make the puzzle harder for the miners to solve.
B) Number of Miners -- The program will ask the user how many miners to simulate in the blockchain. This integer should be greater than 0.
The Logger has 3 methods that define its behavior.
UpdateBlock()
creates the next to-be-solved block on the blockchain and sends it to all the miners to be mined.CheckNonce()
confirms whether the proposed puzzle solution fits the target difficulty value.ListenForUpdate()
runs in aGo-routine
and callsCheckNonce()
on any proposed puzzle solution that is sent by a miner into the logger’s channel.
The Blockchain is a chain of Block structs
that are linked together by HashPointer struct
s. Each HashPointer contains the unique hash value of its Block's BlockHeader
fields, as well as a pointer to the Block
.
The Miners have 2 methods that define their behavior.
Mine()
runs in aGo-routine
and houses the main life-cycle of the miner. It callsHasUpdate()
to check for new blocks from the logger. It repeatedly tries int values as a nonce to solve the puzzle, starting with value 1 and incrementing by 1. Finally, it terminates if the blockchain has been preserved for 5 minutes.HasUpdate()
checks the miner’s channel for a new block sent from the logger. If it has received a new block, the method returns true. Otherwise, it returns false.
At the beginning of the program, the user inputs the difficulty of the mining puzzles. This difficulty is represented as the bits
value in each BlockHeader
. At the creation of a new block, each miner is notified by the logger of this new block and the beginning of a new puzzle. Each miner begins guessing a nonce value whose combined hash value with its BlockHeader
hash value matches the target difficulty level. If a miner is the first to guess a correct solution, the block is added to the Blockchain.
Our program accounts for the Byzantine fault of a miner sending a bogus solution to the logger. The logger's CheckNonce() function returns a boolean false value of 0 if the miner's proposed solution does not solve the puzzle.
The following are screenshots of code from the Bitcoin repository. These lines served as inspiration for our implementation of MP2.
The following screenshot shows an example run with a set difficulty of 2^240. This example consists of 5 miners (B, C, D, E & F).
The following screenshot shows an example run where the a miner proposes a nonce that does not satisfy the puzzle. In this example, we have reversed the compare statement such that as long as the hash value using the proposed nonce is greater than the difficulty, we send the guessed nonce value to the mailbox of the logger. As you can see, this does not force any block update and will just have the miner continue trying other values, hence the repetitive sends to the mailbox of the logger.
type BlockHeader struct {
version int
//hashPrevBlockHeader [32]byte
prevBlockHashPointer HashPointer
merkleRootHashFiller []byte
time int
bits [32]byte
nonce int
}
type HashPointer struct {
hash [32]byte
ptr *Block
}
type Block struct {
blockHeader BlockHeader
transaction string
}
type Message struct {
identity string
nonce int
block Block
}
type Miner struct {
identity string
block Block
mailbox *chan Block
currBlockHash [32]byte
}
type Logger struct {
block Block
currBlockHash [32]byte
mailbox *chan Message
}
0
: Successful1
: Incorrect command line input format2
: External package function error
crypto/sha256