Errata

Programming Bitcoin

Errata for Programming Bitcoin

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date submitted
PDF Page chapter10 networking
page 181

testnet.programmingbitcoin.com,
502 Bad Gateway
nginx/1.21.6

Anonymous  Jan 08, 2023 
Printed Page Page 57-58
Coding for binary expansion

I always get an exception when I try to scalar Multiplication for 4*G (just a test)

When you test 4*G thru non Binary expansion you receive an new point.

When you run 4*G thru Binary expansion you get an error on: 2(G) + 2(G)


Here is the loop for 4*G. 4 in binary is 100

So thru the while (Binary Expansion)you would get:

G + G = 2(G) = current
second time thru:
2(G) + 2(G) = 4(G) = current. this returns a point not on the curve

Third time you would get
result = result +current = result = 4(G)
4(G) + 4(G) = 8(G)

then you return result which is 4(G)

what happens when 8(G) is not on the curve? you will get an error before returning


David Ramer  Jan 09, 2023 
PDF Page Chapter 1: Finite Fields page 2
Chapter 1: Finite Fields page 2


In the Chapter 1: Finite Fields page 2 there might be an error or this text is just redundant:
"neither is 2 + 2 = 4"

Oleg  Jan 25, 2023 
Printed Page x
7

I tried to install package by inputting
C:\programmingbitcoin> virtualenv -p
on command prompt, but was not successful with following message:

It is not recognized as an internal commands, external commands, operable program or batch file.

Could you let me know how to fix it?

Junya Matsubayashi  Jan 25, 2023 
Printed Page Page-278
Line 9, 10, and 19

On page 278 solution for Exercise 12 of Chapter 9,
line 9 reads last_block = ...block1_hex..., it should be last_block = ...block2_hex...
line 10 reads first_block = ...block2_hex..., it should be first_block = ...block1_hex...
As a result, the final printout (line 19) should be 308d0118 instead of 80df6217.
More details: block1_hex is from block height 471744 and block2_hex is from block height 473759, so block1_hex is the first block while block2_hex is the last block. I have also confirmed that the final printout of 308d0118 agrees with the block header found in the next block 473760.

Hongzheng Jin  Aug 09, 2023 
PDF Page Preface, page xix
Right in the middle of the page

In the book, a typographical or typewriting error was identified in the phrase 'This element indicates a waning or caution.' The correct term should be 'This element indicates a warning or caution.', where the word 'waning' is incorrect and should be replaced by 'warning' to accurately reflect the intended meaning.

Alexandre Leite  Dec 02, 2023 
Printed Page Page 13 (Coding Exponentiation in Python)
Exercise 7

The set in exercise 7 is supposed to have p elements, per the definition of p on page 3. But, since it starts with 1^(p-1) and ends with (p-1)^(p-1), we end up with p-1, not p, elements in the set.

This is confirmed in the solution on page 253, where p = 7 => [1, 1, 1, 1, 1, 1] (six, not seven, elements).

Yngve Høiseth  Feb 15, 2024 
Printed Page 14
3rd paragraph

It states that "$n^(p-1)$ is always 1 for every p that is prime and every n > 0". It forgets one important condition - n must not be divisible by p.

In the following explanation for Fermat's Little Theorem, this condition was also missing.

Xinyu Xiang  Jul 19, 2021 
Printed, PDF, ePub Page 17
first paragraph

The two _pow__ implementations on page 13 and page 17 don't always produce the same results when num is zero

For example, FieldElement(0, 13) ** 12 yields different results:
(Page 13): FieldElement(0, 13)
(Page 17): FieldElement(1, 13)

Simon Liu  May 17, 2022 
Printed Page 43
Figure 3-2

Finite Fields example uses order 103 but the graph 3-2 has points that go up to 200.

Franck Murialdo  May 11, 2019 
PDF Page 44
last paragraph

"We will do this using the results of Exercise 2:"

should be:

"We will do this using the results of Exercise 1:"

