Previous example used python to describe how PoW works. Replace
the first example with a bash one-liner and remove the unnecessary
details.
Inspired by review comments from Jorge Lesmes
- Remove appendix dedicated to `bx`. They had already been slated for
deletion, as I wrote to a reviewer on 2023-07-27: "I'm also probably
going to delete the library/tool focused appendixes as I don't think
they add anything". After the disclosure of CVE-2023-39910 on August
8th, it's clear that this appendix was worse than useless: it was
harmful.
- Remove other mentions of `bx` in the book. I had not previously
intended this because it looked like a pain, but mentions of a tool
often come across as endorsements to readers and no tool created by
the team behind Libbitcoin is one I would ever want to endorse. I
regret that I didn't remove the mentions earlier in the process of
updating the book.
- Remove appendix dedicated to pycoin. I'm now aware of any problems
with pycoin, but I don't think these sort of short detached tutorials
add anything. Programming Bitcoin is an entire book built on pycoin,
and all of these tools have their own webpages that get updated more
frequently than the book.
- Mention the reason for the long validation time is the verification of
transactions. We previously implied it was download time, but some
people have really fast internet.
- Better describe bitcoind cookie authentication and provide an example
to make it even more clear.
- Add a link to bitcoin-s
- Make the long sidebar on collision attacks even longer by descripting
a pre-image attack in addition to the previous descriptions of second
pre-image and collision. That way we don't conflate pre-image and
second pre-image.
- Remove redundant tip box about an oddity in language about compressed
and uncompressed private keys.
- Link to information about vanity address "mining" (brute forcing)
- Explain why almost nobody uses vanity addresses any more---HD wallets
killed them, plus they suck for privacy.
- Remove example code. It's only useful for base58check addresses, but
those are no longer recommended and (as mentioned above) almost nobody
uses vanity addresses any more, so there's not much point in updating
it for bech32(m).
- Remove vanity address security section with unvetted security claims.
- Replace outdated claim about miners using GPUs.
- Remove specific amount for cost of vanity address pooling and URL for
a pool. That pool doesn't work, I don't know of any others, and I
have no idea what the pricing would be even if there were existing
pools.
The commit ab5ae32bae is the last commit
for the second edition, so all changes since then are dropped except for
several commits for the third edition authored by Andreas Antonopoulos.
No attempt is made to remove CC-BY-SA or other licensed content present
in the already-published first or second editions.
This revert may itself be reverted for versions of the book published
under CC-BY-SA.
The 'pybitcointools' library is deprecated. Vitalik mentions using the
fork from 'primal100'. This updates the code sample which is currently
broken, to use the Python package for that fork.
Runs all good now.
When testing with a `private_key = '0000000000000000000000000000000000000000000000000000000000000001'` instead of `private_key = bitcoin.random_key()`,
the generated Private Key (WIF-Compressed) is wrong `5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsrefhvB5QZ`, it should be `KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn`. As it turns out, the proper way to get the correct compressed WIF is to pass `'wif_compressed'` and not `'wif'` to the `bitcoin.encode_privkey` function, as pointed out in the Main.py from the bitcoin python package.
```
def encode_privkey(priv, formt, vbyte=0):
if not isinstance(priv, int_types):
return encode_privkey(decode_privkey(priv), formt, vbyte)
if formt == 'decimal': return priv
elif formt == 'bin': return encode(priv, 256, 32)
elif formt == 'bin_compressed': return encode(priv, 256, 32)+b'\x01'
elif formt == 'hex': return encode(priv, 16, 64)
elif formt == 'hex_compressed': return encode(priv, 16, 64)+'01'
elif formt == 'wif':
return bin_to_b58check(encode(priv, 256, 32), 128+int(vbyte))
elif formt == 'wif_compressed':
return bin_to_b58check(encode(priv, 256, 32)+b'\x01', 128+int(vbyte))
else: raise Exception("Invalid format!")
```
The fix can be done in a couple ways:
`bitcoin.encode_privkey(bitcoin.decode_privkey(compressed_private_key, 'hex'), 'wif')` -> 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsrefhvB5QZ (WRONG)
`bitcoin.encode_privkey(bitcoin.decode_privkey(compressed_private_key, 'hex'), 'wif_compressed')` -> KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU9FMLM39zT (WRONG)
`bitcoin.encode_privkey(bitcoin.decode_privkey(compressed_private_key, 'hex_compressed'), 'wif_compressed')` -> KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn (CORRECT)
`bitcoin.encode_privkey(bitcoin.decode_privkey(private_key, 'hex'), 'wif_compressed')` -> KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn (CORRECT)
If line#24 use 'wif_compressed', it will produce a wrong Key (WIF-Compressed) started with 2.
So there should be 'wif', unless :
wif_compressed_private_key = bitcoin.encode_privkey(
bitcoin.decode_privkey(private_key, 'hex'), 'wif_compressed')
This is also right.
However, use the 'compressed_private_key' and 'wif_compressed' is wrong.
The bug is that `x % 255` is not quite the same thing as `x % 256`;
but `x & 255` is.
The stylistic issue is that `numeric_limits<uint8_t>::max()` is a
very verbose way of spelling `255`.
The code is very possible to miss a leading '0'.
E.g:
Private Key (hex) is: 57c003d31cca32f79a22e70334fff37875617e89c04d2746b5efc22067ccb8fd
Before: Compressed Public Key (hex) is: 03 8f0de2360796ae0fe17f1a2b0be30af6fb45eccc4a1c7afb5ebea21d041b6e0
After: Compressed Public Key (hex) is: 03 08f0de2360796ae0fe17f1a2b0be30af6fb45eccc4a1c7afb5ebea21d041b6e0
The bug is in the pybitcointools, but it is not updated, we can only repair it ourselves.
As input and hash are inbuilt functions, so I'd suggest using other names for variables.
here is output from python interpreter.
>>> hash
<built-in function hash>
>>> input
<built-in function input>
`from __future__ import print_function` to bring the print function from Python 3 into Python 2.6 and 2.7.
Properly deals with comma separated values in print() function.