mirror of
https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line.git
synced 2025-06-07 16:06:26 +00:00
Compare commits
1296 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
bba348c944 | ||
|
a4122976ef | ||
|
9b97c50471 | ||
|
2c7301f91b | ||
|
0cadc9b8dc | ||
|
598791eff3 | ||
|
9d1282bdea | ||
|
f95809a912 | ||
|
8a2a6955ff | ||
|
bea17662dd | ||
|
bdf45fbc7b | ||
|
89330cadc5 | ||
|
e53f72a06f | ||
|
aaa618699c | ||
|
f07ae7b521 | ||
|
5683c85f7d | ||
|
ad57c78450 | ||
|
cb02a570f9 | ||
|
42c164e556 | ||
|
bfe10b20d7 | ||
|
70f731609c | ||
|
9a683856e6 | ||
|
7aac2a9b6d | ||
|
3b6a307024 | ||
|
c0dca5cfc3 | ||
|
3034ebdf6d | ||
|
484eb6af95 | ||
|
5645833b30 | ||
|
6c500d0762 | ||
|
0b97a267ef | ||
|
0dd7e727f7 | ||
|
284549f53b | ||
|
5ac684c08c | ||
|
0db4652c6d | ||
|
d991df57fd | ||
|
a7d9a3f4e8 | ||
|
63618ce278 | ||
|
2261e14e0e | ||
|
3e2892ec88 | ||
|
263660920d | ||
|
85f5923a2d | ||
|
7fe45f88a9 | ||
|
8b6ebc0966 | ||
|
b31f033328 | ||
|
4009e4a729 | ||
|
42f5e96d3f | ||
|
6856f8c88a | ||
|
153369fae9 | ||
|
f5b314b436 | ||
|
cf2db7fb42 | ||
|
7780bd37e5 | ||
|
1dec061839 | ||
|
920fcbcdee | ||
|
b3da46f4bf | ||
|
14c3c1a828 | ||
|
5744135fb1 | ||
|
c903a1ff5b | ||
|
ff4d5167f8 | ||
|
795667e68a | ||
|
0e0b239786 | ||
|
2b3a885511 | ||
|
2f13b37bca | ||
|
1a8340459c | ||
|
1678ecc53c | ||
|
1b75a6ec0d | ||
|
d571451049 | ||
|
2f8e873de7 | ||
|
7cf298d9df | ||
|
98e3660476 | ||
|
e95fb3bb00 | ||
|
1b322dda97 | ||
|
1aee47763b | ||
|
180ef03e39 | ||
|
d543ef59fa | ||
|
48cf28fc2e | ||
|
c8dcbe88f1 | ||
|
e29cb22fac | ||
|
63604d2e35 | ||
|
11fbf899d2 | ||
|
8d51e38a36 | ||
|
e2d28f4409 | ||
|
2a4e99ffa1 | ||
|
ddf3ba3097 | ||
|
e6cd795039 | ||
|
d3be23c178 | ||
|
ab42c7fa27 | ||
|
bcccd686b4 | ||
|
80e3125c4a | ||
|
56b62df8ba | ||
|
19f3959513 | ||
|
7dc2ac27f3 | ||
|
9c29fb297f | ||
|
9ad9d9a154 | ||
|
91c6d1b42f | ||
|
46b811b982 | ||
|
ec887633eb | ||
|
4ea88427ed | ||
|
87cfbf38ac | ||
|
1ab9692904 | ||
|
96a743f247 | ||
|
d5dc23c38d | ||
|
93e9ac5b82 | ||
|
f2ebf377e7 | ||
|
6c8a92416d | ||
|
e38146adbb | ||
|
614dc77cc8 | ||
|
d2c83e337b | ||
|
09911855b0 | ||
|
6b9c0cb48c | ||
|
acc0d1f55e | ||
|
519a8b23c2 | ||
|
daf8fd0abb | ||
|
10a7c31bc4 | ||
|
7a874df5e0 | ||
|
fe36e9677e | ||
|
a7e4cbf1f8 | ||
|
16da5bf3e3 | ||
|
d4d08e5b1f | ||
|
ac09a55d0b | ||
|
912f480fd2 | ||
|
aba966c5af | ||
|
906673a3c0 | ||
|
6c50ba3359 | ||
|
5ae603b46c | ||
|
c78ca0be4d | ||
|
2132750203 | ||
|
2f4b3ce070 | ||
|
235d8964e7 | ||
|
df1ae00ae0 | ||
|
a6a72b158c | ||
|
a2fce3da8c | ||
|
753d2bc9c9 | ||
|
28725209fc | ||
|
f91556b3fc | ||
|
82cbf16d06 | ||
|
5898e4afb2 | ||
|
438bf61cca | ||
|
c86a51bb15 | ||
|
d3b157d87d | ||
|
a65f477e8d | ||
|
c2d751d747 | ||
|
be8922735f | ||
|
84e8995d6c | ||
|
3d98ca01c4 | ||
|
b158aee798 | ||
|
62a677dda9 | ||
|
aa598a2f35 | ||
|
b63690f7e2 | ||
|
66f588b257 | ||
|
5f867061fc | ||
|
47a6e4767d | ||
|
d292a53ffa | ||
|
51e1633d5a | ||
|
3d4d0abd05 | ||
|
a6174a7927 | ||
|
5a6d3f1bfe | ||
|
55ed2b0346 | ||
|
85ead1b659 | ||
|
6045bc5d29 | ||
|
7e0abd0ad6 | ||
|
0f69cdb92e | ||
|
488a590926 | ||
|
85c1295a3d | ||
|
469fd38a33 | ||
|
91841e655c | ||
|
e0d2c93b9d | ||
|
a0cfea22bd | ||
|
0e51860eb5 | ||
|
b8ddf3d092 | ||
|
24e93f6b50 | ||
|
f5cb57d481 | ||
|
8d209636d1 | ||
|
db9cb47ee3 | ||
|
f1693a01a2 | ||
|
2a2d6a1b1b | ||
|
d2f65ffcdc | ||
|
2c1643dfc3 | ||
|
6cc2ec4629 | ||
|
ada831304c | ||
|
e2e234ca34 | ||
|
f79d8cac58 | ||
|
6f6bc25361 | ||
|
90512e527e | ||
|
41f0f7854f | ||
|
fcf0efc6af | ||
|
e56eac346a | ||
|
935226b003 | ||
|
0266655474 | ||
|
21f7affe44 | ||
|
07c11b2a9c | ||
|
13b1437370 | ||
|
f012a81f82 | ||
|
e6ad79a8e5 | ||
|
8133f1f6a4 | ||
|
739198f62d | ||
|
343ea7364a | ||
|
489fd1019b | ||
|
6cd28d921e | ||
|
ddc89b36f5 | ||
|
a05782593a | ||
|
abd36c28ac | ||
|
023909e0cc | ||
|
33e38c15e0 | ||
|
59e1ff85b6 | ||
|
0713a672d0 | ||
|
f04ffe5965 | ||
|
94e0b243c7 | ||
|
1a434ece5a | ||
|
f18a9dbba4 | ||
|
d40aa0ab66 | ||
|
920ab1213c | ||
|
b2daf49b80 | ||
|
b23a93148c | ||
|
ec7420936a | ||
|
f42274a6b3 | ||
|
78554ade58 | ||
|
d04dacd847 | ||
|
a0f14d72f1 | ||
|
1c890c7177 | ||
|
a89f4c3b66 | ||
|
ad512f6999 | ||
|
c77ead3926 | ||
|
41657338d5 | ||
|
f2e551e9ad | ||
|
66e8da64a9 | ||
|
d2642d6531 | ||
|
255bb7822f | ||
|
c98d25180f | ||
|
e5b650732b | ||
|
d4b73e5f95 | ||
|
d4277dae06 | ||
|
72f0eea840 | ||
|
71f0da240c | ||
|
6e380c073a | ||
|
3471e3f246 | ||
|
5490feff67 | ||
|
0bcfbf8071 | ||
|
e3b10f7e7c | ||
|
69af86c053 | ||
|
076645b729 | ||
|
44ed34d6ab | ||
|
97f790a53a | ||
|
58ee5d7904 | ||
|
69afc41db8 | ||
|
34d0dcac74 | ||
|
a240e42873 | ||
|
cbe336a9fd | ||
|
c99c99d39c | ||
|
4f87582498 | ||
|
9eabc7e907 | ||
|
b21063952c | ||
|
621cb9453e | ||
|
d42fd81006 | ||
|
9d5057d1a2 | ||
|
80e50fec33 | ||
|
4f99d61337 | ||
|
50b7e3ce9b | ||
|
f700664ec8 | ||
|
8c02ba00ca | ||
|
d9a06468d4 | ||
|
746e9d135a | ||
|
0b122e43cf | ||
|
755dfeecee | ||
|
36e30e0380 | ||
|
9dab153d90 | ||
|
5f0e49e818 | ||
|
500a00e81b | ||
|
b16c7ad9f4 | ||
|
b4fa2d6024 | ||
|
e6b9c900cf | ||
|
ef79bf5caf | ||
|
65fd8b5059 | ||
|
574545ce27 | ||
|
e7b38b6fd1 | ||
|
86b7e7b45a | ||
|
e950816c6a | ||
|
40dc2f1ead | ||
|
ed567da44f | ||
|
0ece71c6af | ||
|
f4d554353d | ||
|
77f19acb1a | ||
|
d0756f637c | ||
|
33bc0e8da3 | ||
|
270576a2d9 | ||
|
0f2c0e370c | ||
|
c3be3b7825 | ||
|
05ba5ae4c0 | ||
|
3d8b3d4533 | ||
|
c4384baea5 | ||
|
ef2ec75a7b | ||
|
21bf3ad094 | ||
|
83889c5a69 | ||
|
bf4e9ffcab | ||
|
a568c98579 | ||
|
c45aed55d7 | ||
|
70ad923237 | ||
|
d55a32bc63 | ||
|
9aeb033ebb | ||
|
14aa736a62 | ||
|
55fb576c95 | ||
|
aba46e6efb | ||
|
240ff78b96 | ||
|
47cd0998d5 | ||
|
276d5da9f1 | ||
|
b057f22f3f | ||
|
d0dd93099e | ||
|
d990c4bf41 | ||
|
630c384193 | ||
|
05efe2c757 | ||
|
3761810009 | ||
|
788d952a99 | ||
|
ce14af20b4 | ||
|
801a45f0e1 | ||
|
2ccb199fa1 | ||
|
1a629fc2ce | ||
|
bb9be873c1 | ||
|
f1c4403e19 | ||
|
76728baf0c | ||
|
19a4e352d8 | ||
|
d5d1fc36b1 | ||
|
cf94bb2bdc | ||
|
cd1ebf4174 | ||
|
e0223a5743 | ||
|
76926597a6 | ||
|
534b39b2e5 | ||
|
5fee49b6c8 | ||
|
0362bf6198 | ||
|
cf77bec66f | ||
|
7e2ee9bfb6 | ||
|
571fa86972 | ||
|
a24eda599f | ||
|
a9a9056681 | ||
|
65617c873d | ||
|
7ed3215cf0 | ||
|
642a642e56 | ||
|
acb6c1f8f0 | ||
|
41eefa15ff | ||
|
c12abd1938 | ||
|
df6329a101 | ||
|
405c9fc7f9 | ||
|
a69d882a6a | ||
|
586d16c79a | ||
|
d0ccb881a2 | ||
|
1b7776a040 | ||
|
bf1400eb6c | ||
|
7ce59c0584 | ||
|
c4cf1ef060 | ||
|
ed9557875f | ||
|
66228ec5b9 | ||
|
5573718e84 | ||
|
3898913533 | ||
|
8f308d4e1c | ||
|
82949bfa1b | ||
|
542417258d | ||
|
2a4485f311 | ||
|
789fc155ec | ||
|
1b2a0ae565 | ||
|
0657079b28 | ||
|
214dd882ec | ||
|
702a1dd403 | ||
|
4a44502eca | ||
|
faac3f6cc6 | ||
|
2963347005 | ||
|
08f0d0d744 | ||
|
1015338f7d | ||
|
8a87dd5762 | ||
|
0692c6847a | ||
|
7fc3bf539c | ||
|
ef7022d62f | ||
|
dce0a34516 | ||
|
b8dba71922 | ||
|
91cd6d4f06 | ||
|
eb288f3ae0 | ||
|
5d6288116c | ||
|
d9f7e45e58 | ||
|
3220db1945 | ||
|
958279461c | ||
|
92353a8eef | ||
|
1803841bbd | ||
|
f382b1cca3 | ||
|
90506a3c88 | ||
|
75359ad3f1 | ||
|
35784585d2 | ||
|
c1a863bef9 | ||
|
1be5100213 | ||
|
53f9b35b2b | ||
|
5ec64054ad | ||
|
e776376189 | ||
|
e6c5a33049 | ||
|
7b9023b038 | ||
|
11c784be7c | ||
|
24bde9990f | ||
|
7908a360dc | ||
|
df9f83c510 | ||
|
8478ef2a7b | ||
|
6c2bef3dcc | ||
|
b82cba592b | ||
|
bf80c0ebed | ||
|
6ece2fd383 | ||
|
aed111d876 | ||
|
e6eff07dfa | ||
|
1c51b6caaf | ||
|
74545968d2 | ||
|
f4f602cee6 | ||
|
ed81abcce2 | ||
|
d10f15f93d | ||
|
16894ed92a | ||
|
46e98eef97 | ||
|
0c2c422092 | ||
|
0ff72ebcc0 | ||
|
63f0ef8fb3 | ||
|
908e77217e | ||
|
10f09de8c9 | ||
|
08c20ada2e | ||
|
bb2593bc94 | ||
|
c2bc52035d | ||
|
2447f663a0 | ||
|
ffc2a46f0b | ||
|
43cedbd8a1 | ||
|
79217d814f | ||
|
ec703953fa | ||
|
a068005b2a | ||
|
1f04c23573 | ||
|
75e18fa9bf | ||
|
a1836b335d | ||
|
2dcf9780a0 | ||
|
8a38f669cb | ||
|
3ec8af8a04 | ||
|
53fe8ba4da | ||
|
d1071085d1 | ||
|
b4082955b8 | ||
|
16d0ae1681 | ||
|
7650ae20ab | ||
|
ce2b2cf59f | ||
|
8beb904f5a | ||
|
e8e4236f8b | ||
|
0c34b2b35f | ||
|
7c1d09933e | ||
|
1978315b54 | ||
|
551d23ca9b | ||
|
1b279a7205 | ||
|
e50dbb88a5 | ||
|
edf7da8bb7 | ||
|
edccd79166 | ||
|
fbc1f8015d | ||
|
7e8ee7a9da | ||
|
d0d97269ea | ||
|
61ad4d9b21 | ||
|
df901c9f43 | ||
|
6d10979d9e | ||
|
5cd1eceaab | ||
|
54c98023f2 | ||
|
2c98dc3971 | ||
|
5c178488a8 | ||
|
44c84f129d | ||
|
24099cdc08 | ||
|
44f3a511f2 | ||
|
af14b0303e | ||
|
15d860a289 | ||
|
c1727d2b81 | ||
|
fdd3234dac | ||
|
787affa4d6 | ||
|
786c307a09 | ||
|
00298f9e0d | ||
|
461c7e25ec | ||
|
27a59ee528 | ||
|
a240718617 | ||
|
71571de701 | ||
|
d071e516a6 | ||
|
8739750289 | ||
|
602d8f4fde | ||
|
502716908d | ||
|
e308cb4b04 | ||
|
3675f6e5d7 | ||
|
89461e478b | ||
|
08ecb935f9 | ||
|
ced7f10769 | ||
|
1d84d824bf | ||
|
1fc0a69ca6 | ||
|
7e0eebda42 | ||
|
0d7a40481d | ||
|
ea97380ab7 | ||
|
a902cf9bec | ||
|
b525df970c | ||
|
64707aa383 | ||
|
52c8cf85ef | ||
|
f91205fb25 | ||
|
3fb9f13281 | ||
|
4ec425122f | ||
|
e3ad77e313 | ||
|
ae8ddea69b | ||
|
55eed41ce7 | ||
|
60180e84f5 | ||
|
45faf2e4ff | ||
|
5006f1a191 | ||
|
7a05d7e33b | ||
|
15ea6ca148 | ||
|
2f1c6a317c | ||
|
34afbb3ea7 | ||
|
b270d1dac9 | ||
|
334d9f5b24 | ||
|
ebbdccdc16 | ||
|
1f184def89 | ||
|
fdfdac055d | ||
|
5633bb4cd2 | ||
|
4122c56e16 | ||
|
e18d52dd9a | ||
|
53f83e1d41 | ||
|
13dac40716 | ||
|
0e9b2bf3f4 | ||
|
8026045ed4 | ||
|
0751a20fae | ||
|
271f867edc | ||
|
9b3388b2c8 | ||
|
8a3ebcb6bf | ||
|
ea302fe9ca | ||
|
ff0186b08f | ||
|
09c91d8885 | ||
|
9253e04338 | ||
|
dd86c8986f | ||
|
ad277c0805 | ||
|
e1a8caf8ec | ||
|
651a33aef6 | ||
|
a1631407c9 | ||
|
3a6175202d | ||
|
e8a990796e | ||
|
9a725c161c | ||
|
b9b86e0716 | ||
|
fc43363f4b | ||
|
0353a2f884 | ||
|
e03d698a2b | ||
|
98d90b6343 | ||
|
d34cb20842 | ||
|
6e35f0967b | ||
|
ea54a60021 | ||
|
8471f4d9ae | ||
|
bb370fab88 | ||
|
3bfd746428 | ||
|
1e00b40942 | ||
|
6083908549 | ||
|
d13691fc4e | ||
|
96b63ddceb | ||
|
f698a6c7b2 | ||
|
a6e61c7087 | ||
|
866267a290 | ||
|
7d0f7ccc3d | ||
|
8fe118d453 | ||
|
dc9f00a3fe | ||
|
8adccaff4e | ||
|
c623f645c3 | ||
|
28979322af | ||
|
c389e18264 | ||
|
e9bda63a98 | ||
|
122dae075c | ||
|
cfd260fff8 | ||
|
37c8cf47ee | ||
|
f3fd33c9be | ||
|
f83b3d293a | ||
|
2293aa2150 | ||
|
57cb31c9e3 | ||
|
68331abcfa | ||
|
2cba69b67f | ||
|
cca0ae2705 | ||
|
dc457b790b | ||
|
72d97eaed0 | ||
|
84759982df | ||
|
cc3939470f | ||
|
723ef35429 | ||
|
1f635a92c8 | ||
|
a359b90e25 | ||
|
ee938c600d | ||
|
3a31191cf4 | ||
|
af86e95491 | ||
|
4b09279886 | ||
|
3f6234aaae | ||
|
19b96412d1 | ||
|
59ebebce40 | ||
|
3d2cbd2a53 | ||
|
eaab92a582 | ||
|
0f01295f4a | ||
|
77bcee3472 | ||
|
91e31784bf | ||
|
2f6dafe082 | ||
|
b804f5147b | ||
|
e54c2dafa3 | ||
|
1b36e74550 | ||
|
851d2a74d4 | ||
|
485176ee59 | ||
|
cfa1479e00 | ||
|
c311318701 | ||
|
26b2dd7977 | ||
|
a1a457f072 | ||
|
0ae3949065 | ||
|
cb8b8deadb | ||
|
73e1a65e35 | ||
|
9cbc5e18e6 | ||
|
1a5e5694bf | ||
|
7ab1c58a0a | ||
|
1be8fd8453 | ||
|
4df18c9aa1 | ||
|
46d385810e | ||
|
dd5dd5d823 | ||
|
fadb5a5bbd | ||
|
ae2f32a191 | ||
|
dfdcdb4e05 | ||
|
f59849d8a9 | ||
|
44c594dbdd | ||
|
f54d67c5a7 | ||
|
7876104d0d | ||
|
30e32c9449 | ||
|
b139a7611e | ||
|
22adecbe00 | ||
|
ba2e128dfe | ||
|
0f53828866 | ||
|
2fb00fac92 | ||
|
4f34de4ff7 | ||
|
6f00cc77dc | ||
|
b267b840c0 | ||
|
9b3917a4e8 | ||
|
75b2dc7dab | ||
|
a4c2cdad3a | ||
|
8dbcbd76e2 | ||
|
a87ec94f70 | ||
|
acc04c5ec3 | ||
|
dcb45e5ec7 | ||
|
cfee6bc119 | ||
|
c3578c8c1f | ||
|
2502bd0751 | ||
|
8512f44de4 | ||
|
317ca7e195 | ||
|
c75011293f | ||
|
df8686f3ed | ||
|
c8258c1e69 | ||
|
46683fbfd9 | ||
|
f3a6cc7e55 | ||
|
802d0e9f10 | ||
|
0cb604f4ab | ||
|
48c3ef65ef | ||
|
f0f2a2533d | ||
|
d19f1d7f13 | ||
|
80ba7bad67 | ||
|
7abc26bc22 | ||
|
3a75ecc3b7 | ||
|
d4dee8c51e | ||
|
04167948c9 | ||
|
02d7d2e3d2 | ||
|
d7d86f98c5 | ||
|
7639044de8 | ||
|
e5044393ff | ||
|
f1f8950ae6 | ||
|
75da52f482 | ||
|
d1fe13d8c1 | ||
|
ab8d6a1094 | ||
|
a61e330dee | ||
|
f9d1023d53 | ||
|
97e2f7c856 | ||
|
3b77bf4732 | ||
|
9f391ffc34 | ||
|
227468d02a | ||
|
a0ef924e0d | ||
|
bb219da47d | ||
|
810af6c917 | ||
|
47164907e2 | ||
|
de34b357bf | ||
|
d962e7d1f8 | ||
|
c04cc0a0e3 | ||
|
9823a2b8db | ||
|
f804a036a8 | ||
|
07308cb02c | ||
|
3d2b675b5d | ||
|
e2cd52d77e | ||
|
51cc8fc35a | ||
|
ebc0e66a4e | ||
|
a1e148fa5c | ||
|
1574a0d414 | ||
|
0f3daf77dd | ||
|
0d560827e4 | ||
|
2ba762da22 | ||
|
92f86fa393 | ||
|
a1facbe4ce | ||
|
ddb2c2e601 | ||
|
0a24d3c6d5 | ||
|
6f88c95c30 | ||
|
cd08fb26a7 | ||
|
a7287ded3d | ||
|
eec2d21b8e | ||
|
30e945b6a3 | ||
|
36803fb6e0 | ||
|
7ed52a53db | ||
|
a306efdc6e | ||
|
411d238b02 | ||
|
57cf4e7600 | ||
|
8484b7e546 | ||
|
d55adbf72a | ||
|
99986ff0a4 | ||
|
d70392955b | ||
|
30bc9e8230 | ||
|
256d54e831 | ||
|
ecfa758cc5 | ||
|
abaeec981e | ||
|
6732f2f778 | ||
|
bf9eb432d8 | ||
|
7bedbed4f0 | ||
|
63658e1b40 | ||
|
8c4f6bb931 | ||
|
51362eebdd | ||
|
3082375f69 | ||
|
6854713ddd | ||
|
86288d619b | ||
|
911b1ff467 | ||
|
e84a30cb58 | ||
|
ed99ab1b99 | ||
|
4e26ab0313 | ||
|
20df31110e | ||
|
60f2d201d1 | ||
|
54f5842e22 | ||
|
af83a5b00b | ||
|
ff9d7c398d | ||
|
a965b6ce5a | ||
|
632e4fc830 | ||
|
d2d9fbf31b | ||
|
a4c1beedfd | ||
|
9779f8f06b | ||
|
d0ab082bd1 | ||
|
db1b77dae9 | ||
|
1635d2bdc1 | ||
|
6a0645ab66 | ||
|
9aecfd6b87 | ||
|
5188613af7 | ||
|
4299a5018a | ||
|
e1edd19a40 | ||
|
2a56eec18b | ||
|
48f3e5ae87 | ||
|
9a7ae7183d | ||
|
80b8ebf8a2 | ||
|
342687aa16 | ||
|
c7710a55c5 | ||
|
67a386ae85 | ||
|
3347fc570b | ||
|
54e37d4f5b | ||
|
4f380e5180 | ||
|
b89ca218a6 | ||
|
a0e422b75e | ||
|
e612796ff8 | ||
|
d0dfc62770 | ||
|
4db091eb85 | ||
|
28d9eb75b1 | ||
|
31594298c0 | ||
|
e294214ada | ||
|
6f18e057cd | ||
|
f726c60359 | ||
|
e537667287 | ||
|
fdaaac3856 | ||
|
7491a68ed7 | ||
|
3d9fdbb288 | ||
|
4a6ce39532 | ||
|
89aa4ce0c4 | ||
|
4fb508a054 | ||
|
e5d6eec796 | ||
|
dce2f7eefe | ||
|
11fb617d74 | ||
|
ca406ce081 | ||
|
58a40b8559 | ||
|
392b66c0de | ||
|
4f4b624b35 | ||
|
604163a8b2 | ||
|
66cd73989b | ||
|
523d3e6a12 | ||
|
5746b96ddb | ||
|
b042cd480d | ||
|
528a272d18 | ||
|
e515da4a7c | ||
|
161ad35fb5 | ||
|
fd345a450f | ||
|
ae46342eb2 | ||
|
33f49586a0 | ||
|
ebc0c56fd4 | ||
|
9fd43b3ddf | ||
|
ccadbfd70a | ||
|
b2c72e1d8d | ||
|
be853e25f8 | ||
|
99cb8f3a94 | ||
|
fbb0e14a9d | ||
|
7f876516a8 | ||
|
1f7713a0a3 | ||
|
ddc5dae330 | ||
|
9ca5d0eb70 | ||
|
c3ce8432b5 | ||
|
5dc4f00740 | ||
|
33bbc5d9ee | ||
|
17d4959c31 | ||
|
8e53068b94 | ||
|
e679000b60 | ||
|
a187905899 | ||
|
1f00c0a009 | ||
|
7e0fbc1697 | ||
|
68cbfef186 | ||
|
267f1aa16f | ||
|
5cd941e4ab | ||
|
abf66f3125 | ||
|
3d9e1b1518 | ||
|
3d71a09ebf | ||
|
80c6bd55f5 | ||
|
05374400c0 | ||
|
7790a39da7 | ||
|
fe5e4f9be2 | ||
|
07f9ffb537 | ||
|
1baf06366d | ||
|
ce2dfef0c2 | ||
|
e495a85d72 | ||
|
57c34e4764 | ||
|
5aa947d008 | ||
|
8afe14c464 | ||
|
14440544b1 | ||
|
2cb9d66eea | ||
|
5c17cf67a6 | ||
|
0906139603 | ||
|
876dcddb1a | ||
|
e85ff14c92 | ||
|
7e4aa84b84 | ||
|
6e1910d9ca | ||
|
5b52d7099c | ||
|
e374ec7ff8 | ||
|
45f707551b | ||
|
34a2fbc5f8 | ||
|
ccab59c8db | ||
|
7427136127 | ||
|
8ff7f36eb3 | ||
|
6df5f6fee2 | ||
|
cf46cc4760 | ||
|
8598756ae1 | ||
|
306e7c89d4 | ||
|
fa5b1ab46c | ||
|
6dc135c54b | ||
|
f332c8250e | ||
|
9c454701e4 | ||
|
0ad361b74c | ||
|
f8efd8081e | ||
|
852e96aae2 | ||
|
58f41aa3a9 | ||
|
35dfd68e62 | ||
|
544171bd4d | ||
|
d262a8c422 | ||
|
4f31ab28ba | ||
|
cd9a715a3e | ||
|
25e48d6ac5 | ||
|
3321457d21 | ||
|
eb23f1ea50 | ||
|
44379d9b6f | ||
|
69b99a9fd6 | ||
|
0fc6fef526 | ||
|
8b997692b2 | ||
|
0c92c4d572 | ||
|
3985cb0144 | ||
|
b630588e1d | ||
|
2e94b36c43 | ||
|
1cbb9b85ce | ||
|
68ffe9426b | ||
|
26c5fb9e1c | ||
|
13bf01df11 | ||
|
d383dc9a0e | ||
|
cdea601972 | ||
|
04259d81a2 | ||
|
62595e603b | ||
|
59356bb93f | ||
|
21438d9312 | ||
|
a13bfdbde4 | ||
|
8e1b1b5081 | ||
|
ee97c03e97 | ||
|
9f4d6e7f83 | ||
|
40ee335e0f | ||
|
a8a5e5400e | ||
|
746a1268c7 | ||
|
cb764d8a6f | ||
|
1965926e9d | ||
|
75f541b728 | ||
|
bea00c7cbf | ||
|
4966fb9bd7 | ||
|
531a8b5332 | ||
|
494b1f9d5f | ||
|
491b75c0cb | ||
|
335b5c0c85 | ||
|
e77e60344c | ||
|
9f426b46b9 | ||
|
8117b511f7 | ||
|
6d6e096360 | ||
|
11fa794c9f | ||
|
610d0041dc | ||
|
b64f371c98 | ||
|
0855904994 | ||
|
8195533f4d | ||
|
9d1c663037 | ||
|
6da28bbe1f | ||
|
816dedf129 | ||
|
a8ee206ab9 | ||
|
7541259c9b | ||
|
4b4af9db4b | ||
|
1d6825a39e | ||
|
0041878ee6 | ||
|
2d1903aca0 | ||
|
0db9545945 | ||
|
d6be459d3e | ||
|
79414943d1 | ||
|
81d2e776e8 | ||
|
81bf6567ca | ||
|
61aef75904 | ||
|
9bc1d302d9 | ||
|
6406fb5c1e | ||
|
44df1aab1b | ||
|
4cfeca92e1 | ||
|
01397ac7c0 | ||
|
8d39339830 | ||
|
7b94b72920 | ||
|
68ad4dfb5f | ||
|
2d11e276ff | ||
|
0d53a656e5 | ||
|
f674e44519 | ||
|
fa1b48bcd1 | ||
|
1d9c64b8fd | ||
|
3419e6852a | ||
|
2411b05715 | ||
|
f6d97c2f2b | ||
|
26a6fb1a7f | ||
|
53818e6337 | ||
|
5c5642dd6e | ||
|
4330d0f779 | ||
|
e35c5ae4fd | ||
|
fe1da712e3 | ||
|
14ed5f9f62 | ||
|
d7889093d9 | ||
|
d39e890173 | ||
|
45ccb82661 | ||
|
aafcaee91b | ||
|
79193edf02 | ||
|
f2cb55ffe2 | ||
|
ee82235f99 | ||
|
f7ac3170e9 | ||
|
816fb4055a | ||
|
92c1994ba7 | ||
|
6ea2bbec92 | ||
|
a16039f068 | ||
|
a3cb190eb1 | ||
|
86f890669a | ||
|
286ff4841b | ||
|
49fca598a3 | ||
|
52baa5e6a0 | ||
|
4d84776f0d | ||
|
829177a37f | ||
|
f358fbe223 | ||
|
6bfc182a3a | ||
|
e4c923cb72 | ||
|
65f4cc8cf7 | ||
|
d4edf6985c | ||
|
ad06362641 | ||
|
1b9baabf5d | ||
|
e00f732d53 | ||
|
d3e8ca6247 | ||
|
d555f72e35 | ||
|
2452670750 | ||
|
8e673c4f5f | ||
|
33c9f8d726 | ||
|
27c8bfc7de | ||
|
227a137da0 | ||
|
91e0a12789 | ||
|
48011d3c60 | ||
|
7d9d905e62 | ||
|
1fcdaaf245 | ||
|
e56dfe08f7 | ||
|
d777b644a4 | ||
|
57d46c8572 | ||
|
d41ef23eb7 | ||
|
870c5d3301 | ||
|
a09801cebe | ||
|
bb6dd6cfde | ||
|
46708b34e0 | ||
|
47a4019900 | ||
|
53c999893d | ||
|
806d1db577 | ||
|
aee2872f95 | ||
|
3a5e10dd85 | ||
|
731181873e | ||
|
ea5b78185a | ||
|
a3f6c45ccf | ||
|
ca69456c68 | ||
|
af565f0b37 | ||
|
9a0c86326c | ||
|
803081cd64 | ||
|
28710981d2 | ||
|
0578346b32 | ||
|
d6cfd9984a | ||
|
3c0e39e706 | ||
|
9fb3522ba2 | ||
|
112613e029 | ||
|
67523d4b0c | ||
|
9a4f0ac19d | ||
|
1e85f88a90 | ||
|
969fc8219e | ||
|
39d28bd8f4 | ||
|
f4f7e4199f | ||
|
a9325e552d | ||
|
a75034324c | ||
|
9ec21b57cd | ||
|
d5fb91ac00 | ||
|
bc4705795f | ||
|
6e6f2de6ca | ||
|
8b9ba852b7 | ||
|
43d0a40d91 | ||
|
ed4ca1aac4 | ||
|
0e25987213 | ||
|
9aadfc2e6f | ||
|
6acee857fb | ||
|
6fcc30e40b | ||
|
eb708033a5 | ||
|
65458a0047 | ||
|
77d013c8c9 | ||
|
4843dcb510 | ||
|
0a2700100d | ||
|
1d8a1c7b7b | ||
|
7e9d2d1bf3 | ||
|
0741ea0cf7 | ||
|
577e4b4d44 | ||
|
0092827376 | ||
|
cbeda81f66 | ||
|
244e9ca411 | ||
|
242d52a863 | ||
|
abae7fbc6e | ||
|
4e964fd934 | ||
|
a9efcf736a | ||
|
38cba921fc | ||
|
b59fccacc4 | ||
|
7764e1601d | ||
|
5b1bde60fc | ||
|
fe1795eab1 | ||
|
72fae9437b | ||
|
2c25daed50 | ||
|
013b27c9d2 | ||
|
7fac0c0594 | ||
|
a85ec0afe6 | ||
|
f6e6dcfefa | ||
|
cf626c2125 | ||
|
59e7dcbe6c | ||
|
a5c061104c | ||
|
37275e39b8 | ||
|
4b3dc0d2cd | ||
|
613047b5d7 | ||
|
13393d2809 | ||
|
74a37d065a | ||
|
89288a1b58 | ||
|
d1b35cd4ab | ||
|
f772dd069f | ||
|
65f8cf6ceb | ||
|
c9127e47ef | ||
|
b3d06253cc | ||
|
6dc97de117 | ||
|
17a3735e73 | ||
|
e1ef3c8467 | ||
|
c242393c5e | ||
|
51c232f841 | ||
|
e29aef1cf6 | ||
|
901f531695 | ||
|
7e7fee1634 | ||
|
004fb7a88e | ||
|
5031312d78 | ||
|
e1cf5d398b | ||
|
1e5aef6014 | ||
|
f04e857436 | ||
|
f113a2c81a | ||
|
2c61577e55 | ||
|
57add3eed8 | ||
|
7c8062c700 | ||
|
f8086fee46 | ||
|
f3f6b808c6 | ||
|
de6631877e | ||
|
77ee6d0e6d | ||
|
de33c0fb30 | ||
|
a746f261fd | ||
|
ece0a7f774 | ||
|
01faf540ca | ||
|
587f25eb3b | ||
|
4033e5adbf | ||
|
933ed49f94 | ||
|
463e1570ea | ||
|
5c4265cb90 | ||
|
30112af2ea | ||
|
676f753b68 | ||
|
2dcf2b9d60 | ||
|
53230f69c9 | ||
|
eb78a37ffc | ||
|
e2543d64b3 | ||
|
072a9f7ade | ||
|
c97b2d8b7c | ||
|
2d1aab54e8 | ||
|
a40a2005ea | ||
|
cac5dbc243 | ||
|
b0e25e7a8e | ||
|
36613e3451 | ||
|
6d2eca2940 | ||
|
7f643a4478 | ||
|
3fe95b214a | ||
|
a8de9d37fa | ||
|
5c4993d945 | ||
|
5c0e764251 | ||
|
aac7d4ed35 | ||
|
bab511d71e | ||
|
570ebb8cdf | ||
|
88c6a4e12b | ||
|
7231f589f8 | ||
|
0aaaafb045 | ||
|
1bb7c04818 | ||
|
93e029caf3 | ||
|
4944a4f26e | ||
|
850132d000 | ||
|
7547e3dc99 | ||
|
0ca4a04ce6 | ||
|
3854c66540 | ||
|
d90a85d012 | ||
|
36b946f222 | ||
|
22dfbdb570 | ||
|
7a791e5e62 | ||
|
1f722ca941 | ||
|
797229d522 | ||
|
dc0446fb73 | ||
|
0301a292e1 | ||
|
bc3431ea09 | ||
|
a0fcae116c | ||
|
835aa32238 | ||
|
db47d723b9 | ||
|
2a062b6a93 | ||
|
b1529ebb70 | ||
|
240f7ad010 | ||
|
6ba639af99 | ||
|
cde0e237c3 | ||
|
9712478a77 | ||
|
8b3b568850 | ||
|
f82b60e419 | ||
|
286976dc4d | ||
|
3d9d4eec19 | ||
|
2c321c21e9 | ||
|
8be593a08f | ||
|
f0bedd25c1 | ||
|
ca46d48674 | ||
|
2afd0d2679 | ||
|
5b467c817f | ||
|
f26f691a2d | ||
|
9c675f05b6 | ||
|
d93085157b | ||
|
b0a37e21ee | ||
|
c9f31b3b17 | ||
|
6ecdf65b29 | ||
|
07a1e4bab6 | ||
|
703ba198e5 | ||
|
baf06ca282 | ||
|
5672610986 | ||
|
15f106201f | ||
|
e9c4af5bf0 | ||
|
fbe0862054 | ||
|
8e92ee0cc2 | ||
|
cb074778f8 | ||
|
0fad79c78b | ||
|
6202e526b1 | ||
|
b462f66564 | ||
|
ae887c4193 | ||
|
cbf889f4cb | ||
|
9916b65adc | ||
|
77aa33b5f9 | ||
|
d33808e68c | ||
|
56ff02ee75 | ||
|
c5306f6885 | ||
|
238d5b396d | ||
|
0568399ecc | ||
|
db2d05f870 | ||
|
ae7c0f6c21 | ||
|
2be84491cf | ||
|
a47fd6ef39 | ||
|
4fdae44c5c | ||
|
c8aeb00d64 | ||
|
a84f1f7574 | ||
|
44b84b5998 | ||
|
b5677ca649 | ||
|
c736c1ce77 | ||
|
1c0ca8ad32 | ||
|
f33d5539d8 | ||
|
e000664dd2 | ||
|
26ddb69bc8 | ||
|
5011902760 | ||
|
e8a45e5f05 | ||
|
0f9a7859e9 | ||
|
1a01a6d4bd | ||
|
ce86b71551 | ||
|
1841b699c9 | ||
|
a920060ed2 | ||
|
daeb8bbe8b | ||
|
62ae49fd0b | ||
|
2674bdec2c | ||
|
82c232c491 | ||
|
aa1174727e | ||
|
a8516ee36e | ||
|
c4c2b0fb26 | ||
|
85df221a79 | ||
|
098666fc68 | ||
|
33ffbb490b | ||
|
48667a7bb6 | ||
|
7d1e793f0b | ||
|
a612ffb4c2 | ||
|
82ca897286 | ||
|
9df9904129 | ||
|
80467579f9 | ||
|
0d1070fd8f | ||
|
dceb9b68cf | ||
|
5a9ba9c59b | ||
|
3b70f86c79 | ||
|
11ccda91f0 | ||
|
f1bb218f43 | ||
|
7c8a226ea5 | ||
|
ced4a14057 | ||
|
e733798af8 | ||
|
a5f978cb78 | ||
|
5575f96c00 | ||
|
facc43f1e0 | ||
|
224c0a7e42 | ||
|
488a3e915c | ||
|
ddbd6e8909 | ||
|
3137bc2ffe | ||
|
422d59807a | ||
|
3e5703907e | ||
|
060e1419b2 | ||
|
d73d4cc822 | ||
|
a398b0c72c | ||
|
a344a65520 | ||
|
5ae223897f | ||
|
10d22f6e96 | ||
|
cbd715a293 | ||
|
d4f8a19bc5 | ||
|
f739de85d5 | ||
|
873c5f946f | ||
|
798e3911f0 | ||
|
6b451ae7f6 | ||
|
c43f9fa982 | ||
|
4bd351fdbb | ||
|
d89669325a | ||
|
1b8ef8c39f | ||
|
391b10382b | ||
|
1c29b87fda | ||
|
fc24e48c84 | ||
|
f70e474a9c | ||
|
c5d0ef1f99 | ||
|
d9fdeab142 | ||
|
47dacdd84b | ||
|
d34c187e2a | ||
|
266d7e13a3 | ||
|
16980cbd04 | ||
|
f424bd5370 | ||
|
25d8852244 | ||
|
c27f2b638c | ||
|
9ff63a4a66 | ||
|
ad0a09329d | ||
|
a9d592233c | ||
|
04efed7974 | ||
|
5ac748e82f | ||
|
d59a049c7c | ||
|
0ac9fb0ca2 | ||
|
63954f440e | ||
|
fcb294b17e | ||
|
d8babd752c | ||
|
cd0678c249 | ||
|
2254cb8c7b | ||
|
866e9cdb71 | ||
|
30fe0c1cab | ||
|
6097d8e11a | ||
|
d28c5a6db0 | ||
|
d7ed97274a | ||
|
5f989f0833 | ||
|
de28f0c6cd | ||
|
9aafcb04d6 | ||
|
9c901c3054 | ||
|
b8c7da9529 | ||
|
e015cd475e | ||
|
5e114757a5 | ||
|
a8a344f583 | ||
|
7b2705e9a3 | ||
|
cf83300fba | ||
|
b9713a8e2e | ||
|
60ee4bb655 | ||
|
3ce394a327 | ||
|
b9ffcd22d1 | ||
|
99a3fc2a72 | ||
|
b5eeee69ab | ||
|
ad56f04a27 | ||
|
e95dede691 | ||
|
f9ec4c958f | ||
|
43ca374e4b | ||
|
0a27bda86f | ||
|
cd341da0a6 | ||
|
0093975bb8 | ||
|
cda172c521 | ||
|
87c141c2f3 |
@ -8,9 +8,9 @@ These centralization risks were some of the prime catalysts behind the creation
|
||||
|
||||
If you're one of those entrepreneurs or developers, then this course is for you, because it's all about learning to program Bitcoin. It's an introductory course that explains all the nuances and features of Bitcoin as it goes. It also takes a very specific tack, by offering lessons in how to work _directly_ with Bitcoin Core and with the c-lightning server using their RPC interfaces.
|
||||
|
||||
Why not use some of the more fully featured libraries found in various programming languages? Why not create your own from scratch? It's because working with cryptocurrency is dangerous. There are no safety nets. If you accidentally overpay your fees or lose a signing key or create an invalid transaction or make any number of potential mistakes, then your cryptocurrency will been gone forever. Much of that responsibility will, of course, lie with you as a cryptocurrency programmer, but it can be minimized by working with the most robust, secure, and safe cryptocurrency interfaces around, the ones created by the cryptocurrency programming teams themselves: ``bitcoind`` and ``lightningd``.
|
||||
Why not use some of the more fully featured libraries found in various programming languages? Why not create your own from scratch? It's because working with cryptocurrency is dangerous. There are no safety nets. If you accidentally overpay your fees or lose a signing key or create an invalid transaction or make any number of potential mistakes, then your cryptocurrency will be gone forever. Much of that responsibility will, of course, lie with you as a cryptocurrency programmer, but it can be minimized by working with the most robust, secure, and safe cryptocurrency interfaces around, the ones created by the cryptocurrency programming teams themselves: ``bitcoind`` and ``lightningd``.
|
||||
|
||||
Much of this book thus discusses how to script Bitcoin (and Lightning) directly from the command line. Some later chapters deals with more sophisticated programming languages, but again they continue to interact directly with the ``bitcoind`` and ``lightningd`` daemons by using RPC or by interacting with the files they create. This allows you to stand on the shoulders of giants and use their trusted technology to learn how to create your own trusted systems.
|
||||
Much of this book thus discusses how to script Bitcoin (and Lightning) directly from the command line. Some later chapters deal with more sophisticated programming languages, but again they continue to interact directly with the ``bitcoind`` and ``lightningd`` daemons by using RPC or by interacting with the files they create. This allows you to stand on the shoulders of giants and use their trusted technology to learn how to create your own trusted systems.
|
||||
|
||||
## Required Skill Level
|
||||
|
||||
@ -40,10 +40,10 @@ If you have different levels of skill or want to learn different things, you mig
|
||||
|
||||
* If you've already got a Bitcoin environment ready to be used, jump to [Chapter Three: Understanding Your Bitcoin Setup](03_0_Understanding_Your_Bitcoin_Setup.md).
|
||||
* If you only care about Bitcoin scripting, jump to [Chapter Nine: Introducing Bitcoin Scripts](09_0_Introducing_Bitcoin_Scripts.md).
|
||||
* If you just want to read about using programming languages, jump to [Chapter Fifteen: Talking to Bitcoin](15_0_Talking_to_Bitcoind.md).
|
||||
* If you just want to read about using programming languages, jump to [Chapter Sixteen: Talking to Bitcoin](16_0_Talking_to_Bitcoind.md).
|
||||
* If you conversely don't want to do any programming, definitely skip chapters 15-17 while you're reading, and perhaps skip chapters 9-13. The rest of the course should still make sense without them.
|
||||
* If you are only interested in Lightning, zap over to [Chapter Eighteen: Understanding Your Lightning Setup](18_0_Understanding_Your_Lightning_Setup.md).
|
||||
* If you want to read the major new content added for v2 of the course (2020), following on v1 (2017), read [§3.5: Understanding the Descriptor](03_5_Understanding_the_Descriptor.md), [§4.6: Creating a SegWit Transaction](04_6_Creating_a_Segwit_Transaction.md), [Chapter 7: Expanding Bitcoin with PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md), [§9.5: Scripting a P2WPKH](09_5_Scripting_a_P2WPKH.md), [§10.5: Scripting a SegWit Script](10_5_Scripting_a_Segwit_Script.md), [Chapter 14: Using Tor](14_0_Using_Tor.md), [Chapter 15: Talking to Bitcoind with C](15_0_Talking_to_Bitcoind.md), [Chapter 16: Programming with Libwally](16_0_Programming_with_Libwally.md), [Chapter Seventeen: Talking to Bitcoind with Other Languages](17_0_Talking_to_Bitcoind_Other.md), [Chapter Eighteen: Understanding ](18_0_Understanding_Your_Lightning_Setup.md), and [Chapter Nineteen: Using Lightning](19_0_Using_Lightning.md).
|
||||
* If you are only interested in Lightning, zap over to [Chapter Nineteen: Understanding Your Lightning Setup](19_0_Understanding_Your_Lightning_Setup.md).
|
||||
* If you want to read the major new content added for v2 of the course (2020), following on v1 (2017), read [§3.5: Understanding the Descriptor](03_5_Understanding_the_Descriptor.md), [§4.6: Creating a SegWit Transaction](04_6_Creating_a_Segwit_Transaction.md), [Chapter 7: Expanding Bitcoin with PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md), [§9.5: Scripting a P2WPKH](09_5_Scripting_a_P2WPKH.md), [§10.5: Scripting a SegWit Script](10_5_Scripting_a_Segwit_Script.md), [Chapter 14: Using Tor](14_0_Using_Tor.md), [Chapter 15: Using i2p](15_0_Using_i2p.md), [Chapter 16: Talking to Bitcoind with C](16_0_Talking_to_Bitcoind.md), [Chapter 17: Programming with Libwally](17_0_Programming_with_Libwally.md), [Chapter 18: Talking to Bitcoind with Other Languages](18_0_Talking_to_Bitcoind_Other.md), [Chapter 19: Understanding Your Lighting Setup](19_0_Understanding_Your_Lightning_Setup.md), and [Chapter 20: Using Lightning](20_0_Using_Lightning.md).
|
||||
|
||||
## Why to Use this Course
|
||||
|
||||
|
@ -6,7 +6,7 @@ Before you can get started programming Bitcoin (and Lightning), you should have
|
||||
|
||||
Bitcoin is a programmatic system that allows for the transfer of the bitcoin currency. It is enabled by a decentralized, peer-to-peer system of nodes, which include full nodes, wallets, and miners. Working together, they ensure that bitcoin transactions are fast and non-repudiable. Thanks to the decentralized nature of the system, these transactions are also censor-resistant and can provide other advantages such as pseudonymity and non-correlation if used well.
|
||||
|
||||
Obviously, Bitcoin is the heart of this book, but it's also the originator of many other systems, including blockchains and Lightning, which are both detailed in this tutorial, and many other cryptocurrencies such as Ethereum and Litecoins, which are not.
|
||||
Obviously, Bitcoin is the heart of this book, but it's also the originator of many other systems, including blockchains and Lightning, which are both detailed in this tutorial, and many other cryptocurrencies such as Ethereum and Litecoin, which are not.
|
||||
|
||||
**_How Are Coins Transferred?_** Bitcoin currency isn't physical coins. Instead it's an endless series of ownership reassignments. When one person sends coins to another, that transfer is stored as a transaction. It's the transaction that actually records the ownership of the money, not any token local to the owner's wallet or their machine.
|
||||
|
||||
@ -56,11 +56,11 @@ ECC does not receive much attention in this tutorial. That's because this tutori
|
||||
|
||||
**_What is an Elliptic Curve?_** An elliptic curve is a geometric curve that takes the form `y`<sup>`2`</sup> = `x`<sup>`3`</sup>` + ax + b`. A specific elliptic curve is chosen by selecting specific values of `a` and `b`. The curve must then be carefully examined to determine if it works well for cryptography. For example, the secp256k1 curve used by Bitcoin is defined as `a=0` and `b=7`.
|
||||
|
||||
Any line that intersects an elliptic curve will do so at either 1 or 3 points ... and that's the basis of elliptic-curve cryptopgrahy.
|
||||
Any line that intersects an elliptic curve will do so at either 1 or 3 points ... and that's the basis of elliptic-curve cryptography.
|
||||
|
||||
**_What are Finite Fields?_** A finite field is a finite set of numbers, where all addition, subtraction, multiplication, and division is defined so that it results in other numbers also in the same finite field. One simple way to create a finite field is through the use of a modulo function.
|
||||
|
||||
**_How is an Elliptic Curve Defined Over a Finite Field?_** An ellipitic curve defined over a finite field has all of the points on its curve drawn from a specific finite field. This takes the form: `y`<sup>`2`</sup> `% field-size = (x`<sup>`3`</sup>` + ax + b) % field-size` The finite field used for secp256k1 is `2`<sup>`256`</sup>` - 2`<sup>`32`</sup>` - 2`<sup>`9`</sup>` - 2`<sup>`8`</sup>` - 2`<sup>`7`</sup>` - 2`<sup>`6`</sup>` - 2`<sup>`4`</sup>` - 1`.
|
||||
**_How is an Elliptic Curve Defined Over a Finite Field?_** An elliptic curve defined over a finite field has all of the points on its curve drawn from a specific finite field. This takes the form: `y`<sup>`2`</sup> `% field-size = (x`<sup>`3`</sup>` + ax + b) % field-size` The finite field used for secp256k1 is `2`<sup>`256`</sup>` - 2`<sup>`32`</sup>` - 2`<sup>`9`</sup>` - 2`<sup>`8`</sup>` - 2`<sup>`7`</sup>` - 2`<sup>`6`</sup>` - 2`<sup>`4`</sup>` - 1`.
|
||||
|
||||
**_How Are Elliptic Curves Used in Cryptography?_** In elliptic-curve cryptography, a user selects a very large (256-bit) number as his private key. He then adds a set base point on the curve to itself that many times. (In secp256k1, the base point is `G = 04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8`, which prefixes the two parts of the tuple with an `04` to say that the data point is in uncompressed form. If you prefer a straight geometric definition, it's the point "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8") The resultant number is the public key. Various mathematical formula can then be used to prove ownership of the public key, given the private key. As with any cryptographic function, this one is a trap door: it's easy to go from private key to public key and largely impossible to go from public key to private key.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 2.1: Setting Up a Bitcoin-Core VPS with Bitcoin Standup
|
||||
|
||||
This document explains how to set up a VPS (Virtual Private Sever) to run a Bitcoin node on Linode.com, installed using an automated StackScript from the [Bitcoin Standup project](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). You just need to enter a few commands and boot your VPS. Almost immediately after you boot, you'll find find your new Bitcoin node happily downloading blocks.
|
||||
This document explains how to set up a VPS (Virtual Private Sever) to run a Bitcoin node on Linode.com, installed using an automated StackScript from the [Bitcoin Standup project](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). You just need to enter a few commands and boot your VPS. Almost immediately after you boot, you'll find your new Bitcoin node happily downloading blocks.
|
||||
|
||||
> :warning: **WARNING:** Don’t use a VPS for a bitcoin wallet with significant real funds; see http://blog.thestateofme.com/2012/03/03/lessons-to-be-learned-from-the-linode-bitcoin-incident/ . It is very nice to be able experiment with real bitcoin transactions on a live node without tying up a self-hosted server on a local network. It's also useful to be able to use an iPhone or iPad to communicate via SSH to your VPS to do some simple bitcoin tasks. But a higher level of safety is required for significant funds.
|
||||
|
||||
@ -20,11 +20,9 @@ You can create a Linode account by going here:
|
||||
https://www.linode.com
|
||||
```
|
||||
|
||||
If you prefer, the following referral code will give you about a months worth of free usage, great for learning Bitcoin:
|
||||
If you prefer, the following referral code will give you two months worth of free usage (up to $100), great for learning Bitcoin:
|
||||
|
||||
```
|
||||
https://www.linode.com/?r=23211828bc517e2cb36e0ca81b91cc8c0e1b2d96
|
||||
```
|
||||
[https://www.linode.com/?r=3c7fa15a78407c9a3d4aefb027539db2557b3765](https://www.linode.com/?r=3c7fa15a78407c9a3d4aefb027539db2557b3765)
|
||||
|
||||
You'll need to provide an email address and later preload money from a credit card or PayPal for future costs.
|
||||
|
||||
@ -38,7 +36,7 @@ Your server security won't be complete if people can break into your Linode acco
|
||||
|
||||
### Load the StackScript
|
||||
|
||||
Download the [Linode Standup Script](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) from the [Bitcoin Standup Scripts repo](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). This script basically automates the Bitcoin VPS setup instructions from [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_by_Hand.md). If you want to be particulary prudent, read it over carefully. If you are satisfied, you can copy that StackScript into your own account by going to the [Stackscripts page](https://cloud.linode.com/stackscripts?type=account) on your Linode account and selecting to [Create New Stackscript](https://cloud.linode.com/stackscripts/create). Give it a good name (we use `Bitcoin Standup`), then copy and paste the script. Choose Debian 10 for your target image and "Save" it.
|
||||
Download the [Linode Standup Script](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) from the [Bitcoin Standup Scripts repo](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). This script basically automates all Bitcoin VPS setup instructions. If you want to be particulary prudent, read it over carefully. If you are satisfied, you can copy that StackScript into your own account by going to the [Stackscripts page](https://cloud.linode.com/stackscripts?type=account) on your Linode account and selecting to [Create New Stackscript](https://cloud.linode.com/stackscripts/create). Give it a good name (we use `Bitcoin Standup`), then copy and paste the script. Choose Debian 12 for your target image and "Save" it.
|
||||
|
||||
### Do the Initial Setup
|
||||
|
||||
@ -49,35 +47,32 @@ You're now ready to create a node based on the Stackscript.
|
||||
* **Short Hostname.** Pick a name for your VPS. For example, "mybtctest".
|
||||
* **Fully Qualified Hostname.** If you're going to include this VPS as part of a network with full DNS records, type in the hostname with its domain. For example, "mybtctest.mydomain.com". Otherwise, just repeat the short hostname and add ".local", for example "mybtctest.local".
|
||||
3. Enter the password for the "standup" user.
|
||||
4. Choose an Installation Type in the advanced options.
|
||||
* **Installation Type.** This is likely "Mainnet" or "Pruned Mainnet" if you are setting up a node for usage and "Testnet" or "Pruned Testnet" if you're just playing around. See the [Synopsis](#synopsis-bitcoin-installation-types) for more information on these options. (Note that if you plan to try out the Lightning chapters, you'll probably want to use an Unpruned node, as working with Pruned nodes on Lightning is iffy. See [§18.1](18_1_Verifying_Your_Lightning_Setup.md#compiling-the-source-code) for the specifics.)
|
||||
5. Fill in any other appropriate advanced options.
|
||||
4. Fill in the appropriate advanced options.
|
||||
* **X25519 Public Key.** This is a public key to add to Tor's list of authorized clients. If you don't use it, anyone who gets the QR code for your node can access it. You'll get this public key from whichever client you're using to connect to your node. For example, if you use [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2), you can go to its settings and "Export Tor V3 Authentication Public Key" for use here.
|
||||
* **Installation Type.** This is likely "Mainnet" or "Pruned Mainnet" if you are setting up a node for usage and "Testnet" or "Pruned Testnet" if you're just playing around. The bulk of this tutorial will assume you chose "Pruned Testnet", but you should still be able to follow along with other types. See the [Synopsis](#synopsis-bitcoin-installation-types) for more information on these options. (Note that if you plan to try out the Lightning chapters, you'll probably want to use an Unpruned node, as working with Pruned nodes on Lightning is iffy. See [§18.1](18_1_Verifying_Your_Lightning_Setup.md#compiling-the-source-code) for the specifics.)
|
||||
* **SSH Key.** Copy your local computer's SSH key here; this allows you be able to automatically login in via SSH to the standup account. If you haven't setup an SSH key on your local computer yet, there are good instructions for it on [Github](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/). You may also want to add your SSH key into your Linode LISH (Linode Interactive Shell) by going to your "Linode Home Page / My Preferences / LISH Settings / LISH Keys". Using an SSH key will give you a simpler and safer way to log in to your server.
|
||||
* **SSH-Allowed IPs.** This is a comma-separated list of IPs that will be allowed to SSH into the VPS. For example "192.168.1.15,192.168.1.16". If you do not enter any IPs, _your VPS will not be very secure_. It will constantly be bombarded by attackers trying to find their way in, and they may very well succeed.
|
||||
4. Select an Image
|
||||
* **Target Image.** If you followed the instructions, this will only allow you to select "Debian 10" (though "Debian 9" did also work with previous versions of this Stackscript and might still).
|
||||
5. Choose a region for where the Linode will be located.
|
||||
5. Select an Image
|
||||
* **Target Image.** If you followed the instructions, this will only allow you to select "Debian 12" (though previous versions of this Stackscript worked with Debian 9 or 10 or 12 and might still).
|
||||
6. Choose a region for where the Linode will be located.
|
||||
|
||||
*The remaining questions all have to do with the mechanics of the VPS deployment and should be left as they are with one exception: bump the Swap Disk from 256MB to 512MB, to ensure that you have enough memory to download the blockchain._
|
||||
|
||||
Finally, you'll need to fill in a root password, which will be the password used for the root account.
|
||||
*The remaining questions all have to do with the mechanics of the VPS deployment and should be left as they are with one exception: bump the Swap Disk from 256MB to 512MB, to ensure that you have enough memory to download the blockchain.*
|
||||
|
||||
### Choose Other Standup Options
|
||||
|
||||
Blockchain Commons is currently in the process of expandings its Bitcoin Standup Scripts with options to install Lightning and other Bitcoin apps of note. Take a look at any extra options, and see if they're things that you'd like to play with. In particular, if Lightning is an option, we suggest installing it, because it will make [Chapter 18](18_0_Understanding_Your_Lightning_Setup.md) and [Chapter 19](19_0_Using_Lightning.md) much easier.
|
||||
Blockchain Commons is currently in the process of expanding its Bitcoin Standup Scripts with options to install Lightning and other Bitcoin apps of note. Take a look at any extra options, and see if they're things that you'd like to play with. In particular, if Lightning is an option, we suggest installing it, because it will make [Chapter 18](18_0_Understanding_Your_Lightning_Setup.md) and [Chapter 19](19_0_Using_Lightning.md) much easier.
|
||||
|
||||
### Choose a Linode Plan
|
||||
|
||||
You'll next to choose a Linode plan.
|
||||
|
||||
A Linode 4GB will suffice for most setups, including: Pruned Mainnet, Pruned Testnet, and even non-Pruned Testnet. They all use less than 50G of storage and 4GB is a comfortable amount of memory. This is the setup we suggest. It runs $20 per month.
|
||||
Linode will default to Dedicated-CPU plans, but you can select the more cost-efficient Shared-CPU instead. A Shared-CPU Linode 4GB will suffice for most setups, including: Pruned Mainnet, Pruned Testnet, and even non-Pruned Testnet. They all use less than 50G of storage and 4GB is a comfortable amount of memory. This is the setup we suggest. It runs $20 per month.
|
||||
|
||||
If you want to instead have a non-Pruned Mainnet in a VPS, you'll need to install a Linode with a disk in excess of 280G(!), which is currently the Linode 16GB, which has 320G of storage and 16G of memory and costs approximately $80 per month. We do _not_ suggest this.
|
||||
|
||||
The following chart shows minimum requirements
|
||||
|
||||
| Setup | Memory | Storage | Linnode |
|
||||
| Setup | Memory | Storage | Linode |
|
||||
|-------|--------|---------|---------|
|
||||
| Mainnet | 2G | 280G | Linode 16GB |
|
||||
| Pruned Mainnet | 2G | ~5G | Linode 4GB |
|
||||
@ -90,6 +85,8 @@ Note, there may be ways to reduce both costs.
|
||||
* For the machines we suggest as **Linode 4GB**, you may be able to reduce that to a Linode 2GB. Some versions of Bitcoin Core have worked well at that size, some have occasionally run out of memory and then recovered, and some have continuously run out of memory. Remember to up that swap space to maximize the odds of this working. Use at your own risk.
|
||||
* For the Unpruned Mainnet, which we suggest as a **Linode 16GB**, you can probably get by with a Linode 4GB, but add [Block Storage](https://cloud.linode.com/volumes) sufficient to store the blockchain. This is certainly a better long-term solution since the Bitcoin blockchain's storage requirements continuously increase if you don't prune, while the CPU requirements don't (or don't to the same degree). A 320 GibiByte storage would be $32 a month, which combined with a Linode 4GB is $52 a month, instead of $80, and more importantly you can keep growing it. We don't fully document this setup for two reasons (1) we don't suggest the unpruned mainnet setup, and so we suspect it's a much less common setup; and (2) we haven't tested how Linodes volumes compare to their intrinic SSDs for performance and usage. But there's full documentation on the Block Storage page. You'd need to set up the Linode, run its stackscript, but then interrupt it to move the blockchain storage overly to a newly commissioned volume before continuing.
|
||||
|
||||
If you are running a deployment that will be transacting real Bitcoins, you may want to alternatively consider a Dedicated-CPU Linode, which tends to run 50% more expensive than the Shared-CPU Linode. We've generally found the Shared CPUs to be entirely sufficient, but for a wide deployment, you may wish to consider higher levels of reliability.
|
||||
|
||||
### Do the Final Setup
|
||||
|
||||
The last thing you need to do is enter a root password. (If you missed anything, you'll be told so now!)
|
||||
@ -124,7 +121,7 @@ Here's a little catch: _your StackScript is running right now_. The BASH script
|
||||
|
||||
The total run time is about 10 minutes. So, go take a break, get an espresso, or otherwise relax for a few minutes. There are two parts of the script that take a while: the updating of all the Debian packages; and the downloading of the Bitcoin code. They shouldn't take more than 5 minutes each, which means if you come back in 10 minutes, you'll probably be ready to go.
|
||||
|
||||
If you're impatient you can jump ahead and `sudo tail -f ~root/standup.log` which will display the current progress of installation, as described in the next section.
|
||||
If you're impatient you can jump ahead and `sudo tail -f /standup.log` which will display the current progress of installation, as described in the next section.
|
||||
|
||||
## Verify Your Installation
|
||||
|
||||
@ -138,7 +135,7 @@ At that point, your home directory should look like this:
|
||||
|
||||
```
|
||||
$ ls
|
||||
bitcoin-0.20.0-x86_64-linux-gnu.tar.gz laanwj-releases.asc SHA256SUMS.asc
|
||||
bitcoin-22.0-x86_64-linux-gnu.tar.gz keys.txt SHA256SUMS SHA256SUMS.asc
|
||||
```
|
||||
|
||||
These are the various files that were used to install Bitcoin on your VPS. _None_ of them are necessary. We've just left them in case you want to do any additional verification. Otherwise, you can delete them:
|
||||
@ -152,16 +149,32 @@ $ rm *
|
||||
In order to ensure that the downloaded Bitcoin release is valid, the StackScript checks both the signature and the SHA checksum. You should verify that both of those tests came back right:
|
||||
|
||||
```
|
||||
$ sudo grep VERIFICATION ~root/standup.log
|
||||
$ sudo grep VERIFICATION /standup.log
|
||||
```
|
||||
|
||||
If you see something like the following, all should be well:
|
||||
|
||||
```
|
||||
/root/StackScript - VERIFICATION SUCCESS / SIG: gpg: Good signature from "Wladimir J. van der Laan (Bitcoin Core binary release signing key) <laanwj@gmail.com>" [unknown]
|
||||
/root/StackScript - VERIFICATION SUCCESS / SHA: 35ec10f87b6bc1e44fd9cd1157e5dfa4```
|
||||
./standup.sh - SIG VERIFICATION SUCCESS: 9 GOOD SIGNATURES FOUND.
|
||||
./standup.sh - SHA VERIFICATION SUCCESS / SHA: bitcoin-22.0-x86_64-linux-gnu.tar.gz: OK
|
||||
```
|
||||
However, if either of those two checks instead reads "VERIFICATION ERROR", then there's a problem. Since this is all scripted, it's possible that there's just been a minor change that has caused the script's checks not to work right. (This has happened a few times over the existence of the script that became Standup.) But, it's also possible that someone is trying to encourage you to run a fake copy of the Bitcoin daemon. So, _be very sure you know what happened before you make use of Bitcoin!_
|
||||
If either of those two checks instead reads "VERIFICATION ERROR", then there's a problem.
|
||||
|
||||
The log also contains more information on the Signatures, if you want to make sure you know _who_ signed the Bitcoin release:
|
||||
```
|
||||
$ sudo grep -i good /standup.log
|
||||
./standup.sh - SIG VERIFICATION SUCCESS: 9 GOOD SIGNATURES FOUND.
|
||||
gpg: Good signature from "Andrew Chow (Official New Key) <achow101@gmail.com>" [unknown]
|
||||
gpg: Good signature from "Ben Carman <benthecarman@live.com>" [unknown]
|
||||
gpg: Good signature from "Antoine Poinsot <darosior@protonmail.com>" [unknown]
|
||||
gpg: Good signature from "Stephan Oeste (it) <it@oeste.de>" [unknown]
|
||||
gpg: Good signature from "Michael Ford (bitcoin-otc) <fanquake@gmail.com>" [unknown]
|
||||
gpg: Good signature from "Oliver Gugger <gugger@gmail.com>" [unknown]
|
||||
gpg: Good signature from "Hennadii Stepanov (hebasto) <hebasto@gmail.com>" [unknown]
|
||||
gpg: Good signature from "Jon Atack <jon@atack.com>" [unknown]
|
||||
gpg: Good signature from "Wladimir J. van der Laan <laanwj@visucore.com>" [unknown]
|
||||
```
|
||||
Since this is all scripted, it's possible that there's just been a minor change that has caused the script's checks not to work right. (This has happened a few times over the existence of the script that became Standup.) But, it's also possible that someone is trying to encourage you to run a fake copy of the Bitcoin daemon. So, _be very sure you know what happened before you make use of Bitcoin!_
|
||||
|
||||
### Read the Logs
|
||||
|
||||
@ -169,13 +182,13 @@ You may also want to read through all of the setup log files, to make sure that
|
||||
|
||||
It's best to look through the standard StackScript log file, which has all of the output, including errors:
|
||||
|
||||
`$ sudo more ~root/standup.log`
|
||||
`$ sudo more /standup.log`
|
||||
|
||||
Note that it is totally normal to see _some_ errors, particularly when running the very noisy gpg software and when various things try to access the non-existant `/dev/tty` device.
|
||||
|
||||
If you want instead to look at a smaller set of info, all of the errors should be in:
|
||||
|
||||
`$ sudo more ~root/standup.err`
|
||||
`$ sudo more /standup.err`
|
||||
|
||||
It still has a fair amount of information that isn't errors, but it's a quicker read.
|
||||
|
||||
@ -183,15 +196,15 @@ If all look good, congratulations, you have a functioning Bitcoin node using Lin
|
||||
|
||||
## What We Have Wrought
|
||||
|
||||
Although the default Debian 10 image that we are using for your VPS has been modified by Linode to be relatively secure, your Bitcoin node as installed through the Linode StackScript is set up with an even high level of security. You may find this limiting, or be unable to do things that you expect. Here are a few notes on that:
|
||||
Although the default Debian 12 image that we are using for your VPS has been modified by Linode to be relatively secure, your Bitcoin node as installed through the Linode StackScript is set up with an even higher level of security. You may find this limiting, or be unable to do things that you expect. Here are a few notes on that:
|
||||
|
||||
### Protected Services
|
||||
|
||||
Your Bitcoin VPS installation is minimal and allows almost no communication. This is done through the uncomplicated firewall (`ufw`), which blocks everything except SSH connections. There's also some additional security possible for your RFC ports, thanks to the hidden services installed by Tor.
|
||||
|
||||
**Adjusting UFW.** You should probably leave UFW in its super-protected stage! You don't want to use a Bitcoin machine for other services, because everyone increases your vulnerability! If you decide otherwise, there are several [guides to UFW](https://www.digitalocean.com/community/tutorials/ufw-essentials-common-firewall-rules-and-commands) that will allow you to add services. As advertised, it's ncomplicated. For example adding mail services would just require opening the mail port: `sudo ufw allow 25`. But don't do that.
|
||||
**Adjusting UFW.** You should probably leave UFW in its super-protected stage! You don't want to use a Bitcoin machine for other services, because everyone increases your vulnerability! If you decide otherwise, there are several [guides to UFW](https://www.digitalocean.com/community/tutorials/ufw-essentials-common-firewall-rules-and-commands) that will allow you to add services. As advertised, it's uncomplicated. For example adding mail services would just require opening the mail port: `sudo ufw allow 25`. But don't do that.
|
||||
|
||||
**Adjusting Tor.** You might want to better protect services like SSH. See [Chapter 12: Using Tor](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/12_0_Using_Tor.md) for more on Tor.
|
||||
**Adjusting Tor.** You might want to better protect services like SSH. See [Chapter 14: Using Tor](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/14_0_Using_Tor.md) for more on Tor.
|
||||
|
||||
### Protected Shells
|
||||
|
||||
@ -245,7 +258,7 @@ You have a few options for what's next:
|
||||
|
||||
## Synopsis: Bitcoin Installation Types
|
||||
|
||||
**Mainnet.** This will download the entirety of the Bitnet blockchain. That's 280G of data (and getting more every day).
|
||||
**Mainnet.** This will download the entirety of the Bitcoin blockchain. That's 280G of data (and getting more every day).
|
||||
|
||||
**Pruned Mainnet.** This will cut the blockchain you're storing down to just the last 550 blocks. If you're not mining or running some other Bitcoin service, this should be plenty for validation.
|
||||
|
||||
|
@ -5,11 +5,13 @@ The previous section, [§2.1: Setting Up a Bitcoin-Core VPS with Bitcoin Standup
|
||||
Following are other setup methodologies that we are aware of:
|
||||
|
||||
* *[Compiling from Source](A2_0_Compiling_Bitcoin_from_Source.md).* If you prefer to compile Bitcoin Core by hand, that's covered in Appendix 2.
|
||||
* *[Using GordianNode-macOS](https://github.com/BlockchainCommons/GordianNode-macOS).* If you have a modern Mac, you can use Blockchain Commons' *GordianNode* app, powered by *BitocinStandup*, to install a full node on your Mac.
|
||||
* *[Using Other Bitcoin Standup Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts).* Blockchain Commons also offers a version of the Linode script that you used that can be run from the command line on any Debian or Ubuntu machine. This tends to be the leading-edge script, which means that it's more likely to feature new functions, like Lightnign installation.
|
||||
* *[Using GordianServer-macOS](https://github.com/BlockchainCommons/GordianServer-macOS).* If you have a modern Mac, you can use Blockchain Commons' *GordianNode* app, powered by *BitcoinStandup*, to install a full node on your Mac.
|
||||
* *[Using Other Bitcoin Standup Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts).* Blockchain Commons also offers a version of the Linode script that you used that can be run from the command line on any Debian or Ubuntu machine. This tends to be the leading-edge script, which means that it's more likely to feature new functions, like Lightning installation.
|
||||
* *[Setting Up a Bitcoin Node on AWS](https://wolfmcnally.com/115/developer-notes-setting-up-a-bitcoin-node-on-aws/).* @wolfmcnally has written a step-by-step tutorial for setting up Bitcoin-Core with Amazon Web Services (AWS).
|
||||
* *[Setting Up a Bitcoin Node on a Raspberry Pi 3](https://medium.com/@meeDamian/bitcoin-full-node-on-rbp3-revised-88bb7c8ef1d1).* Damian Mee explains how to set up a headless full node on a Raspberry Pi 3.
|
||||
|
||||
Be sure that you are installing on a current version of your OS, to avoid problems down the line. As of this writing, this course is tested on Debian 11.
|
||||
|
||||
## What's Next?
|
||||
|
||||
Unless you want to return to one of the other methodologies for creating a Bitcoin-Core node, you should:
|
||||
|
@ -6,7 +6,7 @@ Before you start playing with Bitcoin, you should ensure that everything is setu
|
||||
|
||||
We suggest creating some aliases to make it easier to use Bitcoin.
|
||||
|
||||
You can do so by putting them in your `.bash_profile`.
|
||||
You can do so by putting them in your `.bash_profile`, `.bashrc` or `.profile`.
|
||||
```
|
||||
cat >> ~/.bash_profile <<EOF
|
||||
alias btcdir="cd ~/.bitcoin/" #linux default bitcoind path
|
||||
@ -19,7 +19,7 @@ After you enter these aliases you can either `source .bash_profile` to input the
|
||||
|
||||
Note that these aliases includes shortcuts for running `bitcoin-cli`, for running `bitcoind`, and for going to the Bitcoin directory. These aliases are mainly meant to make your life easier. We suggest you create other aliases to ease your use of frequent commands (and arguments) and to minimize errors. Aliases of this sort can be even more useful if you have a complex setup where you regularly run commands associated with Mainnet, with Testnet, _and_ with Regtest, as explained further below.
|
||||
|
||||
With that said, use of these aliases in _this_ document might accidentally obscure the core lessons being taught about Bitcoin, so the only alias directly used here is `btcinfo` because it encapsulatea much longer and more complex command. Otherwise, we show the full commands; adjust for your own use as appropriate.
|
||||
With that said, use of these aliases in _this_ document might accidentally obscure the core lessons being taught about Bitcoin, so the only alias directly used here is `btcinfo` because it encapsulates much longer and more complex command. Otherwise, we show the full commands; adjust for your own use as appropriate.
|
||||
|
||||
## Run Bitcoind
|
||||
|
||||
@ -45,15 +45,13 @@ You can do this by looking at a blocknet explorer, such as [the Blockcypher Test
|
||||
|
||||
If you'd like an alias to look at everything at once, the following currently works for Testnet, but may disappear at some time in the future:
|
||||
```
|
||||
$ cat >> ~/.bash_profile << EOF
|
||||
> alias btcblock="echo \\\`bitcoin-cli getblockcount 2>&1\\\`/\\\`wget -O - https://blockstream.info/testnet/api/blocks/tip/height 2> /dev/null | cut -d : -f2 | rev | cut -c 1- | rev\\\`"
|
||||
EOF
|
||||
$ echo "alias btcblock='echo \$(bitcoin-cli -testnet getblockcount)/\$(curl -s https://blockstream.info/testnet/api/blocks/tip/height)'" >> .bash_profile
|
||||
$ source .bash_profile
|
||||
$ btcblock
|
||||
1804372/1804372
|
||||
```
|
||||
|
||||
> :link: **TESTNET vs MAINNET:** Remember that this tutorial generally assumes that you are using testnet. If you're using the mainnet instead, you can retrieve the current block height with: `wget -O - http://blockchain.info/q/getblockcount 2>/dev/null`. You can replace the latter half of the `btblock` alias (after `/`) with that.
|
||||
> :link: **TESTNET vs MAINNET:** Remember that this tutorial generally assumes that you are using testnet. If you're using the mainnet instead, you can retrieve the current block height with: `curl -s https://blockchain.info/q/getblockcount`. You can replace the latter half of the `btcblock` alias (after `/\$(`) with that.
|
||||
|
||||
If you're not up-to-date, but your `getblockcount` is increasing, no problem. Total download time can take from an hour to several hours, depending on your setup.
|
||||
|
||||
|
@ -16,7 +16,7 @@ The setup guides in [Chapter Two: Creating a Bitcoin-Core VPS](02_0_Setting_Up_a
|
||||
Moving back to your ~/.bitcoin directory, you'll find that the testnet3 directory contains all of the guts:
|
||||
```
|
||||
$ ls ~/.bitcoin/testnet3
|
||||
banlist.dat blocks debug.log mempool.dat peers.dat
|
||||
banlist.json blocks debug.log mempool.dat peers.dat
|
||||
bitcoind.pid chainstate fee_estimates.dat onion_private_key wallets
|
||||
```
|
||||
You shouldn't mess with most of these files and directories — particularly not the `blocks` and `chainstate` directories, which contain all of the blockchain data, and the information in your `wallets` directory, which contains your personal wallet. However, do take careful note of the `debug.log` file, which you should refer to if you ever have problems with your setup.
|
||||
@ -204,6 +204,37 @@ Examples:
|
||||
## Optional: Know Your Bitcoin Info
|
||||
|
||||
A variety of bitcoin-cli commands can give you additional information on your bitcoin data. The most general ones are:
|
||||
|
||||
`bitcoin-cli -getinfo` returns information from different RPCs (user-friendly)
|
||||
|
||||
```diff
|
||||
$ bitcoin-cli -getinfo
|
||||
|
||||
! Chain: test
|
||||
Blocks: 1977694
|
||||
Headers: 1977694
|
||||
Verification progress: 0.9999993275374796
|
||||
Difficulty: 1
|
||||
|
||||
+ Network: in 0, out 8, total 8
|
||||
Version: 219900
|
||||
Time offset (s): 0
|
||||
Proxy: N/A
|
||||
Min tx relay fee rate (BTC/kvB): 0.00001000
|
||||
|
||||
@@ Wallet: ""@@
|
||||
Keypool size: 1000
|
||||
Unlocked until: 0
|
||||
Transaction fee rate (-paytxfee) (BTC/kvB): 0.00000000
|
||||
|
||||
# Balance: 0.02853102
|
||||
|
||||
- Warnings: unknown new rules activated (versionbit 28)
|
||||
|
||||
```
|
||||
|
||||
Other commands to get information about blockchain, mining, network, wallet etc.
|
||||
|
||||
```
|
||||
$ bitcoin-cli getblockchaininfo
|
||||
$ bitcoin-cli getmininginfo
|
||||
|
@ -1,28 +1,67 @@
|
||||
# 3.3: Setting Up Your Wallet
|
||||
|
||||
You're now ready to start working with Bitcoin. To begin with, you'll need to create an address for receiving funds.
|
||||
You're now ready to start working with Bitcoin. To begin with, you'll need to create a wallet for sending and receiving funds.
|
||||
|
||||
## Create a Wallet
|
||||
|
||||
> :warning: **VERSION WARNING:** Newer versions of Bitcoin Core, starting with v0.21.0, will no longer automatically create a default wallet on startup. So, you will need to manually create one. But if you're running an older version of Bitcoin Core, a new wallet has already been created for you, in which case you can skip ahead to [Create an Address](#create-an-address).
|
||||
|
||||
The first thing you need to do is create a new wallet, which can be done with the `bitcoin-cli createwallet` command. By creating a new wallet, you'll be creating your public-private key pair. Your public key is the source from which your addresses will be created, and your private key is what will allow you to spend any funds you receive into your addresses. Bitcoin Core will automatically save that information into a `wallet.dat` file in your `~/.bitcoin/testnet3/wallets` directory.
|
||||
|
||||
If you check your `wallets` directory, you'll see that it's currently empty.
|
||||
```
|
||||
$ ls ~/.bitcoin/testnet3/wallets
|
||||
$
|
||||
```
|
||||
|
||||
Although Bitcoin Core won't create a new wallet for you, it will still load a top-level unnamed ("") wallet on startup by default. You can take advantage of this by creating a new unnamed wallet.
|
||||
```
|
||||
$ bitcoin-cli -named createwallet wallet_name="" descriptors=false
|
||||
|
||||
{
|
||||
"name": "",
|
||||
"warning": ""
|
||||
}
|
||||
```
|
||||
|
||||
Now, your `wallets` directory should be populated.
|
||||
```
|
||||
$ ls ~/.bitcoin/testnet3/wallets
|
||||
database db.log wallet.dat
|
||||
```
|
||||
|
||||
> :book: ***What is a Bitcoin wallet?*** A Bitcoin wallet is the digital equivalent of a physical wallet on the Bitcoin network. It stores information on the amount of bitcoins you have and where it's located (addresses), as well as the ways you can use to spend it. Spending physical money is intuitive, but to spend bitcoins users need to provide the correct _private key_. We will explain this in more detail throughout the course, but what you should know for now is that this public-private key dynamic is part of what makes Bitcoin secure and trustless. Your key pair information is saved in the `wallet.dat` file, in addition to data about preferences and transactions. For the most part, you won't have to worry about that private key: `bitcoind` will use it when it's needed. However, this makes the `wallet.dat` file extremely important: if you lose it, you lose your private keys, and if you lose your private keys, you lose your funds!
|
||||
|
||||
Sweet, now you have a Bitcoin wallet. But a wallet will be of little use for receiving bitcoins if you don't create an address first.
|
||||
|
||||
> :warning: **VERSION WARNING:** Starting in Bitcoin Core v 23.0, descriptor wallets became the default. That's great, because descriptor wallets are very powerful, except they don't currently work with multisigs! So, we turn them off with the "descriptors=false" argument. See [§3.5](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/03_5_Understanding_the_Descriptor.md) for more on descriptors.
|
||||
|
||||
## Create an Address
|
||||
|
||||
The first thing you need to do is create an address for receiving payments. This is done with the `bitcoin-cli getnewaddress` command. Remember that if you want more information on this command, you should type `bitcoin-cli help getnewaddress`. Currently, there are three types of addresses: `legacy` and the two types of SegWit address, `p2sh-segwit` and `bech32`. If you do not otherwise specify, you'll get the default, which is currently `bech32`.
|
||||
The next thing you need to do is create an address for receiving payments. This is done with the `bitcoin-cli getnewaddress` command. Remember that if you want more information on this command, you should type `bitcoin-cli help getnewaddress`. Currently, there are three types of addresses: `legacy` and the two types of SegWit address, `p2sh-segwit` and `bech32`. If you do not otherwise specify, you'll get the default, which is currently `bech32`.
|
||||
|
||||
However, for the next few sections we're instead going to be using `legacy` addresses, both because `bitcoin-cli` had some teething problems with its early versions of SegWit addresses, and because other people might not be able to send to `bech32` addresses. This is all unlikely to be a problem for you now, but for the moment we want to get your started with transaction examples that are (mostly) guaranteed to work.
|
||||
|
||||
You can require `legacy` address either with the second argument to `getnewaddress` or with the named `addresstype` argument.
|
||||
First, restart `bitcoind` so your new unnamed wallet is set as default and automatically loaded.
|
||||
```
|
||||
$ bitcoin-cli stop
|
||||
Bitcoin Core stopping # wait a minute so it stops completely
|
||||
$ bitcoind -daemon
|
||||
Bitcoin Core starting # wait a minute so it starts completely
|
||||
```
|
||||
|
||||
You can now create an address. You can require `legacy` address either with the second argument to `getnewaddress` or with the named `addresstype` argument.
|
||||
```
|
||||
$ bitcoin-cli getnewaddress -addresstype legacy
|
||||
moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B
|
||||
```
|
||||
Note that this address begins with an "m" (or sometimes an "n") to signify a testnet Legacy address. It would be a "2" for a P2SH address or a "tb1" for a Bech32 address.
|
||||
|
||||
> :link: **TESTNET vs MAINNET:** The equivalent mainnet address would start with a "1" (for Legacy), "3" (for P2SH), or "bc1" (for Bech320.
|
||||
|
||||
> :link: **TESTNET vs MAINNET:** The equivalent mainnet address would start with a "1" (for Legacy), "3" (for P2SH), or "bc1" (for Bech32).
|
||||
|
||||
Take careful note of the address. You'll need to give it to whomever will be sending you funds.
|
||||
|
||||
> :book: ***What is a Bitcoin address?*** A Bitcoin address is literally where you receive money. It's like an email address, but for funds. Technically, it's a public key, though different address schemes adjust that in different ways. However unlike an email address, a Bitcoin address should be considered single use: use it to receive funds just _once_. When you want to receive funds from someone else or at some other time, generate a new address. This is suggested in large part to improve your privacy. The whole blockchain is immutable, which means that explorers can look at long chains of transactions over time, making it possible to statistically determine who you and your contacts are, no matter how careful you are. However, if you keep reusing the same address, then this becomes even easier.
|
||||
|
||||
> :book: ***What is a Bitcoin wallet?*** By creating your first Bitcoin address, you've also begun to fill in your Bitcoin wallet. More precisely, you've begun to fill the `wallet.dat` file in your `~/.bitcoin/testnet3 /wallets`directory. The `wallet.dat` file contains data about preferences and transactions, but more importantly it contains all of the key pairs that you create: both the public key (which is the source of the address where you receive funds) and the private key (which is how you spend those funds). For the most part, you won't have to worry about that private key: `bitcoind` will use it when it's needed. However, this makes the `wallet.dat` file extremely important: if you lose it, you lose your private keys, and if you lose your private keys, you lose your funds!
|
||||
> :book: ***What is a Bitcoin address?*** A Bitcoin address is literally where you receive money. It's like an email address, but for funds. Technically, it's a public key, though different address schemes adjust that in different ways. However unlike an email address, a Bitcoin address should be considered single use: use it to receive funds just _once_. When you want to receive funds from someone else or at some other time, generate a new address. This is suggested in large part to improve your privacy. The whole blockchain is immutable, which means that explorers can look at long chains of transactions over time, making it possible to statistically determine who you and your contacts are, no matter how careful you are. However, if you keep reusing the same address, then this becomes even easier. By creating your first Bitcoin address, you've also begun to fill in your Bitcoin wallet. More precisely, you've begun to fill the `wallet.dat` file in your `~/.bitcoin/testnet3 /wallets` directory.
|
||||
|
||||
With a single address in hand, you could jump straight to the next section and begin receiving funds. However, before we get there, we're going to briefly discuss the other sorts of addresses that you'll meet in the future and talk about a few other wallet commands that you might want to use in the future.
|
||||
|
||||
@ -36,9 +75,9 @@ Classic Bitcoin transactions created P2PKH addresses that added an additional cr
|
||||
|
||||
> :book: ***What is a Legacy (P2PKH) address?*** This is a Legacy address of the sort used by the early Bitcoin network. We'll be using it in examples for the next few sections. It's called a Pay to PubKey Hash (or P2PKH) address because the address is a 160-bit hash of a public key. Using a hash of your public key as your address creates a two-step process where to spend funds you need to reveal both the private key and the public key, and it increases future security accordingly. This sort of address remains important for receiving funds from people with out-of-date wallet software.
|
||||
|
||||
As described more fully in [§4.6: Creating a Segwit Transaction](04_6_Creating_a_Segwit_Transaction.md), the Block Size Wars of the late '10s resulted in a new sort of address: SegWit. This is the preferred sort address currently, and should be fully integrated into Bitcoin-Core at this point, but nonetheless we're saving it for §4.6.
|
||||
As described more fully in [§4.6: Creating a Segwit Transaction](04_6_Creating_a_Segwit_Transaction.md), the Block Size Wars of the late '10s resulted in a new sort of address: SegWit. This is the preferred sort of address currently, and should be fully integrated into Bitcoin-Core at this point, but nonetheless we're saving it for §4.6.
|
||||
|
||||
SegWit simply means "segregated witness" and it's a way of separating the transaction signatures out from the rest of the transaction to reduce transaction size. Some SegWit addresses with sneak into some of our examples prior to §4.6 as change addresses, which you'll see as addresses that begin with "tb". This is fine because the `bitcoin-cli` entirely supports their usage. But we won't use them otherwise
|
||||
SegWit simply means "segregated witness" and it's a way of separating the transaction signatures out from the rest of the transaction to reduce transaction size. Some SegWit addresses will sneak into some of our examples prior to §4.6 as change addresses, which you'll see as addresses that begin with "tb". This is fine because the `bitcoin-cli` entirely supports their usage. But we won't use them otherwise.
|
||||
|
||||
There are two addresses of this sort:
|
||||
|
||||
|
@ -14,7 +14,7 @@ To use a faucet, you'll usually need to go to a URL and copy and paste in your a
|
||||
|
||||
## Verify Your Money
|
||||
|
||||
After you've requested your money, you should be able to verify it with the 'bitcoin-cli getbalance' command:
|
||||
After you've requested your money, you should be able to verify it with the `bitcoin-cli getbalance` command:
|
||||
```
|
||||
$ bitcoin-cli getbalance
|
||||
0.00000000
|
||||
@ -187,7 +187,7 @@ $ bitcoin-cli gettransaction "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc
|
||||
"hex": "0200000000010114d04977d1b0137adbf51dd5d79944b9465a2619f3fa7287eb69a779977bf5800100000017160014e85ba02862dbadabd6d204fcc8bb5d54658c7d4ffeffffff02df690f000000000017a9145c3bfb36b03f279967977ca9d1e35185e39917788740420f00000000001976a9141b72503639a13f190bf79acf6d76255d772360b788ac0247304402201e74bdfc330fc2e093a8eabe95b6c5633c8d6767249fa25baf62541a129359c202204d462bd932ee5c15c7f082ad7a6b5a41c68addc473786a0a9a232093fde8e1330121022897dfbf085ecc6ad7e22fc91593414a845659429a7bbb44e2e536258d2cbc0c270b1b00"
|
||||
}
|
||||
```
|
||||
The `gettransaction` command will detail transanctions that are in your wallet, such as this one, that was sent to us.
|
||||
The `gettransaction` command will detail transactions that are in your wallet, such as this one, that was sent to us.
|
||||
|
||||
Note that `gettransaction` has two optional arguments:
|
||||
```
|
||||
@ -285,7 +285,7 @@ $ bitcoin-cli gettransaction "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc
|
||||
```
|
||||
Now you can see the full information on the transaction, including all of the inputs ("vin") and all the outputs ("vout). One of the interesting things to note is that although we received .01 BTC in the transaction, another .01010143 was sent to another address. That was probably a change address, a concept that is explored in the next section. It is quite typical for a transaction to have multiple inputs and/or multiple outputs.
|
||||
|
||||
There is another command, `getrawtransaction`, which allows you to look at transactions that are not in your wallet. However, it requires you to have unpruned node and `txindex=1` in your `bitcoin.conf` file. Unless you have a serious need for information not in your wallet, it's probably just better to use a Bitcoin explorer for this sort of thing ...
|
||||
There is another command, `getrawtransaction`, which allows you to look at transactions that are not in your wallet. However, it requires you to have an unpruned node and `txindex=1` in your `bitcoin.conf` file. Unless you have a serious need for information not in your wallet, it's probably just better to use a Bitcoin explorer for this sort of thing ...
|
||||
|
||||
## Optional: Use a Block Explorer
|
||||
|
||||
|
@ -25,5 +25,6 @@ Supporting objectives include the ability to:
|
||||
* [Interlude: Using JQ](04_2__Interlude_Using_JQ.md)
|
||||
* [Section Three: Creating a Raw Transaction with Named Arguments](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md)
|
||||
* [Section Four: Sending Coins with Raw Transactions](04_4_Sending_Coins_with_a_Raw_Transaction.md)
|
||||
* [Interlude: Using Curl](04_4__Interlude_Using_Curl.md)
|
||||
* [Section Five: Sending Coins with Automated Raw Transactions](04_5_Sending_Coins_with_Automated_Raw_Transactions.md)
|
||||
* [Section Six: Creating a SegWit Transaction](04_6_Creating_a_Segwit_Transaction.md)
|
||||
|
@ -22,15 +22,12 @@ txconfirmtarget=1
|
||||
```
|
||||
You should enter these into `~/.bitcoin/bitcoin.conf`, in the main section, toward the top of the file or if you want to be sure you never use it elsewhere, under the `[test]` section.
|
||||
|
||||
In order to get through this tutorial, we're willing to spend 100,00 satoshis per kB on every transaction (about $10!), and we want to get each transaction into the next block! (To put that in perspective, a typical transaction runs between .25 kB and 1 kB, so you'll actually be paying more like $2.50 than $10 ... if this were real money.)
|
||||
In order to get through this tutorial, we're willing to spend 100,000 satoshis per kB on every transaction (about $10!), and we want to get each transaction into the next block! (To put that in perspective, a typical transaction runs between .25 kB and 1 kB, so you'll actually be paying more like $2.50 than $10 ... if this were real money.)
|
||||
|
||||
After you've edited your bitcoin.conf file, you'll want to kill and restart bitcoind.
|
||||
```
|
||||
$ ps auxww | grep -i bitcoind
|
||||
standup 455 1.3 38.4 3387012 1555520 ? SLsl Jun16 60:01 /usr/local/bin/bitcoind -conf=/home/standup/.bitcoin/bitcoin.conf
|
||||
standup 21073 0.0 0.0 6076 876 pts/0 R+ 15:00 0:00 grep -i bitcoind
|
||||
$ kill 455
|
||||
$ /usr/local/bin/bitcoind -conf=/home/standup/.bitcoin/bitcoin.conf &
|
||||
$ bitcoin-cli stop
|
||||
$ bitcoind -daemon
|
||||
```
|
||||
|
||||
## Get an Address
|
||||
@ -43,14 +40,19 @@ You need somewhere to send your coins to. Usually, someone would send you an add
|
||||
|
||||
You're now ready to send some coins. This is actually quite simple via the command line. You just use `bitcoin-cli sendtoaddress [address] [amount]`. So, to send a little coinage to the address `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi` just requires:
|
||||
```
|
||||
$ txid=$(bitcoin-cli sendtoaddress n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi 0.1)
|
||||
$ txid=$(bitcoin-cli sendtoaddress n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi 0.001)
|
||||
$ echo $txid
|
||||
93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8
|
||||
```
|
||||
|
||||
> 🙏 To help keep testnet faucets alive, try to use the return address of the same faucet you used in the previous chapter on receiving transactions.
|
||||
|
||||
Make sure the address you write in is where you want the money to go. Make _double_ sure. If you make mistakes in Bitcoin, there's no going back.
|
||||
|
||||
You'll receive a txid back when you issue this command.
|
||||
|
||||
> ❕ You may end up with an error code if you don't have enough funds in your wallet to send the transaction. Depending on your current balance `bitcoin-cli getbalance` you may need to adjust the amount to be sent to account for the amount being sent along with the transaction fee. If your current balance is 0.001, then you could try sending 0.0001. Alternatively, it would be better to instead subtract the expected fee given in the error message from your current balance. This is good practice as many wallets expect you to calculate your own amount + fees when withdrawing, even among popular exchanges.
|
||||
|
||||
> :warning: **WARNING:** The `bitcoin-cli` command actually generates JSON-RPC commands when it's talking to the bitcoind. They can be really picky. This is an example: if you list the bitcoin amount without the leading zero (i.e. ".1" instead of "0.1"), then bitcoin-cli will fail with a mysterious message.
|
||||
|
||||
> :warning: **WARNING:** Even if you're careful with your inputs, you could see "Fee estimation failed. Fallbackfee is disabled." Fundamentally, this means that your local `bitcoind` doesn't have enough information to estimate fees. You should really never see it if you've waited for your blockchain to sync and set up your system with Bitcoin Standup. But if you're not entirely synced, you may see this. It also could be that you're not using a standard `bitcoin.conf`: the entry `blocksonly=1` will cause your `bitcoind` to be unable to estimate fees.
|
||||
|
@ -70,7 +70,7 @@ So, txid+vout=UTXO. This will be the foundation of any raw transaction.
|
||||
|
||||
You're now ready to write a simple, example raw transaction that shows how to send the entirety of a UTXO to another party. As noted, this is not necessarily a very realistic real-world case.
|
||||
|
||||
> :warning: **WARNING:** It is very easy to lose money with a raw transaction. Consider all instructions on sending bitcoins via raw transactions to be _very_, _very_ dangerous. Whenever you're actually sending real money to other people, you should instead use one of the other methods explained in this chapter. Creating raw transactions is extremely useful if you're writing bitcoin programs, but _only_ when you're writing bitcoin programs. (For example: in writing this example for one version of this tutorial, we accidently spend the wrong transaction, even though it had about 10x as much value. Almost all of that was lost to the miners.)
|
||||
> :warning: **WARNING:** It is very easy to lose money with a raw transaction. Consider all instructions on sending bitcoins via raw transactions to be _very_, _very_ dangerous. Whenever you're actually sending real money to other people, you should instead use one of the other methods explained in this chapter. Creating raw transactions is extremely useful if you're writing bitcoin programs, but _only_ when you're writing bitcoin programs. (For example: in writing this example for one version of this tutorial, we accidentally spent the wrong transaction, even though it had about 10x as much value. Almost all of that was lost to the miners.)
|
||||
|
||||
### Prepare the Raw Transaction
|
||||
|
||||
@ -105,11 +105,11 @@ Each transaction has a fee associated with. It's _implicit_ when you send a raw
|
||||
|
||||
> :book: ***How much should you spend on transaction fees?*** [Bitcoin Fees](https://bitcoinfees.21.co/) has a nice live assessment. It says that the "fastest and cheapest transaction fee is currently 42 satoshis/byte" and that "For the median transaction size of 224 bytes, this results in a fee of 9,408 satoshis".
|
||||
|
||||
Currently Bitcoin Fees suggests a transaction fee of about 10,000 satoshis, which is the same as .0001 BC. Yes, that's for the mainnet, not the testnet, but we want to test out things realistically, so that's what we're going to use.
|
||||
Currently Bitcoin Fees suggests a transaction fee of about 10,000 satoshis, which is the same as .0001 BTC. Yes, that's for the mainnet, not the testnet, but we want to test out things realistically, so that's what we're going to use.
|
||||
|
||||
In this case, that means taking the .0005 BTC in the UTXO we're selected, reducing it by .0001 BTC for the transaction fee, and sending the remaining .0004 BTC. (And this is an example of why micropayments don't work on the Bitcoin network, because a $1 or so transaction fee is pretty expensive when you're sending $4, let alone if you were trying to make a micropayment of $0.50. But that's always why we have Lightning.)
|
||||
|
||||
> :warning: **WARNING:** The lower that you set your transaction fee, the longer before your transaction is built into a block. The Bitcoin Fees sites lists expected times, from an expected 0 blocks, to 22. Since blocks are built on average every 10 minutes, that's the difference between a few minutes and a few hours! So, choose a transaction fee that's appropriate for what you're sending. Note that you should never drop below the minimum relay fee, which is .0001 BTC.
|
||||
> :warning: **WARNING:** The lower that you set your transaction fee, the longer before your transaction is built into a block. The Bitcoin Fees site lists expected times, from an expected 0 blocks, to 22. Since blocks are built on average every 10 minutes, that's the difference between a few minutes and a few hours! So, choose a transaction fee that's appropriate for what you're sending. Note that you should never drop below the minimum relay fee, which is .0001 BTC.
|
||||
|
||||
### Write the Raw Transaction
|
||||
|
||||
@ -260,7 +260,7 @@ Soon `listtransactions` should show a confirmed transaction of category 'send".
|
||||
"abandoned": false
|
||||
}
|
||||
```
|
||||
You can see that it matches the `txid` and the `recipien` address. Not only does it show the `amount` sent, but it also shows the transaction `fee`. And, it's already received a confirmation, because we offered a fee that would get it swept up into a block quickly.
|
||||
You can see that it matches the `txid` and the `recipient` address. Not only does it show the `amount` sent, but it also shows the transaction `fee`. And, it's already received a confirmation, because we offered a fee that would get it swept up into a block quickly.
|
||||
|
||||
Congratulations! You're now a few satoshis poorer!
|
||||
|
||||
|
@ -4,15 +4,21 @@ Creating a raw transaction revealed how more complex bitcoin-cli results can't e
|
||||
|
||||
## Install JQ
|
||||
|
||||
JQ is available from a [Github repository](https://stedolan.github.io/jq/). Just download for Linux, OS X, or Windows, as appropriate.
|
||||
For modern versions of Debian, you should be able to install JQ using `apt-get`:
|
||||
```
|
||||
# apt-get install jq
|
||||
```
|
||||
> :book: ***What is JQ?*** The repository explains it best, saying "jq is like sed for JSON data - you can use it to slice and filter and map and transform structured data with the same ease that sed, awk, grep and friends let you play with text."
|
||||
|
||||
If that works, you're done!
|
||||
|
||||
Otherwise, you can download JQ from a [Github repository](https://stedolan.github.io/jq/). Just download a binary for Linux, OS X, or Windows, as appropriate.
|
||||
|
||||
Once you've downloaded the binary, you can install it on your system. If you're working on a Debian VPS as we suggest, your installation will look like this:
|
||||
```
|
||||
$ mv jq-linux64 jq
|
||||
$ sudo /usr/bin/install -m 0755 -o root -g root -t /usr/local/bin jq
|
||||
```
|
||||
> :book: ***What is JQ?*** The repository explains it best, saying "jq is like sed for JSON data - you can use it to slice and filter and map and transform structured data with the same ease that sed, awk, grep and friends let you play with text."
|
||||
|
||||
## Use JQ to Access a JSON Object Value by Key
|
||||
|
||||
**Usage Example:** _Capture the hex from a signed raw transaction._
|
||||
@ -51,7 +57,7 @@ $ bitcoin-cli sendrawtransaction $signedtx
|
||||
|
||||
Grabbing data out of a JSON object is easy, but what if that JSON object is in a JSON array? The `listunspent` command offers a great example, because it'll usually contain a number of different transactions. What if you want to capture specific information from _one_ of them?
|
||||
|
||||
When working with a JSON array, the first thing you need to do is tell JQ which index to access. For example, you might have looked through your transactions in `listunspent` and decided that you wanted to work with the second of them. You use `'.[1]'` to access that first element. The `[]` says that we're referencing a JSON array and the `0` says we want the 0th index.
|
||||
When working with a JSON array, the first thing you need to do is tell JQ which index to access. For example, you might have looked through your transactions in `listunspent` and decided that you wanted to work with the second of them. You use `'.[1]'` to access that second element. The `[]` says that we're referencing a JSON array and the `1` says we want the 1st index.
|
||||
```
|
||||
$ bitcoin-cli listunspent | jq -r '.[1]'
|
||||
{
|
||||
@ -68,7 +74,7 @@ $ bitcoin-cli listunspent | jq -r '.[1]'
|
||||
"safe": true
|
||||
}
|
||||
```
|
||||
You can then capture an individual value from that selected array by (1) using a pipe _within_ the JQ arguments; and then (2) requesting the specific value afterward, as in the previous example. The following would capture the `txid` from the 0th JSON object in the JSON array produced by `listunspent`:
|
||||
You can then capture an individual value from that selected array by (1) using a pipe _within_ the JQ arguments; and then (2) requesting the specific value afterward, as in the previous example. The following would capture the `txid` from the 1st JSON object in the JSON array produced by `listunspent`:
|
||||
```
|
||||
$ bitcoin-cli listunspent | jq -r '.[1] | .txid'
|
||||
91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c
|
||||
@ -357,7 +363,7 @@ To complete the transaction fee calculation, you subtract the .vout .amount (1.0
|
||||
|
||||
To do this, you'll need to install `bc`:
|
||||
```
|
||||
$ sudo apt-get intall bc
|
||||
$ sudo apt-get install bc
|
||||
```
|
||||
|
||||
Putting it all together creates a complete calculator in just five lines of script:
|
||||
|
@ -111,9 +111,11 @@ Here's what some parameter arrays will look like:
|
||||
You can now send your first `curl` command by accessing the `getmininginfo` RPC:
|
||||
```
|
||||
$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/
|
||||
{"result":{"blocks":1772428,"difficulty":10178811.40698772,"networkhashps":91963587385939.06,"pooledtx":61,"chain":"test","warnings":"Warning: unknown new rules activated (versionbit 28)"},"error":null,"id":"curltest"}```
|
||||
Note that we provided the method, `getmininginfo`, and the parameter, `[]`, but that everything else was the standard `curl` command line.
|
||||
{"result":{"blocks":1772428,"difficulty":10178811.40698772,"networkhashps":91963587385939.06,"pooledtx":61,"chain":"test","warnings":"Warning: unknown new rules activated (versionbit 28)"},"error":null,"id":"curltest"}
|
||||
```
|
||||
|
||||
Note that we provided the method, `getmininginfo`, and the parameter, `[]`, but that everything else was the standard `curl` command line.
|
||||
|
||||
> **WARNING:** If you get a result like "Failed to connect to 127.0.0.1 port 8332: Connection refused", be sure that a line like `rpcallowip=127.0.0.1` is in your ~/.bitcoin/bitcoin.conf. If things still don't work, be sure that you're allowing access to port 18332 (or 8332) from localhost. Our standard setup from [Chapter Two: Creating a Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) should do all of this.
|
||||
|
||||
The result is another JSON array, which is unfortunately ugly to read if you're using `curl` by hand. Fortunately, you can clean it up simply by piping it through `jq`:
|
||||
@ -224,12 +226,14 @@ $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc"
|
||||
"error": null,
|
||||
"id": "curltest"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
> **WARNING:** The parameters order is important when you are sending RPC commands using curl. There's only one argument for `getrawchangeaddress`, but consider its close cousin `getnewaddress`. That takes two arguments: first label, then type. If we sent that same `"params": ["legacy"]` instead of `"params": ["", "legacy"]`, we would get a `bech32` address with a label of `"legacy"` instead of a `legacy` address, so pay attention to the order!
|
||||
|
||||
At this point, we can even revert to our standard practice of saving results to variables with additional help from `jq`:
|
||||
```
|
||||
$ changeaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result')
|
||||
$ echo $changeaddress
|
||||
$ newaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result')
|
||||
$ echo $newaddress
|
||||
mqdfnjgWr2r3sCCeuTDfe8fJ1CnycF2e6R
|
||||
```
|
||||
No need to worry about the downloading info. It'll go to `STDERR` and be displayed on your screen, while the results go to `STDOUT` and are saved in your variable.
|
||||
|
@ -98,7 +98,7 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3
|
||||
]
|
||||
}
|
||||
```
|
||||
One thing of interest here is the change address, with is the second `vout`. Note that it's a `tb1` address, which means that it's Bech32; when we gave Bitcoin Core the total ability to manage our change, it did so using its default address type, Bech32, and it worked fine. That's why our change to SegWit addresses in [§4.6](04_6_Creating_a_Segwit_Transaction.md) really isn't that big of a deal, but there are some gotchas for wider usage, which we'll talk about there.
|
||||
One thing of interest here is the change address, which is the second `vout`. Note that it's a `tb1` address, which means that it's Bech32; when we gave Bitcoin Core the total ability to manage our change, it did so using its default address type, Bech32, and it worked fine. That's why our change to SegWit addresses in [§4.6](04_6_Creating_a_Segwit_Transaction.md) really isn't that big of a deal, but there are some gotchas for wider usage, which we'll talk about there.
|
||||
|
||||
Though we saw the fee in the `fundrawtransaction` output, it's not visible here. However, you can verify it with the `txfee-calc.sh` JQ script created in the [JQ Interlude](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_2__Interlude_Using_JQ.md):
|
||||
```
|
||||
@ -162,7 +162,7 @@ $ bitcoin-cli listunspent
|
||||
|
||||
If you must send funds with raw transactions then `fundrawtransaction` gives you a nice alternative where fees, inputs, and outputs are calculated for you, so you don't accidentally lose a bunch of money.
|
||||
|
||||
> :fire: ***What the power of sending coins with automated raw transactions?***
|
||||
> :fire: ***What is the power of sending coins with automated raw transactions?***
|
||||
|
||||
> _The advantages._ It provides a nice balance. If you're sending funds by hand and `sendtoaddress` doesn't offer enough control for whatever reason, you can get some of the advantages of raw transactions without the dangers. This methodology should be used whenever possible if you're sending raw transactions by hand.
|
||||
|
||||
|
@ -12,9 +12,9 @@ The catch? SegWit uses different addresses, some of which are compatible with ol
|
||||
|
||||
## Understand a SegWit Transaction
|
||||
|
||||
In classic transactions, signature (witness) information was stored toward the middle of the transaction, while in SegWit transactions, it's at the bottom. This goes hand-in-hand with the blocksize increases that were introduced in the SegWit upgrade. The blocksize was increased from 1M to a variable amount based on how many SegWit transactions are in a block, starting as low as 1M (no SegWit transactions) and going as high as 4M (all SegWit transactions). This variable sized was created to accomodate classic nodes, so that everything remains backward compatible. If a classic node sees a SegWit tranaction, it throws out the witness information (resulting in a smaller sized block, under the old 1M limit), while if a new node sees a SegWit transaction, it keeps the witness information (resulting in a larger sized block, up to the new 4M limit).
|
||||
In classic transactions, signature (witness) information was stored toward the middle of the transaction, while in SegWit transactions, it's at the bottom. This goes hand-in-hand with the blocksize increases that were introduced in the SegWit upgrade. The blocksize was increased from 1M to a variable amount based on how many SegWit transactions are in a block, starting as low as 1M (no SegWit transactions) and going as high as 4M (all SegWit transactions). This variable size was created to accomodate classic nodes, so that everything remains backward compatible. If a classic node sees a SegWit transaction, it throws out the witness information (resulting in a smaller sized block, under the old 1M limit), while if a new node sees a SegWit transaction, it keeps the witness information (resulting in a larger sized block, up to the new 4M limit).
|
||||
|
||||
So that's the what and how of SegWit transactions. Not that you need to know any of it to use them. Most transactions on the BitCoin network are now SegWit. They're what you're going to natively use for more transactions and receipts of money. The details are no more relevant at this point than the details of how most of Bitcoin works.
|
||||
So that's the what and how of SegWit transactions. Not that you need to know any of it to use them. Most transactions on the Bitcoin network are now SegWit. They're what you're going to natively use for more transactions and receipts of money. The details are no more relevant at this point than the details of how most of Bitcoin works.
|
||||
|
||||
## Create a SegWit Address
|
||||
|
||||
@ -111,7 +111,7 @@ $ bitcoin-cli listaddressgroupings
|
||||
|
||||
## Send a SegWit Transaction The Easy Way
|
||||
|
||||
So how do you send a Bitcoin transaction? Exactly like any other transaction. It doesn't matter if the UTXO is SegWit, the address is SegWit, or some combination thereof. You can expect `bitcoin-cli` to do the right thing. Though you can tell the differences via the addresses, they don't matter for interacting with things at the `bitcoin-cli` or RPC level. (And this is one of the advantages of using the command line and the RPC interface, as suggested in this tutorial: experts have already done the hard work for you, including things like how to send to both legacy and Bech32 addresses. You just get to use that functionality to your own advantage.)
|
||||
So how do you send a Segwit transaction? Exactly like any other transaction. It doesn't matter if the UTXO is SegWit, the address is SegWit, or some combination thereof. You can expect `bitcoin-cli` to do the right thing. Though you can tell the differences via the addresses, they don't matter for interacting with things at the `bitcoin-cli` or RPC level. (And this is one of the advantages of using the command line and the RPC interface, as suggested in this tutorial: experts have already done the hard work for you, including things like how to send to both legacy and Bech32 addresses. You just get to use that functionality to your own advantage.)
|
||||
|
||||
Here's an example of sending to a SegWit address, the easy way:
|
||||
```
|
||||
@ -120,7 +120,7 @@ $ bitcoin-cli sendtoaddress tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx 0.005
|
||||
```
|
||||
If you look at your transaction, you can see the use of the Bech32 address:
|
||||
```
|
||||
$ bitcoin-cli gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42" verbose=true
|
||||
$ bitcoin-cli -named gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42" verbose=true
|
||||
{
|
||||
"amount": -0.00500000,
|
||||
"fee": -0.00036600,
|
||||
@ -279,7 +279,7 @@ The big thing to note is that function has changed. It was previously `pkh`, whi
|
||||
|
||||
There's really no complexity to creating SegWit transactions. Internally, they're structured differently from legacy transactions, but from the command line there's no difference: you just use an address with a different prefix. The only thing to watch for is that some people may not be able to send to a Bech32 address if they're using obsolete software.
|
||||
|
||||
> :fire: ***What the power of sending coins with SegWit?***
|
||||
> :fire: ***What's the power of sending coins with SegWit?***
|
||||
|
||||
> _The Advantages._ SegWit transactions are smaller, and so will be cheaper to send than legacy transactions due to lower fees. Bech32 doubles down on this advantage, and also creates addresses that are harder to foul up when transcribing — and that's pretty important, given that user error is one of the most likely ways to lose your bitcoins.
|
||||
|
||||
|
@ -42,7 +42,7 @@ This list of all [unconfirmed transactions](https://blockchain.info/unconfirmed-
|
||||
|
||||
If your transaction is stuck longer than you want, you can typically do one of four things:
|
||||
|
||||
**1. Wait Until it Clears.** If you sent your transaction with a low or medium fee, it should eventually go through. As shown at [Mempool Space](https://mempool.space), those with lower fees _will_ get delayed. (Take a look at the leftmost transation, and see how long it's been waiting and how much it paid for its fee.)
|
||||
**1. Wait Until it Clears.** If you sent your transaction with a low or medium fee, it should eventually go through. As shown at [Mempool Space](https://mempool.space), those with lower fees _will_ get delayed. (Take a look at the leftmost transaction, and see how long it's been waiting and how much it paid for its fee.)
|
||||
|
||||
**2. Wait Until it Expires.** If you accidentally sent with no transaction fee, or if any number or other conditions are met, then your transaction might never go through. However, your coins aren't lost. As long as you don't have a wallet that purposefully resends unconfirmed transactions, it should clear from the mempool in three days or so, and then you can try again.
|
||||
|
||||
@ -50,7 +50,7 @@ If your transaction is stuck longer than you want, you can typically do one of f
|
||||
|
||||
**4. Use CPFP as the Receiver.** Alternatively, if you are the receiver of the transaction, you can use CPFP (Child-pays-for-parent) to use the unconfirmed transaction as an input to a new transaction. See [§5.3: Funding a Transaction with CPFP](05_3_Funding_a_Transaction_with_CPFP.md).
|
||||
|
||||
## Summary: Watching for Stuck Transactios
|
||||
## Summary: Watching for Stuck Transactions
|
||||
|
||||
This is an introduction to the power of Bitcoin transactions. If you know that a transaction is stuck, then you can decide to free it up with features like RBF or CPFP.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 5.2: Resending a Transaction with RBF
|
||||
|
||||
If your Bitcoin transaction is stuck, and you're sender, you can resend it using RBF (replace-by-fee). However, that's not all that RBF can do: it's generally a powerful and multipurpose feature that allows Bitcoin senders to recreate transactions for a variety of reasons.
|
||||
If your Bitcoin transaction is stuck, and you're the sender, you can resend it using RBF (replace-by-fee). However, that's not all that RBF can do: it's generally a powerful and multipurpose feature that allows Bitcoin senders to recreate transactions for a variety of reasons.
|
||||
|
||||
> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.12.0, that reached full maturity in the Bitcoin Core wallet with Bitcoin Core v 0.14.0. Obviously, most people should be using it by now.
|
||||
|
||||
@ -38,7 +38,7 @@ $ bitcoin-cli -named gettransaction txid=5b953a0bdfae0d11d20d195ea43ab7c31a5471d
|
||||
"hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b01000000000100000002ea1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077007dff4df9ce75430e3065c82321dca9f6bdcfd5812f8dc0daeb957d3dfd1602203a624d4e9720a06def613eeea67fbf13ce1fb6188d3b7e780ce6e40e859f275d0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000"
|
||||
}
|
||||
```
|
||||
The `bip125-replaceable` flag will stay `yes` until the transaction receives confirmations. At that point, it is no longer replacable.
|
||||
The `bip125-replaceable` flag will stay `yes` until the transaction receives confirmations. At that point, it is no longer replaceable.
|
||||
|
||||
> :book: ***Should I trust transactions with no confirmations?*** No, never. This was true before RBF and it was true after RBF. Transactions must receive confirmations before they are trustworthy. This is especially true if a transaction is marked as `bip125-replaceable`, because then it can be ... replaced.
|
||||
|
||||
|
@ -87,7 +87,7 @@ $ utxo_vout=0
|
||||
$ recipient2=$(bitcoin-cli getrawchangeaddress)
|
||||
```
|
||||
|
||||
2. Create a raw transaction using your unconfirmed transaction an input.
|
||||
2. Create a raw transaction using your unconfirmed transaction as an input.
|
||||
3. Double the transaction fees (or more).
|
||||
|
||||
When you take these steps, everything should look totally normal, despite the fact that you're working with an unconfirmed transaction. To verify that all was well, we even looked at the results of our signature before we saved off the information to a variable:
|
||||
|
@ -7,7 +7,7 @@ Basic bitcoin transactions: (1) send funds; (2) to a single P2PKH or SegWit reci
|
||||
After working through this chapter, a developer will be able to:
|
||||
|
||||
* Create Multisignature Bitcoin Addresses Using Bitcoin Fundamentals
|
||||
* Create Multisignature Bitcoin Addresses Using Easiser Mechanisms
|
||||
* Create Multisignature Bitcoin Addresses Using Easier Mechanisms
|
||||
|
||||
Supporting objectives include the ability to:
|
||||
|
||||
|
@ -4,11 +4,11 @@ The first way to vary how you send a basic transaction is to use a multisig. Thi
|
||||
|
||||
## Understand How Multisigs Work
|
||||
|
||||
In a typical P2PKH or SegWit transaction, bitcoins are sent to an address based on your public key, which in turn means that the related private key is required to unlock the transaction, solving the cryptographic puzzle and allowing you to reuse the funds. But what if you could instead lock a transaction with _multiple_ private keys. This would effectively allow funds to be sent to a group of people, where those people all have to agree to reuse the funds.
|
||||
In a typical P2PKH or SegWit transaction, bitcoins are sent to an address based on your public key, which in turn means that the related private key is required to unlock the transaction, solving the cryptographic puzzle and allowing you to reuse the funds. But what if you could instead lock a transaction with _multiple_ private keys? This would effectively allow funds to be sent to a group of people, where those people all have to agree to reuse the funds.
|
||||
|
||||
> :book: ***What is a multisignature?*** A multisignature is a methodology that allows more than one person to jointly create a digital signature. It's a general technique for the cryptographic use of keys that goes far beyond Bitcoin.
|
||||
|
||||
Technically, a multisignature cryptographic puzzle is created by Bitcoin using the OP_CHECKMULTISIG command, and typically that's encapsulated in a P2SH address. [§10.4: Scripting a Multisig](10_4_Scripting_a_Multisig.md) will detail how that works more precisely. For now, all you need to know is that you can use `bitcoin-cli` command to create multisignature addresses; funds can be mailed to these addresses just like any normal P2PKH or Segwit address, but multiple private keys will be required for the redemption of the funds.
|
||||
Technically, a multisignature cryptographic puzzle is created by Bitcoin using the OP_CHECKMULTISIG command, and typically that's encapsulated in a P2SH address. [§10.4: Scripting a Multisig](10_4_Scripting_a_Multisig.md) will detail how that works more precisely. For now, all you need to know is that you can use `bitcoin-cli` command to create multisignature addresses; funds can be sent to these addresses just like any normal P2PKH or Segwit address, but multiple private keys will be required for the redemption of the funds.
|
||||
|
||||
> :book: ***What is a multisignature transaction?*** A multisignature transaction is a Bitcoin transaction that has been sent to a multisignature address, thus requiring the signatures of certain people from the multisignature group to reuse the funds.
|
||||
|
||||
@ -65,7 +65,7 @@ machine2$ bitcoin-cli -named getaddressinfo address=$address2
|
||||
```
|
||||
The `pubkey` address (`02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3`) is what's required. Copy it over to your local machine by whatever means you find most efficient and _least error prone_.
|
||||
|
||||
This process needs to be undertaken for _every_ address from a machine other than the one where the multisig is being built. Obviously, if some third-party is creating the address, then you'll to do this for every address.
|
||||
This process needs to be undertaken for _every_ address from a machine other than the one where the multisig is being built. Obviously, if some third-party is creating the address, then you'll need to do this for every address.
|
||||
|
||||
> :warning: **WARNING:** Bitcoin's use of public-key hashes as addresses, instead of public keys, actually represents an additional layer of security. Thus, sending a public key slightly increases the vulnerability of the associated address, for some far-future possibility of a compromise of the elliptic curve. You shouldn't worry about having to occasionally send out a public key for a usage such as this, but you should be aware that the public-key hashes represent security, and so the actual public keys should not be sent around willy nilly.
|
||||
|
||||
@ -97,13 +97,13 @@ The _address_ is what you'll give out to people who want to send funds. You'll n
|
||||
|
||||
> :link: **TESTNET vs MAINNET:** On testnet, the prefix for P2SH addresses is `2`, while on mainnet, it's `3`.
|
||||
|
||||
The _redeemScript_ is what you need to redeem the funds (along with the private keys for "m" of the "n" addresses). This script is another special feature of P2SH addresses and will be fully explained in [§8.1: Building a Bitcoin Script with P2SH](08_1_Building_a_Bitcoin_Script_with_P2SH.md). For now, just be aware that it's a bit of data that's required to get your money.
|
||||
The _redeemScript_ is what you need to redeem the funds (along with the private keys for "m" of the "n" addresses). This script is another special feature of P2SH addresses and will be fully explained in [§10.3: Running a Bitcoin Script with P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md). For now, just be aware that it's a bit of data that's required to get your money.
|
||||
|
||||
The _descriptor_ is the standardized description for an address that we met in [§3.5: Understanding the Descriptor](03_5_Understanding_the_Descriptor.md). It provides one way that you could import this address back to the other machine, using the `importmulti` RPC.
|
||||
|
||||
> :book: ***What is a P2SH address?*** P2SH stands for Pay-to-script-hash. It's a different type of recipient than a standard P2PKH address or even a Bech32, used for funds whose redemption are based on more complex Bitcoin Scripts. `bitcoin-cli` uses P2SH encapsulation to help standardize and simplify its multisigs as "P2SH multisigs", just like P2SH-SegWit was using P2SH to standardize its SegWit addresses and make them fully backward compatible.
|
||||
|
||||
> :warning: **WARNING:** P2SH multisig addresses, like the ones created by `bitcoin-cli`, have a limit for "m" and "n" in multisigs based on the maximum size of the redeem script, which is currently 520 bytes. Pratically, you won't hit this unless you're doing something excessive.
|
||||
> :warning: **WARNING:** P2SH multisig addresses, like the ones created by `bitcoin-cli`, have a limit for "m" and "n" in multisigs based on the maximum size of the redeem script, which is currently 520 bytes. Practically, you won't hit this unless you're doing something excessive.
|
||||
|
||||
### Save Your Work
|
||||
|
||||
@ -199,7 +199,7 @@ As you can see, there was nothing unusual in the creation of the transaction, an
|
||||
|
||||
Multisig addresses lock funds to multiple private keys — possibly requiring all of those private keys for redemption, and possibly requiring just some from the set. They're easy enough to create with `bitcoin-cli` and they're entirely normal to send to. This ease is due in large part to the invisible use of P2SH (pay-to-script-hash) addresses, a large topic that we've touched upon twice now, with P2SH-SegWit and multisig addresses, and one that will get more coverage in the future.
|
||||
|
||||
> :fire: ***What is the power of multisignatures?*** Multisignatures allow the modeling of a variety of financial arrangements such as corporations, partnerships, committees, and other groups. A 1-of-2 multisig might be a married couple's joint bank account, while a 2-of-2 multisig might be used for large expenditures by a Limited Liability Partnership. Multisignatures also form one of the bases of Smart Contracts. For example, a real estate deal could be closed with a 2-of-3 multisig, where the signatures are submitted by the buyer, the seller, and an escrow agent. Once the escrow agent agrees that all of the conditions have been met, he frees up the funds for the seller; or alternatively, the buyer and seller can jointly free the funds.
|
||||
> :fire: ***What is the power of multisignatures?*** Multisignatures allow the modeling of a variety of financial arrangements such as corporations, partnerships, committees, and other groups. A 1-of-2 multisig might be a married couple's joint bank account, while a 2-of-2 multisig might be used for large expenditures by a Limited Liability Partnership. Multisignatures also form one of the bases of Smart Contracts. For example, a real estate deal could be closed with a 2-of-3 multisig, where the signatures are submitted by the buyer, the seller, and a licensed escrow agent. Once the escrow agent agrees that all of the conditions have been met, he frees up the funds for the seller; or alternatively, the buyer and seller can jointly free the funds.
|
||||
|
||||
## What's Next?
|
||||
|
||||
|
@ -8,7 +8,7 @@ To start with, you need to find your funds; your computer doesn't know to look f
|
||||
```
|
||||
$ bitcoin-cli -named importaddress address=2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz
|
||||
```
|
||||
If you've got a pruned node (and you probably do), you'll instead need to tell it no to rescan:
|
||||
If you've got a pruned node (and you probably do), you'll instead need to tell it not to rescan:
|
||||
```
|
||||
$ bitcoin-cli -named importaddress address=2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz rescan="false"
|
||||
```
|
||||
@ -177,7 +177,7 @@ That produces scary errors and says that it's `failing`. This is all fine. You c
|
||||
|
||||
### Repeat for Other Signers
|
||||
|
||||
You can now pass the transaction on, to be signed again by anyone else required for the mutisig. They do this by running the same signing command that you did but: (1) with the longer `hex` that you output from (`bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"]' | jq -r '. | .hex'`); and (2) with their own private key.
|
||||
You can now pass the transaction on, to be signed again by anyone else required for the multisig. They do this by running the same signing command that you did but: (1) with the longer `hex` that you output from (`bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"]' | jq -r '.hex'`); and (2) with their own private key.
|
||||
|
||||
> :information_source: **NOTE — M-OF-N VS N-OF-N:** Obviously, if you have an n-of-n signature (like the 2-of-2 multisignature in this example), then everyone has to sign, but if you hae a m-of-n multisignature where "m < n", then the signature will be complete when only some ("m") of the signers have signed.
|
||||
|
||||
@ -215,7 +215,7 @@ This redemption methodology shows a standard way to sign and reuse P2SH transact
|
||||
|
||||
1. Include the `scriptPubKey`, which explains the P2SH cryptographic puzzle.
|
||||
2. Include the `redeemScript`, which solves the P2SH cryptographic puzzle, and introduces a new puzzle of its own.
|
||||
3. Be run on each machine holding required signatures.
|
||||
3. Be run on each machine holding required private keys.
|
||||
4. Include the relevant signatures, which solve the redeemScript puzzle.
|
||||
|
||||
Here, we saw this methodology used to redeem multisig funds. In the future you can also use it to redeem funds that were locked with other, more complex P2SH scripts, as explained starting in Chapter 9.
|
||||
|
@ -15,13 +15,13 @@ You start off creating P2PKH addresses and retrieving public keys, as usual, for
|
||||
machine1$ address3=$(bitcoin-cli getnewaddress)
|
||||
machine1$ echo $address3
|
||||
tb1q4ep2vmakpkkj6mflu94x5f94q662m0u5ad0t4w
|
||||
machine1$ bitcoin-cli -named getaddressinfo address=$address3 | jq -r '. | .pubkey'
|
||||
machine1$ bitcoin-cli -named getaddressinfo address=$address3 | jq -r '.pubkey'
|
||||
0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc
|
||||
|
||||
machine2$ address4=$(bitcoin-cli getnewaddress)
|
||||
machine2$ echo $address4
|
||||
tb1qa9v5h6zkhq8wh0etnv3ae9cdurkh085xufl3de
|
||||
machine2$ bitcoin-cli -named getaddressinfo address=$address4 | jq -r '. | .pubkey'
|
||||
machine2$ bitcoin-cli -named getaddressinfo address=$address4 | jq -r '.pubkey'
|
||||
02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f
|
||||
```
|
||||
|
||||
@ -49,14 +49,14 @@ As noted in the previous section, it currently doesn't matter whether you use ad
|
||||
|
||||
Afterward, the members of the multisig will still need to run `importaddress` to watch for funds received on the multisig address:
|
||||
```
|
||||
machine1$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8 rescan="false"
|
||||
machine1$ bitcoin-cli -named importaddress address=tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex rescan="false"
|
||||
|
||||
machine2$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8 rescan="false"
|
||||
machine2$ bitcoin-cli -named importaddress address=tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex rescan="false"
|
||||
```
|
||||
|
||||
## Respend with an Automated Transaction
|
||||
|
||||
Afterward, you will be able to receive funds on the multisiganture address as normal. The use of `addmultisigaddress` is simply a bureaucratic issue on the part of the recipients: a bit of bookkeeping to make life easier for them when they want to spend their funds.
|
||||
Afterward, you will be able to receive funds on the multisignature address as normal. The use of `addmultisigaddress` is simply a bureaucratic issue on the part of the recipients: a bit of bookkeeping to make life easier for them when they want to spend their funds.
|
||||
|
||||
But, it makes life a lot easier. Because information was saved into the wallet, the signers will be able to respend the funds sent to the multisignature address exactly the same as any other address ... other than the need to sign on multiple machines.
|
||||
|
||||
@ -113,7 +113,7 @@ As with the shortcut discussed in [§4.5: Sending Coins with Automated Raw Trans
|
||||
|
||||
## Summary: Sending & Spending an Automated Multisig
|
||||
|
||||
There's an easier way to resepend funds sent to multisig addresses that simply requires use of the `addmultisigaddress` command when you create your address. It doesn't demonstrate the intricacies of P2SH respending, and it doesn't give you expansive control, but if you just want to get your money, this is the way to go.
|
||||
There's an easier way to respend funds sent to multisig addresses that simply requires use of the `addmultisigaddress` command when you create your address. It doesn't demonstrate the intricacies of P2SH respending, and it doesn't give you expansive control, but if you just want to get your money, this is the way to go.
|
||||
|
||||
## What's Next?
|
||||
|
||||
|
@ -4,22 +4,22 @@
|
||||
|
||||
Partially Signed Bitcoin Transactions (PSBTs) are the newest way to vary the creation of basic Bitcoin transactions. They do so by introducing collaboration into every step of the process, allowing people (or programs) to not just authenticate transactions together (as with multisigs), but also to easily create, fund, and broadcast collaboratively.
|
||||
|
||||
> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.17.0. Earlier versions of Bitcoin Core will not be able to work with the PSBT while it is in process (though they will still be able to recognize the final transaction). Some updates and upgrades for PSBTs have continued through 0.20.0.
|
||||
> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.17.0. Earlier versions of Bitcoin Core will not be able to work with the PSBT while it is in progress (though they will still be able to recognize the final transaction). Some updates and upgrades for PSBTs have continued through 0.20.0.
|
||||
|
||||
## Understand How PSBTs Work
|
||||
|
||||
Multisignatures were great for the very specific case of jointly holding funds and setting rules for who among the joint signers could authenticate the use of those funds. There are many use cases, such as: a spousal joint bank account (a 1-of-2 signature); a fiduciary requirement for dual control (a 2-of-2 signature); and an escrow (a 2-of-3 signature).
|
||||
Multisignatures were great for the very specific case of jointly holding funds and setting rules for whom among the joint signers could authenticate the use of those funds. There are many use cases, such as: a spousal joint bank account (a 1-of-2 signature); a fiduciary requirement for dual control (a 2-of-2 signature); and an escrow (a 2-of-3 signature).
|
||||
|
||||
> :book: ***What is a PSBT?*** As the name suggests, a PSBT is a transaction that has not been fully signed. That's important, because once a transaction is signed, its content is locked in. [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) defined an abstracted methodology for putting PSBTs together that describes and standardizes roles in their collaborative creation. A *Creator* proposes a transaction; one or more *Updaters* supplement it; and one or more *Signers* authenticate it; before a *Finalizer* completes it; and an *Extracter* turn it into a transaction for the Bitcoin network. There may also be a *Combiner* who merges parallel PSBTs from different users.
|
||||
> :book: ***What is a PSBT?*** As the name suggests, a PSBT is a transaction that has not been fully signed. That's important, because once a transaction is signed, its content is locked in. [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) defined an abstracted methodology for putting PSBTs together that describes and standardizes roles in their collaborative creation. A *Creator* proposes a transaction; one or more *Updaters* supplement it; and one or more *Signers* authenticate it; before a *Finalizer* completes it; and an *Extracter* turns it into a transaction for the Bitcoin network. There may also be a *Combiner* who merges parallel PSBTs from different users.
|
||||
|
||||
PSBTs may initially look sort of the same as multi-sigs because they have a single overlapping bit of functionality: the ability to jointly sign a transaction. However, they were created for a totally different use case. PSBTs recognize the need for multiple programs to jointly create a transaction for a number of different reasons, and they provide a regularized format for doing so. They're especially useful for use cases involving hardware wallets (for which, see §7.3), which are protected from full access to the internet and tend to have minimal transaction history.
|
||||
PSBTs may initially look sort of the same as multi-sigs because they have a single overlapping bit of functionality: the ability to jointly sign a transaction. However, they were created for a totally different use case. PSBTs recognize the need for multiple programs to jointly create a transaction for a number of different reasons, and they provide a regularized format for doing so. They're especially useful for use cases involving hardware wallets (for which, see [§7.3](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_3_Integrating_with_Hardware_Wallets.md)), which are protected from full access to the internet and tend to have minimal transaction history.
|
||||
|
||||
In general, PSBTs provide a number of functional elements that improve this use case:
|
||||
|
||||
1. They provide a _standard_ for collaboratively creating transactions, whereas previous methodologies (including the multi-sig one from the previous chapter) were implementation dependent.
|
||||
2. They support a _wider variety of use cases_, including simple joint funding.
|
||||
3. They support _hardware wallets_ and other cases where a node may not have full transaction history.
|
||||
4. They optional allow for the combination of _non-serialized transactions_, not requiring an ever-bigger hex code to be passed from user to user.
|
||||
4. They optionally allow for the combination of _non-serialized transactions_, not requiring an ever-bigger hex code to be passed from user to user.
|
||||
|
||||
PSBTs do their work by supplementing normal transaction information with a set of inputs and outputs, each of which defines everything you need to know about those UTXOs, so that even an airgapped wallet can make an informed decision about signatures. Thus, an input lists out the amount of money in a UTXO and what needs to be done to spend it, while an output does the same for the UTXOs it's creating.
|
||||
|
||||
@ -28,7 +28,7 @@ This first section will outline the standard PSBT process of: Creator, Updater,
|
||||
## Create a PSBT the Old-Fashioned Way
|
||||
#### PSBT Role: Creator
|
||||
|
||||
The easiest way to create a PSBT is to take an existing transaction and use `converttopsbt` to turn it into a PSBT. This is certainly not the _best_ way since it requires you to make a transaction for one format (a raw transaction) then convert it to another (PSBT), but if you've got old software that can only generate raw transaction, you may need to use it.
|
||||
The easiest way to create a PSBT is to take an existing transaction and use `converttopsbt` to turn it into a PSBT. This is certainly not the _best_ way since it requires you to make a transaction for one format (a raw transaction) then convert it to another (PSBT), but if you've got old software that can only generate a raw transaction, you may need to use it.
|
||||
|
||||
You just create your raw transaction normally:
|
||||
|
||||
@ -467,7 +467,7 @@ $ bitcoin-cli analyzepsbt $psbt_new_f
|
||||
"next": "extractor"
|
||||
}
|
||||
```
|
||||
Now would you realy want to use `walletcreatefundedpsbt` if you were creating a `bitcoin-cli` program? Probably not. But it's the same analysis as whether to use `fundrawtransaction`. Do you let Bitcoin Core do the analysis and calculation and decisions, or do you take that on yourself?
|
||||
Now would you really want to use `walletcreatefundedpsbt` if you were creating a `bitcoin-cli` program? Probably not. But it's the same analysis as whether to use `fundrawtransaction`. Do you let Bitcoin Core do the analysis and calculation and decisions, or do you take that on yourself?
|
||||
|
||||
## Send a PSBT
|
||||
#### PSBT Role: Extractor
|
||||
|
@ -6,7 +6,7 @@ Now that you've learned the basic workflow of generating a PSBT, you probably wa
|
||||
|
||||
Following are three examples of using PSBTs for: multi-sigs, pooling money, and joining coins.
|
||||
|
||||
> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.17.0. Earlier versions of Bitcoin Core will not be able to work with the PSBT while it is in process (though they will still be able to recognize the final transaction).
|
||||
> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.17.0. Earlier versions of Bitcoin Core will not be able to work with the PSBT while it is in progress (though they will still be able to recognize the final transaction).
|
||||
|
||||
## Use a PSBT to Spend MultiSig Funds
|
||||
|
||||
@ -425,7 +425,7 @@ Second, it's a lot more scalable. Consider a 3-of-5 multisig. Under the old meth
|
||||
|
||||
Multisigs like the one used in the previous example are often used to receive payments for collaborative work, whether it be royalties for a book or payments made to a company. In that situation, the above example works great: the two participants receive their money which they then split up. But what about the converse case, where two (or more) participants want to set up a joint venture, and they need to seed it with money?
|
||||
|
||||
The traditional answer is to create a multisig, then to have the participants individually send their funds to it. The problem is that the first payer has to depend on the good faith of the second, and that doesn't built on the strength of Bitcoin, which is its _trustlessness_. Fortunately, with the advent of PSBTs, we can now make trustless payments that pool funds.
|
||||
The traditional answer is to create a multisig, then to have the participants individually send their funds to it. The problem is that the first payer has to depend on the good faith of the second, and that doesn't build on the strength of Bitcoin, which is its _trustlessness_. Fortunately, with the advent of PSBTs, we can now make trustless payments that pool funds.
|
||||
|
||||
> :book: ***What does trustless mean?*** Trustless means that no participant has to trust any other participant. They instead expect the software protocols to ensure that everything is enacted fairly in an expected manner. Bitcoin is a trustless protocol because you don't need anyone else to act in good faith; the system manages it. Similarly, PSBTs allow for the trustless creation of transactions that pool or split funds.
|
||||
|
||||
@ -588,6 +588,8 @@ Each user puts in their own UTXO, and each one receives a corresponding output.
|
||||
|
||||
The best way to manage a CoinJoin is to send out the base PSBT to all the parties (who could be numerous), and then have them each sign the PSBT and send back to a single party who will combine, finalize, and send.
|
||||
|
||||
> :book: ***What is CoinJoin?*** CoinJoin is a methodology whereby a group of people can mix together their cryptocurrency, helping to reduce fungibility for all the coins. Each person puts in and takes out the same amount of coins (minus transaction fees) in a multi-person transaction that is simultaneously conducted by a _large_ number of people. It's designed to be "trustless" so that the parties don't need to know or trust each other. A CoinJoin ultimately increases anonymity by making the coins hard to trace. The Wasabi Wallet and a number of "mixer" services support CoinJoin at the large-scale necessary for improved anonymity.
|
||||
|
||||
## Summary: Using a Partially Signed Bitcoin Transaction
|
||||
|
||||
You've now seen the PSBT process that you learned in [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) in use in three real-life examples: creating a multi-sig, pooling funds, and CoinJoining. These were all theoretically possible in classic Bitcoin by having multiple people sign carefully constructed transactions, but PSBTs make it standardized and simple.
|
||||
@ -598,4 +600,4 @@ That last point, on creating a transaction on one machine and signing on another
|
||||
|
||||
## What's Next?
|
||||
|
||||
Continue "Expanding Bitcoin Transactions with PSBTs" with [§7.3: Inegrating with Hardware Wallets](07_3_Integrating_with_Hardware_Wallets.md).
|
||||
Continue "Expanding Bitcoin Transactions with PSBTs" with [§7.3: Integrating with Hardware Wallets](07_3_Integrating_with_Hardware_Wallets.md).
|
||||
|
@ -2,27 +2,27 @@
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
One of the greatest powers of PSBTs is the ability to hand transactions off to hardware wallets. This will be a great development tool for you if you continue to program with Bitcoin. However, you can't test it out now if you're using one of the configurations we suggest for this course — a VM on Linode per [§2.1](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) or an even more farflung option such an AWS per [§2.2](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/02_2_Setting_Up_Bitcoin_Core_Other.md) — because obviously you won't have any way to hook a hardware wallet up to your remote, virtual machine.
|
||||
One of the greatest powers of PSBTs is the ability to hand transactions off to hardware wallets. This will be a great development tool for you if you continue to program with Bitcoin. However, you can't test it out now if you're using one of the configurations we suggest for this course — a VM on Linode per [§2.1](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) or an even more farflung option such as AWS per [§2.2](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/02_2_Setting_Up_Bitcoin_Core_Other.md) — because obviously you won't have any way to hook a hardware wallet up to your remote, virtual machine.
|
||||
|
||||
>: ***What is a Hardware Wallet?*** A hardware wallet is an electronic device that improves the security of cryptocurrency by maintaing all the private keys on the device, rather than ever putting them on a computer directly connected to the internet. Hardware wallets have specific protocols for providing online interactions, usually managed by a program talking to the device through a USB port. In this chapter, we'll be managing a hardware wallet with `bitcoin-cli` and the `hwy.py` program.
|
||||
> :book: ***What is a Hardware Wallet?*** A hardware wallet is an electronic device that improves the security of a cryptocurrency by maintaining all the private keys on the device, rather than ever putting them on a computer directly connected to the internet. Hardware wallets have specific protocols for providing online interactions, usually managed by a program talking to the device through a USB port. In this chapter, we'll be managing a hardware wallet with `bitcoin-cli` and the `hwy.py` program.
|
||||
|
||||
You have three options for moving through this chapter on hardware wallets: (1) read along without testing the code; (2) install Bitcoin on a local machine to fully test these commands; or (3) skip straight ahead to [Chapter 8: Expanding Bitcoin Transactions in Other Ways](08_0_Expanding_Bitcoin_Transactions_Other.md). We suggest option #1, but if you really want to get your hands dirty we'll also give some support for #2 by talking about using a Macintosh (a hardware-platform supported by [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup)) for testing.
|
||||
|
||||
> :warning: **VERSION WARNING:** PSBTs are an innovation from Bitcoin Core v 0.17.0. Earlier versions of Bitcoin Core will not be able to work with the PSBT while it is in process (though they will still be able to recognize the final transaction). The HWI interface appeared in Bitcoin Core v 0.18.0, but as long as you are using our suggested setup with Bitcoin Standup, it should work.
|
||||
> :warning: **VERSION WARNING:** PSBTs are an innovation from Bitcoin Core v 0.17.0. Earlier versions of Bitcoin Core will not be able to work with the PSBT while it is in progress (though they will still be able to recognize the final transaction). The HWI interface appeared in Bitcoin Core v 0.18.0, but as long as you are using our suggested setup with Bitcoin Standup, it should work.
|
||||
|
||||
The methodology described in this chapter for integrating with a hardware wallet depends on the [Bitcoin Hardware Wallet Interface](https://github.com/bitcoin-core/HWI) released through Bitcoin Core and builds on the [installation](https://github.com/bitcoin-core/HWI/blob/master/README.md) and [usage](https://github.com/bitcoin-core/HWI/blob/master/docs/bitcoin-core-usage.md) instructions found there.
|
||||
The methodology described in this chapter for integrating with a hardware wallet depends on the [Bitcoin Hardware Wallet Interface](https://github.com/bitcoin-core/HWI) released through Bitcoin Core and builds on the [installation](https://github.com/bitcoin-core/HWI/blob/master/README.md) and [usage](https://hwi.readthedocs.io) instructions found there.
|
||||
|
||||
> :warning **FRESHNESS WARNING:** The HWI interface is very new and raw around the edges as of Bitcoin Core v 0.20.0. It may be hard to install correctly, and it may have unintuive errors. What follows is a description of a working setup, but it took several tries to get it right, and your setup may vary.
|
||||
> :warning: **FRESHNESS WARNING:** The HWI interface is very new and raw around the edges as of Bitcoin Core v 0.20.0. It may be hard to install correctly, and it may have unintuitive errors. What follows is a description of a working setup, but it took several tries to get it right, and your setup may vary.
|
||||
|
||||
## Install Bitcoin Core on a Local Machine
|
||||
|
||||
_If you just plan to read over this section and not test out these commands until some future date when you have a local development environment, you can skip this subsection, which is about creating a Bitcoin Core installation on a local machine such as a Mac or UNIX machine._
|
||||
_If you just plan to read over this section and not test out these commands until some future date when you have a local development environment, you can skip this subsection, which is about creating a Bitcoin Core installation on a local machine such as a Mac or Linux machine._
|
||||
|
||||
There are alternate versions of the Bitcoin Standup script that you used to create your VM that will install on a MacOS or on a non-Linode UNIX machine.
|
||||
There are alternate versions of the Bitcoin Standup script that you used to create your VM that will install on a MacOS or on a non-Linode Linux machine.
|
||||
|
||||
If you have MacOS, you can install [Bitcoin Standup MacOS](https://github.com/BlockchainCommons/Bitcoin-Standup-MacOS/blob/master/README.md).
|
||||
|
||||
If you have a local UNIX machine, you can install [Bitcoin Standup Linux Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-MacOS/blob/master/README.md).
|
||||
If you have a local Linux machine, you can install [Bitcoin Standup Linux Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/README.md).
|
||||
|
||||
Once you've gotten Bitcoin Standup running on your local machine, you'll want to sync the "Testnet" blockchain, assuming that you're continuing to follow the standard methodlogy of this course.
|
||||
|
||||
@ -91,7 +91,7 @@ HWI$ python3 setup.py install
|
||||
|
||||
You'll want to create an alias here too, varied by your actual install location:
|
||||
```
|
||||
$ alias hwi="~/Standup/HWI/hwi.py --testnet"
|
||||
$ alias hwi="~/Standup/HWI/hwi.py --chain test"
|
||||
```
|
||||
Again, we've included a reference to testnet in this alias.
|
||||
|
||||
@ -104,7 +104,7 @@ If you are working with Bitcoins on your Ledger, you probably won't need to do a
|
||||
To work with Testnet coins, as suggested by this course, you'll need to make a few updates:
|
||||
|
||||
1. Go to Settings on your Ledger Live app (it's the gear), go to the "Experimental Features" tab, and turn on "Developer Mode".
|
||||
2. Go to the "Manager" and install "Bitcoin Test". The current version requires that you have "Bitcoin" and "Etereum" installed first.
|
||||
2. Go to the "Manager" and install "Bitcoin Test". The current version requires that you have "Bitcoin" installed first.
|
||||
3. Go to the "Manager", scroll to your new "Bitcoin Test", and "Add Account"
|
||||
|
||||
## Link to a Ledger
|
||||
@ -130,7 +130,7 @@ You can watch for funds by importing addresses from your hardware wallet to your
|
||||
|
||||
To use your hardware wallet with `bitcoin-cli`, you'll want to create a specific named wallet in Bitcoin Core, using the `createwallet` RPC, which is a command we haven't previously discussed.
|
||||
```
|
||||
$ bitcoin-cli --named createwallet wallet_name="ledger" disable_private_keys="true"
|
||||
$ bitcoin-cli --named createwallet wallet_name="ledger" disable_private_keys="true" descriptors="false"
|
||||
{
|
||||
"name": "ledger",
|
||||
"warning": ""
|
||||
@ -154,10 +154,10 @@ Because you've created a second wallet, some commands will now require a `-rpcwa
|
||||
|
||||
You now have to import a watch-list of addresses from the hardware wallet. This is done with HWI's `getkeypool` command:
|
||||
```
|
||||
$ hwi -f 9a1d520b getkeypool --wpkh 0 1000
|
||||
$ hwi -f 9a1d520b getkeypool 0 1000
|
||||
[{"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/0/*)#qttxy592", "range": [0, 1000], "timestamp": "now", "internal": false, "keypool": true, "active": true, "watchonly": true}, {"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/1/*)#3lw8ep4j", "range": [0, 1000], "timestamp": "now", "internal": true, "keypool": true, "active": true, "watchonly": true}]
|
||||
```
|
||||
We address HWI with the `fingerprint` and ask for the first 1000 WPKH (native Segwit) addresses. In return, we receive two descriptors for the key pool: one for receiving addresses and one for change addresses.
|
||||
We address HWI with the `fingerprint` and ask for the first 1000 addresses. The WPKH (native Segwit) address type is used as a default. In return, we receive two descriptors for the key pool: one for receiving addresses and one for change addresses.
|
||||
|
||||
> :book: ***What is a key pool?*** A key pool is a group of pregenerated keys. Modern HD wallets create key pools by continuing to determine new hierarchical addresses based on the original seed. The idea of key pools was originally implemented to ease the backup requirements of wallets. This allowed a user to generate a keypool and then backup the wallet immediately, rather than requiring backups after every new address was created. The concept has also proven very useful in the modern day since it allows the importing of a whole set of future addresses from one device to another.
|
||||
|
||||
@ -190,7 +190,7 @@ $ bitcoin-cli -rpcwallet=ledger importmulti '[{"desc": "wpkh([9a1d520b/84h/1h/0h
|
||||
```
|
||||
(Note that HWI helpfully output the derivation path with `h`s to show hardened derivations rather than `'`s, and calculated its checksum accordingly, so that we don't have to do massive quoting like we did in §3.5.)
|
||||
|
||||
You _could_ now list all of the watch-only addresse that you received using the `getaddressesbylabel` command. All 1000 of the receive addresses are right there, in the `ledger` wallet!
|
||||
You _could_ now list all of the watch-only addresses that you received using the `getaddressesbylabel` command. All 1000 of the receive addresses are right there, in the `ledger` wallet!
|
||||
```
|
||||
$ bitcoin-cli -rpcwallet=ledger getaddressesbylabel "" | more
|
||||
{
|
||||
@ -246,7 +246,7 @@ $ bitcoin-cli -rpcwallet=ledger listunspent
|
||||
```
|
||||
## Create a Transaction with PSBT
|
||||
|
||||
Watching and receiving payments is just half the battle. You may also want to make payments using accounts held by your hardware wallet. This is a the fourth real-life example for using PSBTs, per the process outlined in [§7.1: Creating a Partially Signed Bitcoin Transaction](7_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md).
|
||||
Watching and receiving payments is just half the battle. You may also want to make payments using accounts held by your hardware wallet. This is the fourth real-life example for using PSBTs, per the process outlined in [§7.1: Creating a Partially Signed Bitcoin Transaction](7_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md).
|
||||
|
||||
The commands work exactly the same. In this case, use `walletcreatefundedpsbt` to form your PSBT because this is a situation where you don't care what UTXOs are used:
|
||||
```
|
||||
|
@ -6,13 +6,13 @@ The previous chapters showed two different ways to send funds from multiple mach
|
||||
|
||||
When you create a locktime transaction, you lock it with a number that represents either a block height (if it's a small number) or a UNIX timestamp (if it's a big number). This tells the Bitcoin network that the transaction may not be put into a block until either the specified time has arrived or the blockchain has reached the specified height.
|
||||
|
||||
> :book: _What is block height?_ It's the total count of blocks in the chain, going back to the genesis block for Bitcoin.
|
||||
> :book: **_What is block height?_** It's the total count of blocks in the chain, going back to the genesis block for Bitcoin.
|
||||
|
||||
When a locktime transaction is waiting to go into a block, it can be cancelled. This means that it is far, far from finalized. In fact, the ability to cancel is the whole purpose of a locktime transaction.
|
||||
|
||||
> :book: _What is nLockTime?_ It's the same thing as locktime. More specifically, it's what locktime is called internal to the Bitcoin Core source code.
|
||||
> :book: **_What is nLockTime?_** It's the same thing as locktime. More specifically, it's what locktime is called internal to the Bitcoin Core source code.
|
||||
|
||||
> :book: _What is Timelock?_ Locktime is just one way to lock Bitcoin transactions until some point in the future; collectively these methods are called timelocks. Locktime is the most basic timelock method. It locks an entire transaction with an absolute time, and it's available through `bitcoin-cli` (which is why it's the only timelock covered in this section). A parallel method, which locks a transaction with a relative time, is defined in [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) and covered in [§11.3: Using CSV in Scripts](11_3_Using_CSV_in_Scripts.md).
|
||||
> :book: **_What is Timelock?_** Locktime is just one way to lock Bitcoin transactions until some point in the future; collectively these methods are called timelocks. Locktime is the most basic timelock method. It locks an entire transaction with an absolute time, and it's available through `bitcoin-cli` (which is why it's the only timelock covered in this section). A parallel method, which locks a transaction with a relative time, is defined in [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) and covered in [§11.3: Using CSV in Scripts](11_3_Using_CSV_in_Scripts.md).
|
||||
|
||||
> Bitcoin Script further empowers both sorts of timelocks, allowing for the locking of individual outputs instead of entire transactions. Absolute timelocks (such as Locktime) are linked to the Script opcode OP_CHECKLOCKTIMEVERIFY, which is defined in [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) and covered in [§11.2: Using CLTV in Scripts](11_2_Using_CLTV_in_Scripts.md), while relative timelocks (such as Timelock) are linked to the Script opcode OP_CHECKSEQUENCEVERIFY, which is defined in [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) and also covered in [§11.3](11_3_Using_CSV_in_Scripts.md).
|
||||
|
||||
@ -24,7 +24,7 @@ In order to create a locktime transaction, you need to first determine what you
|
||||
|
||||
Most frequently you will set the locktime to a UNIX timestamp representing a specific date and time. You can calculate a UNIX timestamp at a web site like [UNIX Time Stamp](http://www.unixtimestamp.com/) or [Epoch Convertor](https://www.epochconverter.com/). However, it would be better to [write your own script](https://www.epochconverter.com/#code) on your local machine, so that you know the UNIX timestamp you receive is accurate. If you don't do that, at least double check on two different sites.
|
||||
|
||||
> :book: _Why Would I Use a UNIX Timestamp?_ Using a UNIX timestamp makes it easy to definitively link a transaction to a specific time, without worrying about whether the speed of block creation might change at some point. Particularly if you're creating a locktime that's far in the future, it's the safer thing to do. But, beyond that, it's just more intuitive, creating a direct correlation between some calendar date and the time when the transaction can be mined.
|
||||
> :book: **_Why Would I Use a UNIX Timestamp?_** Using a UNIX timestamp makes it easy to definitively link a transaction to a specific time, without worrying about whether the speed of block creation might change at some point. Particularly if you're creating a locktime that's far in the future, it's the safer thing to do. But, beyond that, it's just more intuitive, creating a direct correlation between some calendar date and the time when the transaction can be mined.
|
||||
|
||||
> :warning: **WARNING:** Locktime with UNIX timestamps has a bit of wriggle room: the release of blocks isn't regular and block times can be two hours ahead of real time, so a locktime actually means "within a few hours of this time, plus or minus".
|
||||
|
||||
@ -34,7 +34,7 @@ Alternatively, you can set the locktime to a smaller number representing a block
|
||||
|
||||
Once you've figured out the current height, you can decide how far in the future to set your locktime to. Remember that on average a new block will be created every 10 minutes. So, for example, if you wanted to set the locktime to a week in the future, you'd choose a block height that is 6 x 24 x 7 = 1,008 blocks in advance of the current one.
|
||||
|
||||
> :book: _Why Would I Use a Blockheight?_ Unlike with timestamps, there's no fuzziness for blockheights. If you set a blockheight of 120,000 for your locktime, then there's absolutely no way for it to go into block 119,999. This can make it easier to algorithmically control your locktimed transaction. The downside is that you can't be as sure of when precisely the locktime will be.
|
||||
> :book: **_Why Would I Use a Blockheight?_** Unlike with timestamps, there's no fuzziness for blockheights. If you set a blockheight of 120,000 for your locktime, then there's absolutely no way for it to go into block 119,999. This can make it easier to algorithmically control your locktimed transaction. The downside is that you can't be as sure of when precisely the locktime will be.
|
||||
|
||||
> :warning: **WARNING:** If you want to set a block-height locktime, you must set the locktime to less than 500 million. If you set it to 500 million or over, your number will instead be interpreted as a timestamp. Since the UNIX timestamp of 500 million was November 5, 1985, that probably means that your transaction will be put into a block at the miners' first opportunity.
|
||||
|
||||
@ -128,7 +128,7 @@ Cancelling a locktime transaction is _very_ simple: you send a new transactions
|
||||
|
||||
Locktime offers a way to create a transaction that _should_ not be relayable to the network and that _will_ not be accepted into a block until the appropriate time has arrived. In the meantime, it can be cancelled simply by reusing a UTXO.
|
||||
|
||||
> :fire: _What is the Power of Locktime?_ The power of locktime may not be immediately obvious because of the ability to cancel it so easily. However, it's another of the bases of Smart Contracts: it has a lot of utility in a variety of custodial or contractual applications. For example, consider a situation where a third party is holding your bitcoins. In order to guarantee the return of your bitcoins if the custodian ever disappeared, they could produce a timelock transition to return the coins to you, then update that every once in a while with a new one, further in the future. If they ever failed to update, then the coins would return to you when the current timelock expired. Locktime could similarly be applied to a payment network, where the network holds coins while they're being exchanged by network participants. Finally, a will offers an example of a more complex contract, where payments are sent out to a number of people. These payments would be built on locktime transactions, and would be continually updated as long as the owner continues to show signs of life. (The unifying factor of all of these applications is, of course, _trust_. Simple locktime transactions only work if the holder of the coins can be trusted to send them out under the appropriate conditions.)
|
||||
> :fire: **_What is the Power of Locktime?_** The power of locktime may not be immediately obvious because of the ability to cancel it so easily. However, it's another of the bases of Smart Contracts: it has a lot of utility in a variety of custodial or contractual applications. For example, consider a situation where a third party is holding your bitcoins. In order to guarantee the return of your bitcoins if the custodian ever disappeared, they could produce a timelock transaction to return the coins to you, then update that every once in a while with a new one, further in the future. If they ever failed to update, then the coins would return to you when the current timelock expired. Locktime could similarly be applied to a payment network, where the network holds coins while they're being exchanged by network participants. Finally, a will offers an example of a more complex contract, where payments are sent out to a number of people. These payments would be built on locktime transactions, and would be continually updated as long as the owner continues to show signs of life. (The unifying factor of all of these applications is, of course, _trust_. Simple locktime transactions only work if the holder of the coins can be trusted to send them out under the appropriate conditions.)
|
||||
|
||||
## What's Next?
|
||||
|
||||
|
@ -114,7 +114,7 @@ You may note a warning about the data being in an "unknown protocol". If you wer
|
||||
|
||||
You can use an `OP_RETURN` opcode to store up to 80 bytes of data on the blockchain. You do this with the `data` codeword for a `vout`. You still have to send money along too, but you just send it back to a change address, minus a transaction fee.
|
||||
|
||||
> :fire: _What is the Power of OP_RETURN?_ The OP_RETURN opens up whole new possibilities for the blockchain, because you can embed data that proves that certain things happened at certain times. Various organizations have used OP_RETURNs for proof of existence, for copyright, for colored coins, and [for other purposes](https://en.bitcoin.it/wiki/OP_RETURN). Though 80 bytes might not seem a lot, it can be quite effective if OP_RETURNs are used to store hashes of the actual data. Then, you can prove the existence of your digital data by deminstrating that the hash of it matches the hash on the blockchain.
|
||||
> :fire: _What is the Power of OP_RETURN?_ The OP_RETURN opens up whole new possibilities for the blockchain, because you can embed data that proves that certain things happened at certain times. Various organizations have used OP_RETURNs for proof of existence, for copyright, for colored coins, and [for other purposes](https://en.bitcoin.it/wiki/OP_RETURN). Though 80 bytes might not seem a lot, it can be quite effective if OP_RETURNs are used to store hashes of the actual data. Then, you can prove the existence of your digital data by demonstrating that the hash of it matches the hash on the blockchain.
|
||||
|
||||
Note that there is some controversy over using the Bitcoin blockchain in this way.
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
To date, we've been interacting with Bitcoin at a relatively high level of abstraction. The `bitcoin-cli` program offers access to a variety of RPC commands that support the creation and control of raw Bitcoin transactions that include funds, data, timelocks, and multisigs.
|
||||
|
||||
However, Bitcoin offers much more complexity than that. It includes a simple scripting language that can be used to create even more complex redemption conditions. If multisigs and timelocks provided the bases of Smart Contracts, then Bitcoin Script builds high on that foundation. It's the next step in empowering Bitcoin.
|
||||
However, Bitcoin offers much more complexity than that. It includes a simple scripting language that can be used to create even more complex redemption conditions. If multisigs and timelocks provided the basis of Smart Contracts, then Bitcoin Script builds high on that foundation. It's the next step in empowering Bitcoin.
|
||||
|
||||
## Objectives for This Chapter
|
||||
|
||||
@ -22,6 +22,6 @@ Supporting objectives include the ability to:
|
||||
|
||||
* [Section One: Understanding the Foundation of Transactions](09_1_Understanding_the_Foundation_of_Transactions.md)
|
||||
* [Section Two: Running a Bitcoin Script](09_2_Running_a_Bitcoin_Script.md)
|
||||
* [Section Three: Scripting a P2PKH](09_3_Scripting_a_P2PKH.md)
|
||||
* [Section Four: Testing a Bitcoin Script](09_4_Testing_a_Bitcoin_Script.md)
|
||||
* [Section Three: Testing a Bitcoin Script](09_3_Testing_a_Bitcoin_Script.md)
|
||||
* [Section Four: Scripting a P2PKH](09_4_Scripting_a_P2PKH.md)
|
||||
* [Section Five: Scripting a P2WPKH](09_5_Scripting_a_P2WPKH.md)
|
||||
|
@ -4,20 +4,20 @@ The foundation of Bitcoin is the ability to protect transactions, something that
|
||||
|
||||
## Know the Parts of the Cryptographic Puzzle
|
||||
|
||||
As described in [Chapter 1](01_0_Introducing_Bitcoin.md), the funds in each Bitcoin transaction are locked with a cryptographic puzzle. To be precise, we said that Bitcoin is made up of "a sequence of atomic transactions". We noted that: "Each transaction is authenticated by a sender with the solution to a previous cryptographic puzzle that was stored as a script. The new transaction is locked for the recipient with a new cryptographic puzzle that is also stored as a script." Those scripts, which lock and unlock transactions, are written in Bitcoin Script.
|
||||
As described in [Chapter 1](01_0_Introduction.md), the funds in each Bitcoin transaction are locked with a cryptographic puzzle. To be precise, we said that Bitcoin is made up of "a sequence of atomic transactions". We noted that: "Each transaction is authenticated by a sender with the solution to a previous cryptographic puzzle that was stored as a script. The new transaction is locked for the recipient with a new cryptographic puzzle that is also stored as a script." Those scripts, which lock and unlock transactions, are written in Bitcoin Script.
|
||||
|
||||
> :book: ***What is Bitcoin Script?*** Bitcoin Script is a stack-based Forth-like language that purposefully avoids loops and so is not Turing-complete. It's made up of individual opcodes. Every single transaction in Bitcoin is locked with a Bitcoin Script; when the locking transaction for a UTXO is run with the correct inputs, that UTXO can then be spent.
|
||||
|
||||
The fact that transactions are locked with scripts means that they can be locked in a variety of different ways, requiring a variety of different keys. In fact, we've met a number of different locking mechanisms to date, each of which used different opcodes:
|
||||
|
||||
* OP_CHECKSIG, which checks a public key against a signature, is the basis of the classic P2PKH address, as will be fully detailed in [§9.3: Scripting a P2PKH](09_3_Scripting_a_P2PKH.md).
|
||||
* OP_CHECKSIG, which checks a public key against a signature, is the basis of the classic P2PKH address, as will be fully detailed in [§9.3: Scripting a P2PKH](09_4_Scripting_a_P2PKH.md).
|
||||
* OP_CHECKMULTISIG similarly checks multisigs, as will be fully detailed in [§10.4: Scripting a Multisig](10_4_Scripting_a_Multisig.md).
|
||||
* OP_CHECKLOCKTIMEVERIFY and OP_SEQUENCEVERIFY form the basis of more complex Timelocks, as will be fully detailed in [§11.2: Using CLTV in Scripts](11_2_Using_CLTV_in_Scripts) and [§11.3: Using CSV in Scripts](11_3_Using_CSV_in_Scripts.md).
|
||||
* OP_CHECKLOCKTIMEVERIFY and OP_SEQUENCEVERIFY form the basis of more complex Timelocks, as will be fully detailed in [§11.2: Using CLTV in Scripts](11_2_Using_CLTV_in_Scripts.md) and [§11.3: Using CSV in Scripts](11_3_Using_CSV_in_Scripts.md).
|
||||
* OP_RETURN is the mark of an unspendable transaction, which is why it's used to carry data, as was alluded to in [§8.2: Sending a Transaction with Data](08_2_Sending_a_Transaction_with_Data.md).
|
||||
|
||||
## Access Scripts In Your Transactions
|
||||
|
||||
You may not realize it, but you've already seen these locking and unlocking scripts as part of the raw transactins you've been working with. The best way to look into these scripts in more depth is thus to create a raw transaction, then examine it.
|
||||
You may not realize it, but you've already seen these locking and unlocking scripts as part of the raw transactions you've been working with. The best way to look into these scripts in more depth is thus to create a raw transaction, then examine it.
|
||||
|
||||
### Create a Test Transaction
|
||||
|
||||
|
@ -12,7 +12,7 @@ Bitcoin Scripts are run from left to right. That sounds easy enough, because it'
|
||||
|
||||
For example, if you were adding together "1" and "2", your Bitcoin Script for that would be `1 2 OP_ADD`, _not_ "1 + 2". Since we know that OP_ADD operator takes two inputs, we know that the two inputs before it are its operands.
|
||||
|
||||
> :warning: **WARNING:** Technically, everything in Bitcoin Script is an opcode, thus it would be most appropriate to record the above example as `OP_1 OP_2 OP_ADD`. In our examples, we don't worry about how the constants will be evaluated, as that's a topic of translation, as is explained in [§8.2: Building the Structure of P2SH](08_2_Building_the_Structure_of_P2SH.md). Some writers prefer to also leave the "OP" prefix off all operators, but we have opted not to.
|
||||
> :warning: **WARNING:** Technically, everything in Bitcoin Script is an opcode, thus it would be most appropriate to record the above example as `OP_1 OP_2 OP_ADD`. In our examples, we don't worry about how the constants will be evaluated, as that's a topic of translation, as is explained in [§10.2: Building the Structure of P2SH](10_2_Building_the_Structure_of_P2SH.md). Some writers prefer to also leave the "OP" prefix off all operators, but we have opted not to.
|
||||
|
||||
### Understand the Stack
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Bitcoin Scripting allows for considerable additional control over Bitcoin transactions, but it's also somewhat dangerous. As we'll describe in [§10.1](10_1_Understanding_the_Foundation_of_P2SH.md), the actual Scripts are somewhat isolated from the Bitcoin network, which means that it's possible to write a script and have it accepted by the network even if it's impossible to redeem from that script! So, you need to thoroughly test your Scripts before you put your money into them.
|
||||
|
||||
This chapter thus describes a prime method for testing Bitcoin Scripts, which we'll also be using for occasional examples throughout the rest of this Part.
|
||||
This chapter thus describes a prime method for testing Bitcoin Scripts, which we'll also be using for occasional examples throughout the rest of this section.
|
||||
|
||||
## Install btcdeb
|
||||
|
||||
@ -96,9 +96,9 @@ script | stack
|
||||
--------+--------
|
||||
| 03
|
||||
```
|
||||
And that's where our script ends, with nothing more to execute and an `03` sitting on top of our stack as the result of the Script.
|
||||
And that's where our script ends, with nothing more to execute and a `03` sitting on top of our stack as the result of the Script.
|
||||
|
||||
> :note: **NOTE:** `btcdeb` allows you to repeat the previous command by hitting enter. We will be doing this in subsequent examples, so don't be surprised about `btcdeb>` prompts with nothing as input. It is simply repeating the previous (often `step`) command.
|
||||
> **NOTE:** `btcdeb` allows you to repeat the previous command by hitting enter. We will be doing this in subsequent examples, so don't be surprised about `btcdeb>` prompts with nothing as input. It is simply repeating the previous (often `step`) command.
|
||||
|
||||
### Use btcdeb for a Subtraction Example
|
||||
|
||||
@ -182,11 +182,13 @@ btcdeb> stack
|
||||
```
|
||||
Using these commands can make it easier to see what's going on and where you are.
|
||||
|
||||
> :warning: **WARNING:** `btcdeb` is much more complex to use if you are trying to verify signatures. See [Signature Checking with btcdeb](https://github.com/bitcoin-core/btcdeb/blob/master/doc/btcdeb.md#signature-checking). This is true for any script testing, so we don't suggest it if you're trying to verify an `OP_CHECKSIG` or an `OP_CHECKMULTISIG`.
|
||||
|
||||
## Test a Script Online
|
||||
|
||||
There are also a few web simulators that you can use to test scripts online. They can be superior to a command-line tool by offering a more graphical output, but we also find that they tend to have shortcomings.
|
||||
|
||||
In the past we've tried to give extensive guidelines on using sites such as the [Script Playground](http://www.crmarsh.com/script-playground/) or the [Bitcoin Online Script Debugger](https://bitcoin-script-debugger.visvirial.com/), but they become out of date and/or disappear too quickly to keep up with them.
|
||||
In the past we've tried to give extensive guidelines on using sites such as the [Script Playground](http://www.crmarsh.com/script-playground/) or the [Bitcoin Online Script Debugger](https://bitcoin-script-debugger.visvirial.com/), but they become out of date and/or disappeared too quickly to keep up with them.
|
||||
|
||||
Assume that these debuggers have the nice advantage of showing things visually and explicitly telling you whether a script succeeds (unlocks) or fails (stays locked). Assume that they have disadvantages with signatures, where many of them either always return `true` for signature tests or else have very cumbersome mechanisms for incorporating them.
|
||||
|
||||
|
@ -45,7 +45,7 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$signedtx
|
||||
]
|
||||
}
|
||||
```
|
||||
You can see that its `scriptSig` unlocking script has two values. That's a `<signature>` (and an `[all]`) and a `<pubKey>`:
|
||||
You can see that its `scriptSig` unlocking script has two values. That's a `<signature>` (and an `[ALL]`) and a `<pubKey>`:
|
||||
```
|
||||
304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b
|
||||
```
|
||||
@ -346,7 +346,7 @@ error: Signature is found in scriptCode
|
||||
```
|
||||
(Unfortunately this checking may or may not be working at any point due to vagaries of the Bitcoin Core and `btcdeb` code.)
|
||||
|
||||
As is shown, a P2PKH is quite simple: its protection comes about those the strength of its cryptography.
|
||||
As is shown, a P2PKH is quite simple: its protection comes about through the strength of its cryptography.
|
||||
|
||||
### How to Look Up a Pub Key & Signature by Hand
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
P2PKHs are fine for explaining the fundamental way that Bitcoin Scripts work, but what about native Segwit P2WPKH scripts, which are increasingly becoming the majority of Bitcoin transactions? As it turns out, P2WPKH addresses don't use Bitcoin Scripts like traditional Bitcoin addresses do, and so this section is really a digression from the scripting of this chapter — but an important one, because it outlines the _other_ major way in which Bitcoins can be transacted.
|
||||
P2PKHs are fine for explaining the fundamental way that Bitcoin Scripts work, but what about native SegWit P2WPKH scripts, which are increasingly becoming the majority of Bitcoin transactions? As it turns out, P2WPKH addresses don't use Bitcoin Scripts like traditional Bitcoin addresses do, and so this section is really a digression from the scripting of this chapter — but an important one, because it outlines the _other_ major way in which Bitcoins can be transacted.
|
||||
|
||||
## View a P2WPKH Script
|
||||
|
||||
@ -63,7 +63,7 @@ Here's a comparison of our two examples:
|
||||
| Type | PubKeyHash | PubKey | Signature |
|
||||
|----------------|----------|-------------|---------|
|
||||
| SegWit | 92a0db923b3a13eb576a40c4b35515aa30206cba | 03839e6035b33e37597908c83a2f992ec835b093d65790f43218cb49ffe5538903 | 3044022064f633ccfc4e937ef9e3edcaa9835ea9a98d31fbea1622c1d8a38d4e7f8f6cb602204bffef45a094de1306f99da055bd5a603a15c277a59a48f40a615aa4f7e5038001 |
|
||||
| SegWit | 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | 04402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c |
|
||||
| non-SegWit | 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | 04402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c |
|
||||
|
||||
So how does this work? It depends on old code interpreting this as a valid transaction and new code knowing to check the new "witness" information
|
||||
|
||||
@ -96,7 +96,7 @@ script | sta
|
||||
```
|
||||
Bitcoin Scripts are considered successful if there's something in the Stack, and it's non-zero, so SegWit scripts automatically succeed on old nodes as long as the `scriptPubKey` is correctly created with a non-zero pub-key hash. This is called an "anyone-can-spend" transaction, because old nodes verified them as correct without any need for signatures.
|
||||
|
||||
> :book: ***What can't old nodes steal SegWit UTXOs?*** SegWit was enabled on the Bitcoin network when 95% of miners signalled that they were ready to start using it. That means that only 5% of nodes at that point might have registered anyone-can-spend SegWit transactions as valid without going through the proper work of checking the `txinwitness`. If they incorrectly incorporated an invalid anyone-can-spend UTXO into a block, the other 95% of nodes would refuse to validate that block, and so it would quickly be orphaned rather than being added to the "main" blockchain. (Certainly, 51% of nodes could choose to stop interpreting SegWit transactions correctly, but 51% of nodes can do anything on a consensus network like a blockchain.)
|
||||
> :book: ***Why can't old nodes steal SegWit UTXOs?*** SegWit was enabled on the Bitcoin network when 95% of miners signalled that they were ready to start using it. That means that only 5% of nodes at that point might have registered anyone-can-spend SegWit transactions as valid without going through the proper work of checking the `txinwitness`. If they incorrectly incorporated an invalid anyone-can-spend UTXO into a block, the other 95% of nodes would refuse to validate that block, and so it would quickly be orphaned rather than being added to the "main" blockchain. (Certainly, 51% of nodes could choose to stop interpreting SegWit transactions correctly, but 51% of nodes can do anything on a consensus network like a blockchain.)
|
||||
|
||||
Because old nodes always see SegWit scripts as correct, they will always verify them, even without understanding their content.
|
||||
|
||||
|
@ -8,8 +8,8 @@ Here's the gotcha for using Bitcoin Scripts: for security reasons, most Bitcoin
|
||||
|
||||
* __Pay to Public Key (P2PK)__ — An older, deprecated transaction (`<pubKey> OP_CHECKSIG`) that has been replaced by the better security of P2PKH.
|
||||
* __Pay to Public Key Hash (P2PKH)__ — A standard transaction (`OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG`) that pays to the hash of a public key.
|
||||
* __Pay to Witness Public Key hash (P2WPKH)__ — The newest sort of public-key transaction. It's just (`OP_0 <pubKeyHash`) because it depends on miner consensus to work, as described in [§9.5](09_5_Scripting_a_P2WPKH.md).
|
||||
* __Multisig__ — A transaction for a group of keys, as explained more fully in [§8.4](08_4_Scripting_a_Multisig.md).
|
||||
* __Pay to Witness Public Key hash (P2WPKH)__ — The newest sort of public-key transaction. It's just (`OP_0 <pubKeyHash>`) because it depends on miner consensus to work, as described in [§9.5](09_5_Scripting_a_P2WPKH.md).
|
||||
* __Multisig__ — A transaction for a group of keys, as explained more fully in [§10.4](10_4_Scripting_a_Multisig.md).
|
||||
* __Null Data__ — An unspendable transaction (`OP_RETURN Data`).
|
||||
* __Pay to Script Hash (P2SH)__ — A transaction that pays out to a specific script, as explained more fully here.
|
||||
|
||||
@ -19,7 +19,7 @@ So how do you write a more complex Bitcoin Script? The answer is in that last so
|
||||
|
||||
## Understand the P2SH Script
|
||||
|
||||
You already saw a P2SH transaction when you created a multisig in [§6.1: Sending a Transaction to a Multisig](06_1_Sending_a_Transaction_to_a_Multisig.md). Though multisig is one of the standard transaction types, `bitcoin-cli` simplifies the usage of its multisigs by embedding them into P2SH transactions, as described more fully in [§8.4: Scripting a Multisig](08_4_Scripting_a_Multisig.md).
|
||||
You already saw a P2SH transaction when you created a multisig in [§6.1: Sending a Transaction to a Multisig](06_1_Sending_a_Transaction_to_a_Multisig.md). Though multisig is one of the standard transaction types, `bitcoin-cli` simplifies the usage of its multisigs by embedding them into P2SH transactions, as described more fully in [§10.4: Scripting a Multisig](10_4_Scripting_a_Multisig.md).
|
||||
|
||||
So, let's look one more time at the `scriptPubKey` of that P2SH multisig:
|
||||
```
|
||||
@ -84,7 +84,7 @@ When a UTXO is redeemed, it runs in two rounds of verification:
|
||||
3. Second, the `redeemScript` is run using the prior data that was pushed on the stack.
|
||||
4. If that second round of verification _also_ succeeds, the UTXO is unlocked.
|
||||
|
||||
Whereas you can't easily create a P2SH transaction without an API, you should be able to easily redeem a P2SH transaction with `bitcoin-cli`. In fact, you already did in [§6.2: Sending a Transaction to a Multisig](06_2_Spending_a_Transaction_to_a_Multisig.md). The exact process is described in [§10.6: Spending a P2SH Transaction.md](10_6_Spending_a_P2SH_Transaction.md), after we've finished with all the intricacies of P2SH transaction creation.
|
||||
Whereas you can't easily create a P2SH transaction without an API, you should be able to easily redeem a P2SH transaction with `bitcoin-cli`. In fact, you already did in [§6.2: Sending a Transaction to a Multisig](06_2_Spending_a_Transaction_to_a_Multisig.md). The exact process is described in [§10.6: Spending a P2SH Transaction](10_6_Spending_a_P2SH_Transaction.md), after we've finished with all the intricacies of P2SH transaction creation.
|
||||
|
||||
> :warning: **WARNING:** You can create a perfectly valid transaction with a correcly hashed redeemScript, but if the redeemScript doesn't run, or doesn't run correctly, your funds are lost forever. That's why it is so important to test your Scripts, as discussed in [§9.3: Testing a Bitcoin Script](09_3_Testing_a_Bitcoin_Script.md).
|
||||
|
||||
|
@ -6,7 +6,7 @@ In the previous section we overviewed the theory of how to create P2SH transacti
|
||||
|
||||
Any P2SH transaction starts with a locking script. This is the subject of chapters 9 and 11-12. You can use any of the Bitcoin Script methods described therein to create any sort of locking script, as long as the resulting serialized `redeemScript` is 520 bytes or less.
|
||||
|
||||
> :book: ***Why are P2SH scripts limited to 520 bytes?*** As with many things in Bitcoin, the answer is backward compatibility: new functionality has to constantly be built within the old constraints of the system. Is this case, 520 bytes is the maximum that can be pushed onto the stack at once. Since the whole redeemScript is pushed onto the stack as part of the redemption process, it hits that limit.
|
||||
> :book: ***Why are P2SH scripts limited to 520 bytes?*** As with many things in Bitcoin, the answer is backward compatibility: new functionality has to constantly be built within the old constraints of the system. In this case, 520 bytes is the maximum that can be pushed onto the stack at once. Since the whole redeemScript is pushed onto the stack as part of the redemption process, it hits that limit.
|
||||
|
||||
## Serialize a Locking Script the Hard Way
|
||||
|
||||
@ -30,7 +30,7 @@ The integers are the most troublesome part of a locking-script translation.
|
||||
|
||||
First, you should verify that your number falls between -2147483647 and 2147483647, the range of four-byte integers when the most significant byte is used for signing.
|
||||
|
||||
Second, you need to translate the decimal value into hexidecimal and pad it out to an even number of digits. This can be done with the `printf` command:
|
||||
Second, you need to translate the decimal value into hexadecimal and pad it out to an even number of digits. This can be done with the `printf` command:
|
||||
```
|
||||
$ integer=1546288031
|
||||
$ hex=$(printf '%08x\n' $integer | sed 's/^\(00\)*//')
|
||||
@ -48,7 +48,7 @@ $ lehex=$(echo $hex | tac -rs .. | echo "$(tr -d '\n')")
|
||||
$ echo $lehex
|
||||
9f7b2a5c
|
||||
```
|
||||
In addition, you always need to know the size of any data that you put on the stack, so that you can precede it with the proper opcode. You can just remember that every two hexidecimal characters is one byte. Or, you can use `echo -n` piped to `wc -c`, and divide that in half:
|
||||
In addition, you always need to know the size of any data that you put on the stack, so that you can precede it with the proper opcode. You can just remember that every two hexadecimal characters is one byte. Or, you can use `echo -n` piped to `wc -c`, and divide that in half:
|
||||
```
|
||||
$ echo -n $lehex | wc -c | awk '{print $1/2}'
|
||||
4
|
||||
@ -67,7 +67,7 @@ To complete your serialization, you translate the hexcode into binary. On the co
|
||||
|
||||
## Run The Integer Conversion Script
|
||||
|
||||
A complete script for changing an integer between -2147483647 and 2147483647 to a little-endian signed-magnitude representation in hex can be found in th e[src code directory](src/10_2_integer2lehex.sh). You can download it as `integeer2lehex.sh`.
|
||||
A complete script for changing an integer between -2147483647 and 2147483647 to a little-endian signed-magnitude representation in hex can be found in the [src code directory](src/10_2_integer2lehex.sh). You can download it as `integer2lehex.sh`.
|
||||
|
||||
> :warning: **WARNING:** This script has not been robustly checked. If you are going to use it to create real locking scripts you should make sure to double-check and test your results.
|
||||
|
||||
@ -165,13 +165,13 @@ $ echo -n $redeemScript | xxd -r -p | openssl dgst -sha256 -binary | openssl dgs
|
||||
```
|
||||
## Create a P2SH Transaction
|
||||
|
||||
Creating your 20-bit hash just gives you the hash at the center of a P2SH locking script. You still need to put it together with the other opcodes that create a standard P2SH transaction: `OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL`.
|
||||
Creating your 20-byte hash just gives you the hash at the center of a P2SH locking script. You still need to put it together with the other opcodes that create a standard P2SH transaction: `OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL`.
|
||||
|
||||
Depending on your API, you might be able to enter this as an `asm`-style `scriptPubKey` for your transaction, or you might have to translate it to `hex` code as well. If you have to translate, use the same methods described above for "Creating the Hex Code" (or use `btcc`), resulting in `a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387`.
|
||||
|
||||
Note that the `hex scriptPubKey` for P2SH Script transaction will _always_ start with an `a914`, which is the `OP_HASH160` followed by an `OP_PUSHDATA` of 20 bytes (hex: `0x14`); and it will _always_ end with a `87`, which is an `OP_EQUAL`. So all you have to do is put your hashed redeem script in between those numbers.
|
||||
|
||||
## Summary: Understanding the Foundation of P2SH
|
||||
## Summary: Building the Structure of P2SH
|
||||
|
||||
Actually creating the P2SH locking script dives further into the guts of Bitcoin than you've ever gone before. Though it's helpful to know how all of this works at a very low level, it's most likely that you'll have an API taking care of all of the heavy-lifting for you. Your task will simply be to create the Bitcoin Script to do the locking ... which is the main topic of chapters 9 and 11-12.
|
||||
|
||||
|
@ -10,7 +10,7 @@ Multisig transactions are created in Bitcoin using the `OP_CHECKMULTISIG` code.
|
||||
2. Pop "n" values from the stack as Bitcoin addresses (hashed public keys).
|
||||
3. Pop the next value from the stack (`<m>`).
|
||||
4. Pop "m" values from the stack as potential signatures.
|
||||
5. Pop an `0` from the stack due to a mistake in the original coding.
|
||||
5. Pop a `0` from the stack due to a mistake in the original coding.
|
||||
6. Compare the signatures to the Bitcoin adddresses.
|
||||
7. Push a `True` or `False` depending on the result.
|
||||
|
||||
@ -22,15 +22,15 @@ The requirement for that `0` as the first operand for `OP_CHECKMULTISIG` is a co
|
||||
|
||||
## Create a Raw Multisig
|
||||
|
||||
As discussed in [§10.1: Building a Bitcoin Script with P2SH](10_1_Building_a_Bitcoin_Script_with_P2SH.md), multisigs are one of the standard Bitcoin transaction types. A transaction can be created with a locking script that uses the raw `OP_CHECKMULTISIG` command, and it will be accepted into a block. This is the classic methodology for using multisigs in Bitcoin.
|
||||
As discussed in [§10.1: Understanding the Foundation of P2SH](10_1_Understanding_the_Foundation_of_P2SH.md), multisigs are one of the standard Bitcoin transaction types. A transaction can be created with a locking script that uses the raw `OP_CHECKMULTISIG` command, and it will be accepted into a block. This is the classic methodology for using multisigs in Bitcoin.
|
||||
|
||||
As an example, we will revisit the multisig created in [§8.1](08_1_Sending_a_Transaction_to_a_Multisig.md) one final time and build a new locking script for it using this methodology. As you may recall, that was a 2-of-2 multisig built from `$address1` and `$address2`.
|
||||
As an example, we will revisit the multisig created in [§6.1](06_1_Sending_a_Transaction_to_a_Multisig.md) one final time and build a new locking script for it using this methodology. As you may recall, that was a 2-of-2 multisig built from `$address1` and `$address2`.
|
||||
|
||||
As as `OP_CHECKMULTISIG` locking script requires the "m" (`2`), the addresses, and the "n" (`2`), you could write the following `scriptPubKey`:
|
||||
As `OP_CHECKMULTISIG` locking script requires the "m" (`2`), the addresses, and the "n" (`2`), you could write the following `scriptPubKey`:
|
||||
```
|
||||
2 $address1 $address2 2 OP_CHECKMULTISIG
|
||||
```
|
||||
If this looks familiar, that's because it's the multisig that you deserialized in [§8.2: Building the Structure of P2SH](08_2_Building_the_Structure_of_P2SH.md).
|
||||
If this looks familiar, that's because it's the multisig that you deserialized in [§10.2: Building the Structure of P2SH](10_2_Building_the_Structure_of_P2SH.md).
|
||||
```
|
||||
2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG
|
||||
```
|
||||
@ -99,7 +99,7 @@ These were generally problems with any sort of complex Bitcoin script, but they
|
||||
|
||||
## Create a P2SH Multisig
|
||||
|
||||
P2SH multisigs are the modern methodology for creating multisigs on the Blockchains. They can be created very simply, using the same process seen in the previous sections.
|
||||
P2SH multisigs are the modern methodology for creating multisigs on the Blockchain. They can be created very simply, using the same process seen in the previous sections.
|
||||
|
||||
### Create the Lock for the P2SH Multisig
|
||||
|
||||
@ -142,7 +142,7 @@ Now you know how the multisig transaction in [§6.1](06_1_Sending_a_Transaction_
|
||||
|
||||
## Summary: Creating Multisig Scripts
|
||||
|
||||
Multisigs are a standard transaction type, but they're a bit cumbersome to use, so they're regularly incorporated in P2SH transactions, as was the case in [§6.1](6_1_Sending_a_Transaction_to_a_Multisig.md) when we created our first multisigs. The result is cleaner, smaller, and more standardized — but more importantly, it's a great real-world example of how P2SH scripts really work.
|
||||
Multisigs are a standard transaction type, but they're a bit cumbersome to use, so they're regularly incorporated in P2SH transactions, as was the case in [§6.1](06_1_Sending_a_Transaction_to_a_Multisig.md) when we created our first multisigs. The result is cleaner, smaller, and more standardized — but more importantly, it's a great real-world example of how P2SH scripts really work.
|
||||
|
||||
## What's Next?
|
||||
|
||||
|
@ -36,66 +36,70 @@ $ bitcoin-cli listunspent
|
||||
"safe": true
|
||||
}
|
||||
```
|
||||
More importantly, there's a `redeemScript`, which decodes to `OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a`. The should look familiar, because it's an `OP_0` followed by 20-byte hexcode of a public key hash. In other words, a P2SH-SegWit is just a SegWit `scriptPubKey` jammed into a script. That's all there is to it. It precisely matches how modern multisigs are a multsig jammed into a P2SH, as discussed in [§10.4: Scripting a Multisig](10_4_Scripting_a_Multisig.md).
|
||||
More importantly, there's a `redeemScript`, which decodes to `OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a`. This should look familiar, because it's an `OP_0` followed by 20-byte hexcode of a public key hash. In other words, a P2SH-SegWit is just a SegWit `scriptPubKey` jammed into a script. That's all there is to it. It precisely matches how modern multisigs are a multsig placed inside a P2SH, as discussed in [§10.4: Scripting a Multisig](10_4_Scripting_a_Multisig.md).
|
||||
|
||||
The raw transaction reveals a bit more when you look at the `vout` `1`:
|
||||
Conversely, when we spend this transaction, it looks exactly like a P2SH:
|
||||
```
|
||||
$ hex=$(bitcoin-cli gettransaction "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa" | jq -r '.hex')
|
||||
$ bitcoin-cli decoderawtransaction $hex
|
||||
$ bitcoin-cli getrawtransaction ed752673bfd4338ccf0995983086da846ad652ae0f28280baf87f9fd44b3c45f 1
|
||||
{
|
||||
"txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa",
|
||||
"hash": "6866490b16a92d68179e1cf04380fd08f16ec80bf66469af8d5e78ae624ff202",
|
||||
"txid": "ed752673bfd4338ccf0995983086da846ad652ae0f28280baf87f9fd44b3c45f",
|
||||
"hash": "aa4b1c2bde86ea446c9a9db2f77e27421316f26a8d88869f5b195f03b1ac4f23",
|
||||
"version": 2,
|
||||
"size": 249,
|
||||
"vsize": 168,
|
||||
"weight": 669,
|
||||
"locktime": 1780788,
|
||||
"size": 247,
|
||||
"vsize": 166,
|
||||
"weight": 661,
|
||||
"locktime": 1781316,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "4779bb137ddbcaf796f905e264554b1ec28c0f3ab4538ca02eac5099bfc3fc1e",
|
||||
"vout": 0,
|
||||
"txid": "59178b02cfcbdee51742a4b2658df35b63b51115a53cf802bc6674fd94fa593a",
|
||||
"vout": 1,
|
||||
"scriptSig": {
|
||||
"asm": "0014c4ea10874ae77d957e170bd43f2ee828a8e3bc71",
|
||||
"hex": "160014c4ea10874ae77d957e170bd43f2ee828a8e3bc71"
|
||||
"asm": "00149ef51fb1f5adb44e20eff758d34ae64fa781fa4f",
|
||||
"hex": "1600149ef51fb1f5adb44e20eff758d34ae64fa781fa4f"
|
||||
},
|
||||
"txinwitness": [
|
||||
"3044022025ee4fd38e6865125f7c315406c0b3a8139d482e3be333727d38868baa656d3d02204b35d9b5812cb85894541da611d5cec14c374ae7a7b8ba14bb44495747b5715301",
|
||||
"033cae26cb3fa063c95e2c55a94bd04ab9cf173104555efe448b1bfc3a68c8f873"
|
||||
"3044022069a23fcfc421b44c622d93b7639a2152f941dbfd031970b8cef69e6f8e97bd46022026cb801f38a1313cf32a8685749546a5825b1c332ee4409db82f9dc85d99086401",
|
||||
"030aec1384ae0ef264718b8efc1ef4318c513403d849ea8466ef2e4acb3c5ccce6"
|
||||
],
|
||||
"sequence": 4294967294
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00095000,
|
||||
"value": 8.49029534,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"hex": "76a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac",
|
||||
"asm": "OP_HASH160 b4b656f4c4b14ee0d098299d1d6eb42d2e22adcd OP_EQUAL",
|
||||
"hex": "a914b4b656f4c4b14ee0d098299d1d6eb42d2e22adcd87",
|
||||
"reqSigs": 1,
|
||||
"type": "pubkeyhash",
|
||||
"type": "scripthash",
|
||||
"addresses": [
|
||||
"mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9"
|
||||
"2N9ik3zihJ91VGNF55sZFe9GiCAXh2cVKKW"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": 0.01063793,
|
||||
"value": 0.00095000,
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_HASH160 b780fc2e945bea71b9ee2d8d2901f00914a25fbd OP_EQUAL",
|
||||
"hex": "a914b780fc2e945bea71b9ee2d8d2901f00914a25fbd87",
|
||||
"asm": "OP_HASH160 ee7aceea0865a05a29a28d379cf438ac5b6cd9c6 OP_EQUAL",
|
||||
"hex": "a914ee7aceea0865a05a29a28d379cf438ac5b6cd9c687",
|
||||
"reqSigs": 1,
|
||||
"type": "scripthash",
|
||||
"addresses": [
|
||||
"2N9yWARt5E3TQsX2RjsauxSZaEZVhinAS4h"
|
||||
"2NEzBvokxh4ME4ahdT18NuSSoYvvhS7EnMU"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"hex": "020000000001013a59fa94fd7466bc02f83ca51511b5635bf38d65b2a44217e5decbcf028b175901000000171600149ef51fb1f5adb44e20eff758d34ae64fa781fa4ffeffffff029e299b320000000017a914b4b656f4c4b14ee0d098299d1d6eb42d2e22adcd87187301000000000017a914ee7aceea0865a05a29a28d379cf438ac5b6cd9c68702473044022069a23fcfc421b44c622d93b7639a2152f941dbfd031970b8cef69e6f8e97bd46022026cb801f38a1313cf32a8685749546a5825b1c332ee4409db82f9dc85d9908640121030aec1384ae0ef264718b8efc1ef4318c513403d849ea8466ef2e4acb3c5ccce6442e1b00",
|
||||
"blockhash": "0000000069cbe44925fab2d472870608c7e1e241a1590fd78be10c63388ed6ee",
|
||||
"confirmations": 282952,
|
||||
"time": 1595360859,
|
||||
"blocktime": 1595360859
|
||||
}
|
||||
```
|
||||
This confirms that this is just a normal P2SH, locked by `"OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG"`. It's when the redeem script is run that the magic occurs. Just as with a P2WPKH, an old node wil see `OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a` and verify it automatically, while a new node will see that, know it's a P2WPKH, and so go out to the `witnesses`. See [§9.5: Scripting a P2WPKH](09_5_Scripting_a_P2WPKH.md).
|
||||
Each `vout` is of the form `OP_HASH160 <HASH> OP_EQUAL`. That's a normal P2SH per [§10.2](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/82ca897286aac612804ae849b260750229fa3a52/10_2_Building_the_Structure_of_P2SH.md), which means that it's only when the redeem script is run that the magic occurs. Just as with a P2WPKH, an old node wil see `OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a` in the redeem script and verify it automatically, while a new node will see that, know it's a P2WPKH, and so go out to the `witnesses`. See [§9.5: Scripting a P2WPKH](09_5_Scripting_a_P2WPKH.md).
|
||||
|
||||
> :book: ***What are the disadvantages of nested Segwit transactions?*** They're bigger than native Segwit transactions, so you get some of advantages of Segwit, but not all of them.
|
||||
|
||||
@ -114,7 +118,7 @@ This works just like a P2WPKH address, the only difference being that instead of
|
||||
|
||||
There is also one more variant, a P2WSH script embedded in a P2SH script, which works much like the P2SH-Segwit described above, but for nested P2WSH scripts. (Whew!)
|
||||
|
||||
## Summary: Scripting a Pay to Witness Public Key Hash
|
||||
## Summary: Scripting a Segwit Script
|
||||
|
||||
There are two sorts of P2SH scripts that relate to Segwit.
|
||||
|
||||
|
@ -4,11 +4,11 @@ Before we close out this overview of P2SH transactions, we're going to touch upo
|
||||
|
||||
## Use the Redeem Script
|
||||
|
||||
As we saw in [§6.2: Spending a Transaction to a Multisig](06_2_Spending_a_Transaction_to_a_Multisig.md), spending a P2SH transaction is all about having that serialized version of the locking script, the so-called _redeemScript_. So, the first step in being able to spend a P2SH transaction is making sure that you save the _redeemScript_ before you give out the P2SH address to everyone.
|
||||
As we saw in [§6.2: Spending a Transaction with a Multisig](06_2_Spending_a_Transaction_to_a_Multisig.md), spending a P2SH transaction is all about having that serialized version of the locking script, the so-called _redeemScript_. So, the first step in being able to spend a P2SH transaction is making sure that you save the _redeemScript_ before you give out the P2SH address to everyone.
|
||||
|
||||
### Collect Your Variables
|
||||
|
||||
Because P2SH addresses other than the special multisig and nested Segwit addresses aren't integrated into `bitcoin-cli` there will be no short-cuts for P2SH spending like you saw in [§6.3: Sending an Automated Multisig](6_3_Sending_an_Automated_Multisig.md). You're going to need to collect all the more complex variables on your own!
|
||||
Because P2SH addresses other than the special multisig and nested Segwit addresses aren't integrated into `bitcoin-cli` there will be no short-cuts for P2SH spending like you saw in [§6.3: Sending an Automated Multisig](06_3_Sending_an_Automated_Multisig.md). You're going to need to collect all the more complex variables on your own!
|
||||
|
||||
This means that you need to collect:
|
||||
|
||||
@ -33,7 +33,7 @@ $ bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[
|
||||
```
|
||||
With any other sort of P2SH you're going to be including a different `redeemscript`, but otherwise the practice is exactly the same. The only difference is that after two chapters of work on Scripts you now understand what the `scriptPubKey` is and what the `redeemScript` is, so hopefully what were mysterious elements four chapters ago are now old hat.
|
||||
|
||||
## Summary: Spending a Transaction with a Bitcoin Script
|
||||
## Summary: Spending a P2SH Transaction
|
||||
|
||||
You already spent a P2SH back in Chapter 6, when you resent a multsig transaction the hard way, which required lining up the `scriptPubKey` and `redeemScript` information. Now you know that the `scriptPubKey` is a standardized P2SH locking script, while the `redeemScript` matches a hash in that locking script and that you need to be able to run it with the proper variables to receive a `True` result. But other than knowing more, there's nothing new in spending a P2SH transaction, because you already did it!
|
||||
|
||||
|
@ -38,7 +38,7 @@ Or this:
|
||||
|
||||
### Understand a CLTV Absolute Block Height
|
||||
|
||||
This is how `OPCHECKLOCKTIMEVERIFY` would check against a blockheight that was reached on May 24, 2017:
|
||||
This is how `OP_CHECKLOCKTIMEVERIFY` would check against a blockheight that was reached on May 24, 2017:
|
||||
```
|
||||
467951 OP_CHECKLOCKTIMEVERIFY
|
||||
```
|
||||
@ -51,7 +51,7 @@ But we'll usually abtract it like this:
|
||||
|
||||
The above explanation is sufficient to use and understand CLTV. However, [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) lays out all the details.
|
||||
|
||||
A locking script will only allow a transaction to respend a UTXO locked with a CLTV if `OP_CHECKLOCKTIMEVALUE` verifies all of the following:
|
||||
A locking script will only allow a transaction to respend a UTXO locked with a CLTV if `OP_CHECKLOCKTIMEVERIFY` verifies all of the following:
|
||||
|
||||
* The `nSequence` field must be set to less than 0xffffffff, usually 0xffffffff-1 to avoid confilcts with relative timelocks.
|
||||
* CLTV must pop an operand off the stack and it must be 0 or greater.
|
||||
@ -146,7 +146,7 @@ Finally, the remainder of the script runs, which is a normal check of a signatur
|
||||
|
||||
## Summary: Using CLTV in Scripts
|
||||
|
||||
`OP-CHECKLOCKTIMEVERIFY` is a simple opcode that looks at a single argument, interprets it as a blockheight or UNIX timestamp, and only allows its UTXO to be unlocked if that blockheight or UNIX timestamp is in the past. Setting `nLockTime` on the spending transaction is what allows Bitcoin to make this calculation.
|
||||
`OP_CHECKLOCKTIMEVERIFY` is a simple opcode that looks at a single argument, interprets it as a blockheight or UNIX timestamp, and only allows its UTXO to be unlocked if that blockheight or UNIX timestamp is in the past. Setting `nLockTime` on the spending transaction is what allows Bitcoin to make this calculation.
|
||||
|
||||
> :fire: ***What is the Power of CLTV?*** You've already seem that simple locktimes were one of the bases of Smart Contracts. CLTV takes the next step. Now you can both guarantee that a UTXO can't be spent before a certain time _and_ guarantee that it won't be spent either. In its simplest form, this could be used to create a trust that someone could only access when they reached 18 or a retirement fund that they could only access when they turned 50. However its true power comes when combined with conditionals, where the CLTV only activates in certain situations.
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
## Understand nSequence
|
||||
|
||||
Every input into in a transaction has an `nSequence` (or if you prefer `sequence`) value. It's been a prime tool for Bitcoin expansions as discussed previously in [§5.2: Resending a Transaction with RBF](05_2_Resending_a_Transaction_with_RBF.md) and [§8.1 Sending a Transaction with a Locktime.md](08_1_Sending_a_Transaction_with_a_Locktime.md), where it was used to signal RBF and `nLockTime`, respectively. However, there's one more use for `nSequence`, described by [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): you can use it to create a relative timelock on a transaction.
|
||||
Every input into a transaction has an `nSequence` (or if you prefer `sequence`) value. It's been a prime tool for Bitcoin expansions as discussed previously in [§5.2: Resending a Transaction with RBF](05_2_Resending_a_Transaction_with_RBF.md) and [§8.1 Sending a Transaction with a Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md), where it was used to signal RBF and `nLockTime`, respectively. However, there's one more use for `nSequence`, described by [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): you can use it to create a relative timelock on a transaction.
|
||||
|
||||
A relative timelock is a lock that's placed on a specific input of a transaction and that's calculated in relation to the mining date of the UTXO being used in the input. For example, if a UTXO was mined at block #468260 and a transaction was created where the input for that UTXO was given an `nSequence` of 100, then the new transaction could not be mined until at least block #468360.
|
||||
|
||||
@ -57,7 +57,7 @@ If you convert that back you'll see that 4224679 = 10000000111011010100111. The
|
||||
|
||||
## Create a Transaction with a Relative Timelock
|
||||
|
||||
So you want to create a simple transaction with a relative timelock? All you have to do is issue a tranaction where the `nSequence` in an input is set as shown above: with the `nSequence` for that input set such that the first two bytes define the timelock, the 23rd bit defines the type of timelock, and the 32nd bit is set to false.
|
||||
So you want to create a simple transaction with a relative timelock? All you have to do is issue a transaction where the `nSequence` in an input is set as shown above: with the `nSequence` for that input set such that the first two bytes define the timelock, the 23rd bit defines the type of timelock, and the 32nd bit is set to false.
|
||||
|
||||
Issue the transaction and you'll see that it can't legally be mined until enough blocks or enough time has passed beyond the time that the UTXO was mined.
|
||||
|
||||
|
@ -18,7 +18,7 @@ Manipulate one number:
|
||||
|
||||
Also see: `OP_0NOTEQUAL` (0x92)
|
||||
|
||||
Manipulate two number mathematically:
|
||||
Manipulate two numbers mathematically:
|
||||
|
||||
* OP_ADD (0x93) — Add two numbers
|
||||
* OP_SUB (0x94) — Subtract two numbers
|
||||
|
@ -177,7 +177,7 @@ script | stack
|
||||
|
||||
What if you wanted to instead write an equation system, such as `x + y = 3`, `y + z = 5`, and `x + z = 4`? A bit of algebra tells you that the answers come out to `x = 1`, `y = 2`, and `z = 3`. But, how do you script it?
|
||||
|
||||
Most obviously, after the redeemer inputs the three numbers, you're going to need two copies of each numbers, since each number goes into two different equations. `OP_3DUP` takes care of that and results in `x y z x y z` being on the stack. Popping off two items at a time will give you `y z`, `z x`, and `x y`. Voila! That's the three equations, so you just need to add them up and test them in the right order! Here's the full script: `OP_3DUP OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL`.
|
||||
Most obviously, after the redeemer inputs the three numbers, you're going to need two copies of each number, since each number goes into two different equations. `OP_3DUP` takes care of that and results in `x y z x y z` being on the stack. Popping off two items at a time will give you `y z`, `z x`, and `x y`. Voila! That's the three equations, so you just need to add them up and test them in the right order! Here's the full script: `OP_3DUP OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL`.
|
||||
|
||||
Here's how it runs with the correct unlocking script of `1 2 3`:
|
||||
```
|
||||
@ -481,7 +481,7 @@ This is a nice script because it shows careful use of logic (with the `OP_NOT` a
|
||||
|
||||
`btcdeb` can be run to prove the collision (and the script):
|
||||
```
|
||||
btcdeb $ btcdeb '[255044462d312e330a25e2e3cfd30a0a0a312030206f626a0a3c3c2f57696474682032203020522f4865696768742033203020522f547970652034203020522f537562747970652035203020522f46696c7465722036203020522f436f6c6f7253706163652037203020522f4c656e6774682038203020522f42697473506572436f6d706f6e656e7420383e3e0a73747265616d0affd8fffe00245348412d3120697320646561642121212121852fec092339759c39b1a1c63c4c97e1fffe017f46dc93a6b67e013b029aaa1db2560b45ca67d688c7f84b8c4c791fe02b3df614f86db1690901c56b45c1530afedfb76038e972722fe7ad728f0e4904e046c230570fe9d41398abe12ef5bc942be33542a4802d98b5d70f2a332ec37fac3514e74ddc0f2cc1a874cd0c78305a21566461309789606bd0bf3f98cda8044629a1 255044462d312e330a25e2e3cfd30a0a0a312030206f626a0a3c3c2f57696474682032203020522f4865696768742033203020522f547970652034203020522f537562747970652035203020522f46696c7465722036203020522f436f6c6f7253706163652037203020522f4c656e6774682038203020522f42697473506572436f6d706f6e656e7420383e3e0a73747265616d0affd8fffe00245348412d3120697320646561642121212121852fec092339759c39b1a1c63c4c97e1fffe017346dc9166b67e118f029ab621b2560ff9ca67cca8c7f85ba84c79030c2b3de218f86db3a90901d5df45c14f26fedfb3dc38e96ac22fe7bd728f0e45bce046d23c570feb141398bb552ef5a0a82be331fea48037b8b5d71f0e332edf93ac3500eb4ddc0decc1a864790c782c76215660dd309791d06bd0af3f98cda4bc4629b1 OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL']
|
||||
$ btcdeb '[255044462d312e330a25e2e3cfd30a0a0a312030206f626a0a3c3c2f57696474682032203020522f4865696768742033203020522f547970652034203020522f537562747970652035203020522f46696c7465722036203020522f436f6c6f7253706163652037203020522f4c656e6774682038203020522f42697473506572436f6d706f6e656e7420383e3e0a73747265616d0affd8fffe00245348412d3120697320646561642121212121852fec092339759c39b1a1c63c4c97e1fffe017f46dc93a6b67e013b029aaa1db2560b45ca67d688c7f84b8c4c791fe02b3df614f86db1690901c56b45c1530afedfb76038e972722fe7ad728f0e4904e046c230570fe9d41398abe12ef5bc942be33542a4802d98b5d70f2a332ec37fac3514e74ddc0f2cc1a874cd0c78305a21566461309789606bd0bf3f98cda8044629a1 255044462d312e330a25e2e3cfd30a0a0a312030206f626a0a3c3c2f57696474682032203020522f4865696768742033203020522f547970652034203020522f537562747970652035203020522f46696c7465722036203020522f436f6c6f7253706163652037203020522f4c656e6774682038203020522f42697473506572436f6d706f6e656e7420383e3e0a73747265616d0affd8fffe00245348412d3120697320646561642121212121852fec092339759c39b1a1c63c4c97e1fffe017346dc9166b67e118f029ab621b2560ff9ca67cca8c7f85ba84c79030c2b3de218f86db3a90901d5df45c14f26fedfb3dc38e96ac22fe7bd728f0e45bce046d23c570feb141398bb552ef5a0a82be331fea48037b8b5d71f0e332edf93ac3500eb4ddc0decc1a864790c782c76215660dd309791d06bd0af3f98cda4bc4629b1 OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL]'
|
||||
```
|
||||
|
||||
Peter Todd's other [bounties](https://bitcointalk.org/index.php?topic=293382.0) remain unclaimed at the time of this writing. They're all written in the same manner as the SHA-1 example above.
|
||||
@ -494,7 +494,7 @@ Here's where the security falls down:
|
||||
|
||||
First, anyone can redeem them without knowing much of a secret. They do have to have the `redeemScript`, which offers some protection, but once they do, that's probably the only secret that's necessary — unless your puzzle is _really_ tough, such as a computational puzzle.
|
||||
|
||||
Second, the actual redemption isn't secure. Normally, a Bitcoin transction is protected by the signature. Because the signature covers the transaction, no one on the network can rewrite that transaction to instead send to their address without invalidating the signature (and thus the transaction). That isn't true with a transactions whose inputs are just numbers. Anyone could grab the transaction and rewrite it to allow them to steal the funds. If they can get their transaction into a block before yours, they win, and you don't get the puzzle money. There are solutions for this, but they involve mining the block yourself or having a trusted pool mine it, and neither of those options is rational for an average Bitcoin user.
|
||||
Second, the actual redemption isn't secure. Normally, a Bitcoin transaction is protected by the signature. Because the signature covers the transaction, no one on the network can rewrite that transaction to instead send to their address without invalidating the signature (and thus the transaction). That isn't true with a transactions whose inputs are just numbers. Anyone could grab the transaction and rewrite it to allow them to steal the funds. If they can get their transaction into a block before yours, they win, and you don't get the puzzle money. There are solutions for this, but they involve mining the block yourself or having a trusted pool mine it, and neither of those options is rational for an average Bitcoin user.
|
||||
|
||||
Yet, Peter Todd's cryptographic bounties prove that puzzle scripts do have some real-world application.
|
||||
|
||||
|
@ -78,7 +78,7 @@ Script:
|
||||
Running: 0 <sigVPA> <sigVPB> 2 <pubKeyVPA> <pubKeyVPB> <pubKeyVPC> 3 OP_CHECKMULTISIG
|
||||
Stack: [ ]
|
||||
```
|
||||
You might notice that the President's signature just uses a simple `OP_CHECKSIGNATURE` rather than the more complex code ususally required for a P2PKH. We can get away with including the public key in the locking script, obviating the usual rigamarole, because it's hashed and won't be revealed (through the `redeemScript`) until the transaction is unlocked. This also allows for all of the possible signers to sign using the same methodology.
|
||||
You might notice that the President's signature just uses a simple `OP_CHECKSIGNATURE` rather than the more complex code usually required for a P2PKH. We can get away with including the public key in the locking script, obviating the usual rigamarole, because it's hashed and won't be revealed (through the `redeemScript`) until the transaction is unlocked. This also allows for all of the possible signers to sign using the same methodology.
|
||||
|
||||
The only possible problem is if the President is absent-minded and accidentally signs a transaction with one of his VPs, because he remembers this being a 2-of-3 multisig. One option is to decide that's an acceptable failure condition, because the President is using the multsig incorrectly. Another option is to turn the 2-of-3 multisig into a 2-of-4 multisig, just in case the President doesn't tolerate failure: `OP_DEPTH 1 OP_EQUAL IF <pubKeyPres> OP_CHECKSIGNATURE ELSE 2 <pubKeyVPA> <pubKeyVPB> <pubKeyVPC> <pubKeyPres> 4 OP_CHECKMULTISIG ENDIF`. This would allow the President to mistakenly sign with any Vice President, but wouldn't impact things if two Vice Presidents wanted to (correctly) sign.
|
||||
|
||||
@ -106,7 +106,7 @@ The result of the final `OP_CHECKMULTISIG` that was run will be left on the top
|
||||
|
||||
We've talked a lot about escrows. Complex multisigs combined with timelocks offer an automated way to create them in a robust manner.
|
||||
|
||||
Imagine home buyer Alice and home seller Bob who are working with an escrow agent The easy way to script this would be as a multisig where any two of the three parties could release the money: either the seller and buyer agree or the escrow agent takes over and agrees with one of the parties: `2 <pubKeyA> <pubKeyB> <pubKeyEscrow> 3 OP_CHECKMULTISG`.
|
||||
Imagine home buyer Alice and home seller Bob who are working with an escrow agent. The easy way to script this would be as a multisig where any two of the three parties could release the money: either the seller and buyer agree or the escrow agent takes over and agrees with one of the parties: `2 <pubKeyA> <pubKeyB> <pubKeyEscrow> 3 OP_CHECKMULTISG`.
|
||||
|
||||
However, this weakens the power of the escrow agent and allows the seller and buyer to accidentally make a bad decision between themselves — which is one of the things an escrow system is designed to avoid. So it could be that what we really want is the system that we just laid out, where the escrow agent is a required party in the 2-of-3 multisig: `OP_3DUP 2 <pubKeyEscrow> <pubKeyA> 2 OP_CHECKMULTISIG NOTIF 2 <pubKeyEscrow> <pubKeyB> 2 OP_CHECKMULTISIG ENDIF`.
|
||||
|
||||
@ -130,7 +130,7 @@ First, you test a signature for the buyer and the escrow agent, then a signature
|
||||
|
||||
### Write a Buyer-Centric Escrow Multisig
|
||||
|
||||
[BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki#Escrow_with_Timeout) offers an different example of this sort of escrow that doesn't have the extra protections to prevent going around the escrow agent, but which does give Alice total control if the escrow fails.
|
||||
[BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki#Escrow_with_Timeout) offers a different example of this sort of escrow that doesn't have the extra protections to prevent going around the escrow agent, but which does give Alice total control if the escrow fails.
|
||||
```
|
||||
IF
|
||||
|
||||
|
@ -4,7 +4,7 @@ Bitcoin Scripts can go far beyond the relatively simple financial instruments de
|
||||
|
||||
## Lock for the Lightning Network
|
||||
|
||||
The [Lightning Network](https://rusty.ozlabs.org/?p=450) is a payment channel that allows users to take funds off-chain and engage in numerous microtransactions before finalizing the payment channel and bringing the funds back into Bitcoin. Benefits include lower fees and faster transaction speeds. It's discussed in more detail, with examples of how to use it from the command line, starting [Chapter 18](18_0_Understanding_Your_Lightning_Setup.md).
|
||||
The [Lightning Network](https://rusty.ozlabs.org/?p=450) is a payment channel that allows users to take funds off-chain and engage in numerous microtransactions before finalizing the payment channel and bringing the funds back into Bitcoin. Benefits include lower fees and faster transaction speeds. It's discussed in more detail, with examples of how to use it from the command line, starting [Chapter 19](19_0_Understanding_Your_Lightning_Setup.md).
|
||||
|
||||
[BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) contains a few examples of how these off-chain transactions could be generated, using Bitcoin locking scripts.
|
||||
|
||||
@ -270,7 +270,7 @@ Running through the script reveals that the initial checks, above the `IF`/`ELSE
|
||||
|
||||
#### Understand HTLCs
|
||||
|
||||
HTLCs are quite complex, and this overview doesn't try to explain all of their intricacies. Rusty Russell's [overview](https://rusty.ozlabs.org/?p=462) explains more. and there's even more detail in his [Deployable Lightning](https://github.com/ElementsProject/lightning/blob/master/doc/deployable-lightning.pdf) paper. But don't worry if some of the intricacies still escape you, particularly the interrelations of the two scripts.
|
||||
HTLCs are quite complex, and this overview doesn't try to explain all of their intricacies. Rusty Russell's [overview](https://rusty.ozlabs.org/?p=462) explains more, and there's even more detail in his [Deployable Lightning](https://github.com/ElementsProject/lightning/blob/master/doc/deployable-lightning.pdf) paper. But don't worry if some of the intricacies still escape you, particularly the interrelations of the two scripts.
|
||||
|
||||
For the purposes of this tutorial, there are two important lessons for HTLCs:
|
||||
|
||||
@ -291,6 +291,6 @@ Move on to "Using Tor" with [Chapter Fourteen: Using Tor](14_0_Using_Tor.md).
|
||||
|
||||
Or, if you prefer, there are two alternate paths:
|
||||
|
||||
If you want to stay focused on Bitcoin, move on to "Programming with RPC" with [Chapter Fifteen: Talking to Bitcoind with C](15_0_Talking_to_Bitcoind.md).
|
||||
If you want to stay focused on Bitcoin, move on to "Programming with RPC" with [Chapter Sixteen: Talking to Bitcoind with C](16_0_Talking_to_Bitcoind.md).
|
||||
|
||||
Or, if you want to stay focused on the command-line because you're not a programmer, you can skip to [Chapter Eighteen: Understanding Your Lightning Seutp](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/18_0_Understanding_Your_Lightning_Setup.md) to continue your command-line education with the Lightning Network.
|
||||
Or, if you want to stay focused on the command-line because you're not a programmer, you can skip to [Chapter Nineteen: Understanding Your Lightning Setup](19_0_Understanding_Your_Lightning_Setup.md) to continue your command-line education with the Lightning Network.
|
||||
|
@ -6,13 +6,13 @@ If you did a standard installation with [Bitcoin Standup](https://github.com/Blo
|
||||
|
||||
> :book: ***What is Tor?*** Tor is a low-latency anonymity and overlay network based on onion routing and path-building design for enabling anonymous communication. It's free and open-source software with the name derived from the acronym for the original software project name: "The Onion Router".
|
||||
|
||||
> :book: ***Why Use Tor for Bitcoin?*** The Bitcoin network is a peer-to-peer network that listens for transactions and propagates them using a public IP address. When connecting to the network not using Tor, you would share your IP address, which could expose your location, your uptime, and others details to third parties — which is an undesirable privacy practice. To protect yourself online you should use tools like Tor to hide your connection details. Tor allows improve your privacy online as your data is cryptographically encoded and goes through different nodes, each one decoding a single layer (hence the onion metaphor).
|
||||
> :book: ***Why Use Tor for Bitcoin?*** The Bitcoin network is a peer-to-peer network that listens for transactions and propagates them using a public IP address. When connecting to the network not using Tor, you would share your IP address, which could expose your location, your uptime, and others details to third parties — which is an undesirable privacy practice. To protect yourself online you should use tools like Tor to hide your connection details. Tor allows you to improve your privacy online as your data is cryptographically encoded and goes through different nodes, each one decoding a single layer (hence the onion metaphor).
|
||||
|
||||
## Understand Tor
|
||||
|
||||
So how does Tor work?
|
||||
|
||||
When a user wants to connect to an Internet server, Tor tries to build a path formed by at least three Tor nodes relays, called Guard, Middle, and Exit. While building this path, symmetric encryption keys are negotiated; when a message moves along the path, each relay then strips off its layer of encryption. In this way, the message arrives at the final destination in its original form, and each party only knows the previous and the next hop and cannot determine origin or destination.
|
||||
When a user wants to connect to an Internet server, Tor tries to build a path formed by at least three Tor relay nodes, called Guard, Middle, and Exit. While building this path, symmetric encryption keys are negotiated; when a message moves along the path, each relay then strips off its layer of encryption. In this way, the message arrives at the final destination in its original form, and each party only knows the previous and the next hop and cannot determine origin or destination.
|
||||
|
||||
Here's what a connection looks like without Tor:
|
||||
```
|
||||
@ -94,7 +94,7 @@ mgcym6je63k44b3i5uachhsndayzx7xi4ldmwrm7in7yvc766rykz6yd.onion
|
||||
|
||||
When you have all of that information you can issue a `bitcoin-cli` command using `torify` and specifying the `-rpcconnect` as your onion address, the `-rpcport` as your hidden service port, and the `-rpcpassword` as your password:
|
||||
```
|
||||
$ torify bitcoin-cli -rpcconnect=mgcym6je63k44b3i5uachhsndayzx7xi4ldmwrm7in7yvc766rykz6yd.onion -rpcport=1309 -rpcpassword=685316cc239c24ba71fd0969fa55634f getblockcount
|
||||
$ torify bitcoin-cli -rpcconnect=mgcym6je63k44b3i5uachhsndayzx7xi4ldmwrm7in7yvc766rykz6yd.onion -rpcport=1309 -rpcuser=StandUp -rpcpassword=685316cc239c24ba71fd0969fa55634f getblockcount
|
||||
```
|
||||
|
||||
### Verify Your Tor Setup for Bitcoind
|
||||
@ -104,10 +104,12 @@ Bitcoin Standup also ensures that your `bitcoind` is set up to optionally commun
|
||||
You can verify the initial setup of Tor for `bitcoind` by grepping for "tor" in the `debug.log` in your data directory:
|
||||
```
|
||||
$ grep "tor:" ~/.bitcoin/testnet3/debug.log
|
||||
2020-07-15T17:56:34Z tor: ADD_ONION successful
|
||||
2020-07-15T17:56:34Z tor: Got service ID zbyqk2tmq4c4vzeo, advertising service zbyqk2tmq4c4vzeo.onion:18333
|
||||
2020-07-15T17:56:34Z tor: Cached service private key to /home/standup/.bitcoin/testnet3/onion_private_key
|
||||
2021-06-09T14:07:04Z tor: ADD_ONION successful
|
||||
2021-06-09T14:07:04Z tor: Got service ID vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd, advertising service vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd.onion:18333
|
||||
2021-06-09T14:07:04Z tor: Cached service private key to /home/standup/.bitcoin/testnet3/onion_v3_private_key
|
||||
```
|
||||
> :information_source: **NOTE:** Bitcoin Core does not support v2 addresses anymore. Tor v2 support was removed in [#22050](https://github.com/bitcoin/bitcoin/pull/22050)
|
||||
|
||||
> **TESTNET vs MAINNET:** Mainnet `bitcoind` responds on port 8333, testnet on port 18333.
|
||||
|
||||
You can verify that a Tor hidden service has been created for Bitcoin with the `getnetworkinfo` RPC call:
|
||||
@ -127,14 +129,14 @@ $ bitcoin-cli getnetworkinfo
|
||||
"score": 1
|
||||
},
|
||||
{
|
||||
"address": "zbyqk2tmq4c4vzeo.onion",
|
||||
"address": "vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd.onion",
|
||||
"port": 18333,
|
||||
"score": 4
|
||||
}
|
||||
],
|
||||
...
|
||||
```
|
||||
This shows three addresses to access your Bitcoin server, an IPv4 address (`173.255.245.83`), an IPv6 address (`2600:3c01::f03c:92ff:fe86:f26`), and a Tor address (`zbyqk2tmq4c4vzeo.onion`).
|
||||
This shows three addresses to access your Bitcoin server, an IPv4 address (`173.255.245.83`), an IPv6 address (`2600:3c01::f03c:92ff:fe86:f26`), and a Tor address (`vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd.onion`).
|
||||
|
||||
> :warning: **WARNING:** Obviously: never reveal your Tor address in a way that's associated with your name or other PII!
|
||||
|
||||
@ -191,12 +193,12 @@ You can see similar information with `getnetworkinfo`.
|
||||
"score": 1
|
||||
},
|
||||
{
|
||||
"address": "zbyqk2tmq4c4vzeo.onion",
|
||||
"address": "vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd.onion",
|
||||
"port": 18333,
|
||||
"score": 4
|
||||
}
|
||||
],
|
||||
"warnings": "Warning: unknown new rules activated (versionbit 28)"
|
||||
"warnings": ""
|
||||
}
|
||||
```
|
||||
This hidden service will allow anonymous connections to your `bitcoind` over the Bitcoin Network.
|
||||
|
@ -59,6 +59,8 @@ addnode=address.onion
|
||||
addnode=address.onion
|
||||
addnode=address.onion
|
||||
```
|
||||
See [Bitcoin Onion Nodes](https://github.com/emmanuelrosa/bitcoin-onion-nodes) for a listing and an example of how to add them.
|
||||
|
||||
Afterward, restart `tor` and `bitcoind`.
|
||||
|
||||
You should now be communicating exlusively on Tor. But, unless you are in a hostile state, this level of anonymity is probably not required. It also is not particularly recommended: you might greatly decrease your number of potential peers, inviting problems of censorship or even correlation. You may also see lag. And, this setup may give you a false sense of anonymity that really doesn't exist on the Bitcoin network.
|
||||
|
@ -54,6 +54,6 @@ Now that you've got Tor installed and know how to use it, you can add other serv
|
||||
|
||||
> :fire: ***What's the power of Other Hidden Services?*** Every time you access a service on your server remotely, you leave footprints on the network. Even if the data is encrypted by something like SSH (or TLS), lurkers on the network can see where you're connecting from, where you're connecting to, and what service you're using. Does this matter? This is the question you have to ask. But if the answer is "Yes", you can protect the connection with a hidden service.
|
||||
|
||||
Move on to "Programming with RPC" with [Chapter Fifteen: Talking to Bitcoind with C](15_0_Talking_to_Bitcoind.md).
|
||||
## What's Next?
|
||||
|
||||
Or, if you're not a programmer, you can skip to [Chapter Eighteen: Understanding Your Lightning Seutp](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/18_0_Understanding_Your_Lightning_Setup.md) to continue your command-line education with the Lightning Network.
|
||||
For a different sort of privacy, move on to "Using i2p" with [Chapter Fifteen: Using i2p](15_0_Using_i2p.md).
|
||||
|
20
15_0_Using_i2p.md
Normal file
20
15_0_Using_i2p.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Chapter 15: Using I2P
|
||||
|
||||
There are alternatives to Tor. One is the Invisible Internet Project (I2P), a fully encrypted private network layer. It uses a distributed [network database](https://geti2p.net/en/docs/how/network-database) and encrypted unidirectional tunnels between peers. The biggest difference between Tor and I2P is that Tor is fundamentally a proxy network that offers internet services in a private form, while I2P is fundamentally a sequestered network that offers I2P services only to the I2P network, creating a "network within a network". However, you might just want it as an alternative, so that you're not dependent solely on Tor.
|
||||
|
||||
I2P is not currently installed by [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts), as I2P support was recently added in Bitcoin Core. However, this chapter explains how to manually install it.
|
||||
|
||||
## Objectives for This Chapter
|
||||
|
||||
After working through this chapter, a developer will be able to:
|
||||
|
||||
* Run Bitcoin Core as an I2P (Invisible Internet Project) service
|
||||
|
||||
Supporting objectives include the ability to:
|
||||
|
||||
* Understand the I2P Network
|
||||
* Learn the difference between Tor and I2P
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Section One: Bitcoin Core as an I2P (Invisible Internet Project) service](15_1_i2p_service.md)
|
121
15_1_i2p_service.md
Normal file
121
15_1_i2p_service.md
Normal file
@ -0,0 +1,121 @@
|
||||
# 15.1: Bitcoin Core as an I2P (Invisible Internet Project) service
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
Rather than using the proxy-based Tor service to ensure the privacy of your Bitcoin communications, you may instead wish to use I2P, which is designed to act as a private network within the internet, rather than simply offering private access to internet services.
|
||||
|
||||
## Understand the Differences
|
||||
|
||||
Tor and I2P both offer private access to online services, but with different routing and databases, and with different architectures for relays. Since hidden services (such as Bitcoin access) are core to the design of I2P, they have also been better optimized:
|
||||
|
||||
| | Tor | I2P |
|
||||
| :--- | :---: | ---: |
|
||||
| Routing | [Onion](https://www.onion-router.net/) | [Garlic](https://geti2p.net/en/docs/how/garlic-routing) |
|
||||
| Network Database | Trusted [Directory Servers](https://blog.torproject.org/possible-upcoming-attempts-disable-tor-network) | [Distributed network database](https://geti2p.net/en/docs/how/network-database) |
|
||||
| Relay | **Two-way** encrypted connections between each Relay | **One-way** connections between every server in its tunnels |
|
||||
| Hidden services | Slow | Fast |
|
||||
|
||||
A more detailed comparison may be found at [geti2p.net](https://geti2p.net/en/comparison/tor).
|
||||
|
||||
### Understand Tradeoffs for Limiting Outgoing Connections
|
||||
|
||||
There are [tradeoffs](https://bitcoin.stackexchange.com/questions/107060/tor-and-i2p-tradeoffs-in-bitcoin-core) if you choose to support only I2P, only Tor, or both. These configurations, which limit outgoing clearnet connections, are made in Bitcoin Core using the `onlynet` argument in your `bitcoin.conf`.
|
||||
|
||||
* `onlynet=onion`, which limits outgoing connections to Tor, can expose a node to Sybil attacks and can create network partitioning, because of limited connections between Tornet and the clearnet.
|
||||
* `onlynet=onion` and `onlynet=i2p` in conjunction, which runs Onion service with I2P service is experimental for now.
|
||||
|
||||
## Install I2P
|
||||
|
||||
To install I2P, you should make sure your ports are correctly set up and then you can continue with your setup process.
|
||||
|
||||
### Prepare Ports
|
||||
|
||||
To use I2P, you will need to open the following ports, which are required by I2P:
|
||||
|
||||
1. **Outbound (Internet facing):** a random port between 9000 and 31000 is selected. It is best if all these ports are open for outbound connections, which doesn't affect your security.
|
||||
- You can check firewall status using `sudo ufw status verbose`, which shouldn't deny outgoing connections by default.
|
||||
2. Inbound (Internet facing): optional. A variety of inbound ports are listed in the [I2P docs](https://geti2p.net/en/faq#ports).
|
||||
- For maximum privacy, it is preferable to disable accepting incoming connections.
|
||||
|
||||
### Run I2P
|
||||
|
||||
The following will run Bitcoin Core I2P services:
|
||||
|
||||
1. Install `i2pd` on Ubuntu:
|
||||
|
||||
```
|
||||
sudo add-apt-repository ppa:purplei2p/i2pd
|
||||
sudo apt-get update
|
||||
sudo apt-get install i2pd
|
||||
```
|
||||
|
||||
For installing on other OSes, see [these docs](https://i2pd.readthedocs.io/en/latest/user-guide/install/)
|
||||
|
||||
2. [Run](https://i2pd.readthedocs.io/en/latest/user-guide/run/) the I2P service:
|
||||
|
||||
```
|
||||
$ sudo systemctl start i2pd.service
|
||||
```
|
||||
|
||||
3. Check that I2P is running. You should see it on port 7656:
|
||||
|
||||
```
|
||||
$ ss -nlt
|
||||
|
||||
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
|
||||
|
||||
LISTEN 0 4096 127.0.0.1:7656 0.0.0.0:*
|
||||
```
|
||||
|
||||
4. Add the following lines in `bitcoin.conf`:
|
||||
|
||||
```
|
||||
i2psam=127.0.0.1:7656
|
||||
debug=i2p
|
||||
```
|
||||
The logging option, `debug=i2p`, is used to record additional information in the debug log about your I2P configuration and connections. The default location for this debugging file on Linux is: `~/.bitcoin/debug.log`:
|
||||
|
||||
5. Restart `bitcoind`
|
||||
|
||||
```
|
||||
$ bitcoind
|
||||
```
|
||||
|
||||
6. Check `debug.log` to see if I2P was setup correctly, or if any errors appeared in the logs.
|
||||
```
|
||||
2021-06-15T20:36:16Z i2paccept thread start
|
||||
2021-06-15T20:36:16Z I2P: Creating SAM session with 127.0.0.1:7656
|
||||
|
||||
2021-06-15T20:36:56Z I2P: SAM session created: session id=3e0f35228b, my address=bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333
|
||||
2021-06-15T20:36:56Z AddLocal(bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333,4)
|
||||
```
|
||||
|
||||
The I2P address is mentioned in the logs, ending with _b32.i2p_. For example `bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333`.
|
||||
|
||||
7. Confirm `i2p_private_key` was created in the Bitcoin Core data directory. The first time Bitcoin Core connects to the I2P router, its I2P address (and corresponding private key) will be automatically generated and saved in a file named *i2p_private_key*:
|
||||
```
|
||||
~/.bitcoin/testnet3$ ls
|
||||
|
||||
anchors.dat chainstate i2p_private_key settings.json
|
||||
banlist.dat debug.log mempool.dat wallets
|
||||
blocks fee_estimates.dat peers.dat
|
||||
```
|
||||
|
||||
8. Check that `bitcoin-cli -netinfo` or `bitcoin-cli getnetworkinfo`returns the I2P address:
|
||||
|
||||
```
|
||||
Local addresses
|
||||
bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p port 18333 score 4
|
||||
```
|
||||
|
||||
You now have your Bitcoin server accessible through the I2P network at your new local address.
|
||||
|
||||
## Summary: Bitcoin Core as an I2P (Invisible Internet Project) service
|
||||
|
||||
It is always good to have alternatives for privacy and not depend solely on Tor for running Bitcoin Core as a hidden service. Since I2P was recently added in Bitcoin Core, not many people use it. Experiment with it and report bugs if you find any issues.
|
||||
|
||||
> :information_source: **NOTE:** For the official i2prouter implementation in Java, visit the [I2P download page](https://geti2p.net/en/download) and follow the instructions for your Operating System. Once installed, open a terminal window and type `i2prouter start`. Then visit `127.0.0.1:7657` in your browser to enable SAM. To do so, select: "Configure Homepage", then "Clients", and finally select the "Play Button" next to SAM application Bridge. On the left side of the page, there should be a green light next to "Shared Clients".
|
||||
|
||||
Move on to "Programming with RPC" with [Chapter Sixteen: Talking to Bitcoind with C](16_0_Talking_to_Bitcoind.md).
|
||||
|
||||
Or, if you're not a programmer, you can skip to [Chapter Nineteen: Understanding Your Lightning Setup](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/19_0_Understanding_Your_Lightning_Setup.md) to continue your command-line education with the Lightning Network.
|
@ -1,4 +1,4 @@
|
||||
# Chapter 15: Talking to Bitcoind with C
|
||||
# Chapter 16: Talking to Bitcoind with C
|
||||
|
||||
While working with Bitcoin Scripts, we hit the boundaries of what's possible with `bitcoin-cli`: it can't currently be used to generate transactions containing unusual scripts. Shell scripts also aren't great for some things, such as creating listener programs that are constantly polling. Fortunately, there are other ways to access the Bitcoin network: programming APIs.
|
||||
|
||||
@ -20,6 +20,6 @@ Supporting objectives include the ability to:
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Section One: Accessing Bitcoind in C with RPC Libraries](15_1_Accessing_Bitcoind_with_C.md)
|
||||
* [Section Two: Programming Bitcoind in C with RPC Libraries](15_2_Programming_Bitcoind_with_C.md)
|
||||
* [Section Three: Receiving Notifications in C with ZMQ Libraries](15_3_Receiving_Bitcoind_Notifications_with_C.md)
|
||||
* [Section One: Accessing Bitcoind in C with RPC Libraries](16_1_Accessing_Bitcoind_with_C.md)
|
||||
* [Section Two: Programming Bitcoind in C with RPC Libraries](16_2_Programming_Bitcoind_with_C.md)
|
||||
* [Section Three: Receiving Notifications in C with ZMQ Libraries](16_3_Receiving_Bitcoind_Notifications_with_C.md)
|
@ -1,11 +1,13 @@
|
||||
# 15.1: Accessing Bitcoind in C with RPC Libraries
|
||||
# 16.1: Accessing Bitcoind in C with RPC Libraries
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
You've already seen one alternative way to access the Bitcoind's RPC ports: `curl`, which was covered in a [Chapter 4 Interlude](04_4__Interlude_Using_Curl.md). Interacting with `bitcoind` through a RPC library in C is no different than that, you just need some good libraries to help you out. This section introduces a package called `libbitcoinrpc`, which allows you to access JSON-RPC `bitcoind` port. It uses a `curl` library for accessing the data and it uses the `jansson` library for encoding and decoding the JSON.
|
||||
You've already seen one alternative way to access the Bitcoind's RPC ports: `curl`, which was covered in a [Chapter 4 Interlude](04_4__Interlude_Using_Curl.md). Interacting with `bitcoind` through an RPC library in C is no different than that, you just need some good libraries to help you out. This section introduces a package called `libbitcoinrpc`, which allows you to access JSON-RPC `bitcoind` port. It uses a `curl` library for accessing the data and it uses the `jansson` library for encoding and decoding the JSON.
|
||||
|
||||
## Set Up libbitcoinrpc
|
||||
|
||||
> :warning: **WARNING** It appears that `libbitcoinrpc` has been entirely abandoned. We have logged updating this to a new C library as an [issue](https://github.com/BlockchainCommons/Community/issues/140). In the meantime, the `libbitcoinrpc` library does not currently compile without intervention. As a result 16.1 and 16.2 is mainly viewable as pseudo-code that shows the process of integrating Bitcoin-Core with C.
|
||||
|
||||
To use `libbitcoinrpc`, you need to install a basic C setup and the dependent packages `libcurl`, `libjansson`, and `libuuid`. The following will do so on your Bitcoin Standup server (or any other Ubuntu server).
|
||||
```
|
||||
$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev
|
||||
@ -18,13 +20,13 @@ Need to get 358 kB of archives.
|
||||
After this operation, 1.696 kB of additional disk space will be used.
|
||||
Do you want to continue? [Y/n] y
|
||||
```
|
||||
You can then download [libbitcoinrpc from Github](https://github.com/gitmarek/libbitcoinrpc/blob/master/README.md). Clone it or grab a zip file, as you prefer.
|
||||
You can then download [libbitcoinrpc from Github](https://github.com/BlockchainCommons/libbitcoinrpc/blob/master/README.md). Clone it or grab a zip file, as you prefer.
|
||||
```
|
||||
$ sudo apt-get install git
|
||||
$ git clone https://github.com/gitmarek/libbitcoinrpc
|
||||
$ git clone https://github.com/BlockchainCommons/libbitcoinrpc.git
|
||||
```
|
||||
|
||||
> :warning: **WARNING** A change in the "signrawtransaction" RPC caused signing with `libbitcoinrpc` to segfault for Bitcoin 0.17 or higher. A [PR has been submitted](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) to resolve the problem, but if it hasn't yet been merged, you can just make the one simple change in the source code to `src/bitcoinrpc_method.c` before compiling.
|
||||
> :warning: **WARNING** A change in the "signrawtransaction" RPC caused signing with `libbitcoinrpc` to segfault for Bitcoin 0.17 or higher. A [PR has been submitted](https://github.com/gitmarek/libbitcoinrpc/pull/1) to resolve the problem, but if it hasn't yet been merged, you can just make the one simple change in the source code to `src/bitcoinrpc_method.c` before compiling.
|
||||
|
||||
### Compiling libbitcoinrpc
|
||||
|
||||
@ -106,7 +108,7 @@ First, initialize the library:
|
||||
```
|
||||
bitcoinrpc_global_init();
|
||||
```
|
||||
Then connect to your `bitcoind` with `bitcoinrpc_cl_init_params`. The four arguments for `bitcoinrpc_cl_init_params` are username, password, IP address, and port. You should already know all of this information from your work with [Curl](04_4__Interlude_Using_Curl.md). As you'll recall, the IP address 127.0.0.1 and port 18332 should be correct for the standard testnet setup described in this documents, while you can extract the user and password from `~/.bitcoin/bitcoin.conf`.
|
||||
Then connect to your `bitcoind` with `bitcoinrpc_cl_init_params`. The four arguments for `bitcoinrpc_cl_init_params` are username, password, IP address, and port. You should already know all of this information from your work with [Curl](04_4__Interlude_Using_Curl.md). As you'll recall, the IP address 127.0.0.1 and port 18332 should be correct for the standard testnet setup described in these documents, while you can extract the user and password from `~/.bitcoin/bitcoin.conf`.
|
||||
```
|
||||
$ cat bitcoin.conf
|
||||
server=1
|
||||
@ -147,7 +149,7 @@ bitcoinrpc_global_cleanup();
|
||||
|
||||
### Test the Test Code
|
||||
|
||||
Test code can be found at [15_1_testbitcoin.c in the src directory](src/15_1_testbitcoin.c). Download it to your testnet machine, then insert the correct RPC password (and change the RPC user if you didn't create your server with StandUp).
|
||||
Test code can be found at [16_1_testbitcoin.c in the src directory](src/16_1_testbitcoin.c). Download it to your testnet machine, then insert the correct RPC password (and change the RPC user if you didn't create your server with StandUp).
|
||||
|
||||
You can compile and run this as follows:
|
||||
```
|
||||
@ -160,7 +162,7 @@ Successfully connected to server!
|
||||
|
||||
## Make an RPC Call
|
||||
|
||||
In order to use an RPC method using `libbitcoinrpc`, you must initialize a variable of type `bitcoinrpc_method_t`. You do so with the appropriate value for the method you want to use, all of which are listed in the [bitcoinrpc Reference](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md).
|
||||
In order to use an RPC method using `libbitcoinrpc`, you must initialize a variable of type `bitcoinrpc_method_t`. You do so with the appropriate value for the method you want to use, all of which are listed in the [bitcoinrpc Reference](https://github.com/BlockchainCommons/libbitcoinrpc/blob/master/doc/reference.md).
|
||||
```
|
||||
bitcoinrpc_method_t *getmininginfo = NULL;
|
||||
getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO);
|
||||
@ -213,7 +215,7 @@ printf("Block Count: %d\n",blocks);
|
||||
|
||||
### Test the Info Code
|
||||
|
||||
Retrieve the test code from [the src directory](15_1_getmininginfo.c).
|
||||
Retrieve the test code from [the src directory](src/16_1_getmininginfo.c).
|
||||
```
|
||||
$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo
|
||||
$ ./getmininginfo
|
||||
@ -278,4 +280,4 @@ By linking to the `bitcoinrpc` RPC and `jansson` JSON libraries, you can easily
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Talking to Bitcoind with C" in [15.2: Programming Bitcoind in C with RPC Libraries](15_2_Programming_Bitcoind_with_C.md).
|
||||
Learn more about "Talking to Bitcoind with C" in [16.2: Programming Bitcoind in C with RPC Libraries](16_2_Programming_Bitcoind_with_C.md).
|
@ -1,8 +1,8 @@
|
||||
# 15.2: Programming Bitcoind in C with RPC Libraries
|
||||
# 16.2: Programming Bitcoind in C with RPC Libraries
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
[§15.1](15_1_Accessing_Bitcoind_with_C.md) laid out the methodology for creating C programs using RPC and JSON libraries. We're now going to show the potential of those C libraries by laying out a simplistic, first cut of an actual Bitcoin program.
|
||||
[§16.1](16_1_Accessing_Bitcoind_with_C.md) laid out the methodology for creating C programs using RPC and JSON libraries. We're now going to show the potential of those C libraries by laying out a simplistic, first cut of an actual Bitcoin program.
|
||||
|
||||
## Plan for Your Code
|
||||
|
||||
@ -65,7 +65,7 @@ float tx_total = tx_amount + tx_fee;
|
||||
|
||||
### Step 3: Prepare Your RPC
|
||||
|
||||
Obviously, you're going to need to get all of your variables ready again, as discussed in [§15.1: Accessing Bitcoind with C](15_1_Accessing_Bitcoind_with_C.md). You also need to initialize your library, connect your RPC client, and prepare your response object:
|
||||
Obviously, you're going to need to get all of your variables ready again, as discussed in [§16.1: Accessing Bitcoind with C](16_1_Accessing_Bitcoind_with_C.md). You also need to initialize your library, connect your RPC client, and prepare your response object:
|
||||
```
|
||||
bitcoinrpc_global_init();
|
||||
rpc_client = bitcoinrpc_cl_init_params ("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332);
|
||||
@ -324,7 +324,7 @@ The entire code, with a _little_ more error-checking appears in the Appendix.
|
||||
|
||||
## Test Your Code
|
||||
|
||||
The complete code can be found in the [src directory](src/15_2_sendtoaddress.c).
|
||||
The complete code can be found in the [src directory](src/16_2_sendtoaddress.c).
|
||||
|
||||
Compile this as usual:
|
||||
```
|
||||
@ -344,4 +344,4 @@ With access to a C library, you can create much more fully featured programs tha
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Talking to Bitcoind with C" in [15.3: Receiving Notifications in C with ZMQ Libraries](15_3_Receiving_Bitcoind_Notifications_with_C.md).
|
||||
Learn more about "Talking to Bitcoind with C" in [16.3: Receiving Notifications in C with ZMQ Libraries](16_3_Receiving_Bitcoind_Notifications_with_C.md).
|
@ -1,8 +1,8 @@
|
||||
# 15.3 Receiving Notifications in C with ZMQ Libraries
|
||||
# 16.3 Receiving Notifications in C with ZMQ Libraries
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
[§15.1](15_1_Accessing_Bitcoind_with_C.md) and [§15.2](15_2_Programming_Bitcoind_with_C.md) introduced RPC and JSON libraries for C, and in doing so showed one of the advantages of accessing Bitcoin's RPC commands through a programming language: the ability to reasonably create much more complex programs. This chapter introduces a third library, for [ZMQ](http://zeromq.org/), and in doing so reveals another advantage: the ability to monitor for notifications. It will use that for coding a blockchain listener.
|
||||
[§16.1](16_1_Accessing_Bitcoind_with_C.md) and [§16.2](16_2_Programming_Bitcoind_with_C.md) introduced RPC and JSON libraries for C, and in doing so showed one of the advantages of accessing Bitcoin's RPC commands through a programming language: the ability to reasonably create much more complex programs. This chapter introduces a third library, for [ZMQ](http://zeromq.org/), and in doing so reveals another advantage: the ability to monitor for notifications. It will use that for coding a blockchain listener.
|
||||
|
||||
> :book: ***What is ZMQ?*** ZeroMQ (ZMQ)is a high-performance asynchronous messaging library that provides a message queue. ZeroMQ supports common messaging patterns (pub/sub, request/reply, client/server, and others) over a variety of transports (TCP, in-process, inter-process, multicast, WebSocket, and more), making inter-process messaging as simple as inter-thread messaging. You can find more details about ZMQ notifications and others kind of messages in [this repo](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md).
|
||||
|
||||
@ -121,7 +121,7 @@ Of course when you're done, you should clean up:
|
||||
|
||||
### Test the Notification Code
|
||||
|
||||
The source code is in the [src directory](src/15_3_chainlistener.c) as usual. You should compile it:
|
||||
The source code is in the [src directory](src/16_3_chainlistener.c) as usual. You should compile it:
|
||||
```
|
||||
$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq
|
||||
```
|
||||
@ -151,7 +151,7 @@ By using the ZMQ framework, you can easily receive notifications by subscribing
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Programming with RPC" in [Chapter 16: Programming Bitcoin with Libwally](16_0_Programming_with_Libwally.md).
|
||||
Learn more about "Programming with RPC" in [Chapter 17: Programming Bitcoin with Libwally](17_0_Programming_with_Libwally.md).
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
# Chapter 16: Programming with Libwally
|
||||
# Chapter 17: Programming with Libwally
|
||||
|
||||
The previous chapter presented three C Libraries, for RPC, JSON, and ZMQ, all of which are intended to interact directly with `bitcoind`, just like you've been doing since the start. But, sometimes you might want to code without direct access to a `bitcoind`. This might be due to an offline client, or just because you want to keep some functionality internal to your C program. You also might want to get into deeper wallet functionality, like mnemonic word creation or address derivation. That's where Libwally comes in: it's a wallet library for C, C++, Java, NodeJS, or Python, with wrappers also available for other languages, such as Swift.
|
||||
|
||||
This chapter touches upon the functionality possible within Libwally, most of which complements the work you've done through RPC access to `bitcoind`, but some of which replicates it. It also shows how to integrate that work with the RPC clients that you're more familiar with. However, note that this is just the barest introduction to Libwally. Several of its more improtant function sets are highlighted, but we never do more than stick our toes in. If you find its functions useful or intriguing, then you'll need to dig in much more deeply than this course can cover.
|
||||
This chapter touches upon the functionality possible within Libwally, most of which complements the work you've done through RPC access to `bitcoind`, but some of which replicates it. It also shows how to integrate that work with the RPC clients that you're more familiar with. However, note that this is just the barest introduction to Libwally. Several of its more important function sets are highlighted, but we never do more than stick our toes in. If you find its functions useful or intriguing, then you'll need to dig in much more deeply than this course can cover.
|
||||
|
||||
## Objectives for This Chapter
|
||||
|
||||
@ -20,10 +20,10 @@ Supporting objectives include the ability to:
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Section One: Setting Up Libwally](16_1_Setting_Up_Libwally.md)
|
||||
* [Section Two: Using BIP39 in Libwally](16_2_Using_BIP39_in_Libwally.md)
|
||||
* [Section Three: Using BIP32 in Libwally](16_3_Using_BIP32_in_Libwally.md)
|
||||
* [Section Four: Using PSBTs in Libwally](16_4_Using_PSBTs_in_Libwally.md)
|
||||
* [Section Five: Using Scripts in Libwally](16_5_Using_Scripts_in_Libwally.md)
|
||||
* [Section Six: Using Other Functions in Libwally](16_6_Using_Other_Functions_in_Libwally.md)
|
||||
* [Section Seven: Integrating Libwally and Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md)
|
||||
* [Section One: Setting Up Libwally](17_1_Setting_Up_Libwally.md)
|
||||
* [Section Two: Using BIP39 in Libwally](17_2_Using_BIP39_in_Libwally.md)
|
||||
* [Section Three: Using BIP32 in Libwally](17_3_Using_BIP32_in_Libwally.md)
|
||||
* [Section Four: Using PSBTs in Libwally](17_4_Using_PSBTs_in_Libwally.md)
|
||||
* [Section Five: Using Scripts in Libwally](17_5_Using_Scripts_in_Libwally.md)
|
||||
* [Section Six: Using Other Functions in Libwally](17_6_Using_Other_Functions_in_Libwally.md)
|
||||
* [Section Seven: Integrating Libwally and Bitcoin-CLI](17_7_Integrating_Libwally_and_Bitcoin-CLI.md)
|
@ -1,4 +1,4 @@
|
||||
# 16.1: Setting Up Libwally
|
||||
# 17.1: Setting Up Libwally
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -129,7 +129,7 @@ In both cases, the argument is for flags, but is currently set to `0`.
|
||||
|
||||
## Test a Test Libwally Program
|
||||
|
||||
The src directory contains [testwally.c](src/16_1_testwally.c), which just shows how the initialize and cleanup functions work.
|
||||
The src directory contains [testwally.c](src/17_1_testwally.c), which just shows how the initialize and cleanup functions work.
|
||||
|
||||
You can compile it as follows:
|
||||
```
|
||||
@ -186,12 +186,12 @@ This course will only use `libsodium` for one small (but crucial!) bit of entrop
|
||||
|
||||
## Summary: Setting Up Libwally
|
||||
|
||||
By installing the Libwally (and Libsodium) includes and libraries, you gain access to a number of cryptographic and wallet functions, which can complement your RPC and ZMG libraries (or your command-line `bitcoin-cli`).
|
||||
By installing the Libwally (and Libsodium) includes and libraries, you gain access to a number of cryptographic and wallet functions, which can complement your RPC and ZMQ libraries (or your command-line `bitcoin-cli`).
|
||||
|
||||
So what precisely can you do now? That's what the rest of this chapter is about.
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Programming Bitcoin with Libwally" in [16.2: Using BIP39 in Libwally](16_2_Using_BIP39_in_Libwally.md).
|
||||
Learn more about "Programming Bitcoin with Libwally" in [17.2: Using BIP39 in Libwally](17_2_Using_BIP39_in_Libwally.md).
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# 16.2: Using BIP39 in Libwally
|
||||
# 17.2: Using BIP39 in Libwally
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -14,7 +14,7 @@ All Bitcoin keys start with entropy. This first use of Libwally, and its BIP39 m
|
||||
|
||||
> :book: ***What is Entropy?*** Entropy is a fancy way of saying randomness, but it's a carefully measured randomness that's used as the foundation of a true-random-number generated (TRG). Its measured in "bits", with more bits of entropy resulting in more randomness (and thus more protection for what's being generated). For Bitcoin, entropy is the foundation of your seed, which in an HD wallet generates all of your addresses.
|
||||
|
||||
You'll always start work with Libwally by initializing the library and testing the results, as first demonstrated in [§16.1](16_1_Setting_Up_Libwally.md):
|
||||
You'll always start work with Libwally by initializing the library and testing the results, as first demonstrated in [§17.1](17_1_Setting_Up_Libwally.md):
|
||||
```
|
||||
int lw_response;
|
||||
|
||||
@ -49,7 +49,7 @@ This example, which will be the only way we use the `libsodium` library, creates
|
||||
```
|
||||
Note that you have to pass along the byte size, so if you were to increase the size of your entropy, to generate a longer mnemonic phrase, you'd also need to increase the value in this function.
|
||||
|
||||
> :note: **NOTE:** There are mnemonic word lists for different languages! The default is to use the English-language list, which is the `NULL` variable in these Libwally mnemonic commands, but you can alternatively request a different language!
|
||||
> **NOTE:** There are mnemonic word lists for different languages! The default is to use the English-language list, which is the `NULL` variable in these Libwally mnemonic commands, but you can alternatively request a different language!
|
||||
|
||||
That's it! You've created a mnemonic phrase!
|
||||
|
||||
@ -57,7 +57,7 @@ That's it! You've created a mnemonic phrase!
|
||||
|
||||
### Translate into a Seed
|
||||
|
||||
There are some functions, such as `bip32_key_from_seed` (which we'll meet in the next section) that require you to have theseeddeed rather than the Mnemonic. The two things are functionally identical: if you have the seed, you can generate the mnemonic, and vice-versa.
|
||||
There are some functions, such as `bip32_key_from_seed` (which we'll meet in the next section) that require you to have the seed rather than the Mnemonic. The two things are functionally identical: if you have the seed, you can generate the mnemonic, and vice-versa.
|
||||
|
||||
If you need to generate the seed from your mnemonic, you just use the `bip39_mnemonic_to_seed` command:
|
||||
```
|
||||
@ -82,7 +82,7 @@ If you've done everything right, you should get back a 64-byte seed. (That's the
|
||||
|
||||
## Test Mnemonic Code
|
||||
|
||||
The full code for generating entropy, generating a BIP39 mnemonic, validating the mnemonic, and generating a seed can be found in the [src directory](src/16_2_genmnemonic.c). Download it and compile:
|
||||
The full code for generating entropy, generating a BIP39 mnemonic, validating the mnemonic, and generating a seed can be found in the [src directory](src/17_2_genmnemonic.c). Download it and compile:
|
||||
```
|
||||
$ cc genmnemonic.c -lwallycore -lsodium -o genmnemonic
|
||||
```
|
||||
@ -99,8 +99,8 @@ BIP39 allows you generate a set of 12-24 Mnemonic words from a seed (and the Lib
|
||||
|
||||
> :fire: ***What is the power of BIP39?*** Bitcoin seeds and private keys are prone to all sorts of lossage. You mistype a single digit, and your money is gone forever. Mnemonic Words are a much more user-friendly way of representing the same data, but because they're words in the language of the user's choice, they're less prone to mistakes. The power of BIP39 is thus to improve the accessibility, usability, and safety of Bitcoin.
|
||||
|
||||
> :fire: ***What is the power of BIP39 in Libwally?*** Bitcoind doesn't currently support mnemonic words, so using Libwally can allow you to generate mnemonic words in conjunction with addresses held by `bitcoind` (though as we'll see in §16.7, it requires a bit of a work-around at present to import your keys into Bitcoin Core).
|
||||
> :fire: ***What is the power of BIP39 in Libwally?*** Bitcoind doesn't currently support mnemonic words, so using Libwally can allow you to generate mnemonic words in conjunction with addresses held by `bitcoind` (though as we'll see in §17.7, it requires a bit of a work-around at present to import your keys into Bitcoin Core).
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Programming Bitcoin with Libwally" in [16.3: Using BIP32 in Libwally](16_3_Using_BIP32_in_Libwally.md).
|
||||
Learn more about "Programming Bitcoin with Libwally" in [17.3: Using BIP32 in Libwally](17_3_Using_BIP32_in_Libwally.md).
|
@ -1,15 +1,15 @@
|
||||
# 16.3: Using BIP32 in Libwally
|
||||
# 17.3: Using BIP32 in Libwally
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
In [§16.2](16_2_Using_BIP39_in_Libwally.md), you were able to use entropy to generate a seed and its related mnemonic. As you may recall from [§3.5: Understanding the Descriptor](03_5_Understanding_the_Descriptor.md), a seed is the basis of a Hierchical Deterministic (HD) Wallet, where that single seed can be used to generate many addresses. So how do you get from the seed to actual addresses? That's where [BIP32](https://en.bitcoin.it/wiki/BIP_0032) comes in.
|
||||
In [§17.2](17_2_Using_BIP39_in_Libwally.md), you were able to use entropy to generate a seed and its related mnemonic. As you may recall from [§3.5: Understanding the Descriptor](03_5_Understanding_the_Descriptor.md), a seed is the basis of a Hierchical Deterministic (HD) Wallet, where that single seed can be used to generate many addresses. So how do you get from the seed to actual addresses? That's where [BIP32](https://en.bitcoin.it/wiki/BIP_0032) comes in.
|
||||
|
||||
## Create an HD Root
|
||||
|
||||
To create a HD address requires starting with a seed, and then walking down the hierarchy until the point that you create addresses.
|
||||
|
||||
That starts off easily enough, you just generate a seed, which you already did in the previous section:
|
||||
```
|
||||
```c
|
||||
unsigned char entropy[16];
|
||||
randombytes_buf(entropy, 16);
|
||||
|
||||
@ -23,7 +23,7 @@ That starts off easily enough, you just generate a seed, which you already did i
|
||||
### Generate a Root Key
|
||||
|
||||
With a seed in hand, you can then generate a master extended key with the `bip32_key_from_seed_alloc` function (or alternatively the `bip32_key_from_seed`, which doesn't do the `alloc`):
|
||||
```
|
||||
```c
|
||||
struct ext_key *key_root;
|
||||
lw_response = bip32_key_from_seed_alloc(seed,sizeof(seed),BIP32_VER_TEST_PRIVATE,0,&key_root);
|
||||
```
|
||||
@ -34,7 +34,7 @@ As you can see, you'll need to tell it what version of the key to return, in thi
|
||||
### Generate xpub & xprv
|
||||
|
||||
Whenever you have a key in hand, you can turn it into xpub or xprv keys for distribution with the `bip32_key_to_base58` command. You just tell it whether you want a `PRIVATE` (xprv) or `PUBLIC` (xpub) key:
|
||||
```
|
||||
```c
|
||||
char *xprv;
|
||||
lw_response = bip32_key_to_base58(key_root, BIP32_FLAG_KEY_PRIVATE, &xprv);
|
||||
|
||||
@ -44,7 +44,7 @@ Whenever you have a key in hand, you can turn it into xpub or xprv keys for dist
|
||||
|
||||
## Understand the Hierarchy
|
||||
|
||||
Before going further, you need to understand how the hierarchy of an HD wallet works. As discussed in [§3.5](03_5_Understanding_the_Descriptor.md), a derivation path describes the tree that you follow to get to a hierarchical key, so `[0/1/0]` is the 0th child of the 1st child of the 0th child of a root key. Sometimes part of that derivation are marked with `'`s or `h`s to show "hardened derivations, which increase security: `[0'/1'/0']`.
|
||||
Before going further, you need to understand how the hierarchy of an HD wallet works. As discussed in [§3.5](03_5_Understanding_the_Descriptor.md), a derivation path describes the tree that you follow to get to a hierarchical key, so `[0/1/0]` is the 0th child of the 1st child of the 0th child of a root key. Sometimes part of that derivation are marked with `'`s or `h`s to show hardened derivations, which increase security: `[0'/1'/0']`.
|
||||
|
||||
However, for HD wallets, each of those levels of the hierachy is used in a very specific way. This was originally defined in [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and was later updated for Segwit in [BIP84].
|
||||
|
||||
@ -71,18 +71,18 @@ To generate an address, you thus have to dig down through the whole hierarchy.
|
||||
### Generate an Account Key
|
||||
|
||||
One way to do this is to use the `bip32_key_from_parent_path_alloc` function to drop down several levels of a hierarchy. You embed the levels in an array:
|
||||
```
|
||||
```c
|
||||
uint32_t path_account[] = {BIP32_INITIAL_HARDENED_CHILD+84, BIP32_INITIAL_HARDENED_CHILD+1, BIP32_INITIAL_HARDENED_CHILD};
|
||||
```
|
||||
Here we'll be looking at the zeroth hardened child (that's the account) or the first hardened child (that's testnet coins) of the 84th hardened child (that's the BIP84 standard): `[m/84'/1'/0']`.
|
||||
|
||||
You can then use that path to generate a new key from your old key:
|
||||
```
|
||||
```c
|
||||
struct ext_key *key_account;
|
||||
lw_response = bip32_key_from_parent_path_alloc(key_root,path_account,sizeof(path_account),BIP32_FLAG_KEY_PRIVATE,&key_account);
|
||||
```
|
||||
Every time you have a new key, you can use that to generate new xprv and xpub keys, if you desire:
|
||||
```
|
||||
```c
|
||||
lw_response = bip32_key_to_base58(key_account, BIP32_FLAG_KEY_PRIVATE, &a_xprv);
|
||||
lw_response = bip32_key_to_base58(key_account, BIP32_FLAG_KEY_PUBLIC, &a_xpub);
|
||||
```
|
||||
@ -90,19 +90,19 @@ Every time you have a new key, you can use that to generate new xprv and xpub ke
|
||||
### Generate an Address Key
|
||||
|
||||
Alternatively, you can use the `bip32_key_from_parent_alloc` function, which just drops down one level of the hierarchy at a time. The following example drops down to the 0th child of the account key (which is the external address) and then the 0th child of that. This would be useful because then you could continue generating the 1st address, the 2nd address, and so on from that external key:
|
||||
```
|
||||
```c
|
||||
struct ext_key *key_external;
|
||||
lw_response = bip32_key_from_parent_alloc(key_account,0,BIP32_FLAG_KEY_PRIVATE,&key_external);
|
||||
|
||||
struct ext_key *key_address;
|
||||
lw_response = bip32_key_from_parent_alloc(key_external,0,BIP32_FLAG_KEY_PRIVATE,&key_address);
|
||||
```
|
||||
> :warning: **WARNING::** At some point in this hierarchy, you might decide to generate `BIP32_FLAG_KEY_PUBLIC` instead of `BIP32_FLAG_KEY_PRIVATE`. Obviously this decision will be based on your security and your needs, but remember that you only need a public key to generate the actual address.
|
||||
> :warning: **WARNING:** At some point in this hierarchy, you might decide to generate `BIP32_FLAG_KEY_PUBLIC` instead of `BIP32_FLAG_KEY_PRIVATE`. Obviously this decision will be based on your security and your needs, but remember that you only need a public key to generate the actual address.
|
||||
|
||||
### Generate an Address
|
||||
|
||||
Finally, you're ready to generate an address from your final key. All you do is run `wally_bip32_to_addr_segwit` using your final key and a description of what sort of address this is.
|
||||
```
|
||||
```c
|
||||
char *segwit;
|
||||
lw_response = wally_bip32_key_to_addr_segwit(key_address,"tb",0,&segwit);
|
||||
|
||||
@ -115,7 +115,7 @@ There is also a `wally_bip32_key_to_address` function, which can be used to gene
|
||||
|
||||
## Test HD Code
|
||||
|
||||
The code for these HD example can, as usual, be found in the [src directory](src/16_3_genhd.c).
|
||||
The code for these HD example can, as usual, be found in the [src directory](src/17_3_genhd.c).
|
||||
|
||||
You can compile and test it:
|
||||
```
|
||||
@ -139,4 +139,4 @@ An HD wallet allows you to generate a vast number of keys from a single seed. Yo
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Programming Bitcoin with Libwally" in [16.4: Using PSBTs in Libwally](16_4_Using_PSBTs_in_Libwally.md).
|
||||
Learn more about "Programming Bitcoin with Libwally" in [17.4: Using PSBTs in Libwally](17_4_Using_PSBTs_in_Libwally.md).
|
@ -1,4 +1,4 @@
|
||||
# 16.4: Using PSBTs in Libwally
|
||||
# 17.4: Using PSBTs in Libwally
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -116,7 +116,7 @@ Obviously, there's a lot more you could look at in the PSBTs. In fact, looking i
|
||||
|
||||
### Test Your PSBT Reader
|
||||
|
||||
Again, the code for this (extremely rudimentary and specific) PSBT reader is in the [src directory](src/16_4_examinepsbt.c).
|
||||
Again, the code for this (extremely rudimentary and specific) PSBT reader is in the [src directory](src/17_4_examinepsbt.c).
|
||||
|
||||
You can compile it as normal:
|
||||
```
|
||||
@ -289,7 +289,7 @@ But what you have is not yet a legal PSBT, because of the lack of inputs. You ca
|
||||
```
|
||||
### Test Your PSBT Creation
|
||||
|
||||
At this point, you should have an empty, but working PSBT, which you can see by compiling and running [the program](src/16_4_createemptypsbt.c).
|
||||
At this point, you should have an empty, but working PSBT, which you can see by compiling and running [the program](src/17_4_createemptypsbt.c).
|
||||
```
|
||||
$ cc createemptypsbt.c -lwallycore -o createemptypsbt
|
||||
$ ./createemptypsbt
|
||||
@ -373,4 +373,4 @@ This section could be an entire chapter, as working with PSBTs at a low level is
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Programming Bitcoin with Libwally" in [16.5: Using Scripts in Libwally](16_5_Using_Scripts_in_Libwally.md).
|
||||
Learn more about "Programming Bitcoin with Libwally" in [17.5: Using Scripts in Libwally](17_5_Using_Scripts_in_Libwally.md).
|
@ -1,4 +1,4 @@
|
||||
# 16.5: Using Scripts in Libwally
|
||||
# 17.5: Using Scripts in Libwally
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -82,7 +82,7 @@ One more command adds it to your transaction:
|
||||
|
||||
Creating the input is much harder because you have to pile information into the creation routines, not all of which is intuitively accessible when you're using Libwally. So, rather than going that deep into the weeds, here's where we take our shortcut. We write our code so that it's passed the hex code for a transaction that's already been created, and then we just reuse the input.
|
||||
|
||||
The conversion from the hex code is done with `wally_tx_from_hex:
|
||||
The conversion from the hex code is done with `wally_tx_from_hex`:
|
||||
```
|
||||
struct wally_tx *utxo;
|
||||
lw_response = wally_tx_from_hex(utxo_hex,0,&utxo);
|
||||
@ -98,7 +98,7 @@ As you might expect, you then add that input to your transaction:
|
||||
lw_response = wally_tx_add_input(tx,tx_input);
|
||||
```
|
||||
|
||||
> :note: **NOTE** Obviously, you'll want to be able to create your own inputs if you're using Libwally for real applications, but this is intended as a first step. And, it can actually be useful for integrating with `bitcoin-cli`, as we'll see in [§16.7](16_7_Integrating_Libwally_and_Bitcoin-CLI.md).
|
||||
> **NOTE** Obviously, you'll want to be able to create your own inputs if you're using Libwally for real applications, but this is intended as a first step. And, it can actually be useful for integrating with `bitcoin-cli`, as we'll see in [§16.7](17_7_Integrating_Libwally_and_Bitcoin-CLI.md).
|
||||
|
||||
### Print a Transaction
|
||||
|
||||
@ -113,7 +113,7 @@ We'll show how to make use of that in §16.7.
|
||||
|
||||
## Test Your Replacement Script
|
||||
|
||||
You can grab the test code from the [src directory](src/16_5_replacewithscript.c) and compile it:
|
||||
You can grab the test code from the [src directory](src/17_5_replacewithscript.c) and compile it:
|
||||
```
|
||||
$ cc replacewithscript.c -lwallycore -o replacewithscript
|
||||
```
|
||||
@ -177,4 +177,4 @@ Creating transactions in Libwally is another topic that could take up a whole ch
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Programming Bitcoin with Libwally" in [§16.6: Using Other Functions in Libwally](16_6_Using_Other_Functions_in_Libwally.md).
|
||||
Learn more about "Programming Bitcoin with Libwally" in [§17.6: Using Other Functions in Libwally](17_6_Using_Other_Functions_in_Libwally.md).
|
@ -1,4 +1,4 @@
|
||||
# 16.6: Using Other Functions in Libwally
|
||||
# 17.6: Using Other Functions in Libwally
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -45,7 +45,7 @@ Some relate to the wallet import format (WIF):
|
||||
|
||||
## Use BIP32 Functions
|
||||
|
||||
There are additional BIP32 HD-wallet functions, beyond what was covered in [§16.3: Using BIP32 in Libwally](16_3_Using_BIP32_in_Libwally.md).
|
||||
There are additional BIP32 HD-wallet functions, beyond what was covered in [§17.3: Using BIP32 in Libwally](17_3_Using_BIP32_in_Libwally.md).
|
||||
|
||||
* `bip32_key_get_fingerprint` — Generate a BIP32 fingerprint for an extended key
|
||||
* `bip32_key_serialize` — Transform an extended key into serialized bytes
|
||||
@ -65,7 +65,7 @@ The main functions are:
|
||||
|
||||
## Use BIP39 Functions
|
||||
|
||||
A few BIP39 mnemonic-word functions were just overviewed in [§16.2: Using BIP39 in Libwally](16_2_Using_BIP39_in_Libwally.md):
|
||||
A few BIP39 mnemonic-word functions were just overviewed in [§17.2: Using BIP39 in Libwally](17_2_Using_BIP39_in_Libwally.md):
|
||||
|
||||
* `bip39_get_languages` — See a list of supported languages
|
||||
* `bit39_get_word` — Retrieve a specific word from a language's word list
|
||||
@ -73,11 +73,11 @@ A few BIP39 mnemonic-word functions were just overviewed in [§16.2: Using BIP39
|
||||
|
||||
## Use PSBT Functions
|
||||
|
||||
Listings of most PSBT functions can be found in [16.4: Using PSBTs in Libwally](16_4_Using_PSBTs_in_Libwally.md).
|
||||
Listings of most PSBT functions can be found in [17.4: Using PSBTs in Libwally](17_4_Using_PSBTs_in_Libwally.md).
|
||||
|
||||
## Use Script Functions
|
||||
|
||||
[§16.5: Using Scripts in Libwally](16_5_Using_Scripts_in_Libwally.md) just barely touched upon Libwally's Scripts functions.
|
||||
[§17.5: Using Scripts in Libwally](17_5_Using_Scripts_in_Libwally.md) just barely touched upon Libwally's Scripts functions.
|
||||
|
||||
There's another function that lets you determine the sort of script found in a transaction:
|
||||
|
||||
@ -102,7 +102,7 @@ Then there are a slew of functions that create `scriptPubKey` from bytes, `scrip
|
||||
|
||||
## Use Transaction Functions
|
||||
|
||||
We also just barely touched upon the functions that can be used to create and convert functions in [§16.5](16_5_Using_Scripts_in_Libwally.md).
|
||||
We also just barely touched upon the functions that can be used to create and convert functions in [§17.5](17_5_Using_Scripts_in_Libwally.md).
|
||||
|
||||
There are numerous informational functions, some of the more interesting of which are:
|
||||
|
||||
@ -122,6 +122,6 @@ There is much more that you can do with Libwally, more than can be covered in th
|
||||
|
||||
## What's Next?
|
||||
|
||||
Finish learning about "Programming Bitcoin with Libwally" in [§16.7: Integrating Libwally and Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md).
|
||||
Finish learning about "Programming Bitcoin with Libwally" in [§17.7: Integrating Libwally and Bitcoin-CLI](17_7_Integrating_Libwally_and_Bitcoin-CLI.md).
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# 16.7: Integrating Libwally and Bitcoin-CLI
|
||||
# 17.7: Integrating Libwally and Bitcoin-CLI
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -8,7 +8,7 @@ This final section will offer some examples of using Libwally programs to comple
|
||||
|
||||
## Share a Transaction
|
||||
|
||||
[§16.5: Using Scripts in Libwally](16_5_Using_Scripts_in_Libwally.md) detailed how Libwally could be used to rewrite an existing transaction, to do something that `bitcoin-cli` can't: produce a transaction that contains a unique P2SH. Obviously, this is a building block; if you decide to dig further into Libwally you'll create entire transactions on your own. But, this abbreviated methodology also has its own usage: it shows how transactions can be passed back and forth between `bitcoin-cli` and Libwally, demonstrating a first example of using them in a complementary fashion.
|
||||
[§17.5: Using Scripts in Libwally](17_5_Using_Scripts_in_Libwally.md) detailed how Libwally could be used to rewrite an existing transaction, to do something that `bitcoin-cli` can't: produce a transaction that contains a unique P2SH. Obviously, this is a building block; if you decide to dig further into Libwally you'll create entire transactions on your own. But, this abbreviated methodology also has its own usage: it shows how transactions can be passed back and forth between `bitcoin-cli` and Libwally, demonstrating a first example of using them in a complementary fashion.
|
||||
|
||||
To fully demonstrate this methodology, you'll create a transaction with `bitcoin-cli`, using this UTXO:
|
||||
```
|
||||
@ -33,7 +33,7 @@ $ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout')
|
||||
$ recipient=tb1qycsmq3jas5wkhf8xrfn8k7438cm5pc8h9ae2k0
|
||||
$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.0009 }''')
|
||||
```
|
||||
Though you placed a recipient and an amount in the output, it's irrelevent, because you'll be rewriting those. A fancier bit of code could read the existing `vout` info before rewriting, but we're keeping things very close to our [original code](src/16_5_replacewithscript.c).
|
||||
Though you placed a recipient and an amount in the output, it's irrelevent, because you'll be rewriting those. A fancier bit of code could read the existing `vout` info before rewriting, but we're keeping things very close to our [original code](src/17_5_replacewithscript.c).
|
||||
|
||||
Here's the one change necessary, to allow you to specify the satoshi `vout`, without having to hardcode it, as in the original:
|
||||
```
|
||||
@ -170,7 +170,7 @@ $ bitcoin-cli decoderawtransaction $signedtx
|
||||
```
|
||||
Voila! That's the power of Libwally with `bitcoin-cli`.
|
||||
|
||||
Obviously, you can also pass around a PSBT using the functions described in [§16.4](16_4_Using_PSBTs_in_Libwally.md) and that's a more up-to-date methodology for the modern-day usage of Bitcoin, but in either example, the concept of passing transactions from `bitcoin-cli` to Libwally code and back should be similar.
|
||||
Obviously, you can also pass around a PSBT using the functions described in [§17.4](17_4_Using_PSBTs_in_Libwally.md) and that's a more up-to-date methodology for the modern-day usage of Bitcoin, but in either example, the concept of passing transactions from `bitcoin-cli` to Libwally code and back should be similar.
|
||||
|
||||
## Import & Export BIP39 Seeds
|
||||
|
||||
@ -178,11 +178,11 @@ Unfortunately, not all interactions between Libwally and `bitcoin-cli` go as smo
|
||||
|
||||
> :book: ***What's the Difference Between Entropy & a Seed?*** Libwally says that it creates its mnemonic phrases from entropy. That's essentially the same thing as a seed: they're both large, randomized numbers. So, if `bitcoin-cli` was compatible with 512-bit mnemonic-phrase seeds, you could use one to generate the mneomnic phrases, and get the results that you'd expect.
|
||||
|
||||
> :book: ***What's the difference between Entropy & Raw Entropy?*** Not all entropy is the same. When you input entropy into a command that creates a mnemonic seed, it has to a specific, well-understand length. Changing raw entropy into entropy requires massaging the raw entropy until it's the right length and format, and at that point you could reuse that (non-raw) entropy to always recreate the same mnemonics (which is why entropy is effectively the same thing as a seed at that point, but raw entropy isn't).
|
||||
> :book: ***What's the difference between Entropy & Raw Entropy?*** Not all entropy is the same. When you input entropy into a command that creates a mnemonic seed, it has to a specific, well-understood length. Changing raw entropy into entropy requires massaging the raw entropy until it's the right length and format, and at that point you could reuse that (non-raw) entropy to always recreate the same mnemonics (which is why entropy is effectively the same thing as a seed at that point, but raw entropy isn't).
|
||||
|
||||
## Import Private Keys
|
||||
|
||||
Fortunately, you can do much the same thing by importing a private key generated in Libwally. Take a look at [genhd-for-import.c](src/16_7_genhd_for_import.c), a simplified version of the `genhd` program from [§16.3](16_3_Using_BIP32_in_Libwally.md) that also uses the `jansson` library from [§15.1](15_1_Accessing_Bitcoind_with_C.md) for regularized output.
|
||||
Fortunately, you can do much the same thing by importing a private key generated in Libwally. Take a look at [genhd-for-import.c](src/17_7_genhd_for_import.c), a simplified version of the `genhd` program from [§17.3](17_3_Using_BIP32_in_Libwally.md) that also uses the `jansson` library from [§16.1](15_1_Accessing_Bitcoind_with_C.md) for regularized output.
|
||||
|
||||
The updated code also contains one change of note: it requests a fingerprint from Libwally so that it can properly create a derivation path:
|
||||
```
|
||||
@ -195,7 +195,7 @@ The updated code also contains one change of note: it requests a fingerprint fro
|
||||
|
||||
> :warning: **WARNING:** Remember that the fingerprint in derivation paths is arbitrary. Because Libwally provides one, we're using it, but if you didn't have one, you could add an arbitrary 4-byte hexcode as a fingerprint to your derivation path.
|
||||
|
||||
Be sure to compile the new code with the `jansson` library, after installing it (if necessary) per [§15.1](15_1_Accessing_Bitcoind_with_C.md).
|
||||
Be sure to compile the new code with the `jansson` library, after installing it (if necessary) per [§16.1](15_1_Accessing_Bitcoind_with_C.md).
|
||||
```
|
||||
$ cc genhd-for-import.c -lwallycore -lsodium -ljansson -o genhd-for-import
|
||||
```
|
||||
@ -327,4 +327,4 @@ With a foundational knowledge of Libwally, you can now complement all of the wor
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn about other sorts of programming in [Chapter 17: Talking to Bitcoind with Other Languages](17_0_Talking_to_Bitcoind_Other.md).
|
||||
Learn about other sorts of programming in [Chapter 18: Talking to Bitcoind with Other Languages](18_0_Talking_to_Bitcoind_Other.md).
|
@ -1,4 +1,4 @@
|
||||
# Chapter 17: Talking to Bitcoind with Other Languages
|
||||
# Chapter 18: Talking to Bitcoind with Other Languages
|
||||
|
||||
You should now have a solid foundation for working with Bitcoin in C, not only using RPC, JSON, and ZMQ libraries to directly interact with `bitcoind`, but also utilizing the Libwally libraries to complement that work. And C is a great language for prototyping and abstraction — but it's probably not what you're programming in. This chapter thus takes a whirlwind tour of six other programming languages, demonstrating the barest Bitcoin functionality in each and allowing you to expand the lessons of the command line and C to the programming language of your choice.
|
||||
|
||||
@ -18,9 +18,9 @@ Supporting objectives include the ability to:
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Section One: Accessing Bitcoind with Go](17_1_Accessing_Bitcoind_with_Go.md)
|
||||
* [Section Two: Accessing Bitcoind with Java](17_2_Accessing_Bitcoind_with_Java.md)
|
||||
* [Section Three: Accessing Bitcoind with NodeJS](17_3_Accessing_Bitcoind_with_NodeJS.md)
|
||||
* [Section Four: Accessing Bitcoind with Python](17_4_Accessing_Bitcoind_with_Python.md)
|
||||
* [Section Five: Accessing Bitcoind with Rust](17_5_Accessing_Bitcoind_with_Rust.md)
|
||||
* [Section Six: Accessing Bitcoind with Swift](17_6_Accessing_Bitcoind_with_Swift.md)
|
||||
* [Section One: Accessing Bitcoind with Go](18_1_Accessing_Bitcoind_with_Go.md)
|
||||
* [Section Two: Accessing Bitcoind with Java](18_2_Accessing_Bitcoind_with_Java.md)
|
||||
* [Section Three: Accessing Bitcoind with NodeJS](18_3_Accessing_Bitcoind_with_NodeJS.md)
|
||||
* [Section Four: Accessing Bitcoind with Python](18_4_Accessing_Bitcoind_with_Python.md)
|
||||
* [Section Five: Accessing Bitcoind with Rust](18_5_Accessing_Bitcoind_with_Rust.md)
|
||||
* [Section Six: Accessing Bitcoind with Swift](18_6_Accessing_Bitcoind_with_Swift.md)
|
@ -1,4 +1,4 @@
|
||||
# 17.1: Accessing Bitcoind with Go
|
||||
# 18.1: Accessing Bitcoind with Go
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -126,7 +126,7 @@ Every `bitcoind` function in Go begins with creating the RPC connection, using t
|
||||
```
|
||||
The ```connCfg``` parameters allow you to choose the Bitcoin RPC port, username, password and whether you are on testnet or mainnet.
|
||||
|
||||
> :note: **NOTE:** Again, be sure to substitute the `User` and `Pass` with the one found in your `~/.bitcoin/bitcon.conf`.
|
||||
> **NOTE:** Again, be sure to substitute the `User` and `Pass` with the one found in your `~/.bitcoin/bitcon.conf`.
|
||||
|
||||
The```rpcclient.New(connCfg, nil)``` function then configures ```client``` to connect to your Bitcoin node.
|
||||
|
||||
@ -160,7 +160,7 @@ However, a quirk with hashes in `rpcclient` is that they will typically print in
|
||||
|
||||
### Run Your Code
|
||||
|
||||
You can download the complete code from the [src directory](src/17_1_blockinfo.go).
|
||||
You can download the complete code from the [src directory](src/18_1_blockinfo.go).
|
||||
|
||||
You can then run:
|
||||
```
|
||||
@ -185,7 +185,7 @@ Due to limitations of the `btcd` `rpcclient`, you can't make a use of the ```get
|
||||
```
|
||||
```client.GetBalance("*")``` requires the ```"*"``` input, due to a quirk with `btcd`. The asterisk signifies that you want to get the balance of all of your wallets.
|
||||
|
||||
If you run [the src code](src/17_1_getbalance.go), you should get an output similar to this:
|
||||
If you run [the src code](src/18_1_getbalance.go), you should get an output similar to this:
|
||||
```
|
||||
$ go run getbalance.go
|
||||
0.000689 BTC
|
||||
@ -268,7 +268,7 @@ The defaultNet variable is now used to specify whether your Bitcoin node is on t
|
||||
}
|
||||
```
|
||||
|
||||
> :note: **NOTE:** Change the address (`mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha`) for one actually your wallet; you can use `bitcoin-cli listunspent` to find some addresses with funds for this test. If you want to be really fancy, modify the Go code to take an argument, then write a script that runs `listunspent`, saves the info to a variable, and runs the Go code on that.
|
||||
> **NOTE:** Change the address (`mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha`) for one actually your wallet; you can use `bitcoin-cli listunspent` to find some addresses with funds for this test. If you want to be really fancy, modify the Go code to take an argument, then write a script that runs `listunspent`, saves the info to a variable, and runs the Go code on that.
|
||||
|
||||
Only afterward do you use the `getreceivedbyaddress` RPC, on your decoded address:
|
||||
```
|
||||
@ -279,7 +279,7 @@ Only afterward do you use the `getreceivedbyaddress` RPC, on your decoded addres
|
||||
|
||||
fmt.Println(wallet)
|
||||
```
|
||||
When you run [the code](src/17_1_getamountreceived.go), you should get output similar to:
|
||||
When you run [the code](src/18_1_getamountreceived.go), you should get output similar to:
|
||||
```
|
||||
$ go run getamountreceived.go
|
||||
0.0085 BTC
|
||||
@ -331,7 +331,7 @@ func main() {
|
||||
fmt.Println(sent)
|
||||
}
|
||||
```
|
||||
When you run [the code](src/17_1_sendtransaction.go), the txid of the transaction is outputted:
|
||||
When you run [the code](src/18_1_sendtransaction.go), the txid of the transaction is outputted:
|
||||
|
||||
```
|
||||
$ go run sendtransaction.go
|
||||
@ -378,7 +378,7 @@ func main() {
|
||||
fmt.Println(transactions)
|
||||
}
|
||||
```
|
||||
> :note: **NOTE:** Again, you'll want to change out the txid for one actually recognized by your system.
|
||||
> **NOTE:** Again, you'll want to change out the txid for one actually recognized by your system.
|
||||
|
||||
When you run [the code](17_1_lookuptransaction.go) it will print out the details associated with a transaction, such as its amount and how many times it has been confirmed:
|
||||
|
||||
@ -415,4 +415,4 @@ Although the `btcd` `rpcclient` has some limits, you can still perform the main
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Talking to Bitcoin in Other Languages" in [17.2: Accessing Bitcoin with Java](17_2_Accessing_Bitcoind_with_Java.md).
|
||||
Learn more about "Talking to Bitcoin in Other Languages" in [18.2: Accessing Bitcoin with Java](18_2_Accessing_Bitcoind_with_Java.md).
|
@ -1,4 +1,4 @@
|
||||
# 17.2: Accessing Bitcoind with Java
|
||||
# 18.2: Accessing Bitcoind with Java
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -154,7 +154,7 @@ PubKey: 0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65
|
||||
|
||||
### Run Your Code
|
||||
|
||||
The code for these examples can be found in [the src directory](src/17_2_App-getinfo.java) and should be installed into the standard directory structure created here as `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. It can then be compiled and run.
|
||||
The code for these examples can be found in [the src directory](src/18_2_App-getinfo.java) and should be installed into the standard directory structure created here as `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. It can then be compiled and run.
|
||||
|
||||
```
|
||||
$ mvn compile
|
||||
@ -273,12 +273,12 @@ You now can sign transaction with the method `signRawTransactionWithKey`. This m
|
||||
Finally, sending requires the `sendRawTransaction` command:
|
||||
```java
|
||||
String sentRawTransactionID = rpcClient.sendRawTransaction(srTx.hex());
|
||||
System.out.println("Sent signedRawTx (txID): " + sentRawTransactionID);```
|
||||
System.out.println("Sent signedRawTx (txID): " + sentRawTransactionID);
|
||||
```
|
||||
|
||||
### Run Your Code
|
||||
|
||||
You can now run [the transaction code](src/17_2_App-sendtx.java) as `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`.
|
||||
You can now run [the transaction code](src/18_2_App-sendtx.java) as `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`.
|
||||
|
||||
```
|
||||
$ mvn compile
|
||||
@ -317,7 +317,7 @@ To do this, use `JavaBitcoindRpcClient`'s `BitcoinAcceptor` class, which allows
|
||||
acceptor.run();
|
||||
```
|
||||
|
||||
See [the src directory](src/17_2_App-listen.java) for the complete code. Every time a transaction is sent or a new block is generated, you should see output on your console:
|
||||
See [the src directory](src/18_2_App-listen.java) for the complete code. Every time a transaction is sent or a new block is generated, you should see output on your console:
|
||||
```
|
||||
Transaction: {account=Tests, address=mhopuJzgmTwhGfpNLCJ9CRknugY691oXp1, category=receive, amount=5.0E-4, label=Tests, vout=1, confirmations=0, trusted=false, txid=361e8fcff243b74ebf396e595a007636654f67c3c7b55fd2860a3d37772155eb, walletconflicts=[], time=1513132887, timereceived=1513132887, bip125-replaceable=unknown}
|
||||
|
||||
@ -330,5 +330,5 @@ By using the javabitcoinrpc library, you can easily access bitcoind via RPC call
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Talking to Bitcoin in Other Languages" in [17.3: Accessing Bitcoin with NodeJS](17_3_Accessing_Bitcoind_with_NodeJS.md).
|
||||
Learn more about "Talking to Bitcoin in Other Languages" in [18.3: Accessing Bitcoin with NodeJS](18_3_Accessing_Bitcoind_with_NodeJS.md).
|
||||
|
@ -1,4 +1,4 @@
|
||||
# 17.3: Accessing Bitcoind with NodeJS
|
||||
# 18.3: Accessing Bitcoind with NodeJS
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -34,7 +34,7 @@ $ export BITCOIND_PASS=d8340efbcd34e312044c8431c59c792c
|
||||
$ export BITCOIND_PORT=18332
|
||||
```
|
||||
|
||||
> :warning: **WARNING:** Obviously, you'd never put set your password in an environmental variable in a production environment.
|
||||
> :warning: **WARNING:** Obviously, you'd never put your password in an environmental variable in a production environment.
|
||||
|
||||
> :link: **MAINNET VS TESTNET:** The port would be 8332 for a mainnet setup.
|
||||
|
||||
@ -111,7 +111,7 @@ The result of the BCRPC functions is a JSON object containing information about
|
||||
|
||||
### Run Your Code
|
||||
|
||||
You can find the `getinfo` code in [the src directory](src/17_3_getinfo.js).
|
||||
You can find the `getinfo` code in [the src directory](src/18_3_getinfo.js).
|
||||
```
|
||||
$ node getinfo.js
|
||||
1831094
|
||||
@ -163,7 +163,7 @@ agent.getWalletInfo(function (err, walletInfo) {
|
||||
});
|
||||
```
|
||||
|
||||
The source is available as [walletinfo.js](src/17_3_walletinfo.js).
|
||||
The source is available as [walletinfo.js](src/18_3_walletinfo.js).
|
||||
```
|
||||
$ node walletinfo.js
|
||||
0.008498
|
||||
@ -261,7 +261,7 @@ You should get an output similar to this:
|
||||
}
|
||||
```
|
||||
|
||||
The full code is available as [sendtx.js](src/17_3_sendtx.js).
|
||||
The full code is available as [sendtx.js](src/18_3_sendtx.js).
|
||||
|
||||
## Summary: Accessing Bitcoind with Node
|
||||
|
||||
@ -271,4 +271,4 @@ Based on these examples you should be able to incorporate Bitcoin in a Node.js p
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Talking to Bitcoin in Other Languages" in [17.4: Accessing Bitcoin with Python](17_4_Accessing_Bitcoind_with_Python.md).
|
||||
Learn more about "Talking to Bitcoin in Other Languages" in [18.4: Accessing Bitcoin with Python](18_4_Accessing_Bitcoind_with_Python.md).
|
@ -1,4 +1,4 @@
|
||||
# 17.4: Accessing Bitcoind with Python
|
||||
# 18.4: Accessing Bitcoind with Python
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -125,7 +125,7 @@ print("---------------------------------------------------------------\n")
|
||||
|
||||
### Run Your Code
|
||||
|
||||
You can retrieve [the src code](src/17_4_getinfo.py) and run it with `python3`:
|
||||
You can retrieve [the src code](src/18_4_getinfo.py) and run it with `python3`:
|
||||
```
|
||||
$ python3 getinfo.py
|
||||
---------------------------------------------------------------
|
||||
@ -218,7 +218,7 @@ pprint(utxos)
|
||||
print("------------------------------------------\n")
|
||||
```
|
||||
|
||||
In order to manipulate an array like the one returned from `listtransactions` or `listunpsent`, you just grab the appropriate item from the appropriate element of the array:
|
||||
In order to manipulate an array like the one returned from `listtransactions` or `listunspent`, you just grab the appropriate item from the appropriate element of the array:
|
||||
```
|
||||
## Select a UTXO - first one selected here
|
||||
utxo_txid = utxos[0]['txid']
|
||||
@ -239,7 +239,7 @@ pprint(utxo_tx_details)
|
||||
print("---------------------------------------------------------------\n")
|
||||
```
|
||||
|
||||
This code is available at [walletinfo.py](src/17_4_walletinfo.py).
|
||||
This code is available at [walletinfo.py](src/18_4_walletinfo.py).
|
||||
|
||||
```
|
||||
$ python3 walletinfo.py
|
||||
@ -379,7 +379,7 @@ change_amt = float('%.8f'%((utxo_amt - recipient_amt) - miner_fee))
|
||||
|
||||
> :warning: **WARNING:** Obviously a real program would make more sophisticated choices about what UTXO to use, what to do with the funds, and what miner's fee to pay.
|
||||
|
||||
### 2. Create Raw Transacion
|
||||
### 2. Create Raw Transaction
|
||||
|
||||
Now you have all the information to send a transaction, but before you can send one, you have to create a transaction.
|
||||
|
||||
@ -418,7 +418,7 @@ send_tx = rpc_client.sendrawtransaction(signed_tx['hex'])
|
||||
```
|
||||
### Run Your Code
|
||||
|
||||
The [sample code](src/17_4_sendtx.py) is full of `print` statements to demonstrate all of the data available at every point:
|
||||
The [sample code](src/18_4_sendtx.py) is full of `print` statements to demonstrate all of the data available at every point:
|
||||
```
|
||||
$ python3 sendtx.py
|
||||
Creating a Transaction
|
||||
@ -453,15 +453,16 @@ TXID of sent transaction: 187f8baa222f9f37841d966b6bad59b8131cfacca861cbe9bfc86
|
||||
|
||||
## Summary: Accessing Bitcoind with Python
|
||||
|
||||
Accessing Bitcoind with Python is very easy while using the `python-bitcoinrpc` library. The first thing to always do is to establish a connection with your `bitcoind` instance, then you can call all of the bitcoin API calls as described in the bitcoin-core documentation. This makes it easy to create small or large prorgrams to manage your own node, check balances, or create cool applications on top, as you access the full power of `bitcoin-cli`.
|
||||
Accessing Bitcoind with Python is very easy while using the `python-bitcoinrpc` library. The first thing to always do is to establish a connection with your `bitcoind` instance, then you can call all of the bitcoin API calls as described in the bitcoin-core documentation. This makes it easy to create small or large programs to manage your own node, check balances, or create cool applications on top, as you access the full power of `bitcoin-cli`.
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Talking to Bitcoin in Other Languages" in [17.5: Accessing Bitcoin with Rust](17_5_Accessing_Bitcoind_with_Rust.md).
|
||||
Learn more about "Talking to Bitcoin in Other Languages" in [18.5: Accessing Bitcoin with Rust](18_5_Accessing_Bitcoind_with_Rust.md).
|
||||
|
||||
## Variant: Build Python from Source
|
||||
|
||||
If you need to install Python 3 from source, follow these instructions, then continue with ["Creating a BitcoinRPC Project"](17_4_Accessing_Bitcoind_with_Python.md#creating-a-bitcoinrpc-project).
|
||||
If you need to install Python 3 from source, follow these instructions, then continue with ["Create a BitcoinRPC Project"](18_4_Accessing_Bitcoind_with_Python.md#create-a-bitcoinrpc-project).
|
||||
|
||||
|
||||
### 1. Install Dependencies
|
||||
```sh
|
@ -1,4 +1,4 @@
|
||||
# 17.5: Accessing Bitcoind with Rust
|
||||
# 18.5: Accessing Bitcoind with Rust
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -131,11 +131,11 @@ Here's the complete code to retrieve a block hash, turn that into a block, and p
|
||||
println!("{:?}", block);
|
||||
```
|
||||
|
||||
> :note: **NOTE:** Another possible call that we considered for this section was `get_address_info`, but unfortunately as of this writing, the `bitcoincore-rpc` function doesn't work with recent versions of Bitcoin Core due to the crate not addressing the latest API changes in Bitcoin Core. We expect this will be solved in the next crate's release, but in the meantime, _caveat programmer_.
|
||||
> **NOTE:** Another possible call that we considered for this section was `get_address_info`, but unfortunately as of this writing, the `bitcoincore-rpc` function doesn't work with recent versions of Bitcoin Core due to the crate not addressing the latest API changes in Bitcoin Core. We expect this will be solved in the next crate's release, but in the meantime, _caveat programmer_.
|
||||
|
||||
### Run Your Code
|
||||
|
||||
You can access the [src code](src/17_5_main-getinfo.rs) and run it. Unfortunately, the "Block" info will come out a bit ugly because this example doesn't include a library to prettify it.
|
||||
You can access the [src code](src/18_5_main-getinfo.rs) and run it. Unfortunately, the "Block" info will come out a bit ugly because this example doesn't include a library to prettify it.
|
||||
```
|
||||
$ cargo run
|
||||
Compiling btc_test v0.1.0 (/home/standup/btc_test)
|
||||
@ -289,7 +289,7 @@ println!("{:?}", txid_sent);
|
||||
|
||||
### Run Your Code
|
||||
|
||||
You can now run the complete code from the [src](src/17_5_main-sendtx.rs).
|
||||
You can now run the complete code from the [src](src/18_5_main-sendtx.rs).
|
||||
|
||||
```
|
||||
$ cargo run
|
||||
@ -358,5 +358,5 @@ b0eda3517e6fac69e58ae315d7fe7a1981e3a858996cc1e3135618cac9b79d1a
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn more about "Talking to Bitcoin in Other Languages" in [17.6: Accessing Bitcoin with Swift](17_6_Accessing_Bitcoind_with_Swift.md).
|
||||
Learn more about "Talking to Bitcoin in Other Languages" in [18.6: Accessing Bitcoin with Swift](18_6_Accessing_Bitcoind_with_Swift.md).
|
||||
|
@ -1,4 +1,4 @@
|
||||
# 17.6: Accessing Bitcoind with Swift
|
||||
# 18.6: Accessing Bitcoind with Swift
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -191,7 +191,7 @@ makeCommand(method: method,param: param) { result in
|
||||
|
||||
### Run Your Code
|
||||
|
||||
The complete code is available in the [src directory](src/17_6_getinfo.playground). Load it into your Xcode playground and then "Editor -> Run Playground" and you should get results like:
|
||||
The complete code is available in the [src directory](src/18_6_getinfo.playground). Load it into your Xcode playground and then "Editor -> Run Playground" and you should get results like:
|
||||
```
|
||||
{
|
||||
bestblockhash = 00000000000000069725608ebc5b59e520572a8088cbc57ffa5ba87b7f300ac7;
|
||||
@ -385,7 +385,7 @@ Sending your transaction is equally simple:
|
||||
}
|
||||
```
|
||||
|
||||
The code for this transaction sender can be found in the [src directory](src/17_6_sendtx.playground).
|
||||
The code for this transaction sender can be found in the [src directory](src/18_6_sendtx.playground).
|
||||
|
||||
## Use Swift in Other Ways
|
||||
|
||||
@ -400,7 +400,7 @@ Swift is a robust modern programming language that unfortunately doesn't yet hav
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn about Lightning in [Chapter 18: Understanding Your Lightning Setup](18_0_Understanding_Your_Lightning_Setup.md).
|
||||
Learn about Lightning in [Chapter 19: Understanding Your Lightning Setup](19_0_Understanding_Your_Lightning_Setup.md).
|
||||
|
||||
## Variant: Deploy Swift on Ubuntu
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Chapter 18: Understanding Your Lighting Setup
|
||||
# Chapter 19: Understanding Your Lighting Setup
|
||||
|
||||
> :information_source: **NOTE:** This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning.
|
||||
|
||||
@ -20,7 +20,7 @@ Supporting objectives include the ability to:
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Section One: Verifying Your c-lightning Setup](18_1_Verifying_Your_Lightning_Setup.md)
|
||||
* [Section Two: Knowing Your c-lightning Setup](18_2_Knowing_Your_lightning_Setup.md)
|
||||
* [Interlude: Accessing a Second Lightning Node](18_2__Interlude_Accessing_a_Second_Lightning_Node.md)
|
||||
* [Section Three: Creating a Lightning Channel](18_3_Setting_Up_a_Channel.md)
|
||||
* [Section One: Verifying Your c-lightning Setup](19_1_Verifying_Your_Lightning_Setup.md)
|
||||
* [Section Two: Knowing Your c-lightning Setup](19_2_Knowing_Your_lightning_Setup.md)
|
||||
* [Interlude: Accessing a Second Lightning Node](19_2__Interlude_Accessing_a_Second_Lightning_Node.md)
|
||||
* [Section Three: Creating a Lightning Channel](19_3_Setting_Up_a_Channel.md)
|
@ -1,5 +1,4 @@
|
||||
|
||||
# 18.1: Creating a c-lightning Setup
|
||||
# 19.1: Creating a c-lightning Setup
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -167,9 +166,9 @@ $ sudo ufw allow 9735
|
||||
You can check if your Lightning node is ready to go by comparing the output of `bitcoin-cli getblockcount` with the `blockheight` result from `lightning-cli getinfo`.
|
||||
|
||||
```
|
||||
$ bitcoin-cli getblockcount
|
||||
$ bitcoin-cli -testnet getblockcount
|
||||
1838587
|
||||
$ lightning-cli getinfo
|
||||
$ lightning-cli --testnet getinfo
|
||||
{
|
||||
"id": "03d4592f1244cd6b5a8bb7fba6a55f8a91591d79d3ea29bf8e3c3a405d15db7bf9",
|
||||
"alias": "HOPPINGNET",
|
||||
@ -266,7 +265,7 @@ Before you start playing with lightning, you should make sure that your aliases
|
||||
|
||||
## What's Next?
|
||||
|
||||
Continue "Understanding Your Lightning Setup" with [§18.2: Knowing Your Lightning Setup](18_2_Knowing_Your_lightning_Setup.md).
|
||||
Continue "Understanding Your Lightning Setup" with [§19.2: Knowing Your Lightning Setup](19_2_Knowing_Your_lightning_Setup.md).
|
||||
|
||||
## Variant: Install from Ubuntu ppa
|
||||
|
||||
@ -288,5 +287,3 @@ $ cd /
|
||||
$ sudo tar xf ~/clightning-v0.9.1-Ubuntu-20.04.tar.xz
|
||||
```
|
||||
Warning: this will require you to have the precise same libraries as were used to create the binary. It's often easier to just recompile.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# 18.2: Knowing Your c-lightning Setup
|
||||
# 19.2: Knowing Your c-lightning Setup
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -334,6 +334,6 @@ The `~/.lightning` directory contains all of your files, while `lightning-cli he
|
||||
|
||||
## What's Next?
|
||||
|
||||
You're going to need to have a second Linode node to test out the actual payment of invoices. If you need support in setting one up, read [Interlude: Accessing a Second Lightning Node](18_2__Interlude_Accessing_a_Second_Lightning_Node.md).
|
||||
You're going to need to have a second Linode node to test out the actual payment of invoices. If you need support in setting one up, read [Interlude: Accessing a Second Lightning Node](19_2__Interlude_Accessing_a_Second_Lightning_Node.md).
|
||||
|
||||
Otherwise, continue "Understanding Your Lightning Setup" with [§18.3: Setting Up_a_Channel](18_3_Setting_Up_a_Channel.md).
|
||||
Otherwise, continue "Understanding Your Lightning Setup" with [§19.3: Setting Up_a_Channel](19_3_Setting_Up_a_Channel.md).
|
@ -52,7 +52,7 @@ They can then tell you their `id` (`03240a4878a9a64aea6c3921a434e573845267b86e89
|
||||
|
||||
## Create a New c-lightning Node
|
||||
|
||||
However, for testing purposes, you probably want to have a second node under you own control. The easiest way to do so is to create a second c-lightning node on a new machine, using either Bitcoin Standup, per [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) or compiling it by hand, per [§18.1](18_1_Verifying_Your_Lightning_Setup.md).
|
||||
However, for testing purposes, you probably want to have a second node under you own control. The easiest way to do so is to create a second c-lightning node on a new machine, using either Bitcoin Standup, per [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) or compiling it by hand, per [§19.1](19_1_Verifying_Your_Lightning_Setup.md).
|
||||
|
||||
Once you have your node running, you can run `getinfo` to retrieve your information, as shown above.
|
||||
|
||||
@ -87,7 +87,7 @@ go version go1.14.4 linux/amd64
|
||||
You'll also need `git` and `make`:
|
||||
```
|
||||
$ sudo apt-get install git
|
||||
$ apt-get install build-essential
|
||||
$ sudo apt-get install build-essential
|
||||
```
|
||||
You're now ready to retrieve LND. Be sure to get the current verison (currently `v0.11.0-beta.rc4`).
|
||||
```
|
||||
@ -111,24 +111,18 @@ $ sudo cp $GOPATH/bin/lnd $GOPATH/bin/lncli /usr/bin
|
||||
|
||||
Unlike with c-lightning, you will need to create a default config file for LND.
|
||||
|
||||
First, you need to retrieve your rpcuser and rpcpassword. Here's an automated way to do so:
|
||||
```
|
||||
$ BITCOINRPC_USER=$(cat ~standup/.bitcoin/bitcoin.conf | grep rpcuser | awk -F = '{print $2}')
|
||||
$ BITCOINRPC_PASS=$(cat ~standup/.bitcoin/bitcoin.conf | grep rpcpassword | awk -F = '{print $2}')
|
||||
```
|
||||
However first, you need to enable ZMQ on your Bitcoind, if you didn't already in [§16.3](16_3_Receiving_Bitcoind_Notifications_with_C.md).
|
||||
|
||||
> :warning: **WARNING:** Obviously, never store your RPC password in a shell variable in a production environment.
|
||||
|
||||
Second, you need to enable ZMQ on your Bitcoind, if you didn't already in [§15.3](15_3_Receiving_Bitcoind_Notifications_with_C.md).
|
||||
|
||||
This requires adding the following to your `~/.bitcoin/bitcoin.conf` file:
|
||||
This requires adding the following to your `~/.bitcoin/bitcoin.conf` file if it's not already there:
|
||||
```
|
||||
zmqpubrawblock=tcp://127.0.0.1:28332
|
||||
zmqpubrawtx=tcp://127.0.0.1:28333
|
||||
```
|
||||
You must then restart bitcoin. You can test that it's working as follows:
|
||||
If you're using a Bitcoin config file from Standup or some other specialized `conf`, be sure you're putting your new commands in the correct section. Ideally, they should go near the top of the file, otherwise in the `[test]` section (assuming, as usual, that you're testing on testnet).
|
||||
|
||||
You must then restart bitcoin (or just reboot your machine). You can test that it's working as follows:
|
||||
```
|
||||
bitcoin-cli getzmqnotifications
|
||||
$ bitcoin-cli getzmqnotifications
|
||||
[
|
||||
{
|
||||
"type": "pubrawblock",
|
||||
@ -142,7 +136,17 @@ bitcoin-cli getzmqnotifications
|
||||
}
|
||||
]
|
||||
```
|
||||
Now you're ready to create a config file:
|
||||
Now you're ready to create a config file.
|
||||
|
||||
First, you need to retrieve your rpcuser and rpcpassword. Here's an automated way to do so:
|
||||
```
|
||||
$ BITCOINRPC_USER=$(cat ~standup/.bitcoin/bitcoin.conf | grep rpcuser | awk -F = '{print $2}')
|
||||
$ BITCOINRPC_PASS=$(cat ~standup/.bitcoin/bitcoin.conf | grep rpcpassword | awk -F = '{print $2}')
|
||||
```
|
||||
|
||||
> :warning: **WARNING:** Obviously, never store your RPC password in a shell variable in a production environment.
|
||||
|
||||
Then, you can write the file:
|
||||
```
|
||||
$ mkdir ~/.lnd
|
||||
$ cat > ~/.lnd/lnd.conf << EOF
|
||||
@ -318,4 +322,4 @@ You always need two Lightning nodes to form a channel. If you don't have someone
|
||||
|
||||
Though you've possibly created an LND, c-lightning will remain the heart of our examples until we need to start using both of them, in [Chapter 19](19_0_Understanding_Your_Lightning_Setup.md).
|
||||
|
||||
Continue "Understanding Your Lightning Setup" with [§18.3: Setting Up_a_Channel](18_3_Setting_Up_a_Channel.md).
|
||||
Continue "Understanding Your Lightning Setup" with [§19.3: Setting Up_a_Channel](19_3_Setting_Up_a_Channel.md).
|
@ -1,4 +1,4 @@
|
||||
# 18.3: Creating a Lightning Channel
|
||||
# 19.3: Creating a Lightning Channel
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -80,7 +80,7 @@ Now that you have funded your c-lightning wallet you will need information about
|
||||
|
||||
The next thing you need to do is connect your node to a peer. This is done with the `lightning-cli connect` command. Remember that if you want more information on this command, you should type `lightning-cli help connect`.
|
||||
|
||||
To connect your node to a remote peer you need its id, which represents the target node’s public key. As a convenience, `id` may be of the form `id@host` or `id@host:port`. You may have retrieved this with `lightning-cli getinfo` (on c-lightning) or `lncli --network=testnet getinfo` (on LND) as discussed in the [previous interlude](18_2__Interlude_Accessing_a_Second_Lightning_Node.md).
|
||||
To connect your node to a remote peer you need its id, which represents the target node’s public key. As a convenience, `id` may be of the form `id@host` or `id@host:port`. You may have retrieved this with `lightning-cli getinfo` (on c-lightning) or `lncli --network=testnet getinfo` (on LND) as discussed in the [previous interlude](19_2__Interlude_Accessing_a_Second_Lightning_Node.md).
|
||||
|
||||
We've selected the LND node, `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543`, which is located at IP address `45.33.35.151`, which we're going to connect to from our c-lightning node:
|
||||
|
||||
@ -182,5 +182,4 @@ You need to create a channel with a remote node to be able to receive and send m
|
||||
|
||||
## What's Next?
|
||||
|
||||
You're ready to go! Move on to [Chapter Nineteen: Using Lightning](19_0_Using_Lightning.md).
|
||||
|
||||
You're ready to go! Move on to [Chapter 20: Using Lightning](20_0_Using_Lightning.md).
|
@ -1,4 +1,4 @@
|
||||
# Chapter Nineteen: Using Lightning
|
||||
# Chapter 20: Using Lightning
|
||||
|
||||
> :information_source: **NOTE:** This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning.
|
||||
|
||||
@ -19,7 +19,7 @@ Supporting objectives include the ability to:
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Section One: Generating a Payment Request](19_1_Generate_a_Payment_Request.md)
|
||||
* [Section Two: Paying an Invoice](19_2_Paying_a_Invoice.md)
|
||||
* [Section Three: Closing a Lightning Channel](19_3_Closing_a_Channel.md)
|
||||
* [Section Four: Expanding the Lightning Network](19_4_Lightning_Network_Review.md)
|
||||
* [Section One: Generating a Payment Request](20_1_Generate_a_Payment_Request.md)
|
||||
* [Section Two: Paying an Invoice](20_2_Paying_a_Invoice.md)
|
||||
* [Section Three: Closing a Lightning Channel](20_3_Closing_a_Channel.md)
|
||||
* [Section Four: Expanding the Lightning Network](20_4_Lightning_Network_Review.md)
|
@ -1,9 +1,8 @@
|
||||
|
||||
# 19.1: Generating a Payment Request
|
||||
# 20.1: Generating a Payment Request
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
This section describes how payments work on the Lightning Network, how to create a payment request (or _invoice_), and finally how to make sense of it. Issuing invoices depends on your having a second Lightning node, as described in [Accessing a Second Lightning Node](18_2__Interlude_Accessing_a_Second_Lightning_Node.md). These examples will use an LND node as their secondary node, to further demonstrate the possibilities of the Lightning Network. To differentiate between the nodes in these examples, the prompts will be shown as `c$` for the c-lightning node and `lnd$` as the LND node. If you want to reproduce this steps, you should [install your own secondary LND node](18_2__Interlude_Accessing_a_Second_Lightning_Node.md#creating-a-new-lnd-node).
|
||||
This section describes how payments work on the Lightning Network, how to create a payment request (or _invoice_), and finally how to make sense of it. Issuing invoices depends on your having a second Lightning node, as described in [Accessing a Second Lightning Node](19_2__Interlude_Accessing_a_Second_Lightning_Node.md). These examples will use an LND node as their secondary node, to further demonstrate the possibilities of the Lightning Network. To differentiate between the nodes in these examples, the prompts will be shown as `c$` for the c-lightning node and `lnd$` as the LND node. If you want to reproduce this steps, you should [install your own secondary LND node](19_2__Interlude_Accessing_a_Second_Lightning_Node.md#creating-a-new-lnd-node).
|
||||
|
||||
> :book: ***What is an Invoice?** Almost all payments made on the Lightning Network require an invoice, which is nothing more than a **request for payment** made by the recipient of the money and sent by variety of means to the paying user. All payment requests are single use. Lightning invoices use bech32 encoding, which is already used by Segregated Witness for Bitcoin.
|
||||
|
||||
@ -98,7 +97,7 @@ Here's what the most relevent elements mean:
|
||||
|
||||
> :book: ***What is a Hashed Time Locked Contract (HTLC)?*** A Hashed Time Locked Contract is a conditional payment that use hashlocks and timelocks to ensure payment security. The receiver must present a payment preimage or generate a cryptographic proof of payment before a given time, otherwise the payer can cancel the contract by spending it. These contracts are created as outputs from the **Commitment Transaction**.
|
||||
|
||||
> :book: ***What is a Commitment Transaction?*** A Commitment Transaction is a transaction that spends the original funding transaction. Each peer holds the other peer's signature, meaning that either one can spent his commitment transaction whatever he wants. After each new commitment transaction is created the old one is revoked. The commitment transaction is one way that the funding transaction can be unlocked on the blockchain, as discussed in [§19.3](19_3_Closing_a_Channel.md).
|
||||
> :book: ***What is a Commitment Transaction?*** A Commitment Transaction is a transaction that spends the original funding transaction. Each peer holds the other peer's signature, meaning that either one can spent his commitment transaction whatever he wants. After each new commitment transaction is created the old one is revoked. The commitment transaction is one way that the funding transaction can be unlocked on the blockchain, as discussed in [§20.3](20_3_Closing_a_Channel.md).
|
||||
|
||||
### Check Your Invoice
|
||||
|
||||
@ -108,7 +107,7 @@ There are two crucial elements to check in the invoice. The first, obviously, is
|
||||
```
|
||||
You need to check that's the expected recipient.
|
||||
|
||||
Looking back at [§18.3](18_3_Setting_Up_a_Channel.md#opening-a-channel), you can see that's indeed the peer ID that you used when you created your channel. You could also verify it on the opposite node with the `getinfo` command.
|
||||
Looking back at [§20.3](20_3_Closing_a_Channel.md), you can see that's indeed the peer ID that you used when you created your channel. You could also verify it on the opposite node with the `getinfo` command.
|
||||
```
|
||||
lnd$ lncli -n testnet getinfo
|
||||
{
|
||||
@ -182,4 +181,4 @@ In most cases you need to receive an invoice to use Lightning Network payments.
|
||||
|
||||
## What's Next?
|
||||
|
||||
Continue "Using Lightning" with [§19.2: Paying_a_Invoice](19_2_Paying_a_Invoice.md).
|
||||
Continue "Using Lightning" with [§20.2: Paying_a_Invoice](20_2_Paying_a_Invoice.md).
|
@ -1,8 +1,8 @@
|
||||
# 19.2: Paying an Invoice
|
||||
# 20.2: Paying an Invoice
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
In this chapter you will learn how to pay an invoice using `lightning-cli pay` command. It assumes that you've already looked over the invoice, per [§19.1](19_1_Generate_a_Payment_Request.md) and determined it was valid.
|
||||
In this chapter you will learn how to pay an invoice using `lightning-cli pay` command. It assumes that you've already looked over the invoice, per [§20.1](20_1_Generate_a_Payment_Request.md) and determined it was valid.
|
||||
|
||||
## Check your Balance
|
||||
|
||||
@ -203,4 +203,4 @@ Once you've got an invoice, it's easy enough to pay with a single command in Lig
|
||||
|
||||
## What's Next?
|
||||
|
||||
Continue "Using Lighting" with [§19.3: Closing a Channel](19_3_Closing_a_Channel.md).
|
||||
Continue "Using Lighting" with [§20.3: Closing a Channel](20_3_Closing_a_Channel.md).
|
@ -1,4 +1,4 @@
|
||||
# 19.3: Closing a Channel
|
||||
# 20.3: Closing a Channel
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
||||
@ -179,7 +179,7 @@ $ bitcoin-cli --named getrawtransaction txid=f68de52d80a1076e36c677ef640539c50e3
|
||||
"blocktime": 1602713519
|
||||
}
|
||||
```
|
||||
The input of the transaction is `66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d`, which was the funding transaction in [§18.3](18_3_Setting_Up_a_Channel.md). The transaction then has two outputs, one for the remote node and the other for the local c-lightning wallet. The output on index 0 corresponds to the remote node with a value of 0.00010012 BTC; and the output on index 1 corresponds to the local node with a value of 0.00089804 BTC.
|
||||
The input of the transaction is `66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d`, which was the funding transaction in [§19.3](19_3_Setting_Up_a_Channel.md). The transaction then has two outputs, one for the remote node and the other for the local c-lightning wallet. The output on index 0 corresponds to the remote node with a value of 0.00010012 BTC; and the output on index 1 corresponds to the local node with a value of 0.00089804 BTC.
|
||||
|
||||
Lightning will similarly show 89804 satoshis returned as a new UTXO in its wallet:
|
||||
```
|
||||
@ -257,4 +257,4 @@ When you close a channel you perform an on-chain transaction ending your financi
|
||||
|
||||
## What's Next?
|
||||
|
||||
Continue "Using Lightning" with [§19.4: Expanding the Lightning Network](19_4_Lightning_Network_Review.md).
|
||||
Continue "Using Lightning" with [§20.4: Expanding the Lightning Network](20_4_Lightning_Network_Review.md).
|
@ -1,4 +1,4 @@
|
||||
# 19.4: Expanding the Lightning Network
|
||||
# 20.4: Expanding the Lightning Network
|
||||
|
||||
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Appendices
|
||||
|
||||
The main body of this course suggests a fairly standard setup for Bitcoin testing. What follows is these appendices are a better explanation of that setup and some options for alternatives.
|
||||
The main body of this course suggests a fairly standard setup for Bitcoin testing. What follows in these appendices are a better explanation of that setup and some options for alternatives.
|
||||
|
||||
## Objectives for This Section
|
||||
|
||||
|
@ -28,7 +28,7 @@ $ su root
|
||||
|
||||
### Step 1: Update Your System
|
||||
|
||||
Fir, update the system using:
|
||||
First, update the system using:
|
||||
```
|
||||
$ sudo apt-get update
|
||||
```
|
||||
|
@ -8,9 +8,13 @@ The majority of this course presumes that you will either use the Mainnet or Tes
|
||||
|
||||
After [setting up your Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) or [compiling from source](A2_0_Compiling_Bitcoin_from_Source.md), you are now able to use regtest. To start your `bitcoind` on regtest and create a private Blockchain, use the following command:
|
||||
```
|
||||
$ bitcoind -regtest -daemon
|
||||
$ bitcoind -regtest -daemon -fallbackfee=1.0 -maxtxfee=1.1
|
||||
```
|
||||
|
||||
The arguments `-fallbackfee=1.0 -maxtxfee=1.1` will prevent the `Fee estimation failed. Fallbackfee is disabled` error.
|
||||
|
||||
On regtest, usually there are not enough transactions so bitcoind cannot give a reliable estimate and, without it, the wallet will not create transactions unless it is explicitly set the fee.
|
||||
|
||||
### Reset the Regtest Blockchain
|
||||
|
||||
If you wish, you can later restart your Regtest with a new blockchain.
|
||||
@ -25,12 +29,20 @@ To start a brand new Blockchain using regtest, all you have to do is delete the
|
||||
```
|
||||
$ rm -rf regtest
|
||||
```
|
||||
## Generate Regtest Wallet
|
||||
|
||||
Before generating blocks, it is necessary to load a wallet using `loadwallet` or create a new one with `createwallet`. Since version 0.21, Bitcoin Core does not automatically create new wallets on startup.
|
||||
|
||||
The argument `descriptors=true` creates a native descriptor wallet, that stores scriptPubKey information using output descriptors. If it is `false`, it will create a legacy wallet, where keys are used to implicitly generate scriptPubKeys and addresses.
|
||||
```
|
||||
$ bitcoin-cli -regtest -named createwallet wallet_name="regtest_desc_wallet" descriptors=true
|
||||
```
|
||||
|
||||
## Generate Blocks
|
||||
|
||||
You can generate (mine) new blocks on a regtest chain using the RPC method `generate` with an argument for how many blocks to generate. It only makes sense to use this method on regtest; due to the high difficulty it's very unlikely that it will yield to new blocks on the mainnet or testnet:
|
||||
```
|
||||
$ bitcoin-cli -regtest generate 101
|
||||
$ bitcoin-cli -regtest -generate 101
|
||||
[
|
||||
"57f17afccf28b9296048b6370312678b6d8e48dc3a7b4ef7681d18ed3d91c122",
|
||||
"631ff7b8135ce633c774828be3b8505726459eb65c339aab981b10363befe5a7",
|
||||
@ -42,11 +54,11 @@ $ bitcoin-cli -regtest generate 101
|
||||
|
||||
> :warning: WARNING. Note that you must add the `-regtest` argument after each `bitcoin-cli` command to correctly access your Regtest environment. If you prefer, you can include a `regtest=1` command in your `~/.bitcoin/bitcoin.conf` file.
|
||||
|
||||
Because a block must have 100 confirmations before that reward can be spent, you generate 101 blocks, providing access to the coinbase transaction from block #1. Because this is a new blockchain using Bitcoin’s default rules, the first blocks pays a block reward of 50 bitcoins. Unlike mainnet, in regtest mode only the first 150 blocks pay a reward of 50 bitcoins. The reward halves after 150 blocks, so it pays 25, 12.5, and so on...
|
||||
Because a block must have 100 confirmations before that reward can be spent, you generate 101 blocks, providing access to the coinbase transaction from block #1. Because this is a new blockchain using Bitcoin’s default rules, the first blocks pay a block reward of 50 bitcoins. Unlike mainnet, in regtest mode only the first 150 blocks pay a reward of 50 bitcoins. The reward halves after 150 blocks, so it pays 25, 12.5, and so on...
|
||||
|
||||
The output is the block hash of every block generated.
|
||||
|
||||
> :book: ***What is a coinbase transaction?*** A coinbase is the inputless transaction created when a new block is mined and given to the miner. It's how new bitcoins enter the ecosystem. The value of coinbase transactions decay over time. On the mainnet, it halves every 210,000 transactions and ends entirely with the 6,929,999th block, which is currently predicted for the 22nd century. As of May 2020, the coinbase reward is 6.25 BTC.
|
||||
> :book: ***What is a coinbase transaction?*** A coinbase is the inputless transaction created when a new block is mined and given to the miner. It's how new bitcoins enter the ecosystem. The value of coinbase transactions decay over time. On the mainnet, it halves every 210,000 blocks and ends entirely with the 6,929,999th block, which is currently predicted for the 22nd century. As of May 2020, the coinbase reward is 6.25 BTC.
|
||||
|
||||
### Verify Your Balance
|
||||
|
||||
@ -62,7 +74,7 @@ Now you should be able to use this balance for any type of interaction on your p
|
||||
|
||||
It is important to note that for any transactions to complete, you will have to generate (mine) new blocks, so that the transactions can be included.
|
||||
|
||||
For example, to create a transaction and include it in a block, you should ufirst se the `sendtoaddress` command:
|
||||
For example, to create a transaction and include it in a block, you should first use the `sendtoaddress` command:
|
||||
```
|
||||
$ bitcoin-cli -regtest sendtoaddress [address] 15.1
|
||||
e834a4ac6ef754164c8e3f0be4f34531b74b768199ffb244ab9f6cb1bbc7465a
|
||||
@ -107,9 +119,9 @@ $ bitcoin-cli -regtest gettransaction e834a4ac6ef754164c8e3f0be4f34531b74b768199
|
||||
```
|
||||
|
||||
However, you must now finalize it by creating blocks on the blockchain.
|
||||
Most applications require a six-block confirmations to consider the transaction as irreversible. If that is your case, you can mine additional six blocks into your regtest chain:
|
||||
Most applications require six block confirmations to consider the transaction as irreversible. If that is your case, you can mine additional six blocks into your regtest chain:
|
||||
```
|
||||
$ bitcoin-cli -regtest generate 6
|
||||
$ bitcoin-cli -regtest -generate 6
|
||||
[
|
||||
"33549b2aa249f0a814db4a2ba102194881c14a2ac041c23dcc463b9e4e128e9f",
|
||||
"2cc5c2012e2cacf118f9db4cdd79582735257f0ec564418867d6821edb55715e",
|
||||
@ -127,7 +139,7 @@ When you are on regtest, you are able to simulate edge cases and attacks that mi
|
||||
|
||||
As discussed elsewhere in this course, using software libraries might give you more sophisticated access to some RPC commands. In this case, [bitcointest by dgarage](https://github.com/dgarage/bitcointest) for NodeJS can be used to simulate a transaction from one wallet to another; you can check [their guide](https://www.npmjs.com/package/bitcointest) for more specific attack simulations, such as double spend.
|
||||
|
||||
See [§17.3](17_3_Accessing_Bitcoind_with_NodeJS.md) for the most up-to-date info on install NodeJS, then add `bitcointest`:
|
||||
See [§18.3](18_3_Accessing_Bitcoind_with_NodeJS.md) for the most up-to-date info on install NodeJS, then add `bitcointest`:
|
||||
```
|
||||
$ npm install -g bitcointest
|
||||
```
|
||||
|
74
CLA-signed/CLA.HGRAMS.AED496548E2F3810CCAB.asc
Normal file
74
CLA-signed/CLA.HGRAMS.AED496548E2F3810CCAB.asc
Normal file
@ -0,0 +1,74 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA512
|
||||
|
||||
# Contributor License Agreement
|
||||
|
||||
Version 1.0
|
||||
|
||||
Name: hgrams
|
||||
|
||||
E-Mail: hgrams@protonmail.ch
|
||||
|
||||
Legal Jurisdiction: Wyoming, United States of America
|
||||
|
||||
Project: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line
|
||||
|
||||
Date: 11/04/2021
|
||||
|
||||
## Purpose
|
||||
|
||||
This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time.
|
||||
|
||||
## License
|
||||
|
||||
I hereby license Blockchain Commons, LLC to:
|
||||
|
||||
1. do anything with my contributions that would otherwise infringe my copyright in them
|
||||
|
||||
2. do anything with my contributions that would otherwise infringe patents that I can or become able to license
|
||||
|
||||
3. sublicense these rights to others on any terms they like
|
||||
|
||||
## Reliability
|
||||
|
||||
I understand that Blockchain Commons will rely on this license. I may not revoke this license.
|
||||
|
||||
## Awareness
|
||||
|
||||
I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it.
|
||||
|
||||
## Copyright Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately.
|
||||
|
||||
## Patent Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms.
|
||||
|
||||
## Open Source Guarantee
|
||||
|
||||
I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms.
|
||||
|
||||
## Disclaimers
|
||||
|
||||
***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.***
|
||||
|
||||
- ---
|
||||
|
||||
To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./CLA-signed/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAEBCgAdFiEErtSWVI4vOBDMq+zPtqv4+8oqhOAFAmGEPzAACgkQtqv4+8oq
|
||||
hOCgTA/+KMuHLFjAK/ifKuRMpKXyQWvfYlQTmaDhEUbwBs3SiF+0bN2XcDQy1/rf
|
||||
ha5OEdNB8m7RxfU30fcWAHOlPRFxaaoPTDtZCETreQsIPYoccW4aXViq0B4Ww0/I
|
||||
DuO49De423vPwLjfSGF+s4EQEUHVY9lERBkjhrgRKSJ28Bym/QaPhZWaWsQl9HS6
|
||||
/MsvR+xbqNHFwnfJkrRHXldQzafMcH5aqWwVMFlkcOvA2rBz5zdFx/CYozOF7pcd
|
||||
iV/t6ZTZJwkBWbjlzjoG4OkS+ncOEzkRK9kCfrEU7zKctXKSgh8FVvnP8gfzGh7q
|
||||
tZQXecc/ojfcGRp32pcDs9IuTeEirjcJZZjHhVk3cHnULa/Bfq077Iu2yCLEgI+E
|
||||
Z1BtfGdd7lvqGg9CtK9hfFSvJ4KyQQ48dOxTfg6jKXnF1t63jQ86AANJ2FCsl2tx
|
||||
TWQMhYG4Ahqd/fCajxy5rG+9/muVOow/IFekKsNpb63AIerW3YwpXk28Ozl8htZo
|
||||
igScab9opps3rrwEa/w9OqUkph5BpmesZdq09aHCwkBuFS92BMlpb0PXVpzk39kM
|
||||
LsEvT3kDwQNsmxZgh4zYYkQFn7JBN+kMsvRvaVpEksUEEcgFFSWh8NPuETUWTBwD
|
||||
/kYTr8lmBZ1PE38IWD0Bhjz+3O4vI6/u5c0c2PxiuSwtrvXyYe8=
|
||||
=b5Wo
|
||||
-----END PGP SIGNATURE-----
|
@ -0,0 +1,85 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1
|
||||
Comment: A revocation certificate should follow
|
||||
|
||||
iQGFBCABAgBvBQJg+iKHaB0CQWNjaWRlbnRhbGx5IHVwbG9hZGVkIHByaXZhdGUg
|
||||
a2V5IHRvIHB1YmxpYyBnaXRodWIgcmVwbzsgcmVtb3ZlZCBjb21taXRzIGJ1dCBz
|
||||
dGlsbCBpdCdzIGJlZW4gb3V0IHRoZXJlAAoJEEzhMayhJCnMhnoH/0HoVE58CR35
|
||||
LhSBBtOXrGSOnRo45ss9/G+sNzMsUGAwuwVqS9cELS+BJbJTsA/ZYCsq09AtNqy5
|
||||
thr9VrV4eonYZ9rZ2RIw89R15ytYBERO/R1mM+TCaMp7tFk3G9wNbkjaNPxQh4td
|
||||
7mf4HExstLWy7LIGgQdsZWn4zcOH6SG4H82jZBNpRnp0L4T+tcDoRYYO2f6pOQm7
|
||||
k5ls05gjx50YeCUeVIwqqZYCoCao/NFJNDkL3GzBUes8Cvgx2s+oiZdpdcY4Nb0l
|
||||
z52CyHbVhqBcumbL5oirnLjTCLP+bKpb4CjafHZdYygYaZdSkbODIBbq17169g1j
|
||||
U7nqW0ryAH0=
|
||||
=sc+j
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA256
|
||||
|
||||
# Contributor License Agreement
|
||||
|
||||
Version 1.0
|
||||
|
||||
Name: Ian Culp
|
||||
|
||||
E-Mail: icculp@gmail.com
|
||||
|
||||
Legal Jurisdiction: Oklahoma, United States of America
|
||||
|
||||
Project: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line
|
||||
|
||||
Date: 07/03/2021
|
||||
|
||||
## Purpose
|
||||
|
||||
This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time.
|
||||
|
||||
## License
|
||||
|
||||
I hereby license Blockchain Commons, LLC to:
|
||||
|
||||
1. do anything with my contributions that would otherwise infringe my copyright in them
|
||||
|
||||
2. do anything with my contributions that would otherwise infringe patents that I can or become able to license
|
||||
|
||||
3. sublicense these rights to others on any terms they like
|
||||
|
||||
## Reliability
|
||||
|
||||
I understand that Blockchain Commons will rely on this license. I may not revoke this license.
|
||||
|
||||
## Awareness
|
||||
|
||||
I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it.
|
||||
|
||||
## Copyright Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately.
|
||||
|
||||
## Patent Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms.
|
||||
|
||||
## Open Source Guarantee
|
||||
|
||||
I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms.
|
||||
|
||||
## Disclaimers
|
||||
|
||||
***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.***
|
||||
|
||||
- ---
|
||||
|
||||
To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./signed-cla/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v1
|
||||
|
||||
iQEcBAEBCAAGBQJg4KFsAAoJEEzhMayhJCnMLoQH/jw2Dchpc5aV/rYcmCAzdqT5
|
||||
R13cEr+XHOendw/9SLEGF7io2KWCCJwcZ95jyG9etSbFJHDmwSnONBpJgH7IiMgV
|
||||
OYuz0LloM44WiHTwBujsb9ezjVztqgvfQqhFwVc28BB52MnXfiBzCXpfZIvcmj/H
|
||||
vbTmk2o6SAyoHiZm9Jwe+R9fiTeHYEM680R1M18CWfjY04JxtTv7tXuPRedBqJzU
|
||||
R9BYutO0voUJVDF3CcC3CbGKc+cHcU14MH5gjKZsMi/YPqu8XPU0tjIiDPjtSGxT
|
||||
5WyFgTMoH3Wm9Xzg9eFg74feN4LlDJl2XV/ISgfkoXFowMmJlOD74RE0fo9F3iw=
|
||||
=qvM2
|
||||
-----END PGP SIGNATURE-----
|
@ -0,0 +1,65 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA512
|
||||
|
||||
# Contributor License Agreement
|
||||
|
||||
Version 1.0
|
||||
|
||||
Name: `$name`
|
||||
|
||||
E-Mail: `$email`
|
||||
|
||||
Legal Jurisdiction: Wyoming, United States of America
|
||||
|
||||
Project: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line
|
||||
|
||||
Date: `$date`
|
||||
|
||||
## Purpose
|
||||
|
||||
This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time.
|
||||
|
||||
## License
|
||||
|
||||
I hereby license Blockchain Commons, LLC to:
|
||||
|
||||
1. do anything with my contributions that would otherwise infringe my copyright in them
|
||||
|
||||
2. do anything with my contributions that would otherwise infringe patents that I can or become able to license
|
||||
|
||||
3. sublicense these rights to others on any terms they like
|
||||
|
||||
## Reliability
|
||||
|
||||
I understand that Blockchain Commons will rely on this license. I may not revoke this license.
|
||||
|
||||
## Awareness
|
||||
|
||||
I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it.
|
||||
|
||||
## Copyright Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately.
|
||||
|
||||
## Patent Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms.
|
||||
|
||||
## Open Source Guarantee
|
||||
|
||||
I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms.
|
||||
|
||||
## Disclaimers
|
||||
|
||||
***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.***
|
||||
|
||||
- ---
|
||||
|
||||
To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./CLA-signed/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iHUEARYKAB0WIQSQSH/jgB3kAxc6LtvGhebZN/3CAwUCYfxLmQAKCRDGhebZN/3C
|
||||
AxImAQCBq6rX67QtcvLaUbZWGiGcb6Lwfh5Nfot2W1U0aX9MDgEAilSaykUsHmmb
|
||||
+dH7vvIb5o3Su5xstebNxx9wqbBL4Ao=
|
||||
=N//+
|
||||
-----END PGP SIGNATURE-----
|
@ -0,0 +1,72 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA512
|
||||
|
||||
# Contributor License Agreement
|
||||
|
||||
Version 1.0
|
||||
|
||||
Name: Luke Pavksy
|
||||
|
||||
E-Mail: lukedevj.contact@protonmail.com
|
||||
|
||||
Legal Jurisdiction: Wyoming, United States of America
|
||||
|
||||
Project: https://github.com/BlockchainCommons/bc-lethe-kit
|
||||
|
||||
Date: `06/20/2021`
|
||||
|
||||
## Purpose
|
||||
|
||||
This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time.
|
||||
|
||||
## License
|
||||
|
||||
I hereby license Blockchain Commons, LLC to:
|
||||
|
||||
1. do anything with my contributions that would otherwise infringe my copyright in them
|
||||
|
||||
2. do anything with my contributions that would otherwise infringe patents that I can or become able to license
|
||||
|
||||
3. sublicense these rights to others on any terms they like
|
||||
|
||||
## Reliability
|
||||
|
||||
I understand that Blockchain Commons will rely on this license. I may not revoke this license.
|
||||
|
||||
## Awareness
|
||||
|
||||
I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it.
|
||||
|
||||
## Copyright Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately.
|
||||
|
||||
## Patent Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms.
|
||||
|
||||
## Open Source Guarantee
|
||||
|
||||
I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms.
|
||||
|
||||
## Disclaimers
|
||||
|
||||
***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.***
|
||||
|
||||
- ---
|
||||
|
||||
To sign this Contributor License Agreement, fill in `Luke Pavksy`, `lukedevj.contact@protonmail.com`, and `06/20/2021` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./signed-cla/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQGzBAEBCgAdFiEEiI+rRgnjX7UPocqXDrHPI+yBO78FAmDPoSUACgkQDrHPI+yB
|
||||
O78efQv+IJG+7qrfk+DdLLDoubgxTUs9TUPf9SRbt71VM3tuSZ/qdnStbvQ6PRrl
|
||||
qCm23cCIh0f/2icwzn1oVnMzVQs3qkmCJm25gkCUY0ABFW+4FsXXIL/kYmr3YV6+
|
||||
EoU5IYhTjJJ7w5hP+cjfRQfqCSArVxUHKqazYqVe2dYNydL9drrDfAZrlfksobuE
|
||||
+tZmXz1ZZ1RCn1BFExSWWK0c4ZNOKJxV3sfm4EblAx8GTFHk3lQYeP+d7uOqJdrw
|
||||
BdAcNzp3hYmPCdEwiZB9IC3Jlbb0uBpclB29ADdk3N87OXrA3VpImTz0f4Mf5wla
|
||||
U3ZJReuqVJdWd7jWPJELZldjumEZsP4Qfg0Q44tskrukUVUAIYFngkmstpllyabm
|
||||
L9VUqpXMcFCzFtBs4waeaiWuWU5I4HJCTXrgiMwyoV8oA99+Sy+JdS0UbpokjzwQ
|
||||
zF9b43K6JcOWY1ZEIx0hTeg2IlqVEE/iYJw6JeiaCJHHlR/rG7A15+0zuwppkuh5
|
||||
WQp4ouPE
|
||||
=M9k+
|
||||
-----END PGP SIGNATURE-----
|
@ -0,0 +1,72 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA256
|
||||
|
||||
# Contributor License Agreement
|
||||
|
||||
Version 1.0
|
||||
|
||||
Name: Maximiliano Goyheneche
|
||||
|
||||
E-Mail: maxigoyheneche@gmail.com
|
||||
|
||||
Legal Jurisdiction: Wyoming, United States of America
|
||||
|
||||
Project: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line
|
||||
|
||||
Date: 10/22/2021
|
||||
|
||||
## Purpose
|
||||
|
||||
This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time.
|
||||
|
||||
## License
|
||||
|
||||
I hereby license Blockchain Commons, LLC to:
|
||||
|
||||
1. do anything with my contributions that would otherwise infringe my copyright in them
|
||||
|
||||
2. do anything with my contributions that would otherwise infringe patents that I can or become able to license
|
||||
|
||||
3. sublicense these rights to others on any terms they like
|
||||
|
||||
## Reliability
|
||||
|
||||
I understand that Blockchain Commons will rely on this license. I may not revoke this license.
|
||||
|
||||
## Awareness
|
||||
|
||||
I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it.
|
||||
|
||||
## Copyright Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately.
|
||||
|
||||
## Patent Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms.
|
||||
|
||||
## Open Source Guarantee
|
||||
|
||||
I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms.
|
||||
|
||||
## Disclaimers
|
||||
|
||||
***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.***
|
||||
|
||||
- ---
|
||||
|
||||
To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./signed-cla/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQGzBAEBCAAdFiEEmT8Glpq2YD0e7okNSmUz25XU4WYFAmGMAWcACgkQSmUz25XU
|
||||
4WaTKAwAnSq5WktSyRlv+k0MFCpK3PFpaZuYdHF+MrmwIWRboGc8j/NYvcV50eGb
|
||||
VoovOetzVqv0lkIU3u2Q8lpLTIz0uLEi0mrOv+MdKXMos7/k1W0F4t+PuPZtk6r0
|
||||
bStvN3XC/kwoQW43+pO8g1bWMYzIH13b9QrJXdvGaaVm2x5s77jJCz+xQYY3bDCd
|
||||
ujlRJU5mh8iGes037kFCdX+IFgee+LYd3PaoTVBs1GXBDR2eHDJK7/NIZhacsDAs
|
||||
fql1lkr/LenM5XwE9+ZbG7qyABjPrGX16rq+Gl/uufxyW3GdQwwPSbPH0eC3WdPb
|
||||
pF6tFqKv0mMOmq3cCln8W2M20dK8nrhtOjUIoAaBON7UuR80EiZIrab/nAamukH0
|
||||
IEMlHJImNG2OTjbWzmJxMxdxpSah5w0oEYwiD/+9wF+N0mOcV7ICg4ilEBqynwf2
|
||||
yq2vCMFpY5VTH3Dku6d+mqPnhcGGmadF/V0wQ70/tlE7K7jDtknB3KtnaWP7t5Ef
|
||||
geVUNjwN
|
||||
=dh9y
|
||||
-----END PGP SIGNATURE-----
|
@ -0,0 +1,69 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA256
|
||||
|
||||
# Contributor License Agreement
|
||||
|
||||
Version 1.0
|
||||
|
||||
Name: Namcios
|
||||
|
||||
E-Mail: namcios@protonmail.com
|
||||
|
||||
Legal Jurisdiction: Wyoming, United States of America
|
||||
|
||||
Project: https://github.com/BlockchainCommons/bc-lethe-kit
|
||||
|
||||
Date: 06/23/2021
|
||||
|
||||
## Purpose
|
||||
|
||||
This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time.
|
||||
|
||||
## License
|
||||
|
||||
I hereby license Blockchain Commons, LLC to:
|
||||
|
||||
1. do anything with my contributions that would otherwise infringe my copyright in them
|
||||
|
||||
2. do anything with my contributions that would otherwise infringe patents that I can or become able to license
|
||||
|
||||
3. sublicense these rights to others on any terms they like
|
||||
|
||||
## Reliability
|
||||
|
||||
I understand that Blockchain Commons will rely on this license. I may not revoke this license.
|
||||
|
||||
## Awareness
|
||||
|
||||
I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it.
|
||||
|
||||
## Copyright Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately.
|
||||
|
||||
## Patent Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms.
|
||||
|
||||
## Open Source Guarantee
|
||||
|
||||
I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms.
|
||||
|
||||
## Disclaimers
|
||||
|
||||
***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.***
|
||||
|
||||
- ---
|
||||
|
||||
To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./signed-cla/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQEzBAEBCAAdFiEEVaJL4K7l20FSxqQQjjo2gxcmmrQFAmDTgZ4ACgkQjjo2gxcm
|
||||
mrRTpQgAoFpCTvov11jIeyu4kNTbFy/lxdx5vXViWSvsPa2I/Q8TgTgWoAcBw84H
|
||||
lqCDweT9dFFf3XXh2NTpgpAZ+TYbzBQgC3lNMc9BhKfgUOHnR+UFwAj7HyD2fPiE
|
||||
e92BCLEmuSxk4ls8KFZ0wLySXNZGSehOb/K0EdYbw1szPQGEVmOvZq+vTkPfEDqO
|
||||
XK3T81r5+YCwazQHNXbOwnpbVryqi700ndF8R7MTZ6Z1LqOKQCfXBLSBiDhQ8Wk6
|
||||
BhYbpXpJFGzlSrlfBG1jvQdUq2grAQ8CEhMprNJXPt294a6RAHMZ4bNz65OiAM4e
|
||||
d/AaQ/DlwNvVZM7ARxorsucuqYkQUA==
|
||||
=sF7Q
|
||||
-----END PGP SIGNATURE-----
|
@ -0,0 +1,97 @@
|
||||
# Contributor License Agreement
|
||||
|
||||
Version 1.0
|
||||
|
||||
Name: SAID RAHAL
|
||||
|
||||
E-Mail: HOLA@SAIDRAHAL.COM
|
||||
|
||||
Legal Jurisdiction: MADRID, SPAIN
|
||||
|
||||
Project: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line
|
||||
|
||||
Date: 11/11/2021
|
||||
|
||||
## Purpose
|
||||
|
||||
This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time.
|
||||
|
||||
## License
|
||||
|
||||
I hereby license Blockchain Commons, LLC to:
|
||||
|
||||
1. do anything with my contributions that would otherwise infringe my copyright in them
|
||||
|
||||
2. do anything with my contributions that would otherwise infringe patents that I can or become able to license
|
||||
|
||||
3. sublicense these rights to others on any terms they like
|
||||
|
||||
## Reliability
|
||||
|
||||
I understand that Blockchain Commons will rely on this license. I may not revoke this license.
|
||||
|
||||
## Awareness
|
||||
|
||||
I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it.
|
||||
|
||||
## Copyright Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately.
|
||||
|
||||
## Patent Guarantee
|
||||
|
||||
I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms.
|
||||
|
||||
## Open Source Guarantee
|
||||
|
||||
I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms.
|
||||
|
||||
## Disclaimers
|
||||
|
||||
***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.***
|
||||
|
||||
- ---
|
||||
|
||||
To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./signed-cla/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
|
||||
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
Version: Keybase OpenPGP v2.0.76
|
||||
|
||||
yMXPAnicrVfNbxtFFE8pRWIFEhUXjkNTqR/y2kmQEIo41EnaxMhJTJp+oKhVxrtj
|
||||
7+DdGbMzG8twRUgceuDjiITEEcRfwI2vHhBCggPiipBA6gVx4Fp+b2ZtJ3HSUqlK
|
||||
lWZ33rz5vd/7vTdvv3325Exw+srzc0+0786/euKHH88VM/zO4PYsW9bK5rJdWJ2z
|
||||
poyEMoLVu7kQmVA2CK6L3Eit2Hx1Lgg2eCYW2dV6Y4Vt1dfqzSC4HK5zmS6ytc1m
|
||||
/RItuPfV5c31IGiKLk/Za0UuTSwjCy+LbL2+stVYqbCrrXpjIwhauX5TRHaRJdb2
|
||||
zWKt1pU2KdrVSGe1pVRHvSjhUi3rLNPK1JqC50qqbrgkbaSlCju5zkKbiJAsuIrD
|
||||
plQiCFa4Bcz5+Rr+LcwtzAfB7CxrFXlfG6xuJ9IwPoqQdeWeMGxyGCtPq7Bmc5nB
|
||||
OeuLPJPGsSAtU0LEhsFO57HImdWMR5HoW5YNWTTiErZkg0VpDdN9oZjRHTvgOdz5
|
||||
mBnw0m7g5l3hDsIGkaZYK8AbzHCwHdJRNuF2vE/v0bEyE1UXV5mzIGiwROSiPWRp
|
||||
mcVjY9KLQTBfZSwGdjW0CShlAxA/HYI7eKCLNGYaCPOBNASzk2OL8Ob9YS67ifUw
|
||||
RRYEC4/Bcx8ZVLa0arCIE92sLaALwXg7FcRcOor8JZxoivYobrjDb4fKkJ3zjywo
|
||||
wsQsskmOBRHVE47DLZFK3paptEPisVDIrLEuQQRgmkgElaYsF+mQ3FpSVHk6oDSQ
|
||||
0yFT2sJgT/fEwXV3YJ2UoIQxdBwSm0mH2wXLM9bhGcDw3HOXujrKi1QggYSZ7ZwZ
|
||||
6LyHY2LBOiAmkbk44y1unadSQiWRhSELGNA61dSFij+E+CTdM5H1Uz0kdijYKJWO
|
||||
dT1QeJXIPtOd40XpIJSYY+3iBnSeGuTeCd2tefDjcjPEjtOLkV1VhgNldGSMVQlT
|
||||
aEDnGSeVOFBS7dEKPRna44p24q/iU1EYwEM2XFT/Dz8k6UPQExoqIw4qnhCd9bmS
|
||||
YizEjoY2KNQO6jkTWoHC1LgTzUNPqsABdQ8Sn8z3t5WJmNEvvEKWx4W1WvCcw7XY
|
||||
rxVSF0m700EzOFRZ2netsl34hMOC5DsuV6A4mD/nMeFgz2UMVLaliql+D+IcnyV8
|
||||
mZTV5qoKxNxI0OoaJS5+AJkX88Qb0TGWvgaEqHC59Y3k0NZEe44P9JuB7yHELGUr
|
||||
0QNf110K41jYYNglsMFSdJlJV5loltIK5Uz1LCprR9EUjbAuu8yIUBlPGD0OCjHg
|
||||
1AtL2Rke2bBd0nx5RNggs0zEErjToddJy3XKxyKSBuspUDjVhKeD0w+P7Qh1OLyb
|
||||
dBde1UUeiUcHvV/KaHuxgLPYd2BxKBEVAEA7HF80WKNrfw/Tirs/PDzOJpcGzHaW
|
||||
0kKwTd4D/4WKJLouODCsnWv1tvBXkEUwvsnSvNLGBs17AAXrqs67tVQaiz5riihB
|
||||
x3LI1hvbo2saDXigQ/JkE7SwMEp5QVf11ZV9FthS7/MI/40GstEUtlCdq/jNdL2X
|
||||
WNd1LNKxKQY1/Dy4EksOqbrHNLoHVbJ3btywHqVCSy73cY7CTPVoBkDVUCtFinwD
|
||||
HFM/UceKNGAEs02Om/HixYt1g7swH/GY8gH8pXqA7E4Vpy9idGF3JdhEF9bd9yhr
|
||||
EtmQIsWOWJI5+NmkQAmpKrWwc0TLvXV+dlzrYXf0FundOVx3sPT1csAMZ+4cqXiY
|
||||
01QYGvf+wJ5JT4DaGA0mftxBMNSY6L6nuGKeYW40NIRw6kM0Sh7mxClFmslbPWF9
|
||||
fIVWRrUApz1J9dQpb22XiirSEAQhC8MQs7N297b3+sAvhwrrUBSQyu5Zhc+G3Qr+
|
||||
EBnKb9d3692zMXDvYprDQFtl2yRX57swJMXV1mr5F2W+oynt9BT5SZ/tdvtdYOJ5
|
||||
htND1BG+Ddz2METm+0h+tUbPIqYaqy0369U3Nq9trTa2164tbdTXL/vH1uqVxsbq
|
||||
5a3WVmNju8pNxMgyi3ddGSompJMJpssMs/8Q2WLe64Oj9/1VUnb6mlTJXUDl1lYB
|
||||
ZrbEW4UwlnLkaKFvC+zaWU7wvWR1H8fWL019A9EUd+s82WOKf7jpherXt5+cOR3M
|
||||
PHXqCfrcmwmefm70EfjPuydmPvjur/o7a3d+/vSTj/+8tn7z958+uv/K+63PFu+1
|
||||
f2lUb/z61cz91vdnvnjh9WfumuEf1+98eerev3//dvPDk2svfjP3efZy+N7efzAV
|
||||
HA0=
|
||||
=/+Rt
|
||||
-----END PGP MESSAGE-----
|
4
CLA.md
4
CLA.md
@ -8,7 +8,7 @@ E-Mail: `$email`
|
||||
|
||||
Legal Jurisdiction: Wyoming, United States of America
|
||||
|
||||
Project: https://github.com/BlockchainCommons/bc-lethe-kit
|
||||
Project: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line
|
||||
|
||||
Date: `$date`
|
||||
|
||||
@ -52,4 +52,4 @@ I promise not to offer contributions that contain or depend on the work of other
|
||||
|
||||
---
|
||||
|
||||
To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./signed-cla/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
|
||||
To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./CLA-signed/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com).
|
||||
|
@ -11,9 +11,9 @@ We love your input! We want to make contributing to this project as easy and tra
|
||||
## We Develop with Github
|
||||
We use GitHub to host code, to track issues and feature requests, and to accept Pull Requests.
|
||||
|
||||
## Report Bugs using Github's [issues](https://github.com/briandk/transcriptase-atom/issues)
|
||||
## Report Bugs using Github's [issues](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues)
|
||||
|
||||
If you find bugs, mistakes, or inconsistencies in this project's code or documents, please let us know by [opening a new issue](./issues), but consider searching through existing issues first to check and see if the problem has already been reported. If it has, it never hurts to add a quick "+1" or "I have this problem too". This helps prioritize the most common problems and requests.
|
||||
If you find bugs, mistakes, or inconsistencies in this project's code or documents, please let us know by [opening a new issue](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues/new), but consider searching through existing issues first to check and see if the problem has already been reported. If it has, it never hurts to add a quick "+1" or "I have this problem too". This helps prioritize the most common problems and requests.
|
||||
|
||||
### Write Bug Reports with Detail, Background, and Sample Code
|
||||
|
||||
@ -35,7 +35,7 @@ People *love* thorough bug reports. I'm not even kidding.
|
||||
|
||||
Simple Pull Requests to fix typos, to document, or to fix small bugs are always welcome.
|
||||
|
||||
We ask that more significant improvements to the project be first proposed before anybody starts to code as an [issue](./issues) or as a [draft Pull Request](./pulls), which is a [nice new feature](https://github.blog/2019-02-14-introducing-draft-pull-requests/) that gives other contributors a chance to point you in the right direction, give feedback on the design, and maybe discuss if related work is already under way.
|
||||
We ask that more significant improvements to the project be first proposed before anybody starts to code as an [issue](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) or as a [draft Pull Request](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/pulls), which is a [nice new feature](https://github.blog/2019-02-14-introducing-draft-pull-requests/) that gives other contributors a chance to point you in the right direction, give feedback on the design, and maybe discuss if related work is already under way.
|
||||
|
||||
### Use a Consistent Coding Style
|
||||
|
||||
@ -61,5 +61,5 @@ In short, when you submit code changes, your submissions are understood to be av
|
||||
## References
|
||||
|
||||
Portions of this CONTRIBUTING.md document were adopted from best practices of a number of open source projects, including:
|
||||
* [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md)
|
||||
* [Facebook's Draft](https://github.com/facebook/draft-js/blob/master/CONTRIBUTING.md)
|
||||
* [IPFS Contributing](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)
|
||||
|
388
Chapter_word_counts.ipynb
Normal file
388
Chapter_word_counts.ipynb
Normal file
File diff suppressed because one or more lines are too long
109
Chapter_word_counts.md
Normal file
109
Chapter_word_counts.md
Normal file
@ -0,0 +1,109 @@
|
||||
## Translatable word counts by chapter
|
||||
|
||||
Ignores code blocks and other non-translatable characters
|
||||
|
||||
Chapter|Word Count
|
||||
---|---
|
||||
01_0_Introduction.md|1144
|
||||
01_1_Introducing_Bitcoin.md|2735
|
||||
02_0_Setting_Up_a_Bitcoin-Core_VPS.md|226
|
||||
02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md|2746
|
||||
02_2_Setting_Up_Bitcoin_Core_Other.md|254
|
||||
03_0_Understanding_Your_Bitcoin_Setup.md|248
|
||||
03_1_Verifying_Your_Bitcoin_Setup.md|773
|
||||
03_2_Knowing_Your_Bitcoin_Setup.md|517
|
||||
03_3_Setting_Up_Your_Wallet.md|1699
|
||||
03_3__Interlude_Using_Command-Line_Variables.md|347
|
||||
03_4_Receiving_a_Transaction.md|1479
|
||||
03_5_Understanding_the_Descriptor.md|1349
|
||||
04_0_Sending_Bitcoin_Transactions.md|176
|
||||
04_1_Sending_Coins_The_Easy_Way.md|1195
|
||||
04_2_Creating_a_Raw_Transaction.md|1720
|
||||
04_2__Interlude_Using_JQ.md|1956
|
||||
04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md|413
|
||||
04_4_Sending_Coins_with_a_Raw_Transaction.md|1024
|
||||
04_4__Interlude_Using_Curl.md|1643
|
||||
04_5_Sending_Coins_with_Automated_Raw_Transactions.md|614
|
||||
04_6_Creating_a_Segwit_Transaction.md|1172
|
||||
05_0_Controlling_Bitcoin_Transactions.md|149
|
||||
05_1_Watching_for_Stuck_Transactions.md|595
|
||||
05_2_Resending_a_Transaction_with_RBF.md|1372
|
||||
05_3_Funding_a_Transaction_with_CPFP.md|827
|
||||
06_0_Expanding_Bitcoin_Transactions_Multisigs.md|155
|
||||
06_1_Sending_a_Transaction_to_a_Multisig.md|1764
|
||||
06_2_Spending_a_Transaction_to_a_Multisig.md|1079
|
||||
06_3_Sending_an_Automated_Multisig.md|613
|
||||
07_0_Expanding_Bitcoin_Transactions_PSBTs.md|169
|
||||
07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md|1470
|
||||
07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md|1393
|
||||
07_3_Integrating_with_Hardware_Wallets.md|2150
|
||||
08_0_Expanding_Bitcoin_Transactions_Other.md|139
|
||||
08_1_Sending_a_Transaction_with_a_Locktime.md|1483
|
||||
08_2_Sending_a_Transaction_with_Data.md|580
|
||||
09_0_Introducing_Bitcoin_Scripts.md|196
|
||||
09_1_Understanding_the_Foundation_of_Transactions.md|989
|
||||
09_2_Running_a_Bitcoin_Script.md|863
|
||||
09_3_Testing_a_Bitcoin_Script.md|1000
|
||||
09_4_Scripting_a_P2PKH.md|838
|
||||
09_5_Scripting_a_P2WPKH.md|845
|
||||
10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md|170
|
||||
10_1_Understanding_the_Foundation_of_P2SH.md|1164
|
||||
10_2_Building_the_Structure_of_P2SH.md|1284
|
||||
10_3_Running_a_Bitcoin_Script_with_P2SH.md|323
|
||||
10_4_Scripting_a_Multisig.md|1016
|
||||
10_5_Scripting_a_Segwit_Script.md|750
|
||||
10_6_Spending_a_P2SH_Transaction.md|384
|
||||
11_0_Empowering_Timelock_with_Bitcoin_Scripts.md|108
|
||||
11_1_Understanding_Timelock_Options.md|557
|
||||
11_2_Using_CLTV_in_Scripts.md|1197
|
||||
11_3_Using_CSV_in_Scripts.md|1470
|
||||
12_0_Expanding_Bitcoin_Scripts.md|99
|
||||
12_1_Using_Script_Conditionals.md|1120
|
||||
12_2_Using_Other_Script_Commands.md|407
|
||||
13_0_Designing_Real_Bitcoin_Scripts.md|116
|
||||
13_1_Writing_Puzzle_Scripts.md|998
|
||||
13_2_Writing_Complex_Multisig_Scripts.md|996
|
||||
13_3_Empowering_Bitcoin_with_Scripts.md|1467
|
||||
14_0_Using_Tor.md|116
|
||||
14_1_Verifying_Your_Tor_Setup.md|1568
|
||||
14_2_Changing_Your_Bitcoin_Hidden_Services.md|434
|
||||
14_3_Adding_SSH_Hidden_Services.md|330
|
||||
15_0_Talking_to_Bitcoind.md|254
|
||||
15_1_Accessing_Bitcoind_with_C.md|1238
|
||||
15_2_Programming_Bitcoind_with_C.md|1427
|
||||
15_3_Receiving_Bitcoind_Notifications_with_C.md|650
|
||||
16_0_Programming_with_Libwally.md|333
|
||||
16_1_Setting_Up_Libwally.md|559
|
||||
16_2_Using_BIP39_in_Libwally.md|939
|
||||
16_3_Using_BIP32_in_Libwally.md|959
|
||||
16_4_Using_PSBTs_in_Libwally.md|989
|
||||
16_5_Using_Scripts_in_Libwally.md|785
|
||||
16_6_Using_Other_Functions_in_Libwally.md|655
|
||||
16_7_Integrating_Libwally_and_Bitcoin-CLI.md|1380
|
||||
17_0_Talking_to_Bitcoind_Other.md|286
|
||||
17_1_Accessing_Bitcoind_with_Go.md|547
|
||||
17_2_Accessing_Bitcoind_with_Java.md|821
|
||||
17_3_Accessing_Bitcoind_with_NodeJS.md|393
|
||||
17_4_Accessing_Bitcoind_with_Python.md|1158
|
||||
17_5_Accessing_Bitcoind_with_Rust.md|829
|
||||
17_6_Accessing_Bitcoind_with_Swift.md|1503
|
||||
18_0_Understanding_Your_Lightning_Setup.md|192
|
||||
18_1_Verifying_Your_Lightning_Setup.md|1294
|
||||
18_2_Knowing_Your_lightning_Setup.md|399
|
||||
18_2__Interlude_Accessing_a_Second_Lightning_Node.md|886
|
||||
18_3_Setting_Up_a_Channel.md|1173
|
||||
19_0_Using_Lightning.md|146
|
||||
19_1_Generate_a_Payment_Request.md|968
|
||||
19_2_Paying_a_Invoice.md|604
|
||||
19_3_Closing_a_Channel.md|848
|
||||
19_4_Lightning_Network_Review.md|626
|
||||
A0_Appendices.md|112
|
||||
A1_0_Understanding_Bitcoin_Standup.md|420
|
||||
A2_0_Compiling_Bitcoin_from_Source.md|412
|
||||
A3_0_Using_Bitcoin_Regtest.md|980
|
||||
CLA.md|495
|
||||
CONTRIBUTING.md|529
|
||||
LICENSE-CC-BY-4.0.md|2716
|
||||
README.md|1705
|
||||
TRANSLATING.md|686
|
||||
TOTAL|89069
|
145
README.md
145
README.md
@ -1,4 +1,5 @@
|
||||
# Learning Bitcoin from the Command Line
|
||||
# Learning Bitcoin from the Command Line 2.2.0
|
||||
### _by Christopher Allen and Shannon Appelcline_
|
||||
|
||||

|
||||
|
||||
@ -8,6 +9,13 @@ Learning Bitcoin from the Command Line is a tutorial for working with Bitcoin (a
|
||||
|
||||
_This tutorial assumes that you have some minimal background of how to use the command line interface. If not, there are many tutorials available, and I have one for Mac users at https://github.com/ChristopherA/intro-mac-command-line._
|
||||
|
||||
## Translations
|
||||
|
||||
* [Portuguese](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/portuguese-translation/pt/README.md) — v2.0.1 translation
|
||||
* [Spanish](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/spanish-translation/es/README.md) - v2.0.1 translation
|
||||
|
||||
If you'd like to make your own translation, please see [Contributing](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master#contributing), below.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
### PART ONE: PREPARING FOR BITCOIN
|
||||
@ -45,8 +53,8 @@ _This tutorial assumes that you have some minimal background of how to use the c
|
||||
* [5.2: Resending a Transaction with RBF](05_2_Resending_a_Transaction_with_RBF.md)
|
||||
* [5.3: Funding a Transaction with CPFP](05_3_Funding_a_Transaction_with_CPFP.md)
|
||||
* [6.0: Expanding Bitcoin Transactions with Multisigs](06_0_Expanding_Bitcoin_Transactions_Multisigs.md)
|
||||
* [6.1: Sending a Transaction with a Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md)
|
||||
* [6.2: Spending a Transaction with a Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md)
|
||||
* [6.1: Sending a Transaction with a Multisig](06_1_Sending_a_Transaction_to_a_Multisig.md)
|
||||
* [6.2: Spending a Transaction with a Multisig](06_2_Spending_a_Transaction_to_a_Multisig.md)
|
||||
* [6.3: Sending & Spending an Automated Multisig](06_3_Sending_an_Automated_Multisig.md)
|
||||
* [7.0: Expanding Bitcoin Transactions with PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md)
|
||||
* [7.1: Creating a Partially Signed Bitcoin Transaction](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md)
|
||||
@ -85,7 +93,7 @@ _This tutorial assumes that you have some minimal background of how to use the c
|
||||
* [13.2: Writing Complex Multisig Scripts](13_2_Writing_Complex_Multisig_Scripts.md)
|
||||
* [13.3: Empowering Bitcoin with Scripts](13_3_Empowering_Bitcoin_with_Scripts.md)
|
||||
|
||||
### PART FOUR: USING TOR
|
||||
### PART FOUR: PRIVACY
|
||||
|
||||
**Status:** Finished.
|
||||
|
||||
@ -94,44 +102,47 @@ _This tutorial assumes that you have some minimal background of how to use the c
|
||||
* [14.2: Changing Your Bitcoin Hidden Services](14_2_Changing_Your_Bitcoin_Hidden_Services.md)
|
||||
* [14.3: Adding SSH Hidden Services](14_3_Adding_SSH_Hidden_Services.md)
|
||||
|
||||
* [15.0: Using i2p](15_0_Using_i2p.md)
|
||||
* [15.1: Bitcoin Core as an I2P (Invisible Internet Project) service](15_1_i2p_service.md)
|
||||
|
||||
### PART FIVE: PROGRAMMING WITH RPC
|
||||
|
||||
**Status:** Finished.
|
||||
|
||||
* [15.0: Talking to Bitcoind with C](15_0_Talking_to_Bitcoind.md)
|
||||
* [15.1: Accessing Bitcoind in C with RPC Libraries](15_1_Accessing_Bitcoind_with_C.md)
|
||||
* [15.2: Programming Bitcoind in C with RPC Libraries](15_2_Programming_Bitcoind_with_C.md)
|
||||
* [15.3: Receiving Notifications in C with ZMQ Libraries](15_3_Receiving_Bitcoind_Notifications_with_C.md)
|
||||
* [16.0: Programming Bitcoin with Libwally](16_0_Programming_with_Libwally.md)
|
||||
* [16.1: Setting Up Libwally](16_1_Setting_Up_Libwally.md)
|
||||
* [16.2: Using BIP39 in Libwally](16_2_Using_BIP39_in_Libwally.md)
|
||||
* [16.3: Using BIP32 in Libwally](16_3_Using_BIP32_in_Libwally.md)
|
||||
* [16.4: Using PSBTs in Libwally](16_4_Using_PSBTs_in_Libwally.md)
|
||||
* [16.5: Using Scripts in Libwally](16_5_Using_Scripts_in_Libwally.md)
|
||||
* [16.6: Using Other Functions in Libwally](16_6_Using_Other_Functions_in_Libwally.md)
|
||||
* [16.7: Integrating Libwally and Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md)
|
||||
* [17.0: Talking to Bitcoind with Other Languages](17_0_Talking_to_Bitcoind_Other.md)
|
||||
* [17.1: Accessing Bitcoind with Go](17_1_Accessing_Bitcoind_with_Go.md)
|
||||
* [17.2: Accessing Bitcoind with Java](17_2_Accessing_Bitcoind_with_Java.md)
|
||||
* [17.3: Accessing Bitcoind with Node JS](17_3_Accessing_Bitcoind_with_NodeJS.md)
|
||||
* [17.4: Accessing Bitcoind with Python](17_4_Accessing_Bitcoind_with_Python.md)
|
||||
* [17.5: Accessing Bitcoind with Rust](17_5_Accessing_Bitcoind_with_Rust.md)
|
||||
* [17.6: Accessing Bitcoind with Swift](17_6_Accessing_Bitcoind_with_Swift.md)
|
||||
* [16.0: Talking to Bitcoind with C](16_0_Talking_to_Bitcoind.md)
|
||||
* [16.1: Accessing Bitcoind in C with RPC Libraries](16_1_Accessing_Bitcoind_with_C.md)
|
||||
* [16.2: Programming Bitcoind in C with RPC Libraries](16_2_Programming_Bitcoind_with_C.md)
|
||||
* [16.3: Receiving Notifications in C with ZMQ Libraries](16_3_Receiving_Bitcoind_Notifications_with_C.md)
|
||||
* [17.0: Programming Bitcoin with Libwally](17_0_Programming_with_Libwally.md)
|
||||
* [17.1: Setting Up Libwally](17_1_Setting_Up_Libwally.md)
|
||||
* [17.2: Using BIP39 in Libwally](17_2_Using_BIP39_in_Libwally.md)
|
||||
* [17.3: Using BIP32 in Libwally](17_3_Using_BIP32_in_Libwally.md)
|
||||
* [17.4: Using PSBTs in Libwally](17_4_Using_PSBTs_in_Libwally.md)
|
||||
* [17.5: Using Scripts in Libwally](17_5_Using_Scripts_in_Libwally.md)
|
||||
* [17.6: Using Other Functions in Libwally](17_6_Using_Other_Functions_in_Libwally.md)
|
||||
* [17.7: Integrating Libwally and Bitcoin-CLI](17_7_Integrating_Libwally_and_Bitcoin-CLI.md)
|
||||
* [18.0: Talking to Bitcoind with Other Languages](18_0_Talking_to_Bitcoind_Other.md)
|
||||
* [18.1: Accessing Bitcoind with Go](18_1_Accessing_Bitcoind_with_Go.md)
|
||||
* [18.2: Accessing Bitcoind with Java](18_2_Accessing_Bitcoind_with_Java.md)
|
||||
* [18.3: Accessing Bitcoind with Node JS](18_3_Accessing_Bitcoind_with_NodeJS.md)
|
||||
* [18.4: Accessing Bitcoind with Python](18_4_Accessing_Bitcoind_with_Python.md)
|
||||
* [18.5: Accessing Bitcoind with Rust](18_5_Accessing_Bitcoind_with_Rust.md)
|
||||
* [18.6: Accessing Bitcoind with Swift](18_6_Accessing_Bitcoind_with_Swift.md)
|
||||
|
||||
### PART SIX: USING LIGHTNING-CLI
|
||||
|
||||
**Status:** Finished.
|
||||
|
||||
* [18.0: Understanding Your Lightning Setup](18_0_Understanding_Your_Lightning_Setup.md)
|
||||
* [18.1: Verifying Your c-lightning Setup](18_1_Verifying_Your_Lightning_Setup.md)
|
||||
* [18.2: Knowing Your c-lightning Setup](18_2_Knowing_Your_lightning_Setup.md)
|
||||
* [Interlude: Accessing a Second Lightning Node](18_2__Interlude_Accessing_a_Second_Lightning_Node.md)
|
||||
* [18.3: Creating a Lightning Channel](18_3_Setting_Up_a_Channel.md)
|
||||
* [19.0: Using Lightning](19_0_Using_Lightning.md)
|
||||
* [19.1: Generating a Payment Request](19_1_Generate_a_Payment_Request.md)
|
||||
* [19.2: Paying an Invoice](19_2_Paying_a_Invoice.md)
|
||||
* [19.3: Closing a Lighnting Channel]((19_3_Closing_a_Channel.md))
|
||||
* [19.4: Expanding the Lightning Network](19_4_Lightning_Network_Review.md)
|
||||
* [19.0: Understanding Your Lightning Setup](19_0_Understanding_Your_Lightning_Setup.md)
|
||||
* [19.1: Verifying Your c-lightning Setup](19_1_Verifying_Your_Lightning_Setup.md)
|
||||
* [19.2: Knowing Your c-lightning Setup](19_2_Knowing_Your_lightning_Setup.md)
|
||||
* [Interlude: Accessing a Second Lightning Node](19_2__Interlude_Accessing_a_Second_Lightning_Node.md)
|
||||
* [19.3: Creating a Lightning Channel](19_3_Setting_Up_a_Channel.md)
|
||||
* [20.0: Using Lightning](20_0_Using_Lightning.md)
|
||||
* [20.1: Generating a Payment Request](20_1_Generate_a_Payment_Request.md)
|
||||
* [20.2: Paying an Invoice](20_2_Paying_a_Invoice.md)
|
||||
* [20.3: Closing a Lighnting Channel]((20_3_Closing_a_Channel.md))
|
||||
* [20.4: Expanding the Lightning Network](20_4_Lightning_Network_Review.md)
|
||||
|
||||
### APPENDICES
|
||||
|
||||
@ -142,13 +153,40 @@ _This tutorial assumes that you have some minimal background of how to use the c
|
||||
* [Appendix II: Compiling Bitcoin from Source](A2_0_Compiling_Bitcoin_from_Source.md)
|
||||
* [Appendix III: Using Bitcoin Regtest](A3_0_Using_Bitcoin_Regtest.md)
|
||||
|
||||
## Status - Work in Progress
|
||||
## Status - Beta
|
||||
|
||||
Learning Bitcoin from the Command Line is currently under active development and its writing in progress. Current chapters are functional, but need to be updated to more modern versions of Bitcoin-Core. Additional chapters also need to be written to fill out our intended scope.
|
||||
v2.1.0 of **Learning Bitcoin from the Command Line** is feature complete and has undergone full editing and integration. It is ready for learning
|
||||
|
||||
The empty chapters above show some of our current plans for future work. Other plans, mainly drawn from old issues, can be found in [TODO.md](TODO.md)
|
||||
We are also tentatively considering what we could include in a [v3.0](TODO-30.md) of the course. If you'd like to support work of that sort, become a [GitHub Sponsor](https://github.com/sponsors/BlockchainCommons) or support us at our [BTCPay Server](https://btcpay.blockchaincommons.com/), and let us know that **Learning Bitcoin** was the reason why.
|
||||
### Version History
|
||||
|
||||
Obviously, this work in progress should not be used for production tasks until it is completed and has had further testing and auditing.
|
||||
#### 2.2.0 (November 17, 2021)
|
||||
|
||||
* [Portuguese translation](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master/pt)
|
||||
* [Spanish translation](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master/es)
|
||||
|
||||
#### 2.1.0 (October 12, 2021)
|
||||
|
||||
* New chapter 15 (i2p).
|
||||
* Added fixes to wallet usage from 0.21
|
||||
* Updated install to new Bitcoin Scripts for 22.0
|
||||
* Incorporated numerous fixes revealed by first translation projects
|
||||
|
||||
#### 2.0.1 (June 15, 2021)
|
||||
|
||||
* Numerous small patches following 2.0
|
||||
* Intended as baseline for translations (2.2.0), but 2.1.0 material on i2p slipped in
|
||||
|
||||
#### 2.0.0 (November 3, 2020)
|
||||
|
||||
* Second major release of Learning Bitcoin
|
||||
* Added material on Segwit, Tor, hardware wallets, lightning, regtest
|
||||
* Completely previous unfinished work on programming using a variety of languages
|
||||
|
||||
#### 1.0.0 (pre-2020)
|
||||
|
||||
* Original, extensive but incomplete version
|
||||
* Contained comprehensive sections on setup, bitcoin-cli, and scripting
|
||||
|
||||
## Origin, Authors, Copyright & Licenses
|
||||
|
||||
@ -158,21 +196,24 @@ Unless otherwise noted (either in this [/README.md](./README.md) or in the file'
|
||||
|
||||
*Learning Bitcoin from the Command Line* is a project of [Blockchain Commons](https://www.blockchaincommons.com/). We are proudly a "not-for-profit" social benefit corporation committed to open source & open development. Our work is funded entirely by donations and collaborative partnerships with people like you. Every contribution will be spent on building open tools, technologies, and techniques that sustain and advance blockchain and internet security infrastructure and promote an open web.
|
||||
|
||||
To financially support further development of `$projectname` and other projects, please consider becoming a Patron of Blockchain Commons through ongoing monthly patronage as a [GitHub Sponsor](https://github.com/sponsors/BlockchainCommons). You can also support Blockchain Commons with bitcoins at our [BTCPay Server](https://btcpay.blockchaincommons.com/).
|
||||
To financially support further development of *Learning Bitcoin from the Command Line* and other projects, please consider becoming a Patron of Blockchain Commons through ongoing monthly patronage as a [GitHub Sponsor](https://github.com/sponsors/BlockchainCommons). You can also support Blockchain Commons with bitcoins at our [BTCPay Server](https://btcpay.blockchaincommons.com/).
|
||||
|
||||
## Contributing
|
||||
|
||||
We encourage public contributions through issues and pull requests! Please review [CONTRIBUTING.md](./CONTRIBUTING.md) for details on our development process. All contributions to this repository require a GPG signed [Contributor License Agreement](./CLA.md).
|
||||
|
||||
if you would like to provide a translation of Learning Bitcoin into another language, please additionally see [TRANSLATING.md](./TRANSLATING.md).
|
||||
|
||||
### Discussions
|
||||
|
||||
The best place to talk about Blockchain Commons and its projects is in our GitHub Discussions areas.
|
||||
|
||||
[**Blockchain Commons Discussions**](https://github.com/BlockchainCommons/Community/discussions). For developers, interns, and patrons of Blockchain Commons, please use the discussions area of the [Community repo](https://github.com/BlockchainCommons/Community) to talk about general Blockchain Commons issues, the intern program, or topics other than the [Gordian System](https://github.com/BlockchainCommons/Gordian/discussions) or the [wallet standards](https://github.com/BlockchainCommons/AirgappedSigning/discussions), each of which have their own discussion areas.
|
||||
[**Blockchain Commons Discussions**](https://github.com/BlockchainCommons/Community/discussions). For developers, interns, and patrons of Blockchain Commons, please use the discussions area of the [Community repo](https://github.com/BlockchainCommons/Community) to talk about general Blockchain Commons issues, the intern program, or topics other than those covered by the [Gordian Developer Community](https://github.com/BlockchainCommons/Gordian-Developer-Community/discussions) or the
|
||||
[Gordian User Community](https://github.com/BlockchainCommons/Gordian/discussions).'
|
||||
|
||||
### Other Questions & Problems
|
||||
|
||||
As an open-source, open-development community, Blockchain Commons does not have the resources to provide direct support of our projects. Please consider the discussions area as a locale where you might get answers to questions. Alternatively, please use this repository's [issues](./issues) feature. Unfortunately, we can not make any promises on response time.
|
||||
As an open-source, open-development community, Blockchain Commons does not have the resources to provide direct support of our projects. Please consider the discussions area as a locale where you might get answers to questions. Alternatively, please use this repository's [issues](../../issues) feature. Unfortunately, we can not make any promises on response time.
|
||||
|
||||
If your company requires support to use our projects, please feel free to contact us directly about options. We may be able to offer you a contract for support from one of our contributors, or we might be able to point you to another entity who can offer the contractual support that you need.
|
||||
|
||||
@ -191,10 +232,32 @@ Additional contributions are listed below:
|
||||
|
||||
| Role | Names |
|
||||
| ------------------- | ---------------------------------------- |
|
||||
| ***Contributors:*** | [gg2001](https://github.com/gg2001) (Go, Node.js sections), [gorazdko](https://github.com/gorazdko) (Rust section), [Javier Vargas](https://github.com/javiervargas) (C, Java, Lightning, Tor sections), [jodobear](https://github.com/jodobear) (Appendix: Compiling Bitcoin, Python section) |
|
||||
| ***Contributors:*** | [gg2001](https://github.com/gg2001) (Go, Node.js sections), [gorazdko](https://github.com/gorazdko) (Rust section), [Javier Vargas](https://github.com/javiervargas) (C, Java, Lightning, Tor sections), [jodobear](https://github.com/jodobear) (Appendix: Compiling Bitcoin, Python section), [Prayank]( https://github.com/prayank23) (i2p sections) |
|
||||
| ***Reviewers:*** | Glen Willem [@gwillem](https://github.com/gwillem) |
|
||||
| ***Sponsors:*** | Blockstream Corporation |
|
||||
|
||||
### Translation Credits
|
||||
|
||||
Thanks to the volunteers who spent extensive time writing and reviewing other-language translations of the original English-language course.
|
||||
|
||||
#### Portuguese Translation
|
||||
|
||||
| Name | Role | Github |
|
||||
| ----------------- | ------------------- | ------------------------------------------------- |
|
||||
| Namcios | Translator & Reviewer | [@namcios](https://github.com/namcios) |
|
||||
| Korea | Translator & Reviewer | [@KoreaComK](https://github.com/KoreaComK) |
|
||||
| Luke Pavsky | Translator & Reviewer | [@lukedevj](https://github.com/lukedevj) |
|
||||
| hgrams | Translator & Reviewer | [@hgrams](https://github.com/hgrams) |
|
||||
|
||||
#### Spanish Translation
|
||||
|
||||
Name | Role | GitHub |
|
||||
| ---------- | -------- | ------------ |
|
||||
| Ian Culp | Translator & Reviewer | [@icculp](https://github.com/icculp) |
|
||||
| Maxi Goyheneche | Translator | [@maxcrowar](https://github.com/maxcrowar) |
|
||||
| Said Rahal | Translator | [@srahalh](https://github.com/srahalh) |
|
||||
| César A. Vallero | Translator & Reviewer | [@csralvall](https://github.com/csralvall) |
|
||||
| Javier Vargas | Translator & Reviewer | [@javiervargas](https://github.com/javiervargas) |
|
||||
|
||||
## Responsible Disclosure
|
||||
|
||||
|
64
TODO-23.md
Normal file
64
TODO-23.md
Normal file
@ -0,0 +1,64 @@
|
||||
# Updates for v2.3 of LBTCftCL
|
||||
|
||||
V2.2 of LBTCftCL was drafted in the summer of 2021. The last major upgrade to the book came with the release of v0.20, but there is a smattering of content through 22.0. Bitcoin Core is now up to v23.0, and the course needs to be updated to best address these recent changes. What follows is a rough listing of updates that are likely to require changes to the course. They will all require investigation, and in some cases it might be determined that there's nothing to be done. Some of the main questions that will determine whether material should be included in the course are listed, as our ideas for where material might go in the course.
|
||||
|
||||
## Legacy Updates
|
||||
|
||||
* [ ] **Segwit**
|
||||
* Segwit is now old enough that we should teach it as the default. That means that sections 3.1-4.5 should be rewritten to use Segwit as the default and 4.6 should be removed (with perhaps a bit of the information about the different types of addresses being preserved).
|
||||
* It's _possible_ that the same should occur with 10.5, but it should first be reviewed to see if it's a meaningful building block in the scripting process (or not).
|
||||
* [ ] **Fees**
|
||||
* There was some question of if `mintxfee` is still current, or if `paytxfee` should be used. I haven't seen any evidence of obsolence, but it'd be good to check this and make sure we're still on the best practices.
|
||||
* This is discussed in [4.1](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_1_Sending_Coins_The_Easy_Way.md)
|
||||
|
||||
## 23.0 Updates
|
||||
|
||||
See also [#575](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues/575) and of course the [Bitcoin Core 23.0 release notes](https://github.com/bitcoin/bitcoin/blob/master/doc/release-notes/release-notes-23.0.md).
|
||||
|
||||
* [ ] **Schnorr & Taproot**
|
||||
* Obviously, the biggest update. We'll need to teach the basics of both and why they're exciting. The main question here is: what commands actually take advantage of Schnorr & Taproot, and how can we show this off.
|
||||
* If there's just a little bit of functionality right now, it can go into chapter 8, probably in two new sections: 8.3 & 8.4, on Schnorr and Taproot. If there's already a lot of functionality, it should go into its own chapter, and 8 (and everything beyond it) should be shifted back.
|
||||
* [ ] **Descriptor Wallets**
|
||||
* Descriptor wallets are now the default. There's some unfortunate lack of integration with multisigs, but we should otherwise give them more attention. What can we do new about inputting and outputting descriptor wallets? Are there any other functions of note?
|
||||
* This will likely go in [3.5](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/03_5_Understanding_the_Descriptor.md), though it's possible it go split into two chapters: Understanding the Descriptor and Understanding the Descriptor Wallet. See the [0.21 release notes at the bottom](https://bitcoincore.org/en/releases/0.21.0/) for everything about Descriptor Wallets. But note that we explicitly turn them off in 3.2, so any discussions explicitly about descriptor wallets will require creating a new wallet for that purpose
|
||||
* [ ] **Freezing Coins**
|
||||
* This is an interesting new ability that allows you to prevent UTXOs from being automatically selected when transactions are created.
|
||||
* This would probably fit well into 4.5 as a final header-section.
|
||||
* [ ] **CJDNS Network**
|
||||
* I'm not familiar with CJDNS, but it sounds like a privacy option that would fit in with Tor and i2p
|
||||
* If that's correctly, this would be a good 15.2, with the 15.0 chapter renamed "Using Other Privacy Options" or something like that
|
||||
* [ ] **RPC Changes**
|
||||
* The following RPC commands have had changes to their output and any examples should be rerun. If they are part of a sequence of commands (e.g., building out a transaction), then the whole sequence should be rerun.
|
||||
* [ ] `createmultisig`,
|
||||
* [ ] `addmultisigaddress`,
|
||||
* [ ] `listunspent`,
|
||||
* [ ] `getblockchaininfo`
|
||||
* Updated RPCs may or may not exist in the text. The best way to find out is to search.
|
||||
|
||||
## 22.0 Updates
|
||||
|
||||
See [release notes](https://bitcoincore.org/en/releases/22.0/).
|
||||
|
||||
* [ ] **New External Signer Commands**
|
||||
* There are some new external signer commands: `enumeratesigners` and `displayaddress`. Are they relevant to what we're teaching? If so, should we add info on them.
|
||||
* See https://github.com/bitcoin/bitcoin/blob/22.x/doc/external-signer.md
|
||||
* Any updates would go in [7.3](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_3_Integrating_with_Hardware_Wallets.md).
|
||||
* [ ] **RPC Changes**
|
||||
* Again, these commands should be reoutput.
|
||||
* [ ] `getpeerinfo`,
|
||||
* [ ] `gettxout`,
|
||||
* [ ] `getrawtransaction`,
|
||||
* [ ] `decoderawtransaction`,
|
||||
* [ ] `decodescript`,
|
||||
* [ ] `getnodeaddresses`
|
||||
|
||||
## 0.21.0 Updates
|
||||
|
||||
See [release notes](https://bitcoincore.org/en/releases/0.21.0/).
|
||||
|
||||
* [ ] **Signet**
|
||||
* Signet is considered more controlled and reliable than testnet, and so should be used as our test network, along with an explanation of what it is and how it differs from other networks.
|
||||
* The setup and explanation of networks appears in [3.1](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/03_1_Verifying_Your_Bitcoin_Setup.md). That should be changed, and with the change of the alias there, we should mostly be used Signet. Then the rest of the course can be searched for any references to testnet.
|
||||
* [ ] **RPC Changes**
|
||||
* As usual, these may or may not be used, but if they are, outputs should be redone.
|
||||
* [ ] `getnetworkinfo`
|
115
TODO-30.md
115
TODO-30.md
@ -2,12 +2,111 @@
|
||||
|
||||
The following TODO items are intended for a 3.0 version of Learning Bitcoin from the Command Line
|
||||
|
||||
1. Section on Libwally Shim for Swift
|
||||
2. Section on Wolf's Bitcoin Lib for Swift
|
||||
2. Full example of creating a PSBT, handing it to Libwally, and signing it
|
||||
3. Miniscript
|
||||
4. Schnorr (2021)
|
||||
5. Other BCC Command-Line Utilities?
|
||||
6. Programming Lightning with C
|
||||
* _Some good docs from one of the developers are here: https://diyhpl.us/wiki/transcripts/blockstream-webinars/2019-07-31-rusty-russell-getting-started-with-c-lightning/._
|
||||
## Medium-Scale Updates
|
||||
|
||||
The following updates involve updates or the creation of new chapters, but their additions are generally bounded and known.
|
||||
|
||||
1. General Update: Consider replacing testnet with signet
|
||||
1. New Interlude: Creating QR Codes (after 3.3)
|
||||
* New Subsection: Creating a QR
|
||||
* New Subsection: Creating a Quick Connect QR
|
||||
1. Revise Section: Understanding the Descriptor (3.5)
|
||||
* New Content: Descriptor Wallets
|
||||
* New Content: Complex Descriptors
|
||||
* Consider: Breaking into Two Sections
|
||||
1. New Interlude: Creating Animated QR Codes (after 7.1)
|
||||
* New Subsection: Understanding Uniform Resources
|
||||
* New Subsection: Creating an Animated QR
|
||||
* New Subsection: Creating an Animated QR of a PSBT
|
||||
1. New Chapter: Using Other Command-Line Tools (between 8+9)
|
||||
* 9.1: Using seedtool
|
||||
* 9.2: Using keytool
|
||||
* 9.3: Using bytewords-cli
|
||||
1. Revise Section: Understanding Timelock Options (11.1)
|
||||
* Explanation: Better distinguish differences
|
||||
* Reference: consider chart at in https://prestwi.ch/bitcoin-time-locks/
|
||||
1. New Chapter: Using Miniscript Command-Line Tools (between 13+14)
|
||||
* 15.1: Using miniscript
|
||||
* 15.2: Using Bitcoin Dev Kit (BDK)
|
||||
* 15.3: Planning for the Future
|
||||
1. New Content: Expand the PSBT Libwally Content (17.4) into Two Sections
|
||||
* 17.4: Signing PSBTs in Libwally
|
||||
* Explanation: Contains the current info on importing a PSBT, and shows how to sign it
|
||||
* 17.5: Creating PSBTs in Libwally
|
||||
* Explanation: Contains the current info on creating a PSBT, and shows how to export it
|
||||
1. New Chapter: Talking to Bitcoind with Swift (between 17+18)
|
||||
* 19.1: Accessing Bitcoind with Swift (existing section)
|
||||
* 19.2: Using Swift with Bitcoin Lib [Wolf's library]
|
||||
* 19.3: Using Swift with Libwally [Wolf's shim]
|
||||
|
||||
## Large-Scale Updates
|
||||
|
||||
The following updates involve the large-scale work done on Schnorr and Taproot in Bitcoin Core 0.21 and 22. This represents a first cut at how to layout the work, but revision and expansion will likely be needed as everyone's understanding of these new technologies matures.
|
||||
|
||||
**Chapter X: Expanding Bitcoin Transactions with Schnorr** (probably between chapters 6+7)
|
||||
|
||||
* New Section X.1: Understanding Schnorr Signatures
|
||||
* New Subsection: Understanding the Math of Schnorr
|
||||
* Explanation: Add + subtract for one signature
|
||||
* New Subsection: Supporting MuSig
|
||||
* New Subsection: Understanding the Use of Adapter Signatures
|
||||
* New Subsection: Knowing the Advantages of Schnorr
|
||||
* Explanation: size, 64 bytes vs 72, better for multisigs
|
||||
* Explanation: speed, linear, validate a million-sig multisig in 2 minutes
|
||||
* Explanation: privacy, no difference between MuSig and sig, no detection of Lightning
|
||||
* Explanation: also better security, non-malleability
|
||||
* Reference: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
|
||||
* New Section X.2: Using Schnorr Signatures
|
||||
* New Subsection: Signing with Schnorr
|
||||
* New Subsection: Adding a Schnorr Signature
|
||||
* New Subsection: Reading a Schnorr Signature
|
||||
* New Subsection: Using Schnorr with Taproot
|
||||
* Update Chapter 6 (Multisigs) to Integrate with Schnorr
|
||||
|
||||
**Chapter Y: Improving Bitcoin Scripts with Taproot** (probably between chapters 13+14, possibly expanding to two chapters)
|
||||
|
||||
* New Section Y.1: Understanding MAST
|
||||
* New Subsection: Improving Privacy with MAST
|
||||
* New Subsection: Laying out a Script in MAST
|
||||
* New Subsection: Knowing the Advantages of MAST
|
||||
* Explanation: larger scripts
|
||||
* Explanation: hidden branches of scripts
|
||||
* Explanation: fungibility
|
||||
* https://github.com/bitcoin/bips/blob/master/bip-0114.mediawiki
|
||||
* New Section Y.2: Understanding Taproot
|
||||
* New Subsection: Integrating MAST with Taproot
|
||||
* Explanation: Expanding Segwit
|
||||
* Explanation: Integrating Schnorr Signatures
|
||||
* New Subsection: KNowing the Advantages of Taproot
|
||||
* Explanation: even more privacy; scripts and other addresses are indistinbuishable
|
||||
* Reference: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki
|
||||
* Reference: https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki
|
||||
* New Subsection Y.3: Creating a Taproot Script
|
||||
* New Subsection: Defining a Taproot Script
|
||||
* Explanation: Segwit v1, 32-byte program, not P2SH wrapped, leaf version is 0xc0
|
||||
* New Codes: OP_CHECKSIGADD and OP_SUCCESS
|
||||
* Cut Codes: OP_CHECKMULTISIG and OP_CHECKMULTISIGVERIFY
|
||||
* Reference: https://twitter.com/pwuille/status/1459778730369368067
|
||||
* New Subsection Y.4: Importing a tr Desciptor
|
||||
* New Subsection Y.5: Using Taproot in Practice
|
||||
* New Subsection: Making a Taproot Payment
|
||||
* New Subsection: Validating a Taproot Script
|
||||
* Update Chapter 9 to Integrate with Taproot
|
||||
* Mention Taproot in 9.1 or 9.2
|
||||
* Add New Section 9.6: Scripting a P2TR (mostly a pointer to Chapter Y)
|
||||
|
||||
## Further Updates
|
||||
|
||||
The following updates could be part of v3.0 or could be further future, depending on interest and funding.
|
||||
|
||||
1. New Graphics: Animated GIFs for key demos.
|
||||
* Reference: https://github.com/faressoft/terminalizer
|
||||
1. New Chapter: Talking to Lightningd with C (after chapter 20)
|
||||
* 22.1: Creating a Lightning Channel with C
|
||||
* 22.2: Creating a Payment Request with C
|
||||
* 22.3: Paying an Invoice with C
|
||||
* 22.4: Closing a Lightning Channel with C
|
||||
* Alternatives: Consider Swift instead of C, depending on Lightning support
|
||||
* Reference: https://diyhpl.us/wiki/transcripts/blockstream-webinars/2019-07-31-rusty-russell-getting-started-with-c-lightning/
|
||||
* Reference: https://twitter.com/roasbeef/status/1389649064753471488_
|
||||
|
||||
|
113
TRANSLATING.md
Normal file
113
TRANSLATING.md
Normal file
@ -0,0 +1,113 @@
|
||||
# Translating Learning Bitcoin from the Command Line
|
||||
|
||||
Thank you for your interest in translating Learning Bitcoin from the Command Line! What follows is our standard procedure for doing so. If you have any questions, please file an Issue.
|
||||
|
||||
1. **Please Follow Our Normal Contributor Procedure.**
|
||||
* Read over [CONTRIBUTING.md](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/CONTRIBUTING.md).
|
||||
* Fill out a [Contributor License Agreement](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/CLA.md), sign it with GPG, and submit it as a PR. Be sure this is done for everyone who contributes to the translation.
|
||||
1. **Choose a Release.**
|
||||
* Choose a [Release](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/releases) as the basis of your translation. We generally suggest the latest release. This will ensure the consistency of all the files in your translation, will insulate you from any changes we make, and will make it easy to see what has changed when we create a new release.
|
||||
* If it looks like there hasn't been a new Release in a while, file an Issue saying you're interested in starting a new translation, and asking if it would make sense for there to be a new Release milestone before you do so. If there's been anything notable, and we're not in the middle of things, we'll likely create a new patch or minor version. If we're in the middle of things, we'll just suggest you use the previous Release.
|
||||
* Label your table of contents and each chapter or section with the release used.
|
||||
1. **Request a Branch.**
|
||||
* File an [Issue](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) requesting a new branch for your translation.
|
||||
* This will be the master place for us to collect work on the translation over time.
|
||||
* We will create a top-level directory for your complete translation using the [ISO 639-1 language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), for example `es` (Spanish), `fr` (French), or `pt` (Portuguese). Work should be done in that directory.
|
||||
1. **Fork the Branch.**
|
||||
* Once we've created a translation branch, you'll then want to fork that into your own GitHub account.
|
||||
* Generally, we suggest that you create one working branch off that translation branch for each separate chapter. This will allow you to work through the process of write/review/revise for each individual chapter without it getting tangled up with your new content for future chapters, and will allow us to merge the chapters as they're completed, which is our preference, and will help everyone to keep track of where things our.
|
||||
* Make sure you [sign your commits](https://docs.github.com/en/github/authenticating-to-github/managing-commit-signature-verification/signing-commits).
|
||||
1. **Submit PRs a Chapter at a Time.**
|
||||
* Submit your PRs for the translation from your working fork to our translation branch in batches of no more than a single chapter at a time.
|
||||
* Submit in smaller batches if it makes sense, for example because different people are writing different sections.
|
||||
* Again, we suggest that there be a branch for each chapter, so when you submit your PR for one chapter, you'll usually then create a branch for the next chapter.
|
||||
1. **Request Approval from a Native Speaker.**
|
||||
* No one can ever do a great edit of their own work, so we require each section to be approved by someone other than the original translator.
|
||||
|
||||
* This fundamentally means that any translation team _should_ contain at least two members, either one translator and one editor or else two people who trade off roles of translator and editor. If your team doesn't have a second member, we can put out a call for an editor/approver when you submit a PR, but it's possible that we won't be able to find one, and your hard work will languish, so it's s better to have one up front.
|
||||
|
||||
* To make the editing and reviewing process easier, independent, and streamlined, we suggest that you and the reviewer [request access to each other's forks](https://docs.github.com/en/enterprise-server@3.0/github/setting-up-and-managing-your-github-user-account/managing-access-to-your-personal-repositories/inviting-collaborators-to-a-personal-repository). Once invited, the _reviewer_ can then:
|
||||
|
||||
1. Easily checkout the PR into their local machine with [GitHub CLI](https://cli.github.com/) by doing `gh pr checkout <pr-number>`. This will automatically create a branch with the PR code for the reviewer to work on.
|
||||
|
||||
2. Then, perform their changes with signed commits.
|
||||
|
||||
3. And do `git push` after finishing the review to have the changes reflected in the PR.
|
||||
1. **Request Approval from the Blockchain Commons Team.**
|
||||
* Once a chapter or section has been approved by a native speaker, request approval from someone on the Blockchain Commons team: currently [@shannona](https://github.com/shannona).
|
||||
1. **Continue!**
|
||||
* Continue through the process, no more than one chapter at a time, until you have a full book.
|
||||
* Be aware of the scope of the overall project. As of v2.01, Learning Bitcoin from the Command Line is 120,000 words in length. As a book, that'd be 250-400 pages, depending on the format and layout. (About 90,000 words of that is text to translate, with the remainder being code.) You want to make sure you have the time for that level of commitment before getting started.
|
||||
1. **Let Us Know When You're Done.**
|
||||
* When you've completed your translation, file an issue to let us know that the translation branch is ready to be merged into the master.
|
||||
* This will also let us know to announce the completed translation and link it into the master README
|
||||
1. **Update Your Translation with New Releases**
|
||||
* It is our hope that translations will stay up to day with new releases, particularly major and minor releases, which are likely to include new content and updates. Currently, these only occur ever few years
|
||||
* If you have decided to stop updating a translation, please let us know in an Issue, so that we can let the community know that we are looking for a new translator to continue updating a translation.
|
||||
|
||||
### WORKFLOW EXAMPLE
|
||||
|
||||
Chapter 3 has 7 subsections: 3.0, 3.1, 3.2, 3.3, Interlude 3.3, 3.4 and 3.5.
|
||||
Suppose you want to translate it to french.
|
||||
|
||||
One approach to its translation would be to create a branch `french-3` from
|
||||
`french-translation` branch (created in the previous step). Then create a
|
||||
translation file for the 3.0 subsection. When you think that chapter 3.0 is
|
||||
ready for review you commit your changes and continue with the next file,
|
||||
subsection 3.1. Repeat the same process for this file and all the following.
|
||||
After this, your branch `french-3` will diverge from the base branch
|
||||
(`french-translation` in this case) by 7 different commits, one for each
|
||||
subsection, plus some more commits if you forgot to make some changes or need
|
||||
to correct others. At this point you are ready to push your changes to your
|
||||
fork and open a pull request to the original repository.
|
||||
|
||||
In the review process you will discuss some decisions with your reviewer and
|
||||
introduce new changes in the form of commits if you have to change some parts
|
||||
of your modifications. Don't forget to commit those changes in meaningful
|
||||
chunks and push them to your fork. After polishing your changes, your reviewer
|
||||
will accept your changes and it will request the merge of those changes on the
|
||||
`french-translation` branch. Note that you can also push your changes and
|
||||
create your pull request after your first commit. This will allow the reviewer
|
||||
to start reviewing before you finish all chapter translation.
|
||||
|
||||
You can track the state of the translation of that particular chapter in the
|
||||
body of the pull request, with the following template:
|
||||
|
||||
```
|
||||
This pull request creates the <translated_language> version of the chapter
|
||||
<chapter_number> of Learning-Bitcoin-from-the-Command-Line.
|
||||
|
||||
Things to check:
|
||||
- Respect filenames and chapter names from translated [README](local/path/to/README).
|
||||
- Correct translation.
|
||||
- Term consistency: review ["translation memory"](local/path/to/file) file.
|
||||
- Good punctuation.
|
||||
- Correct linking.
|
||||
- Nice formatting.
|
||||
|
||||
| Sub chapter | Translated | Reviewed | Done |
|
||||
| ------------- | :--------------: | :--------------: | :--------------: |
|
||||
| _0_ | <ul><li> [ ] </li></ul> | <ul><li> [ ] </li></ul> | <ul><li> [ ] </li></ul> |
|
||||
| _1_ | <ul><li> [ ] </li></ul> | <ul><li> [ ] </li></ul> | <ul><li> [ ] </li></ul> |
|
||||
| _2_ | <ul><li> [ ] </li></ul> | <ul><li> [ ] </li></ul> | <ul><li> [ ] </li></ul> |
|
||||
| _3_ | <ul><li> [ ] </li></ul> | <ul><li> [ ] </li></ul> | <ul><li> [ ] </li></ul> |
|
||||
| _etc_ | <ul><li> [ ] </li></ul> | <ul><li> [ ] </li></ul> | <ul><li> [ ] </li></ul> |
|
||||
```
|
||||
|
||||
### FINAL SUGGESTIONS:
|
||||
- _Keep lines under 80 characters_. Markdown parser will format them right
|
||||
(double check that) and the review process will be easier.
|
||||
- _Translate `README.md` file first_ and use it as reference for the translation
|
||||
of all the following chapter names, filenames and link names. The README
|
||||
represents the state of the master branch at the moment of begin the
|
||||
translation process. It will be consulted by all translators to know how to
|
||||
translate file and chapter names. Try to reach an agreement with the other
|
||||
translators about those names before writing any chapter and keep further
|
||||
changes of this file to minimum.
|
||||
- _Create a "translation memory" file_ with special words that could have
|
||||
multiple translations under the same contexts and the translation chosen for
|
||||
them. Good candidates to be in this list would be domain specific words,
|
||||
like: multisig, input, output, script, timelock, locktime, hash, etc.
|
||||
|
||||
|
||||
Again, thank you!
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user