Richard de Jong  Aug 11, 2022 
PDF Page 61
Above chapter 'Public Key Cryptography'

The code:
G = S256Point(
0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8)

... can be replaced by:
G = S256Point(gx, gy)

Since you've defined those earlier.

Richard de Jong  Aug 31, 2022 
Printed Page 140
1st code block

tx_outs is initialised but not used.

Michael Shearer  Dec 05, 2021 
Printed Page 173
Exercise 9

Exercise 9 tells the reader to implement the bits_to_target function to satisfy test_target, but this test also calls the difficulty method, which is only implemented in exercise 10.

Otto  May 01, 2020 
Printed Page 176
Ex 12

first and last is flipped in the answer, giving a negative time differential and wrong new target/bits

Linnéa Rosenbaum  Aug 23, 2019 
Printed Page 191
Figure 11-1 Merkle Tree

It says Hash(Tx A) for HA, HB, HC and HD when it should be Hash(Tx B) for HB, etc...

Franck Murialdo  Aug 14, 2019 
Printed Page 206
practice 6

The sentence of getdata(TX_DATA_TYPE, tx_obj.hash()) which is included the answer of chapter 12 practice 6 In the page 270,
when I change the parameter tx_obj.hash() to a random data ,the result is success too ,
then I note the sentence , but the result always is success .
so, I have two questions for it, the first one, what is the second parameter tx_obj.hash() effect.
and the second, could you tell me ,why it always print success ,when I note the sentence .

zhiguo  Jan 18, 2022 
Printed Page 208
line 12

Line 12: Hop (13) is given, so the flag is 1 ...
Correction: ..., so the flag is 0...

Hongzheng Jin  Aug 13, 2023 
Printed Page 223
Figure 13-1, 13-2

ScriptPubKey on figures 13-1, 13-2 doesn't seem to match the ScriptPubKey for p2wpkh of: OP_0 <20-byte hash>.

Roberto Serrano  Feb 10, 2022 
PDF Page 252
Exercise 5

The solution of chapter 1, exercise 5 should be:

print([k*i % prime for i in range(0,prime-1)])

and not

print([k*i % prime for i in range(prime)])

Actually, in Chapter1.ipynb says

# loop through all possible k's 0 up to prime-1
# calculate k*iterator % prime

But the solution in answer.py and page 252 of pdf implement range(prime)

Wae Chan  May 31, 2019 
Printed Page 271
Solution for exercise 1

There seem to be a bug in the solution for exercise 1 in chapter 8 (page 271).
For example. Let say we have 1-of-1 multi signature. I can sign a
transaction with arbitrary private key and the function still returns true and a
stack with one element. After the while loop we should check if the verification was
successful. Here is a quick fix.

def op_checkmultisig(stack, z):
if len(stack) < 1:
return False
n = decode_num(stack.pop())
if len(stack) < n + 1:
return False
sec_pubkeys = []
for _ in range(n):
sec_pubkeys.append(stack.pop())
m = decode_num(stack.pop())
if len(stack) < m + 1:
return False
der_signatures = []
for _ in range(m):
# signature is assumed to be using SIGHASH_ALL
der_signatures.append(stack.pop()[:-1])
# OP_CHECKMULTISIG bug
stack.pop()
try:
# parse all the points
points = [S256Point.parse(sec) for sec in sec_pubkeys]
# parse all the signatures
sigs = [Signature.parse(der) for der in der_signatures]
# loop through the signatures
for sig in sigs:
# if we have no more points, signatures are no good
if len(points) == 0:
LOGGER.info("signatures no good or not in right order")
return False
# we loop until we find the point which works with this signature
success = False
while points:
# get the current point from the list of points
point = points.pop(0)
# we check if this signature goes with the current point
if point.verify(z, sig):
succes = True
break
if not success:
return False
# the signatures are valid, so push a 1 to the stack
stack.append(encode_num(1))
except (ValueError, SyntaxError):
return False
return True

Uros Slana  Aug 05, 2019