Mastering Bitcoin Exercises

by Mikong Galero

Welcome to the Mastering Bitcoin Exercises workbook! This book provides supplementary exercises to the book Mastering Bitcoin 2nd Edition by Andreas M. Antonopoulos.

How This Book is Organized

The exercises in this book are simply grouped by the chapters of the Mastering Bitcoin 2nd Edition.

License

"Mastering Bitcoin - Second Edition" by Andreas M. Antonopoulos LLC is licensed under CC BY-SA 4.0.

Creative Commons License

"Mastering Bitcoin Exercises" is therefore also licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Source

The source files from which this book is generated can be found on GitHub.

1. Introduction

1.1 Digital signature with OpenSSL

Use the openssl command-line tool to create an RSA key pair and to sign and verify a text file.

  1. Prepare an arbitrary text file to be signed.
  2. Generate an RSA private key with key length of 2048 bits.
  3. Extract the public key from the private key.
  4. Sign the text file using SHA256 and your private key, and output a signature file.
  5. Verify the signature of the text file using the public key.

1.2 A simple QR code

Use a QR code generator to generate a QR code that simply contains the text "hi". Identify the different parts of the QR code such as the positioning markings, the format information, the timing pattern, and so on. If you can, find where the "h" and "i" is located in the grid of black and white.

2. How Bitcoin Works

2.1 Payment request QR code

Construct a QR code for a payment request with the following details:

  • Bitcoin address: "mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r"
  • Amount: "0.00001"
  • Label: "Blips and Chitz"
  • Message: "Purchase tokens at Blips and Chitz"

Scan the QR code with a QR code reader to verify its contents.

Reading: BIP-21 is a short proposal that describes the URI scheme used in payment request QR codes.

2.2 Cryptographic hash puzzle

Repeatedly compute the SHA256 hash of the following simplified header (in JSON), incrementing the nonce in every iteration, until the resulting hash starts with three consecutive zeros.

{
  "height": 0,
  "version": 1,
  "merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
  "nonce" : 0
}

3. Bitcoin Core: The Reference Implementation

Chapter 3 of the book Mastering Bitcoin 2nd Edition is a highly technical chapter for setting up a development environment. It walks you through compiling Bitcoin Core and configuring/running your own node. If you follow the steps and explore the help documentation as described in the chapter, there's more than enough exercises to work on.

The last section of that chapter is Alternative Clients, Libraries and Toolkits. It lists some libraries, clients and toolkits grouped by programming language. We can work on exercises that use any of these to expand on this chapter. With your programming language of choice, select the software in the list that you would like to explore and see if you can do any of the exercises below.

3.1 Decode a raw transaction

Using a client library, decode Alice's coffee transaction with the following transaction ID:

0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2

Depending on the library, you may have to initially obtain a serialized transaction that you will then have to decode, or you may directly get a human-readable format of the transaction.

Check that you can see the same transaction inputs and outputs as in the book.

3.2 Find Alice's transaction in the block

In the book, we saw that Alice's transaction was included in block 277316. Using a client library, obtain this block and find Alice's transaction in the list of transactions that the block contains.

3.3 Execute getmempoolinfo

The book mentioned getmempoolinfo as one of the more important RPC commands. Using the Bitcoin Core client or an alternative client library with a similar command, execute this command and get the details of the memory pool such as the minimum fee rate for a transaction to be accepted.

4. Keys, Addresses

4.1 Generate a private key

Your program should use a cryptographically secure pseudorandom number generator (CSPRNG) to generate random bits with sufficient entropy (at least 256 bits) and compute its SHA256 hash. Repeat this process in a loop until the value is less than the prime p as defined in the secp256k1 standard:

    p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
= 2256 - 232 - 29 - 28 - 27 - 26 - 24 - 1

Some programming languages may require a bignum library for dealing with very large numbers.

Reading: You may need to read more about entropy to make sure that your random number has sufficient entropy. Different operating systems have different sources of entropy.

4.2 Confirm point is on the elliptic curve

In the Elliptic Curve Cryptography Explained section of the book, the following example point P with coordinates (x, y) on the secp256k1 curve is given:

P = (55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424)

The book then provides a sample Python code to confirm that the point is on the elliptic curve:

p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
x = 55066263022277343669578718895168534326250603453777594175500187360389116729240
y = 32670510020758816978083085130507043184471273380659243275938904335757337482424
(x ** 3 + 7 - y**2) % p

If you're using a different programming language, write a similar program to do the same. Make sure that your program can handle very large signed integers. The secp256k1 curve is defined by the following function that you should use in your program:

    y2 mod p = (x3 + 7) mod p

4.3 Generate a public key with OpenSSL

Use the OpenSSL cryptographic library's EC_POINT_mul() to generate a public key. You can use the private key that you have generated in exercise 4.1 or alternatively, use the example private key from the book:

1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD

Use the library's elliptic curve point multiplication to multiply the private key with the generator point G in order to produce the public key K.

    K = k * G

Remember that Bitcoin uses a specific elliptic curve and set of constants defined in a standard called secp256k1. From the Standards for Efficient Cryptography (SEC), the base point G in compressed form is:

G = 02 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798

and in uncompressed form is:

G = 04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
       483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8

4.4 Convert a public key into a bitcoin address

Using the public key generated from the previous exercise, compute its SHA256 hash and then compute the RIPEMD160 hash of the result to produce a 160-bit bitcoin address.

    A = RIPEMD160(SHA256(K))

This double-hash function is called HASH160.

5. Wallets

5.1 Generate mnemonic words

Write a program to generate and print mnemonic words from a given random sequence of bits.

  1. Create a random sequence (entropy) of 128/160/192/224/256 bits.
  2. Compute the SHA256 hash of the random sequence. Take the first (entropy-length/32) bits of its hash as the checksum.
  3. Concatenate the random sequence and the checksum.
  4. Divide the result into sections of 11 bits.
  5. Map each 11-bit value to a word from the predefined dictionary of 2048 words.
  6. Print the mnemonic words in the correct order.

Table 5-1: Checksum bits and number of mnemonic words depend on length of entropy.

Entropy (bits) Checksum (bits) Mnemonic length (words)
128 4 12
160 5 15
192 6 18
224 7 21
256 8 24

Get the dictionary/wordlist from BIP-39. There's a section that describes the characteristics of an ideal wordlist, and a separate section that links to the actual wordlists.

5.2 PBKDF2

Password-Based Key Derivation Function 2 (PBKDF2) is a key derivation function to make brute force attacks more difficult with key stretching.

    DK = PBKDF2(PRF, Password, Salt, c, dkLen)

Given the following parameters, use a PBKDF2 library to derive a key:

  • c (number of rounds): 4096
  • PRF (pseudorandom function): HMAC-SHA256
  • dkLen (derived key length): 256

The PBKDF2 key derivation function takes two more parameters: a password, and a salt. For this exercise, you can choose arbitrary values for these two.

6. Transactions

7. Advanced Transactions and Scripting

8. The Bitcoin Network

9. The Blockchain

10. Mining and Consensus

11. Bitcoin Security

12. Blockchain Applications