mirror of
https://github.com/bitcoinbook/bitcoinbook
synced 2024-11-22 08:08:11 +00:00
Libbitcoin bx: remove all mentions of vulnerable tool
- 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.
This commit is contained in:
parent
d9f6cf53c7
commit
8d6972d719
@ -1,181 +0,0 @@
|
|||||||
[[appdx_bx]]
|
|
||||||
[appendix]
|
|
||||||
|
|
||||||
== Bitcoin Explorer (bx) Commands
|
|
||||||
|
|
||||||
((("Bitcoin Explorer (bx) commands", id="BX18_1", range="startofrange")))Bitcoin Explorer (bx) is a command-line tool that offers a variety of commands for key management and transaction construction. It is part of the libbitcoin bitcoin library.
|
|
||||||
|
|
||||||
----
|
|
||||||
Usage: bx COMMAND [--help]
|
|
||||||
|
|
||||||
Info: The bx commands are:
|
|
||||||
|
|
||||||
address-decode
|
|
||||||
address-embed
|
|
||||||
address-encode
|
|
||||||
address-validate
|
|
||||||
base16-decode
|
|
||||||
base16-encode
|
|
||||||
base58-decode
|
|
||||||
base58-encode
|
|
||||||
base58check-decode
|
|
||||||
base58check-encode
|
|
||||||
base64-decode
|
|
||||||
base64-encode
|
|
||||||
bitcoin160
|
|
||||||
bitcoin256
|
|
||||||
btc-to-satoshi
|
|
||||||
ec-add
|
|
||||||
ec-add-secrets
|
|
||||||
ec-multiply
|
|
||||||
ec-multiply-secrets
|
|
||||||
ec-new
|
|
||||||
ec-to-address
|
|
||||||
ec-to-public
|
|
||||||
ec-to-wif
|
|
||||||
fetch-balance
|
|
||||||
fetch-header
|
|
||||||
fetch-height
|
|
||||||
fetch-history
|
|
||||||
fetch-stealth
|
|
||||||
fetch-tx
|
|
||||||
fetch-tx-index
|
|
||||||
hd-new
|
|
||||||
hd-private
|
|
||||||
hd-public
|
|
||||||
hd-to-address
|
|
||||||
hd-to-ec
|
|
||||||
hd-to-public
|
|
||||||
hd-to-wif
|
|
||||||
help
|
|
||||||
input-set
|
|
||||||
input-sign
|
|
||||||
input-validate
|
|
||||||
message-sign
|
|
||||||
message-validate
|
|
||||||
mnemonic-decode
|
|
||||||
mnemonic-encode
|
|
||||||
ripemd160
|
|
||||||
satoshi-to-btc
|
|
||||||
script-decode
|
|
||||||
script-encode
|
|
||||||
script-to-address
|
|
||||||
seed
|
|
||||||
send-tx
|
|
||||||
send-tx-node
|
|
||||||
send-tx-p2p
|
|
||||||
settings
|
|
||||||
sha160
|
|
||||||
sha256
|
|
||||||
sha512
|
|
||||||
stealth-decode
|
|
||||||
stealth-encode
|
|
||||||
stealth-public
|
|
||||||
stealth-secret
|
|
||||||
stealth-shared
|
|
||||||
tx-decode
|
|
||||||
tx-encode
|
|
||||||
uri-decode
|
|
||||||
uri-encode
|
|
||||||
validate-tx
|
|
||||||
watch-address
|
|
||||||
wif-to-ec
|
|
||||||
wif-to-public
|
|
||||||
wrap-decode
|
|
||||||
wrap-encode
|
|
||||||
----
|
|
||||||
|
|
||||||
For more information, see the https://github.com/libbitcoin/libbitcoin-explorer[Bitcoin Explorer homepage] and https://github.com/libbitcoin/libbitcoin-explorer/wiki[Bitcoin Explorer user documentation].
|
|
||||||
|
|
||||||
=== Examples of bx Command Use
|
|
||||||
|
|
||||||
Let's look at some examples of using Bitcoin Explorer commands to experiment with keys and addresses.
|
|
||||||
|
|
||||||
Generate a random "seed" value using the +seed+ command, which uses the operating system's random number generator. Pass the seed to the +ec-new+ command to generate a new private key. We save the standard output into the file _private_key_:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx seed | bx ec-new > private_key
|
|
||||||
$ cat private_key
|
|
||||||
73096ed11ab9f1db6135857958ece7d73ea7c30862145bcc4bbc7649075de474
|
|
||||||
----
|
|
||||||
|
|
||||||
Now, generate the public key from that private key using the +ec-to-public+ command. We pass the _private_key_ file into the standard input and save the standard output of the command into a new file _public_key_:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx ec-to-public < private_key > public_key
|
|
||||||
$ cat public_key
|
|
||||||
02fca46a6006a62dfdd2dbb2149359d0d97a04f430f12a7626dd409256c12be500
|
|
||||||
----
|
|
||||||
|
|
||||||
We can reformat the +public_key+ as an address using the +ec-to-address+ command. We pass the _public_key_ into standard input:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx ec-to-address < public_key
|
|
||||||
17re1S4Q8ZHyCP8Kw7xQad1Lr6XUzWUnkG
|
|
||||||
----
|
|
||||||
|
|
||||||
Keys generated in this manner produce a type-0 nondeterministic wallet. That means that each key is generated from an independent seed. Bitcoin Explorer commands can also generate keys deterministically, in accordance with BIP32. In this case, a "master" key is created from a seed and then extended deterministically to produce a tree of subkeys, resulting in a type-2 deterministic wallet.
|
|
||||||
|
|
||||||
First, we use the +seed+ and +hd-new+ commands to generate a master key that will be used as the basis to derive a hierarchy of keys:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx seed > seed
|
|
||||||
$ cat seed
|
|
||||||
eb68ee9f3df6bd4441a9feadec179ff1
|
|
||||||
|
|
||||||
$ bx hd-new < seed > master
|
|
||||||
$ cat master
|
|
||||||
xprv9s21ZrQH143K2BEhMYpNQoUvAgiEjArAVaZaCTgsaGe6LsAnwubeiTcDzd23mAoyizm9cApe51gNfLMkBqkYoWWMCRwzfuJk8RwF1SVEpAQ
|
|
||||||
----
|
|
||||||
|
|
||||||
We now use the +hd-private+ command to generate a hardened "account" key and a sequence of two private keys within the account:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx hd-private --hard < master > account
|
|
||||||
$ cat account
|
|
||||||
xprv9vkDLt81dTKjwHB8fsVB5QK8cGnzveChzSrtCfvu3aMWvQaThp59ueufuyQ8Qi3qpjk4aKsbmbfxwcgS8PYbgoR2NWHeLyvg4DhoEE68A1n
|
|
||||||
|
|
||||||
$ bx hd-private --index 0 < account
|
|
||||||
xprv9xHfb6w1vX9xgZyPNXVgAhPxSsEkeRcPHEUV5iJcVEsuUEACvR3NRY3fpGhcnBiDbvG4LgndirDsia1e9F3DWPkX7Tp1V1u97HKG1FJwUpU
|
|
||||||
|
|
||||||
$ bx hd-private --index 1 < account
|
|
||||||
xprv9xHfb6w1vX9xjc8XbN4GN86jzNAZ6xHEqYxzbLB4fzHFd6VqCLPGRZFsdjsuMVERadbgDbziCRJru9n6tzEWrASVpEdrZrFidt1RDfn4yA3
|
|
||||||
----
|
|
||||||
|
|
||||||
Next, we use the +hd-public+ command to generate the corresponding sequence of two public keys:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx hd-public --index 0 < account
|
|
||||||
xpub6BH1zcTuktiFu43rUZ2gXqLgzu5F3tLEeTQ5t6iE3aQtM2VMTxMcyLN9fYHiGhGpQe9QQYmqL2eYPFJ3vezHz5wzaSW4FiGrseNDR4LKqTy
|
|
||||||
|
|
||||||
$ bx hd-public --index 1 < account
|
|
||||||
xpub6BH1zcTuktiFx6CzhPbGjG3UYQ13WR16CmtbPiagEKpEVtpyjshWyMaMV1cn7nUPUkgQHPVXJVqsrA8xWbGQDhohEcDFTEYMvYzwRD7Juf8
|
|
||||||
----
|
|
||||||
|
|
||||||
The public keys can also be derived from their corresponding private keys using the +hd-to-public+ command:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx hd-private --index 0 < account | bx hd-to-public
|
|
||||||
xpub6BH1zcTuktiFu43rUZ2gXqLgzu5F3tLEeTQ5t6iE3aQtM2VMTxMcyLN9fYHiGhGpQe9QQYmqL2eYPFJ3vezHz5wzaSW4FiGrseNDR4LKqTy
|
|
||||||
|
|
||||||
$ bx hd-private --index 1 < account | bx hd-to-public
|
|
||||||
xpub6BH1zcTuktiFx6CzhPbGjG3UYQ13WR16CmtbPiagEKpEVtpyjshWyMaMV1cn7nUPUkgQHPVXJVqsrA8xWbGQDhohEcDFTEYMvYzwRD7Juf8
|
|
||||||
----
|
|
||||||
|
|
||||||
We can generate a practically limitless number of keys in a deterministic chain, all derived from a single seed. This technique is used in many wallet applications to generate keys that can be backed up and restored with a single seed value. This is easier than having to back up the wallet with all its randomly generated keys every time a new key is created.
|
|
||||||
|
|
||||||
The seed can be encoded using the +mnemonic-encode+ command:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx hd-mnemonic < seed > words
|
|
||||||
adore repeat vision worst especially veil inch woman cast recall dwell appreciate
|
|
||||||
----
|
|
||||||
|
|
||||||
The seed can then be decoded using the +mnemonic-decode+ command:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx mnemonic-decode < words
|
|
||||||
eb68ee9f3df6bd4441a9feadec179ff1
|
|
||||||
----
|
|
||||||
|
|
||||||
Mnemonic encoding can make the seed easier to record and even remember.(((range="endofrange", startref="BX18_1")))
|
|
@ -1,424 +0,0 @@
|
|||||||
[[appdx-pycoin]]
|
|
||||||
[appendix]
|
|
||||||
== pycoin, ku, and tx
|
|
||||||
|
|
||||||
|
|
||||||
((("pycoin library")))The Python library http://github.com/richardkiss/pycoin[+pycoin+], originally written and maintained by Richard Kiss, is a Python-based library that supports manipulation of bitcoin keys and transactions, even supporting the scripting language enough to properly deal with nonstandard transactions.
|
|
||||||
|
|
||||||
The pycoin library supports both Python 2 (2.7.x) and Python 3 (3.3 and later) and comes with some handy command-line utilities, +ku+ and +tx+.
|
|
||||||
|
|
||||||
=== Key Utility (KU)
|
|
||||||
|
|
||||||
((("key utility (ku)", id="keyutil17")))The command-line utility +ku+ ("key utility") is a Swiss Army knife for manipulating keys. It supports BIP32 keys, WIF, and addresses (bitcoin and alt coins). Following are some examples.
|
|
||||||
|
|
||||||
Create a BIP32 key using the default entropy sources of GPG and _/dev/random_:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku create
|
|
||||||
|
|
||||||
input : create
|
|
||||||
network : Bitcoin
|
|
||||||
wallet key : xprv9s21ZrQH143K3LU5ctPZTBnb9kTjA5Su9DcWHvXJemiJBsY7VqXUG7hipgdWaU
|
|
||||||
m2nhnzdvxJf5KJo9vjP2nABX65c5sFsWsV8oXcbpehtJi
|
|
||||||
public version : xpub661MyMwAqRbcFpYYiuvZpKjKhnJDZYAkWSY76JvvD7FH4fsG3Nqiov2CfxzxY8
|
|
||||||
DGcpfT56AMFeo8M8KPkFMfLUtvwjwb6WPv8rY65L2q8Hz
|
|
||||||
tree depth : 0
|
|
||||||
fingerprint : 9d9c6092
|
|
||||||
parent f'print : 00000000
|
|
||||||
child index : 0
|
|
||||||
chain code : 80574fb260edaa4905bc86c9a47d30c697c50047ed466c0d4a5167f6821e8f3c
|
|
||||||
private key : yes
|
|
||||||
secret exponent : 112471538590155650688604752840386134637231974546906847202389294096567806844862
|
|
||||||
hex : f8a8a28b28a916e1043cc0aca52033a18a13cab1638d544006469bc171fddfbe
|
|
||||||
wif : L5Z54xi6qJusQT42JHA44mfPVZGjyb4XBRWfxAzUWwRiGx1kV4sP
|
|
||||||
uncompressed : 5KhoEavGNNH4GHKoy2Ptu4KfdNp4r56L5B5un8FP6RZnbsz5Nmb
|
|
||||||
public pair x : 76460638240546478364843397478278468101877117767873462127021560368290114016034
|
|
||||||
public pair y : 59807879657469774102040120298272207730921291736633247737077406753676825777701
|
|
||||||
x as hex : a90b3008792432060fa04365941e09a8e4adf928bdbdb9dad41131274e379322
|
|
||||||
y as hex : 843a0f6ed9c0eb1962c74533795406914fe3f1957c5238951f4fe245a4fcd625
|
|
||||||
y parity : odd
|
|
||||||
key pair as sec : 03a90b3008792432060fa04365941e09a8e4adf928bdbdb9dad41131274e379322
|
|
||||||
uncompressed : 04a90b3008792432060fa04365941e09a8e4adf928bdbdb9dad41131274e379322
|
|
||||||
843a0f6ed9c0eb1962c74533795406914fe3f1957c5238951f4fe245a4fcd625
|
|
||||||
hash160 : 9d9c609247174ae323acfc96c852753fe3c8819d
|
|
||||||
uncompressed : 8870d869800c9b91ce1eb460f4c60540f87c15d7
|
|
||||||
Bitcoin address : 1FNNRQ5fSv1wBi5gyfVBs2rkNheMGt86sp
|
|
||||||
uncompressed : 1DSS5isnH4FsVaLVjeVXewVSpfqktdiQAM
|
|
||||||
----
|
|
||||||
|
|
||||||
Create a BIP32 key from a passphrase:
|
|
||||||
|
|
||||||
[WARNING]
|
|
||||||
====
|
|
||||||
The passphrase in this example is way too easy to guess.
|
|
||||||
====
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku P:foo
|
|
||||||
|
|
||||||
input : P:foo
|
|
||||||
network : Bitcoin
|
|
||||||
wallet key : xprv9s21ZrQH143K31AgNK5pyVvW23gHnkBq2wh5aEk6g1s496M8ZMjxncCKZKgb5j
|
|
||||||
ZoY5eSJMJ2Vbyvi2hbmQnCuHBujZ2WXGTux1X2k9Krdtq
|
|
||||||
public version : xpub661MyMwAqRbcFVF9ULcqLdsEa5WnCCugQAcgNd9iEMQ31tgH6u4DLQWoQayvtS
|
|
||||||
VYFvXz2vPPpbXE1qpjoUFidhjFj82pVShWu9curWmb2zy
|
|
||||||
tree depth : 0
|
|
||||||
fingerprint : 5d353a2e
|
|
||||||
parent f'print : 00000000
|
|
||||||
child index : 0
|
|
||||||
chain code : 5eeb1023fd6dd1ae52a005ce0e73420821e1d90e08be980a85e9111fd7646bbc
|
|
||||||
private key : yes
|
|
||||||
secret exponent : 65825730547097305716057160437970790220123864299761908948746835886007793998275
|
|
||||||
hex : 91880b0e3017ba586b735fe7d04f1790f3c46b818a2151fb2def5f14dd2fd9c3
|
|
||||||
wif : L26c3H6jEPVSqAr1usXUp9qtQJw6NHgApq6Ls4ncyqtsvcq2MwKH
|
|
||||||
uncompressed : 5JvNzA5vXDoKYJdw8SwwLHxUxaWvn9mDea6k1vRPCX7KLUVWa7W
|
|
||||||
public pair x : 81821982719381104061777349269130419024493616650993589394553404347774393168191
|
|
||||||
public pair y : 58994218069605424278320703250689780154785099509277691723126325051200459038290
|
|
||||||
x as hex : b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f
|
|
||||||
y as hex : 826d8b4d3010aea16ff4c1c1d3ae68541d9a04df54a2c48cc241c2983544de52
|
|
||||||
y parity : even
|
|
||||||
key pair as sec : 02b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f
|
|
||||||
uncompressed : 04b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f
|
|
||||||
826d8b4d3010aea16ff4c1c1d3ae68541d9a04df54a2c48cc241c2983544de52
|
|
||||||
hash160 : 5d353a2ecdb262477172852d57a3f11de0c19286
|
|
||||||
uncompressed : e5bd3a7e6cb62b4c820e51200fb1c148d79e67da
|
|
||||||
Bitcoin address : 19Vqc8uLTfUonmxUEZac7fz1M5c5ZZbAii
|
|
||||||
uncompressed : 1MwkRkogzBRMehBntgcq2aJhXCXStJTXHT
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
Get info as JSON:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku P:foo -P -j
|
|
||||||
----
|
|
||||||
[source,json]
|
|
||||||
----
|
|
||||||
{
|
|
||||||
"y_parity": "even",
|
|
||||||
"public_pair_y_hex": "826d8b4d3010aea16ff4c1c1d3ae68541d9a04df54a2c48cc241c2983544de52",
|
|
||||||
"private_key": "no",
|
|
||||||
"parent_fingerprint": "00000000",
|
|
||||||
"tree_depth": "0",
|
|
||||||
"network": "Bitcoin",
|
|
||||||
"btc_address_uncompressed": "1MwkRkogzBRMehBntgcq2aJhXCXStJTXHT",
|
|
||||||
"key_pair_as_sec_uncompressed": "04b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f826d8b4d3010aea16ff4c1c1d3ae68541d9a04df54a2c48cc241c2983544de52",
|
|
||||||
"public_pair_x_hex": "b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f",
|
|
||||||
"wallet_key": "xpub661MyMwAqRbcFVF9ULcqLdsEa5WnCCugQAcgNd9iEMQ31tgH6u4DLQWoQayvtSVYFvXz2vPPpbXE1qpjoUFidhjFj82pVShWu9curWmb2zy",
|
|
||||||
"chain_code": "5eeb1023fd6dd1ae52a005ce0e73420821e1d90e08be980a85e9111fd7646bbc",
|
|
||||||
"child_index": "0",
|
|
||||||
"hash160_uncompressed": "e5bd3a7e6cb62b4c820e51200fb1c148d79e67da",
|
|
||||||
"btc_address": "19Vqc8uLTfUonmxUEZac7fz1M5c5ZZbAii",
|
|
||||||
"fingerprint": "5d353a2e",
|
|
||||||
"hash160": "5d353a2ecdb262477172852d57a3f11de0c19286",
|
|
||||||
"input": "P:foo",
|
|
||||||
"public_pair_x": "81821982719381104061777349269130419024493616650993589394553404347774393168191",
|
|
||||||
"public_pair_y": "58994218069605424278320703250689780154785099509277691723126325051200459038290",
|
|
||||||
"key_pair_as_sec": "02b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f"
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
Public BIP32 key:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku -w -P P:foo
|
|
||||||
xpub661MyMwAqRbcFVF9ULcqLdsEa5WnCCugQAcgNd9iEMQ31tgH6u4DLQWoQayvtSVYFvXz2vPPpbXE1qpjoUFidhjFj82pVShWu9curWmb2zy
|
|
||||||
----
|
|
||||||
|
|
||||||
Generate a subkey:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku -w -s3/2 P:foo
|
|
||||||
xprv9wTErTSkjVyJa1v4cUTFMFkWMe5eu8ErbQcs9xajnsUzCBT7ykHAwdrxvG3g3f6BFk7ms5hHBvmbdutNmyg6iogWKxx6mefEw4M8EroLgKj
|
|
||||||
----
|
|
||||||
|
|
||||||
Hardened subkey:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku -w -s3/2H P:foo
|
|
||||||
xprv9wTErTSu5AWGkDeUPmqBcbZWX1xq85ZNX9iQRQW9DXwygFp7iRGJo79dsVctcsCHsnZ3XU3DhsuaGZbDh8iDkBN45k67UKsJUXM1JfRCdn1
|
|
||||||
----
|
|
||||||
|
|
||||||
WIF:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku -W P:foo
|
|
||||||
L26c3H6jEPVSqAr1usXUp9qtQJw6NHgApq6Ls4ncyqtsvcq2MwKH
|
|
||||||
----
|
|
||||||
|
|
||||||
Address:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku -a P:foo
|
|
||||||
19Vqc8uLTfUonmxUEZac7fz1M5c5ZZbAii
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Generate a bunch of subkeys:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku P:foo -s 0/0-5 -w
|
|
||||||
xprv9xWkBDfyBXmZjBG9EiXBpy67KK72fphUp9utJokEBFtjsjiuKUUDF5V3TU8U8cDzytqYnSekc8bYuJS8G3bhXxKWB89Ggn2dzLcoJsuEdRK
|
|
||||||
xprv9xWkBDfyBXmZnzKf3bAGifK593gT7WJZPnYAmvc77gUQVej5QHckc5Adtwxa28ACmANi9XhCrRvtFqQcUxt8rUgFz3souMiDdWxJDZnQxzx
|
|
||||||
xprv9xWkBDfyBXmZqdXA8y4SWqfBdy71gSW9sjx9JpCiJEiBwSMQyRxan6srXUPBtj3PTxQFkZJAiwoUpmvtrxKZu4zfsnr3pqyy2vthpkwuoVq
|
|
||||||
xprv9xWkBDfyBXmZsA85GyWj9uYPyoQv826YAadKWMaaEosNrFBKgj2TqWuiWY3zuqxYGpHfv9cnGj5P7e8EskpzKL1Y8Gk9aX6QbryA5raK73p
|
|
||||||
xprv9xWkBDfyBXmZv2q3N66hhZ8DAcEnQDnXML1J62krJAcf7Xb1HJwuW2VMJQrCofY2jtFXdiEY8UsRNJfqK6DAdyZXoMvtaLHyWQx3FS4A9zw
|
|
||||||
xprv9xWkBDfyBXmZw4jEYXUHYc9fT25k9irP87n2RqfJ5bqbjKdT84Mm7Wtc2xmzFuKg7iYf7XFHKkSsaYKWKJbR54bnyAD9GzjUYbAYTtN4ruo
|
|
||||||
----
|
|
||||||
|
|
||||||
[role="pagebreak-before"]
|
|
||||||
Generate the corresponding addresses:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku P:foo -s 0/0-5 -a
|
|
||||||
1MrjE78H1R1rqdFrmkjdHnPUdLCJALbv3x
|
|
||||||
1AnYyVEcuqeoVzH96zj1eYKwoWfwte2pxu
|
|
||||||
1GXr1kZfxE1FcK6ZRD5sqqqs5YfvuzA1Lb
|
|
||||||
116AXZc4bDVQrqmcinzu4aaPdrYqvuiBEK
|
|
||||||
1Cz2rTLjRM6pMnxPNrRKp9ZSvRtj5dDUML
|
|
||||||
1WstdwPnU6HEUPme1DQayN9nm6j7nDVEM
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
Generate the corresponding WIFs:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku P:foo -s 0/0-5 -W
|
|
||||||
L5a4iE5k9gcJKGqX3FWmxzBYQc29PvZ6pgBaePLVqT5YByEnBomx
|
|
||||||
Kyjgne6GZwPGB6G6kJEhoPbmyjMP7D5d3zRbHVjwcq4iQXD9QqKQ
|
|
||||||
L4B3ygQxK6zH2NQGxLDee2H9v4Lvwg14cLJW7QwWPzCtKHdWMaQz
|
|
||||||
L2L2PZdorybUqkPjrmhem4Ax5EJvP7ijmxbNoQKnmTDMrqemY8UF
|
|
||||||
L2oD6vA4TUyqPF8QG4vhUFSgwCyuuvFZ3v8SKHYFDwkbM765Nrfd
|
|
||||||
KzChTbc3kZFxUSJ3Kt54cxsogeFAD9CCM4zGB22si8nfKcThQn8C
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Check that it works by choosing a BIP32 string (the one corresponding to subkey 0/3):
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku -W xprv9xWkBDfyBXmZsA85GyWj9uYPyoQv826YAadKWMaaEosNrFBKgj2TqWuiWY3zuqxYGpHfv9cnGj5P7e8EskpzKL1Y8Gk9aX6QbryA5raK73p
|
|
||||||
L2L2PZdorybUqkPjrmhem4Ax5EJvP7ijmxbNoQKnmTDMrqemY8UF
|
|
||||||
$ ku -a xprv9xWkBDfyBXmZsA85GyWj9uYPyoQv826YAadKWMaaEosNrFBKgj2TqWuiWY3zuqxYGpHfv9cnGj5P7e8EskpzKL1Y8Gk9aX6QbryA5raK73p
|
|
||||||
116AXZc4bDVQrqmcinzu4aaPdrYqvuiBEK
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
Yep, looks familiar.
|
|
||||||
|
|
||||||
From secret exponent:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku 1
|
|
||||||
|
|
||||||
input : 1
|
|
||||||
network : Bitcoin
|
|
||||||
secret exponent : 1
|
|
||||||
hex : 1
|
|
||||||
wif : KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn
|
|
||||||
uncompressed : 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf
|
|
||||||
public pair x : 55066263022277343669578718895168534326250603453777594175500187360389116729240
|
|
||||||
public pair y : 32670510020758816978083085130507043184471273380659243275938904335757337482424
|
|
||||||
x as hex : 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
|
||||||
y as hex : 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
|
||||||
y parity : even
|
|
||||||
key pair as sec : 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
|
||||||
uncompressed : 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
|
||||||
483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
|
||||||
hash160 : 751e76e8199196d454941c45d1b3a323f1433bd6
|
|
||||||
uncompressed : 91b24bf9f5288532960ac687abb035127b1d28a5
|
|
||||||
Bitcoin address : 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
|
|
||||||
uncompressed : 1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
Litecoin version:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku -nL 1
|
|
||||||
|
|
||||||
input : 1
|
|
||||||
network : Litecoin
|
|
||||||
secret exponent : 1
|
|
||||||
hex : 1
|
|
||||||
wif : T33ydQRKp4FCW5LCLLUB7deioUMoveiwekdwUwyfRDeGZm76aUjV
|
|
||||||
uncompressed : 6u823ozcyt2rjPH8Z2ErsSXJB5PPQwK7VVTwwN4mxLBFrao69XQ
|
|
||||||
public pair x : 55066263022277343669578718895168534326250603453777594175500187360389116729240
|
|
||||||
public pair y : 32670510020758816978083085130507043184471273380659243275938904335757337482424
|
|
||||||
x as hex : 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
|
||||||
y as hex : 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
|
||||||
y parity : even
|
|
||||||
key pair as sec : 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
|
||||||
uncompressed : 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
|
||||||
483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
|
||||||
hash160 : 751e76e8199196d454941c45d1b3a323f1433bd6
|
|
||||||
uncompressed : 91b24bf9f5288532960ac687abb035127b1d28a5
|
|
||||||
Litecoin address : LVuDpNCSSj6pQ7t9Pv6d6sUkLKoqDEVUnJ
|
|
||||||
uncompressed : LYWKqJhtPeGyBAw7WC8R3F7ovxtzAiubdM
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
Dogecoin WIF:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku -nD -W 1
|
|
||||||
QNcdLVw8fHkixm6NNyN6nVwxKek4u7qrioRbQmjxac5TVoTtZuot
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
From public pair (on Testnet):
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku -nT 55066263022277343669578718895168534326250603453777594175500187360389116729240,even
|
|
||||||
|
|
||||||
input : 550662630222773436695787188951685343262506034537775941755001873603
|
|
||||||
89116729240,even
|
|
||||||
network : Bitcoin testnet
|
|
||||||
public pair x : 55066263022277343669578718895168534326250603453777594175500187360389116729240
|
|
||||||
public pair y : 32670510020758816978083085130507043184471273380659243275938904335757337482424
|
|
||||||
x as hex : 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
|
||||||
y as hex : 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
|
||||||
y parity : even
|
|
||||||
key pair as sec : 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
|
||||||
uncompressed : 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
|
||||||
483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
|
||||||
hash160 : 751e76e8199196d454941c45d1b3a323f1433bd6
|
|
||||||
uncompressed : 91b24bf9f5288532960ac687abb035127b1d28a5
|
|
||||||
Bitcoin testnet address : mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r
|
|
||||||
uncompressed : mtoKs9V381UAhUia3d7Vb9GNak8Qvmcsme
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
From hash160:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku 751e76e8199196d454941c45d1b3a323f1433bd6
|
|
||||||
|
|
||||||
input : 751e76e8199196d454941c45d1b3a323f1433bd6
|
|
||||||
network : Bitcoin
|
|
||||||
hash160 : 751e76e8199196d454941c45d1b3a323f1433bd6
|
|
||||||
Bitcoin address : 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
((("", startref="pycoin library")))As a Dogecoin address:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ ku -nD 751e76e8199196d454941c45d1b3a323f1433bd6
|
|
||||||
|
|
||||||
input : 751e76e8199196d454941c45d1b3a323f1433bd6
|
|
||||||
network : Dogecoin
|
|
||||||
hash160 : 751e76e8199196d454941c45d1b3a323f1433bd6
|
|
||||||
Dogecoin address : DFpN6QqFfUm3gKNaxN6tNcab1FArL9cZLE
|
|
||||||
----
|
|
||||||
|
|
||||||
==== Transaction Utility (TX)
|
|
||||||
|
|
||||||
((("transaction utility (TX)", id="TX17")))
|
|
||||||
The command-line utility +tx+ will display transactions in human-readable form, fetch base transactions from pycoin's transaction cache or from web services (blockcypher.com, blockr.io and chain.so are currently supported), merge transactions, add or delete inputs or outputs, and sign transactions.
|
|
||||||
|
|
||||||
Following are some examples.
|
|
||||||
|
|
||||||
|
|
||||||
View the famous "pizza" transaction:
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
$ tx 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a
|
|
||||||
warning: consider setting environment variable PYCOIN_CACHE_DIR=~/.pycoin_cache to cache transactions fetched via web services
|
|
||||||
warning: no service providers found for get_tx; consider setting environment variable PYCOIN_BTC_PROVIDERS
|
|
||||||
usage: tx [-h] [-t TRANSACTION_VERSION] [-l LOCK_TIME] [-n NETWORK] [-a]
|
|
||||||
[-i address] [-f path-to-private-keys] [-g GPG_ARGUMENT]
|
|
||||||
[--remove-tx-in tx_in_index_to_delete]
|
|
||||||
[--remove-tx-out tx_out_index_to_delete] [-F transaction-fee] [-u]
|
|
||||||
[-b BITCOIND_URL] [-o path-to-output-file]
|
|
||||||
argument [argument ...]
|
|
||||||
tx: error: can't find Tx with id 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
Oops! We don't have web services set up. Let's do that now:
|
|
||||||
|
|
||||||
|
|
||||||
[source,bash]
|
|
||||||
----
|
|
||||||
$ PYCOIN_CACHE_DIR=~/.pycoin_cache
|
|
||||||
$ PYCOIN_BTC_PROVIDERS="block.io blockexplorer.com"
|
|
||||||
$ export PYCOIN_CACHE_DIR PYCOIN_BTC_PROVIDERS
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
It's not done automatically so a command-line tool won't leak potentially private information about what transactions you're interested in to a third-party website. If you don't care, you could put these lines into your _.profile_.
|
|
||||||
|
|
||||||
Let's try again:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ tx 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a
|
|
||||||
Version: 1 tx hash 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a 159 bytes
|
|
||||||
TxIn count: 1; TxOut count: 1
|
|
||||||
Lock time: 0 (valid anytime)
|
|
||||||
Input:
|
|
||||||
0: (unknown) from 1e133f7de73ac7d074e2746a3d6717dfc99ecaa8e9f9fade2cb8b0b20a5e0441:0
|
|
||||||
Output:
|
|
||||||
0: 1CZDM6oTttND6WPdt3D6bydo7DYKzd9Qik receives 10000000.00000 mBTC
|
|
||||||
Total output 10000000.00000 mBTC
|
|
||||||
including unspents in hex dump since transaction not fully signed
|
|
||||||
010000000141045e0ab2b0b82cdefaf9e9a8ca9ec9df17673d6a74e274d0c73ae77d3f131e000000004a493046022100a7f26eda874931999c90f87f01ff1ffc76bcd058fe16137e0e63fdb6a35c2d78022100a61e9199238eb73f07c8f209504c84b80f03e30ed8169edd44f80ed17ddf451901ffffffff010010a5d4e80000001976a9147ec1003336542cae8bded8909cdd6b5e48ba0ab688ac00000000
|
|
||||||
|
|
||||||
** can't validate transaction as source transactions missing
|
|
||||||
----
|
|
||||||
|
|
||||||
The final line appears because to validate the transactions' signatures, you technically need the source transactions. So let's add +-a+ to augment the transactions with source information:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ tx -a 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a
|
|
||||||
warning: transaction fees recommendations casually calculated and estimates may be incorrect
|
|
||||||
warning: transaction fee lower than (casually calculated) expected value of 0.1 mBTC, transaction might not propogate
|
|
||||||
Version: 1 tx hash 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a 159 bytes
|
|
||||||
TxIn count: 1; TxOut count: 1
|
|
||||||
Lock time: 0 (valid anytime)
|
|
||||||
Input:
|
|
||||||
0: 17WFx2GQZUmh6Up2NDNCEDk3deYomdNCfk from 1e133f7de73ac7d074e2746a3d6717dfc99ecaa8e9f9fade2cb8b0b20a5e0441:0 10000000.00000 mBTC sig ok
|
|
||||||
Output:
|
|
||||||
0: 1CZDM6oTttND6WPdt3D6bydo7DYKzd9Qik receives 10000000.00000 mBTC
|
|
||||||
Total input 10000000.00000 mBTC
|
|
||||||
Total output 10000000.00000 mBTC
|
|
||||||
Total fees 0.00000 mBTC
|
|
||||||
|
|
||||||
010000000141045e0ab2b0b82cdefaf9e9a8ca9ec9df17673d6a74e274d0c73ae77d3f131e000000004a493046022100a7f26eda874931999c90f87f01ff1ffc76bcd058fe16137e0e63fdb6a35c2d78022100a61e9199238eb73f07c8f209504c84b80f03e30ed8169edd44f80ed17ddf451901ffffffff010010a5d4e80000001976a9147ec1003336542cae8bded8909cdd6b5e48ba0ab688ac00000000
|
|
||||||
|
|
||||||
all incoming transaction values validated
|
|
||||||
----
|
|
||||||
|
|
||||||
((("", startref="TX17")))Now, let's look at unspent outputs for a specific address (UTXO). In block #1, we see a coinbase transaction to +12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX+. Let's use +fetch_unspent+ to find all coins in this address:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ fetch_unspent 12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX
|
|
||||||
a3a6f902a51a2cbebede144e48a88c05e608c2cce28024041a5b9874013a1e2a/0/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/333000
|
|
||||||
cea36d008badf5c7866894b191d3239de9582d89b6b452b596f1f1b76347f8cb/31/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/10000
|
|
||||||
065ef6b1463f552f675622a5d1fd2c08d6324b4402049f68e767a719e2049e8d/86/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/10000
|
|
||||||
a66dddd42f9f2491d3c336ce5527d45cc5c2163aaed3158f81dc054447f447a2/0/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/10000
|
|
||||||
ffd901679de65d4398de90cefe68d2c3ef073c41f7e8dbec2fb5cd75fe71dfe7/0/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/100
|
|
||||||
d658ab87cc053b8dbcfd4aa2717fd23cc3edfe90ec75351fadd6a0f7993b461d/5/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/911
|
|
||||||
36ebe0ca3237002acb12e1474a3859bde0ac84b419ec4ae373e63363ebef731c/1/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/100000
|
|
||||||
fd87f9adebb17f4ebb1673da76ff48ad29e64b7afa02fda0f2c14e43d220fe24/0/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/1
|
|
||||||
dfdf0b375a987f17056e5e919ee6eadd87dad36c09c4016d4a03cea15e5c05e3/1/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/1337
|
|
||||||
cb2679bfd0a557b2dc0d8a6116822f3fcbe281ca3f3e18d3855aa7ea378fa373/0/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/1337
|
|
||||||
d6be34ccf6edddc3cf69842dce99fe503bf632ba2c2adb0f95c63f6706ae0c52/1/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/2000000
|
|
||||||
0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098/0/410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac/5000000000
|
|
||||||
----
|
|
@ -22,8 +22,6 @@
|
|||||||
"appdx-bitcoinwhitepaper.asciidoc",
|
"appdx-bitcoinwhitepaper.asciidoc",
|
||||||
"chapters/errata.adoc",
|
"chapters/errata.adoc",
|
||||||
"appdx-bips.asciidoc",
|
"appdx-bips.asciidoc",
|
||||||
"appdx-pycoin.asciidoc",
|
|
||||||
"appdx-bx.asciidoc",
|
|
||||||
"author_bio.html"
|
"author_bio.html"
|
||||||
],
|
],
|
||||||
"formats": {
|
"formats": {
|
||||||
@ -66,4 +64,4 @@
|
|||||||
"templating": false,
|
"templating": false,
|
||||||
"lang": "en",
|
"lang": "en",
|
||||||
"accent_color": ""
|
"accent_color": ""
|
||||||
}
|
}
|
||||||
|
@ -38,10 +38,6 @@ include::chapters/errata.adoc[]
|
|||||||
|
|
||||||
include::appdx-bips.asciidoc[]
|
include::appdx-bips.asciidoc[]
|
||||||
|
|
||||||
include::appdx-pycoin.asciidoc[]
|
|
||||||
|
|
||||||
include::appdx-bx.asciidoc[]
|
|
||||||
|
|
||||||
include::index.asciidoc[]
|
include::index.asciidoc[]
|
||||||
|
|
||||||
include::colo.asciidoc[]
|
include::colo.asciidoc[]
|
||||||
|
@ -1146,8 +1146,6 @@ toolkits, organized by programming languages.
|
|||||||
|
|
||||||
==== C/C++
|
==== C/C++
|
||||||
https://github.com/bitcoin/bitcoin[Bitcoin Core] :: The reference implementation of bitcoin
|
https://github.com/bitcoin/bitcoin[Bitcoin Core] :: The reference implementation of bitcoin
|
||||||
https://github.com/libbitcoin/libbitcoin[libbitcoin]:: Cross-platform C++ development toolkit, node, and consensus library
|
|
||||||
https://github.com/libbitcoin/libbitcoin-explorer[Libbitcoin explorer]:: Libbitcoin's command-line tool
|
|
||||||
|
|
||||||
==== JavaScript
|
==== JavaScript
|
||||||
http://bcoin.io/[bcoin]:: A modular and scalable full-node implementation with API
|
http://bcoin.io/[bcoin]:: A modular and scalable full-node implementation with API
|
||||||
|
@ -720,41 +720,6 @@ into a Bitcoin address in <<pubkey_to_address>>.
|
|||||||
.Public key to Bitcoin address: conversion of a public key into a Bitcoin address
|
.Public key to Bitcoin address: conversion of a public key into a Bitcoin address
|
||||||
image::images/mbc2_0405.png["pubkey_to_address"]
|
image::images/mbc2_0405.png["pubkey_to_address"]
|
||||||
|
|
||||||
==== Decode from Base58Check
|
|
||||||
|
|
||||||
The Bitcoin Explorer commands (see <<appdx_bx>>) make it easy to write
|
|
||||||
shell scripts and command-line "pipes" that manipulate bitcoin keys,
|
|
||||||
addresses, and transactions. You can use Bitcoin Explorer to decode the
|
|
||||||
base58check format on the command line.
|
|
||||||
|
|
||||||
We use the +base58check-decode+ command to decode the uncompressed key:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx base58check-decode 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
|
|
||||||
wrapper
|
|
||||||
{
|
|
||||||
checksum 4286807748
|
|
||||||
payload 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd
|
|
||||||
version 128
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
The result contains the key as payload, the WIF version prefix 128 (0x80
|
|
||||||
in hex), and a checksum.
|
|
||||||
|
|
||||||
Notice that the "payload" of the compressed key is appended with the
|
|
||||||
suffix +01+, signaling that the derived public key is to be compressed:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx base58check-decode KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
|
|
||||||
wrapper
|
|
||||||
{
|
|
||||||
checksum 2339607926
|
|
||||||
payload 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd01
|
|
||||||
version 128
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
[[comp_pub]]
|
[[comp_pub]]
|
||||||
=== Compressed public keys
|
=== Compressed public keys
|
||||||
|
|
||||||
@ -940,17 +905,7 @@ transaction details are correct, the transaction is valid.
|
|||||||
Addresses for Pay-to-Script-Hash (P2SH) are also created with
|
Addresses for Pay-to-Script-Hash (P2SH) are also created with
|
||||||
base58check. The version prefix is set to 5, which results in an
|
base58check. The version prefix is set to 5, which results in an
|
||||||
encoded address starting with a +3+. An example of a P2SH address is
|
encoded address starting with a +3+. An example of a P2SH address is
|
||||||
+3F6i6kwkevjR7AsAd4te2YB2zZyASEm1HM+, which can be derived using the
|
+3F6i6kwkevjR7AsAd4te2YB2zZyASEm1HM+.
|
||||||
Bitcoin Explorer commands +script-encode+, +sha256+, +ripemd160+, and
|
|
||||||
+base58check-encode+ (see <<appdx_bx>>) as follows:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ echo \
|
|
||||||
'DUP HASH160 [89abcdefabbaabbaabbaabbaabbaabbaabbaabba] EQUALVERIFY CHECKSIG' > script
|
|
||||||
$ bx script-encode < script | bx sha256 | bx ripemd160 \
|
|
||||||
| bx base58check-encode --version 5
|
|
||||||
3F6i6kwkevjR7AsAd4te2YB2zZyASEm1HM
|
|
||||||
----
|
|
||||||
|
|
||||||
[TIP]
|
[TIP]
|
||||||
====
|
====
|
||||||
@ -1482,17 +1437,6 @@ can easily be converted to any other format. Note that the "raw binary"
|
|||||||
is not shown in <<table_4-3>> as any encoding for display here would, by
|
is not shown in <<table_4-3>> as any encoding for display here would, by
|
||||||
definition, not be raw binary data.
|
definition, not be raw binary data.
|
||||||
|
|
||||||
We use the +wif-to-ec+ command from Bitcoin Explorer (see <<appdx_bx>>)
|
|
||||||
to show that both WIF keys represent the same private key:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ bx wif-to-ec 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
|
|
||||||
1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd
|
|
||||||
|
|
||||||
$ bx wif-to-ec KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
|
|
||||||
1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd
|
|
||||||
----
|
|
||||||
|
|
||||||
[[comp_priv]]
|
[[comp_priv]]
|
||||||
===== Compressed private keys
|
===== Compressed private keys
|
||||||
|
|
||||||
|
@ -900,10 +900,6 @@ proposed BIP39, in Python
|
|||||||
https://github.com/bitcoinjs/bip39[bitcoinjs/bip39]:: An implementation
|
https://github.com/bitcoinjs/bip39[bitcoinjs/bip39]:: An implementation
|
||||||
of BIP39, as part of the popular bitcoinJS framework, in JavaScript
|
of BIP39, as part of the popular bitcoinJS framework, in JavaScript
|
||||||
|
|
||||||
https://github.com/libbitcoin/libbitcoin/blob/master/src/wallet/mnemonic.cpp[libbitcoin/mnemonic]::
|
|
||||||
An implementation of BIP39, as part of the popular Libbitcoin
|
|
||||||
framework, in pass:[<span class="keep-together">C++</span>]
|
|
||||||
|
|
||||||
[[hd_wallet_details]]
|
[[hd_wallet_details]]
|
||||||
==== Creating an HD Wallet from the Seed
|
==== Creating an HD Wallet from the Seed
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ network", "extended network activities")))As of this writing, the main Bitcoin n
|
|||||||
running the Bitcoin P2P protocol, consists of about 10,000
|
running the Bitcoin P2P protocol, consists of about 10,000
|
||||||
listening nodes running various versions of Bitcoin Core and a few
|
listening nodes running various versions of Bitcoin Core and a few
|
||||||
hundred nodes running various other implementations of the Bitcoin P2P
|
hundred nodes running various other implementations of the Bitcoin P2P
|
||||||
protocol such as BitcoinJ, Libbitcoin, btcd, and bcoin. A small
|
protocol such as BitcoinJ, btcd, and bcoin. A small
|
||||||
percentage of the nodes on the Bitcoin P2P network are also mining
|
percentage of the nodes on the Bitcoin P2P network are also mining
|
||||||
nodes. Various individuals and companies interface with the Bitcoin
|
nodes. Various individuals and companies interface with the Bitcoin
|
||||||
network by running archival full nodes,
|
network by running archival full nodes,
|
||||||
|
@ -551,40 +551,6 @@ longer the case. As per BIP34, version-2 blocks (blocks with the
|
|||||||
version field set to 2 or higher) must contain the block height as a script
|
version field set to 2 or higher) must contain the block height as a script
|
||||||
"push" operation in the beginning of the coinbase field.
|
"push" operation in the beginning of the coinbase field.
|
||||||
|
|
||||||
<<satoshi_words>> uses the libbitcoin library introduced in
|
|
||||||
<<alt_libraries>> to extract the coinbase data from the genesis block,
|
|
||||||
displaying Satoshi's message. Note that the libbitcoin library contains
|
|
||||||
a static copy of the genesis block, so the example code can retrieve the
|
|
||||||
genesis block directly from the library.
|
|
||||||
|
|
||||||
[[satoshi_words]]
|
|
||||||
.Extract the coinbase data from the genesis block
|
|
||||||
====
|
|
||||||
[source, cpp]
|
|
||||||
----
|
|
||||||
include::code/satoshi-words.cpp[]
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
We compile the code with the GNU C++ compiler and run the resulting
|
|
||||||
executable, as shown in <<satoshi_words_run>>.((("",
|
|
||||||
startref="MACaggreg10")))((("", startref="Baggreg10")))((("",
|
|
||||||
startref="Taggreg10")))((("", startref="Tcoinb10")))((("",
|
|
||||||
startref="coinbtrans10")))
|
|
||||||
|
|
||||||
[[satoshi_words_run]]
|
|
||||||
.Compiling and running the satoshi-words example code
|
|
||||||
====
|
|
||||||
[source,bash]
|
|
||||||
----
|
|
||||||
$ # Compile the code
|
|
||||||
$ g++ -o satoshi-words satoshi-words.cpp $(pkg-config --cflags --libs libbitcoin)
|
|
||||||
$ # Run the executable
|
|
||||||
$ ./satoshi-words
|
|
||||||
^D<><44><GS>^A^DEThe Times 03/Jan/2009 Chancellor on brink of second bailout for banks
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
=== Constructing the Block Header
|
=== Constructing the Block Header
|
||||||
|
|
||||||
((("mining and consensus", "constructing block headers")))((("blocks",
|
((("mining and consensus", "constructing block headers")))((("blocks",
|
||||||
|
@ -586,30 +586,8 @@ very long:
|
|||||||
|
|
||||||
This entire script can instead be represented by a 20-byte cryptographic
|
This entire script can instead be represented by a 20-byte cryptographic
|
||||||
hash, by first applying the SHA256 hashing algorithm and then applying
|
hash, by first applying the SHA256 hashing algorithm and then applying
|
||||||
the RIPEMD160 algorithm on the result.
|
the RIPEMD160 algorithm on the result. For example, starting with the
|
||||||
|
hash of Mohammed's redeem script:
|
||||||
We use +libbitcoin-explorer+ (+bx+) on the command-line to produce the
|
|
||||||
script hash, as follows:
|
|
||||||
|
|
||||||
----
|
|
||||||
echo \
|
|
||||||
2 \
|
|
||||||
[04C16B8698A9ABF84250A7C3EA7EEDEF9897D1C8C6ADF47F06CF73370D74DCCA01CDCA79DCC5C395D7EEC6984D83F1F50C900A24DD47F569FD4193AF5DE762C587] \
|
|
||||||
[04A2192968D8655D6A935BEAF2CA23E3FB87A3495E7AF308EDF08DAC3C1FCBFC2C75B4B0F4D0B1B70CD2423657738C0C2B1D5CE65C97D78D0E34224858008E8B49] \
|
|
||||||
[047E63248B75DB7379BE9CDA8CE5751D16485F431E46117B9D0C1837C9D5737812F393DA7D4420D7E1A9162F0279CFC10F1E8E8F3020DECDBC3C0DD389D9977965] \
|
|
||||||
[0421D65CBD7149B255382ED7F78E946580657EE6FDA162A187543A9D85BAAA93A4AB3A8F044DADA618D087227440645ABE8A35DA8C5B73997AD343BE5C2AFD94A5] \
|
|
||||||
[043752580AFA1ECED3C68D446BCAB69AC0BA7DF50D56231BE0AABF1FDEEC78A6A45E394BA29A1EDF518C022DD618DA774D207D137AAB59E0B000EB7ED238F4D800] \
|
|
||||||
5 CHECKMULTISIG \
|
|
||||||
| bx script-encode | bx sha256 | bx ripemd160
|
|
||||||
54c557e07dde5bb6cb791c7a540e0a4796f5e97e
|
|
||||||
----
|
|
||||||
|
|
||||||
The series of commands above first encodes Mohammed's multisig
|
|
||||||
redeem script as a serialized hex-encoded bitcoin Script. The next +bx+ command
|
|
||||||
calculates the SHA256 hash of that. The next +bx+ command hashes again
|
|
||||||
with RIPEMD160, producing the final script-hash:
|
|
||||||
|
|
||||||
The 20-byte hash of Mohammed's redeem script is:
|
|
||||||
|
|
||||||
----
|
----
|
||||||
54c557e07dde5bb6cb791c7a540e0a4796f5e97e
|
54c557e07dde5bb6cb791c7a540e0a4796f5e97e
|
||||||
@ -660,15 +638,7 @@ addresses use the version prefix "5," which results in
|
|||||||
Base58Check-encoded addresses that start with a "3."
|
Base58Check-encoded addresses that start with a "3."
|
||||||
|
|
||||||
For example, Mohammed's complex script, hashed and Base58Check-encoded
|
For example, Mohammed's complex script, hashed and Base58Check-encoded
|
||||||
as a P2SH address, becomes +39RF6JqABiHdYHkfChV6USGMe6Nsr66Gzw+. We can
|
as a P2SH address, becomes +39RF6JqABiHdYHkfChV6USGMe6Nsr66Gzw+.
|
||||||
confirm that with the +bx+ command:
|
|
||||||
|
|
||||||
----
|
|
||||||
echo \
|
|
||||||
'54c557e07dde5bb6cb791c7a540e0a4796f5e97e'\
|
|
||||||
| bx address-encode -v 5
|
|
||||||
39RF6JqABiHdYHkfChV6USGMe6Nsr66Gzw
|
|
||||||
----
|
|
||||||
|
|
||||||
Now, Mohammed can give this "address" to his customers and they can use
|
Now, Mohammed can give this "address" to his customers and they can use
|
||||||
almost any Bitcoin wallet to make a simple payment, like any other
|
almost any Bitcoin wallet to make a simple payment, like any other
|
||||||
@ -1588,29 +1558,8 @@ The data consists of the witness version and Bob's
|
|||||||
|
|
||||||
Bob's wallet then hashes the data, first with
|
Bob's wallet then hashes the data, first with
|
||||||
SHA256, then with RIPEMD160, producing another 20-byte hash.
|
SHA256, then with RIPEMD160, producing another 20-byte hash.
|
||||||
|
Next, the redeem script hash is converted to a Bitcoin address.
|
||||||
Let's use +bx+ on the command-line to replicate that:
|
Finally, Alice's wallet can make a payment to
|
||||||
|
|
||||||
.HASH160 of the P2WPKH witness program
|
|
||||||
----
|
|
||||||
echo \
|
|
||||||
'0 [ab68025513c3dbd2f7b92a94e0581f5d50f654e7]'\
|
|
||||||
| bx script-encode | bx sha256 | bx ripemd160
|
|
||||||
3e0547268b3b19288b3adef9719ec8659f4b2b0b
|
|
||||||
----
|
|
||||||
|
|
||||||
Next, the redeem script hash is converted to a Bitcoin address. Let's
|
|
||||||
use +bx+ on the command-line again:
|
|
||||||
|
|
||||||
.P2SH address
|
|
||||||
----
|
|
||||||
echo \
|
|
||||||
'3e0547268b3b19288b3adef9719ec8659f4b2b0b' \
|
|
||||||
| bx address-encode -v 5
|
|
||||||
37Lx99uaGn5avKBxiW26HjedQE3LrDCZru
|
|
||||||
----
|
|
||||||
|
|
||||||
Now, Alice's wallet can make a payment to
|
|
||||||
+37Lx99uaGn5avKBxiW26HjedQE3LrDCZru+, just as it would to any other
|
+37Lx99uaGn5avKBxiW26HjedQE3LrDCZru+, just as it would to any other
|
||||||
Bitcoin address.
|
Bitcoin address.
|
||||||
|
|
||||||
@ -1638,18 +1587,9 @@ Mohammed's wallet can embed the P2WSH witness program inside a P2SH
|
|||||||
script.
|
script.
|
||||||
|
|
||||||
First, Mohammed's wallet hashes the witness script with SHA256 (just
|
First, Mohammed's wallet hashes the witness script with SHA256 (just
|
||||||
once). Let's use +bx+ to do that on the command-line:
|
once), producing the hash:
|
||||||
|
|
||||||
.Mohammed's wallet creates a P2WSH witness program
|
|
||||||
----
|
----
|
||||||
echo \
|
|
||||||
2 \ [04C16B8698A9ABF84250A7C3EA7EEDEF9897D1C8C6ADF47F06CF73370D74DCCA01CDCA79DCC5C395D7EEC6984D83F1F50C900A24DD47F569FD4193AF5DE762C587] \
|
|
||||||
[04A2192968D8655D6A935BEAF2CA23E3FB87A3495E7AF308EDF08DAC3C1FCBFC2C75B4B0F4D0B1B70CD2423657738C0C2B1D5CE65C97D78D0E34224858008E8B49] \
|
|
||||||
[047E63248B75DB7379BE9CDA8CE5751D16485F431E46117B9D0C1837C9D5737812F393DA7D4420D7E1A9162F0279CFC10F1E8E8F3020DECDBC3C0DD389D9977965] \
|
|
||||||
[0421D65CBD7149B255382ED7F78E946580657EE6FDA162A187543A9D85BAAA93A4AB3A8F044DADA618D087227440645ABE8A35DA8C5B73997AD343BE5C2AFD94A5] \
|
|
||||||
[043752580AFA1ECED3C68D446BCAB69AC0BA7DF50D56231BE0AABF1FDEEC78A6A45E394BA29A1EDF518C022DD618DA774D207D137AAB59E0B000EB7ED238F4D800] \
|
|
||||||
5 CHECKMULTISIG \
|
|
||||||
| bx script-encode | bx sha256
|
|
||||||
9592d601848d04b172905e0ddb0adde59f1590f1e553ffc81ddc4b0ed927dd73
|
9592d601848d04b172905e0ddb0adde59f1590f1e553ffc81ddc4b0ed927dd73
|
||||||
----
|
----
|
||||||
|
|
||||||
@ -1660,25 +1600,16 @@ Next, the hashed witness script is turned into a version-prefixed P2WSH witness
|
|||||||
----
|
----
|
||||||
|
|
||||||
Then, the witness program itself is hashed with SHA256 and RIPEMD160,
|
Then, the witness program itself is hashed with SHA256 and RIPEMD160,
|
||||||
producing a new 20-byte hash, as used in legacy P2SH. Let's use
|
producing a new 20-byte hash:
|
||||||
+bx+ on the command-line to do that:
|
|
||||||
|
|
||||||
.The HASH160 of the P2WSH witness program
|
|
||||||
----
|
----
|
||||||
echo \
|
|
||||||
'0 [9592d601848d04b172905e0ddb0adde59f1590f1e553ffc81ddc4b0ed927dd73]'\
|
|
||||||
| bx script-encode | bx sha256 | bx ripemd160
|
|
||||||
86762607e8fe87c0c37740cddee880988b9455b2
|
86762607e8fe87c0c37740cddee880988b9455b2
|
||||||
----
|
----
|
||||||
|
|
||||||
Next, the wallet constructs a P2SH Bitcoin address from this hash.
|
Next, the wallet constructs a P2SH Bitcoin address from this hash.
|
||||||
Again, we use +bx+ to calculate on the command-line:
|
|
||||||
|
|
||||||
.P2SH Bitcoin address
|
.P2SH Bitcoin address
|
||||||
----
|
----
|
||||||
echo \
|
|
||||||
'86762607e8fe87c0c37740cddee880988b9455b2'\
|
|
||||||
| bx address-encode -v 5
|
|
||||||
3Dwz1MXhM6EfFoJChHCxh1jWHb8GQqRenG
|
3Dwz1MXhM6EfFoJChHCxh1jWHb8GQqRenG
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from pycoin.key import Key
|
|
||||||
|
|
||||||
from pycoin.key.validate import is_address_valid, is_wif_valid
|
|
||||||
from pycoin.services import spendables_for_address
|
|
||||||
from pycoin.tx.tx_utils import create_signed_tx
|
|
||||||
|
|
||||||
|
|
||||||
def get_address(which):
|
|
||||||
while 1:
|
|
||||||
print("enter the %s address=> " % which, end='')
|
|
||||||
address = input()
|
|
||||||
is_valid = is_address_valid(address)
|
|
||||||
if is_valid:
|
|
||||||
return address
|
|
||||||
print("invalid address, please try again")
|
|
||||||
|
|
||||||
|
|
||||||
src_address = get_address("source")
|
|
||||||
spendables = spendables_for_address(src_address)
|
|
||||||
print(spendables)
|
|
||||||
|
|
||||||
while 1:
|
|
||||||
print("enter the WIF for %s=> " % src_address, end='')
|
|
||||||
wif = input()
|
|
||||||
is_valid = is_wif_valid(wif)
|
|
||||||
if is_valid:
|
|
||||||
break
|
|
||||||
print("invalid wif, please try again")
|
|
||||||
|
|
||||||
key = Key.from_text(wif)
|
|
||||||
if src_address not in (key.address(use_uncompressed=False), key.address(use_uncompressed=True)):
|
|
||||||
print("** WIF doesn't correspond to %s" % src_address)
|
|
||||||
print("The secret exponent is %d" % key.secret_exponent())
|
|
||||||
|
|
||||||
dst_address = get_address("destination")
|
|
||||||
|
|
||||||
tx = create_signed_tx(spendables, payables=[dst_address], wifs=[wif])
|
|
||||||
|
|
||||||
print("here is the signed output transaction")
|
|
||||||
print(tx.as_hex())
|
|
@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
Display the genesis block message by Satoshi.
|
|
||||||
*/
|
|
||||||
#include <iostream>
|
|
||||||
#include <bitcoin/bitcoin.hpp>
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
// Create genesis block.
|
|
||||||
bc::chain::block block = bc::chain::block::genesis_mainnet();
|
|
||||||
// Genesis block contains a single coinbase transaction.
|
|
||||||
assert(block.transactions().size() == 1);
|
|
||||||
// Get first transaction in block (coinbase).
|
|
||||||
const bc::chain::transaction& coinbase_tx = block.transactions()[0];
|
|
||||||
// Coinbase tx has a single input.
|
|
||||||
assert(coinbase_tx.inputs().size() == 1);
|
|
||||||
const bc::chain::input& coinbase_input = coinbase_tx.inputs()[0];
|
|
||||||
// Convert the input script to its raw format.
|
|
||||||
const auto prefix = false;
|
|
||||||
const bc::data_chunk& raw_message = coinbase_input.script().to_data(prefix);
|
|
||||||
// Convert this to a std::string.
|
|
||||||
std::string message(raw_message.begin(), raw_message.end());
|
|
||||||
// Display the genesis block message.
|
|
||||||
std::cout << message << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
[[mast]]
|
|
||||||
=== Merkleized Abstract Syntax Trees
|
|
||||||
|
|
||||||
[[merkle_branches]]
|
|
||||||
==== Merkle branches in SegWit v1
|
|
Loading…
Reference in New Issue
Block a user