mirror of
https://github.com/bitcoinbook/bitcoinbook
synced 2024-12-22 22:58:09 +00:00
cleanup alt library code and examples, move some to appendix
This commit is contained in:
parent
3dccacbc67
commit
e51399af22
438
appdx-pycoin.asciidoc
Normal file
438
appdx-pycoin.asciidoc
Normal file
@ -0,0 +1,438 @@
|
||||
== Appendix - pycoin, ku and tx.
|
||||
|
||||
The Python library +pycoin+ (http://github.com/richardkiss/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 non-standard transactions.
|
||||
|
||||
The pycoin library supports both Python 2 (2.7.x) and Python 3 (after 3.3), and comes with some handy command-line utilities, ku and tx.
|
||||
|
||||
=== Pycoin command-line tools: KU and TX
|
||||
|
||||
==== Key Utility (KU)
|
||||
|
||||
The command-line utility ```ku``` ("key utility") is Swiss Army knife for manipulating keys. It supports BIP32 keys, WIF, and address (bitcoin and alt coins). Here 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:
|
||||
|
||||
*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
|
||||
----
|
||||
====
|
||||
|
||||
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
|
||||
----
|
||||
====
|
||||
|
||||
As a Dogecoin address:
|
||||
|
||||
====
|
||||
----
|
||||
$ ku -nD 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
|
||||
input : 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
network : Dogecoin
|
||||
hash160 : 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
Dogecoin address : DFpN6QqFfUm3gKNaxN6tNcab1FArL9cZLE
|
||||
----
|
||||
====
|
||||
|
||||
==== Transaction Utility (TX)
|
||||
|
||||
The command-line utility ```tx``` will display transactions in human-readable form, fetch base transactions from pycoin's transaction cache or from web services (blockchain.info, blockr.io, biteasy.com are currently supported), merge transactions, add or delete inputs or outputs, and sign transactions.
|
||||
|
||||
Examples:
|
||||
|
||||
|
||||
View the famous "pizza" transaction [PIZZA]:
|
||||
|
||||
====
|
||||
----
|
||||
$ 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_SERVICE_PROVIDERS=BLOCKR_IO:BLOCKCHAIN_INFO:BITEASY:BLOCKEXPLORER
|
||||
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_SERVICE_PROVIDERS=BLOCKR_IO:BLOCKCHAIN_INFO:BITEASY:BLOCKEXPLORER
|
||||
$ export PYCOIN_CACHE_DIR PYCOIN_SERVICE_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 web site. 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 to 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
|
||||
----
|
||||
====
|
||||
|
||||
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
|
||||
----
|
||||
====
|
||||
|
@ -1,4 +1,4 @@
|
||||
[[sx_cmds]]
|
||||
[[appdx_sx]]
|
||||
== Appendix: Available commands with sx tools
|
||||
|
||||
----
|
||||
@ -130,4 +130,72 @@ UTILITY
|
||||
|
||||
See 'sx help COMMAND' for more information on a specific command.
|
||||
|
||||
----
|
||||
----
|
||||
|
||||
Below, we look at some examples of using sx tools to experiment with keys and addresses.
|
||||
|
||||
Generate a new private key with the operating system's random number generator by using the +newkey+ command. We save the standard output into the file +private_key+:
|
||||
|
||||
----
|
||||
$ sx newkey > private_key
|
||||
$ cat private_key
|
||||
5Jgx3UAaXw8AcCQCi1j7uaTaqpz2fqNR9K3r4apxdYn6rTzR1PL
|
||||
----
|
||||
|
||||
Now, generate the public key from that private key using the +pubkey+ command. Pass the +private_key+ file into the standard input and save the standard output of the command into a new file +public_key+:
|
||||
|
||||
----
|
||||
$ sx pubkey < private_key > public_key
|
||||
$ cat public_key
|
||||
02fca46a6006a62dfdd2dbb2149359d0d97a04f430f12a7626dd409256c12be500
|
||||
----
|
||||
|
||||
We can re-format the public_key as an address using the +addr+ command. We pass the +public_key+ into standard input:
|
||||
|
||||
----
|
||||
$ sx addr < public_key
|
||||
17re1S4Q8ZHyCP8Kw7xQad1Lr6XUzWUnkG
|
||||
----
|
||||
|
||||
The keys generated above are so called type-0 non-deterministic keys. That means that each one is generated from a random number generator. The sx tools also support type-2 deterministic keys, where a "master" key is created and then extended to produce a chain or tree of subkeys.
|
||||
|
||||
First, we generate a "seed" that will be used as the basis to derive a chain of keys, compatible with the Electrum wallet and other similar implementations. We use the +newseed+ command to produce a seed value:
|
||||
|
||||
----
|
||||
$ sx newseed > seed
|
||||
$ cat seed
|
||||
eb68ee9f3df6bd4441a9feadec179ff1
|
||||
----
|
||||
|
||||
The seed value can also be exported as a word mnemonic that is human readable and easier to store and type than a hexadecimal string
|
||||
using the +mnemonic+ command:
|
||||
|
||||
----
|
||||
$ sx mnemonic < seed > words
|
||||
$ cat words
|
||||
adore repeat vision worst especially veil inch woman cast recall dwell appreciate
|
||||
----
|
||||
|
||||
The mnemonic words can be used to reproduce the seed using the +mnemonic+ command again:
|
||||
|
||||
----
|
||||
$ sx mnemonic < words
|
||||
eb68ee9f3df6bd4441a9feadec179ff1
|
||||
----
|
||||
|
||||
With the seed, we can now generate a sequence of private and public keys, a key chain. We use the +genpriv+ command to generate a sequence of private keys from a seed and the +addr+ command to generate the corresponding public key.
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ sx genpriv 0 < seed
|
||||
5JzY2cPZGViPGgXZ4Syb9Y4eUGjJpVt6sR8noxrpEcqgyj7LK7i
|
||||
$ sx genpriv 0 < seed | sx addr
|
||||
1esVQV2vR9JZPhFeRaeWkAhzmWq7Fi7t7
|
||||
|
||||
$ sx genpriv 1 < seed
|
||||
5JdtL7ckAn3iFBFyVG1Bs3A5TqziFTaB9f8NeyNo8crnE2Sw5Mz
|
||||
$ sx genpriv 1 < seed | sx addr
|
||||
1G1oTeXitk76c2fvQWny4pryTdH1RTqSPW
|
||||
----
|
||||
|
||||
With deterministic keys we can generate and re-generate thousands of keys, all derived from a single seed in a deterministic chain. This technique is used in many wallet applications to generate keys that can be backed up and restored with a simple multi-word mnemonic. This is easier than having to back up the wallet with all its randomly generated keys every time a new key is created.
|
168
ch03.asciidoc
168
ch03.asciidoc
@ -57,7 +57,6 @@ $ cd bitcoin
|
||||
|
||||
By default, the local copy will be synchronized with the most recent code, which may be an unstable or "beta" version of bitcoin. Before compiling the code, we want to select a specific version by checking out a release _tag_. This will synchronize the local copy with a specific snapshot of the code repository identified by a keyword tag. Tags are used by the developers to mark specific releases of the code by version number. First, to find the available tags, we use the +git tag+ command:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ git tag
|
||||
v0.1.5
|
||||
@ -78,7 +77,6 @@ v0.9.0rc1
|
||||
|
||||
The list of tags shows all the released versions of bitcoin. By convention, _release candidates_, which are intended for testing, have the suffix "rc". Stable releases that can be run on production systems have no suffix. From the list above, we select the highest version release, which at this time is v0.9.0rc1. To synchronize the local code with this version, we use the +git checkout+ command:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ git checkout v0.9.0rc1
|
||||
Note: checking out 'v0.9.0rc1'.
|
||||
@ -97,7 +95,6 @@ Carefully review the build pre-requisites which are in the first part of the bui
|
||||
The Bitcoin Core build process was changed to use the autogen/configure/make system starting with version 0.9. Older versions use a simple Makefile and work slightly differently from the example below. Follow the instructions for the version you want to compile. The autogen/configure/make introduced in 0.9 is likely to be the build system used for all future versions of the code and is the system demonstrated in the examples below.
|
||||
====
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ ./autogen.sh
|
||||
configure.ac:12: installing `src/build-aux/config.guess'
|
||||
@ -110,7 +107,6 @@ $
|
||||
|
||||
The +autogen.sh+ script creates a set of automatic configuration scripts that will interrogate your system to discover the correct settings and ensure you have all the necessary libraries to compile the code. The most important of these is the +configure+ script that offers a number of different options to customize the build process. Type +./configure --help+ to see the various options:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ ./configure --help
|
||||
|
||||
@ -148,7 +144,6 @@ $
|
||||
|
||||
The +configure+ script allows you to enable or disable certain features of bitcoind through the use of the +--enable-FEATURE+ and +--disable-FEATURE+ flags, where +FEATURE+ is replaced by the feature name, as listed in the help output above. In this chapter, we will build the bitcoind client with all the default features. We won't be using the configuration flags, but you should review them to understand what optional features are part of the client. Next, we run the +configure+ script to automatically discover all the necessary libraries and create a customized build script for our system:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ ./configure
|
||||
checking build system type... x86_64-unknown-linux-gnu
|
||||
@ -179,7 +174,6 @@ $
|
||||
|
||||
If all goes well, the +configure+ command will end by creating the customized build scripts that will allow us to compile bitcoind. If there are any missing libraries or errors, the +configure+ command will terminate with an error instead of creating the build scripts as shown above. If an error occurs, it is most likely a missing or incompatible library. Review the build documentation again and make sure you install the missing pre-requisites. Then run +configure+ again and see if that fixes the error. Next, we will compile the source code, a process that can take up to an hour to complete. During the compilation process you should see output every few seconds or every few minutes, or an error if something goes wrong. The compilation process can be resumed at any time if interrupted. Type +make+ to start compiling:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ make
|
||||
Making all in src
|
||||
@ -211,7 +205,6 @@ $
|
||||
|
||||
If all goes well, bitcoind is now compiled. The final step is to install the bitcoind executable into the system path using the +make+ command:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ sudo make install
|
||||
Making install in src
|
||||
@ -238,7 +231,6 @@ $ which bitcoin-cli
|
||||
|
||||
The default installation of bitcoind puts it in +/usr/local/bin+. When we first run bitcoind it will remind us to create a configuration file with a strong password for the JSON-RPC interface. We run it by typing +bitcoind+ into the terminal:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ bitcoind
|
||||
Error: To use the "-server" option, you must set a rpcpassword in the configuration file:
|
||||
@ -267,7 +259,6 @@ Now, run the Bitcoin Core client. The first time you run it, it will rebuild the
|
||||
|
||||
Run bitcoind in the background with the option +-daemon+:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ bitcoind -daemon
|
||||
|
||||
@ -296,7 +287,6 @@ The Bitcoin Core client implements a JSON-RPC interface that can also be accesse
|
||||
|
||||
[[bitcoind_commands]]
|
||||
.Bitcoin Core RPC commands
|
||||
[source,bash]
|
||||
----
|
||||
$ bitcoin-cli help
|
||||
addmultisigaddress nrequired ["key",...] ( "account" )
|
||||
@ -491,7 +481,6 @@ $
|
||||
|
||||
The +dumpwallet+ command can be used to dump the wallet into a text file that is human-readable:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ bitcoin-cli dumpwallet wallet.txt
|
||||
$ more wallet.txt
|
||||
@ -637,7 +626,12 @@ The transaction form shown above with the command +gettransaction+ is the simpli
|
||||
[source,bash]
|
||||
----
|
||||
$ bitcoin-cli getrawtransaction 9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3
|
||||
0100000001d717279515f88e2f56ce4e8a31e2ae3e9f00ba1d0add648e80c480ea22e0c7d3000000008b483045022100a4ebbeec83225dedead659bbde7da3d026c8b8e12e61a2df0dd0758e227383b302203301768ef878007e9ef7c304f70ffaf1f2c975b192d34c5b9b2ac1bd193dfba2014104793ac8a58ea751f9710e39aad2e296cc14daa44fa59248be58ede65e4c4b884ac5b5b6dede05ba84727e34c8fd3ee1d6929d7a44b6e111d41cc79e05dbfe5ceaffffffff02404b4c00000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac1f312906000000001976a914107b7086b31518935c8d28703d66d09b3623134388ac00000000
|
||||
0100000001d717279515f88e2f56ce4e8a31e2ae3e9f00ba1d0add648e80c480ea22e0c7d3000000008b483045022100a\
|
||||
4ebbeec83225dedead659bbde7da3d026c8b8e12e61a2df0dd0758e227383b302203301768ef878007e9ef7c304f70ffa\
|
||||
f1f2c975b192d34c5b9b2ac1bd193dfba2014104793ac8a58ea751f9710e39aad2e296cc14daa44fa59248be58ede65e4\
|
||||
c4b884ac5b5b6dede05ba84727e34c8fd3ee1d6929d7a44b6e111d41cc79e05dbfe5ceaffffffff02404b4c0000000000\
|
||||
1976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac1f312906000000001976a914107b7086b31518935c8d2\
|
||||
8703d66d09b3623134388ac00000000
|
||||
----
|
||||
|
||||
To decode this hex string, we can use the +decoderawtransaction+ command. Copy and paste the hex as the first parameter of +decoderawtransaction+ to get the full contents interpreted as a JSON data structure (for formatting reasons the hex string is shortened in the example below):
|
||||
@ -752,7 +746,7 @@ Now that we know which block our transaction was included in, we can query that
|
||||
----
|
||||
$ bitcoin-cli getblock 000000000000000051d2e759c63a26e247f185ecb7926ed7a6624bc31c2a717b true
|
||||
----
|
||||
[source,bash]
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"hash" : "000000000000000051d2e759c63a26e247f185ecb7926ed7a6624bc31c2a717b",
|
||||
@ -877,7 +871,8 @@ $ bitcoin-cli gettxout 9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae
|
||||
"confirmations" : 7,
|
||||
"value" : 0.05000000,
|
||||
"scriptPubKey" : {
|
||||
"asm" : "OP_DUP OP_HASH160 07bdb518fa2e6089fd810235cf1100c9c13d1fd2 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"asm" : "OP_DUP OP_HASH160 07bdb518fa2e6089fd810235cf1100c9c13d1fd2\
|
||||
OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"hex" : "76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac",
|
||||
"reqSigs" : 1,
|
||||
"type" : "pubkeyhash",
|
||||
@ -902,7 +897,6 @@ We will send 25 millibits to the new address +1LnfTn...+ we just created in our
|
||||
|
||||
We use the +createrawtransaction+ to create the transaction described above. As parameters to +createrawtransaction+ we provide the transaction input (the 50 millibit unspent output from our confirmed transaction) and the two transaction outputs (money sent to the new address and change sent back to the previous address):
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ bitcoin-cli createrawtransaction \
|
||||
'[{"txid" : "9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3", "vout" : 0}]' \
|
||||
@ -917,7 +911,6 @@ $ bitcoin-cli createrawtransaction \
|
||||
|
||||
The +createrawtransaction+ command produces a raw hex string that encodes the transaction details we supplied. Let's confirm everything is correct by decoding this raw string using the +decoderawtransaction+ command:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ bitcoin-cli decoderawtransaction \
|
||||
0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c\
|
||||
@ -984,12 +977,21 @@ As you may notice, the transaction contains an empty +scriptSig+ because we have
|
||||
An encrypted wallet must be unlocked before a transaction is signed because signing requires access to the secret keys in the wallet.
|
||||
====
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ bitcoin-cli walletpassphrase foo 360
|
||||
$ bitcoin-cli signrawtransaction 0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c0000000000ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000
|
||||
$ bitcoin-cli signrawtransaction 0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862a\
|
||||
ecf53ebd69f9a89c0000000000ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564\
|
||||
a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000
|
||||
----
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"hex" : "0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c000000006a47304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f00149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a06012103c9700559f690c4a9182faa8bed88ad8a0c563777ac1d3f00fd44ea6c71dc5127ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000",
|
||||
"hex" : "0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c0000\
|
||||
00006a47304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f0\
|
||||
0149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a06012103c9700559f690c4a9182faa8bed88\
|
||||
ad8a0c563777ac1d3f00fd44ea6c71dc5127ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9b\
|
||||
bd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac\
|
||||
00000000",
|
||||
"complete" : true
|
||||
}
|
||||
----
|
||||
@ -1067,7 +1069,6 @@ Now, the inputs used in the transaction contain a +scriptSig+, which is a digita
|
||||
|
||||
Now it's time to submit the newly created transaction to the network. We do that with the command +sendrawtransaction+ which takes the raw hex string produced by +signrawtransaction+. This is the same string we just decoded above:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ bitcoin-cli sendrawtransaction\
|
||||
0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c\
|
||||
@ -1083,7 +1084,6 @@ ae74538baa914f3799081ba78429d5d84f36a0127438e9f721dff584ac17b346
|
||||
|
||||
The command +sendrawtransaction+ returns a _transaction hash (txid)_ as it submits the transaction on the network. We can now query that transaction id with +gettransaction+:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ bitcoin-cli gettransaction \
|
||||
ae74538baa914f3799081ba78429d5d84f36a0127438e9f721dff584ac17b346
|
||||
@ -1162,89 +1162,61 @@ $ wget http://sx.dyne.org/install-sx.sh
|
||||
$ sudo bash ./install-sx.sh
|
||||
----
|
||||
|
||||
You should now have the sx tools installed. Type +sx+ with no parameters to display the help text, which lists all the available commands (See <<sx_cmds_>>)
|
||||
|
||||
===== Generating and manipulating keys with sx
|
||||
|
||||
Generate a new private key with the operating system's random number generator by using the +newkey+ command. We save the standard output into the file +private_key+:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ sx newkey > private_key
|
||||
$ cat private_key
|
||||
5Jgx3UAaXw8AcCQCi1j7uaTaqpz2fqNR9K3r4apxdYn6rTzR1PL
|
||||
----
|
||||
|
||||
Now, generate the public key from that private key using the +pubkey+ command. Pass the +private_key+ file into the standard input and save the standard output of the command into a new file +public_key+:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ sx pubkey < private_key > public_key
|
||||
$ cat public_key
|
||||
02fca46a6006a62dfdd2dbb2149359d0d97a04f430f12a7626dd409256c12be500
|
||||
----
|
||||
|
||||
We can re-format the public_key as an address using the +addr+ command. We pass the +public_key+ into standard input:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ sx addr < public_key
|
||||
17re1S4Q8ZHyCP8Kw7xQad1Lr6XUzWUnkG
|
||||
----
|
||||
|
||||
===== Deterministic keys with sx
|
||||
|
||||
The keys generated above are so called type-0 non-deterministic keys. That means that each one is generated from a random number generator. The sx tools also support type-2 deterministic keys, where a "master" key is created and then extended to produce a chain or tree of subkeys.
|
||||
|
||||
First, we generate a "seed" that will be used as the basis to derive a chain of keys, compatible with the Electrum wallet and other similar implementations. We use the +newseed+ command to produce a seed value:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ sx newseed > seed
|
||||
$ cat seed
|
||||
eb68ee9f3df6bd4441a9feadec179ff1
|
||||
----
|
||||
|
||||
The seed value can also be exported as a word mnemonic that is human readable and easier to store and type than a hexadecimal string
|
||||
using the +mnemonic+ command:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ sx mnemonic < seed > words
|
||||
$ cat words
|
||||
adore repeat vision worst especially veil inch woman cast recall dwell appreciate
|
||||
----
|
||||
|
||||
The mnemonic words can be used to reproduce the seed using the +mnemonic+ command again:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ sx mnemonic < words
|
||||
eb68ee9f3df6bd4441a9feadec179ff1
|
||||
----
|
||||
|
||||
With the seed, we can now generate a sequence of private and public keys, a key chain. We use the +genpriv+ command to generate a sequence of private keys from a seed and the +addr+ command to generate the corresponding public key.
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ sx genpriv 0 < seed
|
||||
5JzY2cPZGViPGgXZ4Syb9Y4eUGjJpVt6sR8noxrpEcqgyj7LK7i
|
||||
$ sx genpriv 0 < seed | sx addr
|
||||
1esVQV2vR9JZPhFeRaeWkAhzmWq7Fi7t7
|
||||
|
||||
$ sx genpriv 1 < seed
|
||||
5JdtL7ckAn3iFBFyVG1Bs3A5TqziFTaB9f8NeyNo8crnE2Sw5Mz
|
||||
$ sx genpriv 1 < seed | sx addr
|
||||
1G1oTeXitk76c2fvQWny4pryTdH1RTqSPW
|
||||
----
|
||||
|
||||
With deterministic keys we can generate and re-generate thousands of keys, all derived from a single seed in a deterministic chain. This technique is used in many wallet applications to generate keys that can be backed up and restored with a simple multi-word mnemonic. This is easier than having to back up the wallet with all its randomly generated keys every time a new key is created.
|
||||
You should now have the sx tools installed. Type +sx+ with no parameters to display the help text, which lists all the available commands (See <<appdx_sx>>)
|
||||
|
||||
[TIP]
|
||||
====
|
||||
The sx toolkit offers many useful commands for encoding and decoding addresses, converting to and from different formats and representations. Use them to explore the various formats such as base58, base58check, hex etc.
|
||||
====
|
||||
|
||||
==== pycoin
|
||||
|
||||
The Python library +pycoin+ (http://github.com/richardkiss/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 non-standard transactions.
|
||||
|
||||
The pycoin library supports both Python 2 (2.7.x) and Python 3 (after 3.3), and comes with some handy command-line utilities, ku and tx.
|
||||
|
||||
|
||||
To install:
|
||||
|
||||
====
|
||||
[source,bash]
|
||||
.Installing pycoin 0.42 under Python 3 in an virtual environment (venv)
|
||||
----
|
||||
$ python3 -m venv /tmp/pycoin
|
||||
$ . /tmp/pycoin/bin/activate
|
||||
$ pip install pycoin==0.42
|
||||
Downloading/unpacking pycoin==0.42
|
||||
Downloading pycoin-0.42.tar.gz (66kB): 66kB downloaded
|
||||
Running setup.py (path:/tmp/pycoin/build/pycoin/setup.py) egg_info for package pycoin
|
||||
|
||||
Installing collected packages: pycoin
|
||||
Running setup.py install for pycoin
|
||||
|
||||
Installing tx script to /tmp/pycoin/bin
|
||||
Installing cache_tx script to /tmp/pycoin/bin
|
||||
Installing bu script to /tmp/pycoin/bin
|
||||
Installing fetch_unspent script to /tmp/pycoin/bin
|
||||
Installing block script to /tmp/pycoin/bin
|
||||
Installing spend script to /tmp/pycoin/bin
|
||||
Installing ku script to /tmp/pycoin/bin
|
||||
Installing genwallet script to /tmp/pycoin/bin
|
||||
Successfully installed pycoin
|
||||
Cleaning up...
|
||||
$
|
||||
----
|
||||
====
|
||||
|
||||
Here's a sample Python script to fetch and spend some bitcoin using the pycoin library:
|
||||
|
||||
====
|
||||
[source,python]
|
||||
----
|
||||
include::code/pycoin_example.py[]
|
||||
----
|
||||
====
|
||||
|
||||
For many examples using the command line utilities +ku+ and +tx+, see <<appdx_pycoin>>.
|
||||
|
||||
==== btcd
|
||||
btcd is a full node bitcoin implementation written in Go. It currently properly downloads, validates, and serves the block chain using the exact rules (including bugs) for block acceptance as the reference implementation, bitcoind. It also properly relays newly mined blocks, maintains a transaction pool, and relays individual transactions that have not yet made it into a block. It ensures all individual transactions admitted to the pool follow the rules required into the block chain and also includes the vast majority of the more strict checks which filter transactions based on miner requirements ("standard" transactions).
|
||||
|
||||
|
40
code/pycoin_example.py
Executable file
40
code/pycoin_example.py
Executable file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
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())
|
Loading…
Reference in New Issue
Block a user